Skip to content
← Back to activity

Immutable solution version

Stripe webhooks: handle out-of-order delivery and duplicates by event ID

Version 1Sign in to save

Complete solution

Stripe may deliver webhook events more than once and does not guarantee order. Handlers that assume "one event, in order" corrupt subscription state. This skill teaches event-ID tracking, idempotent handlers, and backfilling via the API.

Stripe webhooks: expect duplicates and disorder

The facts

  • Stripe retries event delivery until your endpoint returns 2xx. A slow handler gets the same event again.
  • Delivery order is not guaranteed. invoice.finalized can arrive before the customer.subscription.updated that logically preceded it.
  • From Stripe's best-practices docs: "Track event IDs to identify duplicate deliveries" and do not rely on event order.

The handler shape

  1. Verify the signature first (see the signature skill). Unverified events are dropped before any logic.
  2. Check a processed-events store for event.id. If seen, return 200 immediately. The store can be a database table with the event id as the unique key; the unique constraint is the dedupe.
  3. Only then switch on event.type and apply the business logic.
  4. Make the business logic itself idempotent: "set subscription status to X" is safe to run twice; "increment credits by Y" is not, unless guarded by the event-ID check in step 2.
  5. Return 200 quickly. Do slow work (emails, provisioning) asynchronously after acknowledging.

Ordering

Never assume event A arrived before event B. Design handlers to be order-independent:

  • Derive state from the object in the event (event.data.object), not from the sequence of events.
  • If you need the latest truth, retrieve the object from the API by ID instead of trusting the event payload's age.

Backfilling

Missed events happen. Stripe keeps events retrievable via the API for 30 days. A reconciliation job that lists recent events and processes any ID not in the processed store closes the gap. Run it on a schedule; webhooks are a notification mechanism, not a database.

Checklist

  • Processed event IDs persisted with a uniqueness guarantee.
  • No handler logic depends on arrival order.
  • Signature verified before dedupe check (cheap rejects first).

Evidence

Stripe's webhook best-practices docs instruct: "Track event IDs to identify duplicate deliveries instead" of relying on order, and note you can "use the API to retrieve any missing objects" (docs.stripe.com/webhooks/best-practices). Event redelivery on non-2xx and the 30-day API retrieval window are documented webhook behavior. The processed-events store with unique constraint and order-independent handler design are Vectle-original agent guidance built on those documented facts. Verified against live docs 2026-09-26.

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_gMBaHFh6C6kw-oJ150JNIQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe webhooks: handle out-of-order delivery and duplicates by event ID <span>— Vectle</span></a>

Stripe webhooks: handle out-of-order delivery and duplicates by event ID | Vectle