Automating Your Business with Webhook-Driven Crypto Payments
Webhooks are how you stop babysitting your payments.
Normally, when someone sends you money, you have to keep checking: “Did it arrive? Is it confirmed? Should I ship the order yet?” It’s like standing at a window watching for the mailman when you could just get a notification instead.
That’s where webhooks come in. With a crypto payment webhook, your system gets an instant nudge the moment a stablecoin payment confirms. No polling. No delays. No manual intervention. Your app just knows and acts automatically.
Let’s talk about why this matters for your business, and how to build it.
Why webhooks beat traditional polling
When you poll — hitting an API endpoint every 10 seconds to ask “is the payment done yet?” — you’re wasting resources and introducing latency. You’re also increasing your API costs, which adds up fast if you have hundreds of customers.
Webhooks flip the model. Plirin watches the blockchain and tells you when something happens. Your endpoint receives an HTTP POST with all the details. It’s instant, efficient, and cheap.
Think about a typical e-commerce flow:
- Customer clicks “Pay with USDC”
- They send the payment
- Webhook fires immediately when the transaction confirms
- Your system processes the webhook and automatically:
- Marks the order as paid in your database
- Triggers order fulfillment
- Updates accounting records
- Sends a confirmation email to the customer
- Updates inventory
All of that happens in seconds, without a single human touch. That’s automation.
Setting up your webhook endpoint
Plirin’s webhook system is straightforward. Here’s what you need to do:
In the Plirin dashboard:
- Go to Settings → Webhooks
- Click Add Endpoint
- Enter your server’s URL (e.g.,
https://yourapp.com/webhooks/plirin) - Choose which events to listen for (we’ll cover those in a moment)
- Save it and copy your signing secret — keep this safe in your environment variables
On your server: Your endpoint needs to:
- Accept POST requests with
Content-Type: application/json - Verify the webhook signature (super important — we’ll show you how)
- Return a
200status to tell Plirin you got it - Process the event data and trigger your workflows
Verifying webhook signatures
Here’s the thing: anyone could pretend to be Plirin and send your endpoint fake payment confirmations if you’re not careful. That’s why every webhook includes a cryptographic signature.
Plirin signs each webhook with your secret key using HMAC-SHA256. Your job is to verify that signature before trusting the data.
The signature comes in the X-StableX-Signature header and looks like this:
X-StableX-Signature: t=1234567890,v1=abcd1234...
Here’s how to verify it in Node.js:
const crypto = require("crypto");
function verifyWebhook(secret, sigHeader, bodyBuffer, maxSkew = 300) {
const parts = Object.fromEntries(
sigHeader.split(",").map((p) => p.split("=", 2))
);
const ts = parseInt(parts.t, 10);
// Check timestamp isn't too old (prevent replay attacks)
if (Math.abs(Math.floor(Date.now() / 1000) - ts) > maxSkew) return false;
// Compute expected signature
const expected = crypto
.createHmac("sha256", secret)
.update(`${ts}.${bodyBuffer}`)
.digest("hex");
// Compare safely to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1)
);
}
Or in Python:
import hashlib, hmac, time
def verify_webhook(secret, sig_header, body, max_skew=300):
parts = dict(p.split("=", 1) for p in sig_header.split(","))
ts, v1 = int(parts["t"]), parts["v1"]
if abs(int(time.time()) - ts) > max_skew:
return False
expected = hmac.new(
secret.encode(),
f"{ts}.".encode() + body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, v1)
Always verify before processing. This is non-negotiable.
What events can you listen for?
Plirin sends webhooks for several event types. Here are the most useful for automation:
| Event | What it means | Your action |
|---|---|---|
payment.completed | A stablecoin payment confirmed on-chain | Ship the order, send receipt, update accounting |
payment.failed | A payment attempt didn’t go through | Notify the customer, offer retry |
invoice.paid | An invoice was paid | Mark paid in your system, trigger fulfillment |
invoice.overdue | An invoice passed its due date | Send reminder, flag for follow-up |
refund.completed | A refund was processed | Update order status, adjust inventory |
customer.created | A new customer was added | Trigger welcome flow, initialize CRM record |
When a webhook fires, you receive a JSON payload with all the details:
{
"event": "payment.completed",
"data": {
"id": "pay_12345",
"amount": "50.00",
"token": "USDC",
"blockchain": "solana",
"transactionHash": "5xK9...",
"merchantId": "456",
"createdAt": "2026-06-02T12:00:00Z"
}
}
Three real workflows you can automate
1. Instant order fulfillment
When a payment.completed webhook hits:
app.post("/webhooks/plirin", (req, res) => {
if (!verifyWebhook(process.env.PLIRIN_SECRET, req.headers["x-stablex-signature"], req.rawBody)) {
return res.status(401).send("Unauthorized");
}
const { event, data } = req.body;
if (event === "payment.completed") {
// Mark order as paid in your database
Order.update({ id: data.orderId }, { status: "paid" });
// Trigger fulfillment (send to warehouse, print label, etc.)
triggerFulfillment(data.orderId);
// Notify the customer
sendConfirmationEmail(data.customerId);
// Update accounting
logTransaction(data);
}
res.send(200);
});
Your customer receives a shipping confirmation before you even finish typing the invoice. No manual work.
2. Accounting sync
Every payment webhook can automatically sync to your accounting software:
if (event === "payment.completed") {
const transaction = {
amount: parseFloat(data.amount),
currency: data.token,
date: data.createdAt,
reference: data.transactionHash,
};
// Post to QuickBooks, Xero, Wave, etc.
await accounting.createEntry(transaction);
}
Your books stay up-to-date without manual data entry. No reconciliation headaches.
3. Smart notifications
Send the right message at the right time:
if (event === "invoice.overdue") {
// Send payment reminder
await email.send({
to: data.customerEmail,
template: "invoice_reminder",
data: { invoiceId: data.id, amount: data.amount }
});
}
if (event === "payment.failed") {
// Offer a retry link
await slack.notify(`Payment failed for ${data.customerId}. Check details.`);
}
Your team gets alerts when they matter. Your customers get reminders before it becomes an issue.
Handling retries and reliability
Webhooks don’t always deliver on the first try. Networks are messy.
If your endpoint doesn’t return a 200 status within 30 seconds, Plirin retries with exponential backoff:
- Attempt 1: immediately
- Attempt 2: 1 minute later
- Attempt 3: 5 minutes later
- Attempt 4: 30 minutes later
- Attempt 5: 2 hours later
After 5 failures, the delivery is marked as failed and you can manually replay it from the dashboard.
Pro tip: Use the X-StableX-Delivery-ID header to deduplicate webhooks. Store which delivery IDs you’ve processed so if a webhook arrives twice (it happens), you don’t double-process the order.
if (await isDeliveryProcessed(req.headers["x-stablex-delivery-id"])) {
return res.send(200); // Already handled, just ack it
}
// Process the webhook...
markDeliveryProcessed(req.headers["x-stablex-delivery-id"]);
Crypto payments and webhooks: A natural fit
Stablecoin payments move fast. A transaction confirms in seconds (especially on Solana), unlike traditional payment processors that batch settlements every 24 hours. Webhooks let you take advantage of that speed.
If you’re already accepting stablecoins, webhooks are how you unlock the real benefit: instant settlement means instant automation. Read more about how to accept USDC payments if you haven’t set that up yet, or check out how stablecoins compare to Stripe for a deeper look at the advantages.
For teams handling recurring revenue, webhooks power stablecoin-based recurring billing too.
Getting started
Setting up webhooks takes about 15 minutes. You don’t need to be a senior engineer — if you can handle a simple HTTP endpoint and basic cryptography, you’ve got this.
The real win happens when you realize your entire fulfillment chain is now running itself. No manual payments to chase. No accounting backlog. No “wait, did we ship this?” moments.
Ready to automate your payment workflows? Sign up for Plirin and configure your first webhook endpoint. Start with the free Starter tier at just 1.5%, or jump to Growth ($49/mo + 1.3%) if you’re processing higher volumes.
Check out Plirin’s pricing or join the waitlist to get started.