Stripe success page 404 on Netlify

Stripe Checkout returns to your site and Netlify says Page not found? The success URL is a client route. Add the SPA rewrite to index.html.

Reviewed October 17, 2026

What it means in plain English

Checkout finished and Stripe sent the browser to success_url. Netlify looked for a real file at that path, did not find one, and showed "Page not found". The payment can still have succeeded. This page is the missing route, not a failed charge.

Stripe's example success URL looks like http://yoursite.com/order/success?session_id={CHECKOUT_SESSION_ID}. On a Vite or React app, /order/success exists only in the browser router. Netlify does not know that until you rewrite those paths to index.html.

Likely causes

  • No _redirects file or netlify.toml rewrite. Netlify's single-page-app rule is /* /index.html 200, and it should be the last rule.
  • The rewrite file is not in the published folder. Vite only copies files from public/ into dist.
  • success_url points at a path you never added to the router, so index.html loads and the app still has nothing to render.
  • The same URL 404s on refresh of any other page. That is the same rewrite. See Netlify page not found on refresh.

How to fix it, step by step

  1. Set success_url to a route your app actually renders, on the live https origin. Keep Stripe's {CHECKOUT_SESSION_ID} placeholder if the success page looks the session up. Stripe says to pass the Checkout Session ID that way, then look the session up on the success page.
  2. Add the rewrite Netlify documents for pushState apps. In public/_redirects:
/*  /index.html  200

Or in netlify.toml:

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200
  1. Put this last if you have other rules. Netlify says a rewrite does not hide a file that really exists, so assets still load.
  2. Redeploy. Opening the success URL directly should serve the app, not Netlify's 404.
  3. Do not treat that page as proof the user is paid. Stripe says you cannot rely on the landing page alone, because the customer may never reach it. Record the purchase from checkout.session.completed. See Stripe paid, but the user was not upgraded.
  4. Paste this to the AI tool:
After Stripe Checkout, Netlify shows Page not found on the success URL. Add public/_redirects with this last rule: /*  /index.html  200. Point success_url at a route the React app renders, using https and {CHECKOUT_SESSION_ID} if the page looks up the session. Do not change the price, the webhook secret, or the Checkout product.

How to check it worked

  • Open the success path in a new tab. The app loads.
  • Refresh that URL. It still loads.
  • A test Checkout returns to that URL instead of Netlify's "Page not found".

Sources

More Stripe fixes

Keep going on your own.

The guides stay free. A deep leak report is $15. Fix packs are $24, or $49 for all three. There is no done-for-you repair.

See products