Incident pattern

Customer paid, success page loaded, order never created

The charge is there in Stripe and the customer reached your success page, but their account was never upgraded and no order row exists. It works every time you test it and fails for a fraction of real customers.

  • Any stack
  • Bubble
  • Lovable
  • Bolt
  • Webflow
  • Checkout & payments
  • Webhooks

Root cause, in plain English

Redirecting the browser to your success page and delivering the webhook that fulfills the order are two independent events. The redirect is usually faster. If your success page reads an order that only the webhook creates, it will sometimes look before anything has been written — and if fulfillment happens only on the page the customer might close, a customer who closes the tab is never fulfilled at all.

How to fix it

  1. Decide on one source of truth for fulfillment: the webhook. The success page reports on state, it must never be the only thing that creates it.

  2. Make the success page tolerate a missing order — show a pending state and poll briefly — instead of erroring or showing an empty account.

  3. Verify the webhook signature and return quickly, doing slow work asynchronously so deliveries are not retried because your handler timed out.

  4. Make fulfillment idempotent by keying on the payment or session identifier, so a redelivered event upgrades the account once rather than twice.

  5. Reconcile on a schedule: list recent successful payments and confirm each has a matching fulfilled order, repairing any that slipped through.

Go deeper: the full guide to a checkout that won't load.

How Nightlamp detects this automatically

  • Account lifecycle
  • Browser journey
  • API canary

A stateful_journey is the check that matches this failure, because the question is not whether a page loaded but whether an account actually changed state after payment. It runs the purchase path and then asserts the entitlement exists. A browser_journey catches the checkout flow breaking outright, and an api_canary on the webhook endpoint proves deliveries are still being accepted.

Catch this before your customers do

Nightlamp runs these checks continuously against your live app and sends a plain-English diagnosis — not a wall of logs — the moment this pattern shows up.

Frequently asked questions

Why does it only affect some customers?
It is a race, so it depends on timing you do not control: webhook delivery latency, the customer's network, and how fast they land on the success page. Testing on a fast connection with a warm endpoint hides it almost perfectly.
Can I just fulfill on the success page instead?
That trades a rare race for a guaranteed loss. Any customer who closes the tab, loses signal, or gets redirected away after paying never runs that code, and you have taken money without delivering anything.
How do I find customers this already affected?
Reconcile payments against fulfilled orders over the period in question. The mismatch list is exactly the set of customers who paid and got nothing — fix them manually, then keep the reconciliation running as a scheduled safety net.

Newsletter

Get new incident patterns as we publish them

One email when new failure patterns, fixes, and monitoring recipes for no-code and AI-built apps land. No fluff, unsubscribe any time.

Double opt-in. One-click unsubscribe. No spam, ever.