Payment succeeds but the user isn't upgraded
The error
Stripe shows the payment as succeeded but the app still shows the free plan
Why it happens
The app grants access on the success-page redirect, or no webhook is configured in production. Redirects can be skipped (closed tab), so access should be granted from the checkout.session.completed webhook, matched to the user via client_reference_id or metadata.
How to fix it
- Pass client_reference_id (your user id) when creating the Checkout Session.
- Add a production webhook endpoint in Stripe for checkout.session.completed (plus customer.subscription.updated/deleted for subscriptions).
- In the handler, look up the user by client_reference_id and update their plan with a server-side DB client.
- Make the handler idempotent (store the event id).
Fix prompt (paste into Lovable, Bolt, Cursor, Replit or v0)
Payments succeed in Stripe but users aren't upgraded. Pass the user id as client_reference_id when creating the Checkout Session, add a verified webhook route that handles checkout.session.completed and customer.subscription.updated/deleted, updates the user's plan in the database using a server-side client, and ignores duplicate events. Tell me which webhook URL and events to register in the Stripe dashboard.
FAQ
Can I trust the success URL?
No. Treat it as a thank-you page only; grant access from the webhook.
Payment Links?
They support client_reference_id via a URL parameter too.
Related fixes
- Stripe webhook: No signatures found matching the expected signature
- No such price / No such customer (test vs live mode mix-up)
- Supabase query returns an empty array (no error)
- new row violates row-level security policy for table
Want the full checklist for this area? Get a Fix Kit ($29)
Featured slot available: reach thousands of vibe coders. Sponsor this week →
Get one new fix a week
Free newsletter: the newest breakages in Lovable, Bolt, Cursor, Replit and v0 apps, with paste-in fixes.
We only use your email to send the newsletter. Unsubscribe any time. See privacy.