Short, sourced fixes for the bugs that make customers pay and not get access. Every claim links to the official docs.
Why Stripe events never reach your app (redirects, auth walls, wrong secret, slow handlers) and how to confirm each one in minutes.
If buyers pay through Stripe Checkout but your app never unlocks, fulfillment is probably tied to the success page or a failing webhook. Here's the fix.
"No signatures found matching the expected signature for payload" almost always means a parsed body or the wrong whsec_ secret. Fixes for Next.js, Express, Supabase.
A 307/308 in your Stripe delivery log means your URL redirects (www, https or trailing slash). Stripe counts redirects as failures. Use the final URL.
If your Lovable or Bolt app uses Supabase Edge Functions for Stripe, 401 errors mean JWT verification is on, and signature errors need constructEventAsync.
Going live with the test whsec_ (or the Stripe CLI secret) makes every real payment fail verification. How to spot it and switch safely.
Stripe can deliver the same event more than once and in any order. Store event IDs, check session state, and make fulfillment safe to repeat.
If your webhook doesn't verify the Stripe-Signature header, anyone with the URL can post a fake checkout.session.completed and unlock your product.