All posts
2026-07-18FlareStarter Teamengineeringstripecloudflare

Idempotent Stripe webhooks on Cloudflare Workers

Stripe retries, replays, and out-of-order events are not edge cases — they are the normal case. Here is the pattern FlareStarter Pro uses to make every money flow replay-safe.

Stripe delivers webhooks at least once. Retries after timeouts, manual resends from the dashboard, and events arriving out of order are all normal operation — so a handler that is merely correct on the happy path will eventually double-grant credits or double-activate a subscription in production.

FlareStarter Pro treats this with one rule: every mutation a webhook can trigger carries an idempotency ref.

The ledger pattern

Credits move through an append-only ledger. Every grant derives its ref from the event that caused it:

// topup: the checkout session id — a resend of the same session is a no-op
await grantCredits(db, { orgId, amount, reason: 'topup', ref: `topup:${session.id}` })

// subscription cycle: the invoice id
await grantCredits(db, { orgId, amount, reason: 'grant', ref: `orgsub:${invoice.id}` })

grantCredits inserts the ledger row with a unique index on ref and swallows the conflict. Replays are free — no distributed locks, no "did we process this event" table to garbage-collect.

Spends are conditional, not read-then-write

The other half is never reading a balance and writing it back. Spends are a single conditional UPDATE ... WHERE balance >= amount; if it affects zero rows, the spend failed. Two concurrent requests cannot overdraw because the database, not the application, arbitrates.

Branch order is part of the contract

One endpoint receives everything, so metadata-tagged flows (org subscriptions, credits top-ups) must be intercepted before the generic billing branch — upstream billing treats every customer.subscription.* event as a personal-plan upsert. The branch order is documented in the repo and enforced by tests, because it is exactly the kind of invariant a refactor silently breaks.

All of this ships wired and tested in FlareStarter Pro — 80+ replayed test events, all green.