Building Resilient Stripe Webhook Ingestion for SaaS BillingBuilding Resilient Stripe Webhook Ingestion for SaaS Billing
The network for creativity
Join 1.25M professional creatives like you
Connect with clients, get discovered, and run your business 100% commission-free
Creatives on Contra have earned over $150M and we are just getting started
One of the worst bugs you can ship in a SaaS is charging a customer's card and leaving their account locked.
It happens way more often than founders admit. A user finishes Stripe checkout, their bank sends an SMS that money was deducted, but your dashboard still shows "Free Plan". Three minutes later, an angry support ticket lands in your inbox.
The checkout page itself almost never fails. What breaks is what happens three seconds later in the webhook handler.
Most rushed setups try to do everything inside that incoming HTTP request: verify the Stripe signature, query the database, provision team seats, create default settings, and trigger a welcome email. If an external API stutters or the database query hangs for three seconds, Stripe times out and retries the delivery.
If your code doesn't guard against duplicate events, those retries run the same queries twice. Suddenly you have duplicate customer records or corrupted workspace state.
When building PulseMetrics, I stripped the webhook handler down to two strict principles:
First, return a 200 OK fast. The route does nothing except verify the cryptographic signature, save the raw payload to an audit queue, and close the connection in under 40ms. Never let heavy business logic run on the webhook listener thread.
Second, wrap database updates in an atomic transaction keyed directly on Stripe's event ID. If that ID is already flagged as processed in the database, the transaction aborts instantly without touching customer records.
The other trap engineers overlook is event arrival order. Stripe does not guarantee that events arrive chronologically. In production, invoice.payment_succeeded can arrive before customer.subscription.created. If your database schema assumes linear arrival, foreign key lookups fail. You have to decouple invoice state from initial subscription provisioning and reconcile based on event timestamps, not receipt order.
Wiring up a Stripe checkout button takes an afternoon. Engineering resilient webhook ingestion that survives network drops, concurrency, and out-of-order events is what actually keeps a SaaS running.
Post image
Back to feed
The network for creativity
Join 1.25M professional creatives like you
Connect with clients, get discovered, and run your business 100% commission-free
Creatives on Contra have earned over $150M and we are just getting started