Payments Preflight · Check 3 of 15

Handle events that arrive out of order

Stripe does not guarantee webhook events arrive in the order they were created. Fetch the current object from the API instead of trusting event order.

What it is

Stripe doesn't guarantee the delivery of events in the order they are generated. A subscription update can arrive before the create, and an invoice event before the subscription event.

Why it matters

If your code applies events in arrival order, a late, older event can overwrite newer state, for example marking an active customer as incomplete.

How to check

How to fix it

  1. On each relevant event, retrieve the latest object from the API (for example stripe.subscriptions.retrieve(id)) and save that.
  2. Write handlers so any event can arrive first and still produce correct state.
  3. Use the API to retrieve any objects an event references that you have not seen yet.
case "customer.subscription.created":
case "customer.subscription.updated":
case "customer.subscription.deleted": {
  const sub = await stripe.subscriptions.retrieve((event.data.object as Stripe.Subscription).id);
  await saveSubscription(sub); // write current state, not the event snapshot
}

Prompt for your AI coding tool

Paste into Cursor, Claude Code, Lovable or similar. Review the diff before you accept it.

My Stripe webhook handler assumes events arrive in order. Change it so that for subscription, invoice and checkout events it retrieves the current object from the Stripe API and saves that state, and works no matter which event arrives first. Do not use event.created for ordering. Show the diff.

Sources

All payments checks

Sponsor this page: get in touch.

Get new checks by email

New checks and real leak post-mortems, about once a month. No spam.