Stripe Payment Succeeds but the User Never Leaves Checkout
Quick Answer
How do I fix Stripe Payment Succeeds but the User Never Leaves Checkout?
Missing or wrong success_url and cancel_url in the checkout session. The URL must include your production domain. Start with "Add correct redirect URLs" before making broader code changes.
Fix signals
- What this answers
- Why stripe payment succeeds but the user never leaves checkout happens and what to change first.
- Fastest move
- Add correct redirect URLs
- Use this page if
- Payment succeeds but user stays on Stripe page
If this keeps happening
Open the next decision, not just the patch
Use these when the current fix is helpful, but the real answer is a better tool choice, a cleaner workflow layer, or a more trustworthy launch path.
Tool picker
Open this when the payment problem is really making you question the app stack and workflow choice behind it.
Open this next →
Lovable reviews
Open this when repeated billing drift makes you question whether the current generated full-stack path is still worth the cleanup cost.
Open this next →
Cursor review
Open this when the next move is owning more of the billing and entitlement logic directly in code.
Open this next →
Deploy hub
Open this when the payment bug is really part of a bigger production handoff and environment problem.
Open this next →
Firecrawl review
Open this when the app also needs live data or richer infra decisions and the stack question is getting broader than Stripe itself.
Open this next →
Quick Fix Summary
| Most likely cause | Missing or wrong success_url and cancel_url in the checkout session. The URL must include your production domain. |
| Fastest fix | Add correct redirect URLs |
| Use this page if | Payment succeeds but user stays on Stripe page |
Exact errors people search for
If one of these matches what you are seeing, you are likely on the right fix page.
Stripe payment succeeds but the user never leaves checkout Redirect goes to the wrong URL after payment Success page returns 404 after Stripe checkout
You're in the right place if...
- !Payment succeeds but user stays on Stripe page
- !Redirect goes to wrong URL
- !Success page returns 404
Why this happens
Missing or wrong success_url and cancel_url in the checkout session. The URL must include your production domain.
Fix
Add correct redirect URLs
Set success and cancel URLs in your checkout session:
const session = await stripe.checkout.sessions.create({
// ... other options
success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/cancelled`,
})
// Add to Vercel env vars:
// NEXT_PUBLIC_URL=https://your-domain.comPrevent this next time
Always use an environment variable for the base URL. This way the redirect works in both development and production.
Frequently Asked Questions
Stripe replaces {CHECKOUT_SESSION_ID} with the actual session ID in the redirect URL. Use it to verify the payment on your success page.
localhost:3000 in development, your-domain.com in production. One codebase, both environments work.
Related fixes
Stripe Says Webhook Signature Verification Failed
Lovable Stripe Checkout Fails or Cards Are Declined
Stripe Payment Form Shows an Error or the Card Keeps Failing
How to Test Stripe Webhooks Locally
Stripe Payment Succeeds but Subscription Status Never Updates
Accidentally Charged Real Money in Stripe