Reliability
Your Checkout Works. Is Your Billing State Production-Ready?
A successful checkout proves one transaction can complete. Production billing must also survive forged, duplicated, delayed and partially processed events.

A successful Stripe checkout proves that one transaction can complete. It does not prove that your application's billing state is correct.
The difference matters as soon as payment changes something valuable: a subscription, credits, an order, a seat count, an AI allowance or access to a paid feature.
The webhook is a trust boundary
A Stripe webhook endpoint is public by design. Your application therefore needs to establish that an incoming event really came from Stripe before it changes business state.
Stripe's current guidance says to verify the signature using the raw request body, the Stripe-Signature header and the webhook signing secret. Parsing JSON and trusting event.type is not equivalent to verifying the sender.
That is the first gate. It is not the whole design.
Delivery is not the same as business correctness
Production payment flows are state machines. The interesting cases are rarely the first successful checkout:
- the same event is delivered more than once;
- events arrive in an order your code did not expect;
- a renewal fails;
- a customer cancels;
- an update succeeds in Stripe but your database write fails;
- your handler times out after doing half the work;
- the event is valid, but applying it twice would duplicate credits or fulfilment.
A handler can return 200 and still leave the business in the wrong state.
Design the billing path around invariants
The goal is not to add infrastructure because the diagram looks more 'production'. The goal is to make a few important statements reliably true.
1. Only trusted events change billing state. Verify signatures before any entitlement or order mutation.
2. Replaying the same event is safe. Store the provider event ID behind a uniqueness constraint or equivalent durable deduplication mechanism. Business mutations should be idempotent too.
3. Entitlements come from an explicit state model. Avoid scattering isPro = true writes across checkout redirects, webhook handlers and UI callbacks.
4. Slow work does not hold the webhook open unnecessarily. Validate, durably record/enqueue, acknowledge, then process work with observable retry behaviour where the workload justifies it.
5. You can detect drift. For products where billing state matters, reconcile your local subscription/entitlement state against Stripe periodically or when suspicious transitions occur.
What is fine at MVP stage?
You do not need Kafka, five queues and an event-sourcing programme to sell your first subscription.
A small SaaS can be production-sensible with a verified webhook, a processed-events table with a unique event ID, a clear subscription/entitlement model, structured logs and a lightweight reconciliation job. Add queues and dead-letter handling when processing time, traffic or operational consequences justify them.
The architectural decision is not 'microservices or monolith'. It is where the source of truth lives, how external events are authenticated, and how repeated or missed events affect state.
A practical production check
Before trusting billing, test more than 'card succeeds':
- Send the same valid event twice. Does the outcome change twice?
- Send an invalidly signed event. Is it rejected before mutation?
- Simulate a failed renewal. Does access reach the intended state?
- Cancel in Stripe rather than inside your app. Does local state converge?
- Fail the database write after receipt. Can the event be safely retried?
- Compare a sample of Stripe subscriptions with your local entitlements. Can you explain every mismatch?
These tests reveal more about production readiness than another successful checkout demo.
Sources
- Stripe AI webhook guidance
- May 2026 community webhook probe
- June 2026 SaaS billing-review discussion
- August 2026 AI integration verification discussion
What's next for you?
If payments already change customer access or fulfilment, map the full path from Stripe event to business state and test the failure paths deliberately. The Architecture Check can help identify where trust, retry and state-convergence assumptions are hiding.
