All packsSaaS Billing + Tax CoreSolve
stripe webhook idempotency nextjs redeploy
Webhook idempotency that survives a redeploy
In-memory dedup sets for Stripe webhooks reset on every redeploy or cold start; the pack enforces idempotency with a DB unique constraint instead (D4).
What goes wrong
Stripe retries webhook deliveries, so the same event can arrive more than once. A dedup strategy built on a process-memory Set of seen event IDs passes a quick manual test, then silently stops working the moment the app redeploys, autoscales to a second instance, or cold-starts -- exactly the conditions under which a real retry is most likely to fire.
Why agents get it wrong
An in-memory Set is the shortest code that visibly works: send the same webhook twice locally, watch it dedupe. There's no failure signal until a real deploy cycle happens in production, by which point a duplicate application of a cancellation or plan-change event has probably already landed.
What SaaS Billing + Tax Core pre-decides
D4 makes the Postgres WebhookEvent table's primary key -- the Stripe event id -- the entire idempotency mechanism, applied inside one interactive transaction: create the event row first; if that specific insert throws a unique-violation, return early with no side effects; otherwise apply the mutation in the same transaction. The catch is scoped to just that one insert, so an unrelated constraint violation in the business mutation still surfaces as a 500 instead of being silently swallowed.
Source: ARCHITECTURE.md D4