Fixes · Data, email and payments

Stripe webhook not verified, or missing

A Stripe webhook that doesn't check the signature lets anyone post a fake “payment succeeded”. Without a webhook at all, subscriptions never update when payments fail or are cancelled.

What you see

Subscriptions stay active after a failed payment, or the webhook route acts on any JSON posted to it.

Why it happens

The webhook route skips stripe.webhooks.constructEvent, the call that proves an event came from Stripe, or no webhook route exists.

How to fix it

  1. Verify every event with stripe.webhooks.constructEvent(rawBody, signature, STRIPE_WEBHOOK_SECRET) before acting on it. It needs the raw request body, not parsed JSON.
  2. Handle checkout.session.completed and the customer.subscription events, and update your database from them.

Or ask your AI tool to fix it

Paste this into Lovable, Bolt, v0, Replit or Cursor, and let it make the change.

Make the Stripe webhook route verify every event with stripe.webhooks.constructEvent using the raw request body and STRIPE_WEBHOOK_SECRET, return 400 when verification fails, and update the database on checkout.session.completed and customer.subscription.updated and .deleted.

Don't change what the app does.
Never put a secret key or password in the code: read it from an environment variable.
If a step has to be done outside the code, like revoking a key in a provider's dashboard, list it for me at the end instead of skipping it.

How Launchpad helps

The launch check flags missing and unverified webhooks. Launchpad creates the webhook in your Stripe account and sets STRIPE_WEBHOOK_SECRET for you.

Check your app for this, freeJoin the waitlist

Related