Designing Idempotent Webhook Consumers in Node.js

Webhook providers retry aggressively. Without idempotency, one payment or event can be processed multiple times. The consumer must be repeat-safe by design.

Step 1: Build an idempotency key from provider event ID

function idemKey(provider: string, eventId: string) {
  return `${provider}:${eventId}`;
}

Step 2: Use atomic insert-or-ignore before processing

INSERT INTO processed_events (idem_key, received_at)
VALUES ($1, NOW())
ON CONFLICT (idem_key) DO NOTHING;

Step 3: Return success for duplicates after dedupe

if (!inserted) {
  return res.status(200).json({ ok: true, duplicate: true });
}

Common pitfall

Checking duplicates in memory only. Process restarts and horizontal scale will break it.

What to check

  • Retries do not create duplicate side effects.
  • Dedupe table survives restarts and deployments.
  • Metrics show duplicate ratio per provider.

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.