Every major enterprise platform (Stripe, PayPal, GitHub, Twilio) operates under at-least-once delivery semantics. If a network glitch or temporary database lock delays an HTTP 200 response, the provider's retry runner will resend the identical webhook payload minutes or seconds later.
Without robust idempotency guards, duplicate orders are minted, subscription tiers are toggled inconsistently, and customers are charged multiple times.
Cryptographic Verification & Replay Protection
Before parsing webhook bodies, systems must verify the HMAC-SHA256 cryptographic signature and reject requests with timestamp drift exceeding 300 seconds:
export async function verifyWebhookSignature(
payload: string,
headerSignature: string,
secret: string
): Promise<boolean> {
const encoder = new TextEncoder();
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
);
return crypto.subtle.verify('HMAC', key, hexToBuffer(headerSignature), encoder.encode(payload));
}
Atomic Compare-And-Swap (CAS) Deduplication
To prevent race conditions when twin webhooks arrive at separate edge nodes simultaneously, the system claims execution atomically:
INSERT INTO payment_idempotency (idempotency_key, status, locked_until)
VALUES (?, 'processing', datetime('now', '+30 seconds'))
ON CONFLICT(idempotency_key) DO UPDATE SET
status = CASE WHEN locked_until < datetime('now') THEN 'processing' ELSE status END
RETURNING status;
If the claim fails or the status is already 'settled', the duplicate invocation exits immediately with HTTP 200, protecting business invariants.
Zero Locks Held During Third-Party Network I/O
Processing webhooks often requires notifying customers, firing internal alerts, or executing follow-on accounting entries. SazM decouples these side effects:
// Acknowledge webhook in < 20ms
await claimIdempotencyKey(d1, eventId);
await env.OUTREACH_QUEUE.send({ type: 'payment_settled_notification', eventId });
return Response.json({ received: true });