Skip to content
← Back to the blog
integrationsinfrastructure

Moving Stripe from test mode to live: a checklist

Everything that changes when Stripe goes from sandbox to live: keys, products, webhooks, saved customer IDs, emails and the first real payment to check it.

By Devonauts Team5 min read
Leer en español →
A handwritten to-do list with two items ticked on a clipboard next to a laptop

Moving Stripe from test mode to live means recreating almost everything in a second, separate environment: live API keys, live products and prices, a live webhook endpoint with its own signing secret, and live settings for the customer portal and emails. Nothing you built in a sandbox carries over by itself. The usual launch-day failures come from one leftover test value, such as an old webhook secret, a test price ID or a test customer ID saved in your database.

This checklist walks through each item in the order that avoids surprises, then shows how to confirm the switch with one real payment.

What is actually different between a sandbox and live mode?

Stripe designed the two to behave as similarly as possible, so switching is "mostly a matter of swapping your API keys", in Stripe's words. The catch is the word "mostly". Objects created in a sandbox, such as products, prices, coupons and customers, aren't usable in live mode. Webhook endpoints, portal configurations and keys are separate too. Stripe now calls test environments sandboxes; older guides and some menus still say "test mode", and they mean the same idea.

Step 1: Is your Stripe account ready to take real money?

Before any code changes, open the live Dashboard and finish whatever Stripe asks for: business details, bank account for payouts, and identity verification. Then check two things customers will see:

  • Public business name and support details, which appear on Checkout, receipts and the customer portal.
  • Statement descriptor, the text on your customer's card statement. Make it something they will recognise. An unfamiliar descriptor is a common reason people dispute charges they actually made.

Step 2: How should you handle live API keys?

Live keys start with pk_live_, sk_live_ and, for restricted keys, rk_live_. A few rules:

  1. Use a restricted key on the server where you can. Stripe recommends restricted keys for most uses because you choose their permissions.
  2. Copy the key when it's created. In live mode, Stripe shows a secret key you create yourself only once. If you lose it, roll it and make a new one.
  3. Only the publishable key goes in the browser. The secret or restricted key belongs in your server environment, such as Supabase secrets, Vercel environment variables or your host's settings, never in frontend code.
  4. Redeploy after changing variables. Many hosts only read environment variables at build or deploy time.

If a secret key ever ended up in your repository during development, roll it before launch rather than after.

Step 3: How do you recreate products and prices?

Your sandbox price IDs won't exist in live mode, and live prices get new IDs. Two ways to avoid hard-coded mismatches:

  • On each product page in a sandbox, the Copy to live mode button creates the product and its prices in live.
  • Give each price a lookup_key such as pro_monthly and look prices up by that key in your code. Then the same code works in both environments, and you can change a price later without a deploy.

Check that the amounts, currency, billing interval and trial length match what your pricing page promises.

Step 4: Did you create a live webhook endpoint?

This is the item most often missed. A live endpoint is a separate object with a separate signing secret.

  1. In live mode, open Workbench, go to Webhooks and add your production URL. Live endpoints must use HTTPS.
  2. Select the same events you handle in your sandbox, for example checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.paid and invoice.payment_failed.
  3. Reveal the new whsec_ secret and put it in your production environment variable.
  4. Redeploy.

If you skip step 3, every live event fails with a signature error while sandbox events keep working, which makes the bug look random. We cover that failure in Stripe webhook signature verification failed.

Step 5: What else lives separately in each environment?

  • Customer portal configuration. Stripe keeps one set of portal configurations for live mode and one per sandbox, so turn on cancellation, plan switching and invoice history again in live. Our customer portal setup guide lists the options.
  • Customer IDs saved in your database. If test users have a stripe_customer_id from a sandbox, live calls with that ID will fail because the customer doesn't exist there. Clear test data, or keep sandbox and production in different databases.
  • Customer emails. In a sandbox, Stripe only sends customer emails to addresses on your verified domain or to team members. In live, receipts, failed-payment emails and card-expiry reminders go to real customers, so read through those settings before launch.
  • API version. Pin the API version in your server library so a Dashboard upgrade doesn't change the shape of the objects your code reads.

Step 6: How do you confirm it all works?

Run one real end-to-end payment with your own card, at the lowest price you sell.

  1. Sign up as a new user on the production site and buy the plan.
  2. In the live Dashboard, confirm the payment and the subscription exist.
  3. In Workbench, open the live endpoint's Event deliveries tab and confirm each event shows as delivered with a 2xx response.
  4. Confirm your app shows the paid plan, and that the customer portal opens.
  5. Cancel and refund the test purchase. Note that Stripe doesn't return its processing fee on a refund, so this check costs a small amount.

Quick answers

Can I keep using test keys on a staging site after launch? Yes, and you should. Point staging at a sandbox and production at live, each with its own keys and webhook secret.

Do my sandbox customers and subscriptions move to live? No. Nothing in a sandbox moves to live. Real customers start fresh in live mode.

Why do sandbox webhooks work but live ones fail? Almost always the production environment still has the sandbox signing secret, or the live endpoint was never created.

Do I need a different Checkout code path for live? No. The same code works if keys, price lookups and secrets come from environment variables.

Launching soon and want a second pair of eyes?

A switch to live touches keys, webhooks and your database at the same time, which is why it's worth checking once before real customers arrive. See our Stripe payments service, run the free app health check, keep Stripe's own go-live checklist open while you work, or contact us with your launch date.

Still stuck with your app?

Run the free health check on your app's URL, or get the $299 App Rescue Audit: a senior engineer reviews the code and sends you a written report in 2 business days.