Payments stop after a deploy

Checkout reaches the pay step and stalls, or orders never show as paid — and it started right after a publish.

Why it happens

A deploy dropped STRIPE_WEBHOOK_SECRET from the production environment, or set it for preview but not production. Stripe signs every webhook it sends; without the secret your app rejects them as “signature verification failed”, Stripe retries for up to three days, then disables the endpoint. Orders now stop at the payment step because the app waits for a confirmation that never arrives.

How to tell

  • Stripe › Developers › Webhooks shows deliveries failing with HTTP 400, and after about three days the endpoint marked disabled.
  • Server errors reading “Webhook signature verification failed”, first seen minutes after the deploy.
  • The deploy's environment diff shows the key removed or renamed — key names only; values are never in a diff.
  • Zero payments in hours where the same hour of the week usually brings some.

The fix

  1. Add STRIPE_WEBHOOK_SECRET back to the production environment on your host. The value is under Stripe › Developers › Webhooks › your endpoint › Signing secret. Redeploy, because environment variables are read at build or start.
  2. In Stripe, re-enable the endpoint if it was disabled, then send a test event and confirm the app answers 200.
  3. Make the webhook route fail loudly when the secret is missing: return 400 with “webhook secret not configured” instead of throwing inside the signature check, so the next time this happens the error names itself.
  4. Run your checkout once more, end to end, and watch one real payment through.

Where to look

The prompt for your builder

Paste this into Lovable, Bolt, Cursor, Claude Code or whatever built the app. Replace anything in capitals. It never asks you to paste a secret into a chat; keys go into your host’s environment, by you.

Prompt for your builder
The Stripe webhook secret is missing from my production environment after a deploy. Tell me exactly where to set STRIPE_WEBHOOK_SECRET on my host for production (not preview) — I will paste the value there myself, not here. Then change the /api/stripe/webhook route so that when the secret is missing it returns a clear 400 with the message “webhook secret not configured” and logs it, instead of failing inside the signature check.

How Keelnest catches it

Revenue Guard compares each hour's payments with the same hour of the week over the last 28 days, so a quiet checkout is noticed within a couple of hours, once the first seven days have taught it what normal looks like. Publish Verification re-runs the checkout journey within five minutes of every deploy and reads the environment key names of each publish, so the removed key is named in the evidence rather than guessed at.

Know the moment this happens.

Keelnest watches your production app every five minutes and tells you in plain English what broke — with the fix. Free for your first app.

Related