Replay-safe payment webhook fulfillment in Next.js
The risky part of paid checkout is not only signature verification. It is the moment a paid event sends a private ZIP, license key, email, or entitlement. Build fulfillment so provider retries cannot repeat the delivery.
Replay-safe fulfillment flow
Read await request.text(), verify the provider signature, and reject mutated raw bodies before looking at paid fields.
Confirm event type, paid status, expected product or variant, amount, currency, and customer mapping before delivery starts.
Create a unique fulfillment row keyed by provider object ID, line item, and delivery action before sending email or creating a license.
Store delivery timestamp, checksum, template version, support note, and rollback state without exposing API keys or private download URLs.
Next.js handler shape
Keep external side effects behind a process-once guard. A repeated provider event should hit the same fulfillment record and return success without repeating delivery.
export async function POST(request: Request) {
const rawBody = await request.text();
const signature = request.headers.get("x-signature");
const event = verifyPaymentEvent(rawBody, signature);
assertPaidVariant(event, "billing-webhook-kit-pro");
await runOnce(`fulfill:${event.provider}:${event.orderId}`, async () => {
await deliverPrivateZip({
orderId: event.orderId,
customerId: event.customerId,
checksum: PRO_KIT_SHA256
});
});
return new Response("ok", { status: 200 });
}
Tests before checkout traffic
- Signed paid event creates one fulfillment row and one delivery evidence record.
- The same event replayed three times skips email, license, ZIP, and entitlement side effects after the first run.
- Wrong variant, unpaid status, wrong currency, or mutated raw body never reaches delivery code.
- Delivery failure records a retryable state without granting access twice.
- Refund rollback can revoke or mark the fulfillment record without deleting audit evidence.
FAQ
How do you make webhook fulfillment replay-safe?
Verify the raw-body signature, confirm the paid state and expected variant, derive an idempotency key from the provider object, acquire a delivery lock, run fulfillment once, then record checksum and delivery evidence.
Should duplicate paid webhooks resend download emails?
No. Duplicate paid events should return success after confirming the fulfillment record already exists. Resends should be a separate support path with explicit buyer evidence and rate limits.
Turn fulfillment safety into launch evidence
The free fulfillment checklist and idempotency tools cover the delivery path. The CNY 69 Pro Kit is for teams that want copy-ready fixtures, replay tests, delivery evidence templates, and rollback notes already packaged.