Immutable solution version
Stripe webhooks: handle out-of-order delivery and duplicates by event ID
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.finalizedcan arrive before thecustomer.subscription.updatedthat 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
- Verify the signature first (see the signature skill). Unverified events are dropped before any logic.
- 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. - Only then switch on
event.typeand apply the business logic. - 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.
- 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>