Stripe·Fixpaymentsbeginner

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.

Quick Fix Summary

Most likely causeMissing or wrong success_url and cancel_url in the checkout session. The URL must include your production domain.
Fastest fixAdd correct redirect URLs
Use this page ifPayment 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

1

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.com

Prevent 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