Lovable Stripe Checkout Not Working? Find Which Link in the Chain Broke

Updated 19 Oct 2026

Check your app now: free 30-second health check

Paste your live URL. We'll show what visitors and Google actually see. No signup.

Passive check only. We never submit forms or log in.

A broken checkout costs you money every hour it stays broken. Lovable apps also tend to break in ways that look fine on the surface: the button renders, but nothing happens. Here's how the pieces fit together and how to test each one.

How Stripe is wired in a typical Lovable app

Your frontend never talks to Stripe with a secret key. Instead:

  1. Your app calls a backend function (often named something like create-checkout) running on Lovable Cloud or your Supabase project.
  2. That function creates a Checkout Session with your Stripe secret key and returns a URL.
  3. The user pays on Stripe's hosted page and is redirected back to your success URL.
  4. Optionally, a webhook function (e.g. stripe-webhook) receives the "payment succeeded" event and updates your database.

Lovable's docs note that by default its Stripe integration doesn't use webhooks; your app checks status directly with Stripe. If you added webhooks, step 4 is a fourth thing that can break.

Symptom 1: clicking "Buy" does nothing

  • Popup blocker. Lovable's docs say checkout usually opens in a new tab, which popup blockers can stop. Allow popups and try again.
  • Testing inside the Lovable preview. Test on your published URL in a normal browser tab. The customer portal in particular doesn't work inside the preview panel.
  • A JavaScript error. Open DevTools → Console and click the button. A red error here, such as a failed fetch to the function, tells you where to look next.

Symptom 2: checkout fails with an error

The error is coming from your checkout function. Read the details in two places:

  • Function logs: the Cloud view on Lovable Cloud projects, or Supabase Dashboard → Edge Functions → Logs.
  • Stripe Dashboard → Developers → Logs: every API request Stripe received, with Stripe's own error message.

Common culprits:

  • the secret key is missing from function secrets
  • a test-mode key is paired with a live-mode price ID, or the other way round
  • a price ID was deleted or archived

Paste the exact error into Lovable and ask it to fix the function.

Symptom 3: payment succeeds but the app still says "free plan"

This is almost always the webhook.

  • No endpoint. In Stripe → Developers → Webhooks, add an endpoint pointing to your function URL. Subscribe it to the events your code handles, e.g. checkout.session.completed and, for subscriptions, the customer.subscription.* events.
  • 401 errors on delivery. Supabase Edge Functions check for a user JWT by default, and Stripe doesn't send one. Disable JWT verification only for the webhook function, e.g. [functions.stripe-webhook] verify_jwt = false in supabase/config.toml. Putting it in config means a redeploy won't quietly switch it back on.
  • 400 "No signatures found matching…" The signing secret doesn't match. Each endpoint has its own whsec_ secret, test and live mode are separate, and the Stripe CLI's secret is different again. Also verify against the raw request body (await req.text()) using constructEventAsync on Deno.

After fixing, click Resend on a failed delivery in Stripe and confirm it now returns 200.

Symptom 4: wrong page after payment

Check the success_url and cancel_url in your checkout function. If they still point at a preview domain or localhost, real customers end up on a dead page right after paying.

Symptom 5: it worked last week

A regenerated function, a rotated key, or a switch to live mode can each break things silently. That's exactly why a quiet weekly check of your pricing page and checkout button is worth having.

How FlowCanary's free check detects this

FlowCanary's free scan can't make a payment, and it never will. It does catch the surface signs of a broken checkout:

  • /pricing returning an error or rendering blank
  • JavaScript console errors on page load
  • failed network requests on your homepage and key pages
  • broken links on your homepage

You get a paste-ready fix prompt for each issue. Our upcoming daily monitoring will walk your checkout flow up to the Stripe page on a schedule and alert you when it breaks.

Check your pricing page free in 30 seconds →

FAQ

Should my Stripe secret key ever be in a `VITE_` variable?

No. Anything with a `VITE_` prefix is bundled into the browser. Keep secret keys in function secrets only.

Do I need webhooks?

Not always. Lovable's default setup checks status directly with Stripe. You need webhooks when something must happen the moment payment succeeds, such as fulfilment or credits.

How do I test without real money?

Use test-mode keys with Stripe's test cards. Switch to live keys and live price IDs together.

Why does it work in preview but not in production?

Usually it's missing production secrets, a different domain in your redirect URLs, or a popup blocker on the published site.

Related guides

Run the free 30-second check

Back to the FlowCanary homepage