Get an engineer for this one. Webhooks and keys need a server-side check by a developer.
- How serious
- Critical
- Fix it yourself?
- No, get an engineer
- Typical cost
- €99–$990 for a single fix (prices)
- Top rated for Bolt
- Afterbuild Labs · 10.0/10
When a Bolt app breaks after Stripe is added, the cause is almost always on the server side the AI generated: a Supabase Edge Function that rejects Stripe's webhook, a missing secret, or access that is unlocked by the success page instead of a verified webhook. Payment code must live on the server, never in the browser.
What you see, and what it usually means
| What you see | What it usually means |
|---|---|
| Customers pay in Stripe but the app never unlocks the plan. | The webhook never reaches your function, or the function is blocked by JWT verification. |
| The app unlocks for anyone who opens the success page URL. | Access is granted by the browser redirect, not by a signature-verified webhook on the server. |
| "Missing secrets" or a 500 error when checkout starts. | The Stripe secret key or webhook secret is not set in the project's Secrets. |
| Checkout works in Bolt's preview and fails on the published site. | Test keys, a localhost webhook address, or secrets that were never set on the live backend. |
| Payments worked, then auth or the database broke. | The Stripe setup changed tables or RLS rules that other features relied on. |
Why it happens
Bolt's Stripe integration needs a Bolt or Supabase database, user authentication and Edge Functions, and it does not work with Firebase. When you paste a Stripe secret key under the gear icon in Project Settings, Bolt generates server functions for checkout, webhooks and subscriptions, and says it handles webhook registration and signature verification. A custom Stripe setup the AI wrote earlier cannot be migrated into that integration, so many projects end up with two half-working payment paths.
The webhook is the part that fails quietly. Stripe's docs say you cannot rely on the success page to grant access, because a customer can pay and lose their connection before the page loads. Bolt's troubleshooting page explains the other half: outside services do not send your app's sign-in token, so JWT verification blocks them, and the function must verify Stripe's signature itself. Skip either step and money arrives while the app does nothing.
Check these first
Paid accounts are unlocked by a verified payment webhook
Access should change only when your server receives a signed webhook from Stripe or your provider, not when the browser reaches a success page.
No secret keys reach the browser
Open your live app, then DevTools, Sources, and search the loaded JavaScript for sb_secret_, sk_live_, sk-proj- and sk-ant-. Older Supabase keys are long tokens starting with eyJ: decode the middle part of each on your own machine, and if it contains "role":"service_role", your secret key is public. A publishable or anon key in the browser is expected.
Prices and plans come from the server
If the price or plan ID is sent from the browser, someone can edit it. The server should look it up.
Failed payments, cancellations and refunds are tested
Use your provider's test cards for declines and disputes, then check what the user sees and what access they keep.
Secrets live in the host's environment settings
Keys belong in environment variables on the server, not in the repository or in front-end code.
Input is validated on the server
Forms that only check input in the browser accept anything sent directly to the API.
Fix it yourself
- In Stripe, open Developers → Webhooks and look at the Event deliveries tab for your endpoint. A 401 or 403 means your function rejects Stripe. A 404 means the address is wrong. No endpoint means nothing was registered.
- Ask Bolt in Plan mode: "Turn off JWT verification for the webhook function and verify the Stripe-Signature header with the signing secret instead." That is the fix Bolt's own troubleshooting page gives for webhooks.
- Open the Secrets panel under the database icon and confirm the Stripe secret key and the webhook signing secret (it starts with
whsec_) are both set with the exact names the code expects. The dashboard endpoint secret is different from the one the Stripe CLI prints. - Search your published site's JavaScript (F12, Sources) for
sk_live_orsk_test_. A secret key in the browser lets anyone issue refunds. Rotate it in Stripe and move it into Secrets. - Switch Stripe to test mode and run three payments: card 4242 4242 4242 4242 (success), 4000 0000 0000 0002 (decline), and the same successful card twice. Check what the user sees and what access they keep each time.
- Ask Bolt which tables or RLS rules it changed for payments. If sign-in or data broke, Bolt's advice is to remove the rules and add back one rule with the behavior you want, then retest. Version History does not restore your Supabase database, so fix data in the Supabase dashboard.
When to get a human engineer
Get an engineer the moment real customers have paid and not received access, because every hour adds refunds and support email. A single fix for a broken webhook and access unlock sits in the €99 to $990 band and takes about two days. If the project has two competing payment paths, keys in the browser, and no tests, cleanup runs $1,500 to $15,000 over one to eight weeks. Ask for a test that proves a declined card, a repeated webhook and a cancelled subscription all behave. Our Bolt guide has the rest.
Top-rated companies for Bolt apps
Ranked by our score: published prices, scope of work, AI tools named, timing and a low-risk first step. How we score.
- 1Afterbuild Labs10.0/10Best for: A check before launchFree first step · from $49
- 2Redlab10.0/10Best for: A full rescue by one team that keeps buildingFree first step · from $490
- 3Vibe Code Rescue (Lev Arakelyan)9.0/10Best for: A one-off check and a cleanupFrom $299
Questions
Why does Stripe say the payment succeeded but my Bolt app shows nothing?
The webhook that tells your server about the payment is failing or missing. Look at Event deliveries in Stripe. If your Edge Function returns 401, JWT verification is blocking Stripe and the function needs to verify the Stripe signature instead.
Can I just unlock the plan when the user lands on the success page?
No. Stripe says webhooks are required because customers do not always reach that page, and anyone who guesses the URL would get access. Unlock on the server when a signature-verified checkout.session.completed event arrives, and handle the same event arriving twice.
Does the Bolt Stripe integration need Supabase?
It needs a Bolt or Supabase database, user authentication and Edge Functions. It does not work with Firebase.
Sources: Bolt help: Stripe integration; Bolt help: Integrations troubleshooting (webhooks, secrets, RLS); Bolt help: Supabase integration; Stripe docs: Fulfill orders (webhooks are required); Stripe docs: Webhook signatures and endpoint errors.
