Webhook Best Practices
1. Respond Fast
Acknowledge immediately, then process async.
app.post('/webhooks/zkp2p', (req, res) => {
res.status(200).send('OK');
void processWebhook(req.body);
});
2. Verify Signature + Timestamp
Reject forged or replayed requests before processing.
3. Enforce Idempotency
Use X-Webhook-Id as your idempotency key.
if (await isProcessed(eventId)) return;
await markProcessed(eventId);
4. Upsert by Checkout Order ID
Prefer data.order.id as the authoritative external reference.
5. Handle Retries + Reordering
Events can arrive more than once and not strictly in order. Persist latest known status and ignore stale transitions.
6. Log Structured Context
Include eventId, type, orderId, and processing duration in logs.
7. Monitor Delivery Health
Track failure rates and response latency for your webhook endpoint.
Checklist
- Signature verified
- Timestamp checked
- Idempotency enforced
- Fast 2xx response
- Async processing
- Order-level reconciliation