Stripe test mode on a live site: switch from pk_test to your live keys
If your live site's code contains a Stripe key that starts with pk_test_, your checkout is running in a Stripe sandbox: no real card can be charged, so nobody can pay you. Replace it with your live publishable key (pk_live_), switch the server to a live secret or restricted key, and recreate any prices, products, Payment Links and webhooks in live mode, because sandbox objects don't carry over.
Why test keys stop real payments
Stripe's key guide: in a sandbox, "card networks and payment providers don't process payments" and "You can't accept real payment methods or work with real accounts." Its testing guide says it directly: "You can't process live payments if your integration is still using your test API keys."
Stripe also notes that "Each mode has its own set of API keys, and objects in one mode aren't accessible to the other." A price ID created in the sandbox (price_...) doesn't exist in live mode, so swapping only the key usually produces "No such price" errors.
Switch to live mode
- Work through Stripe's go-live checklist. Stripe: "Switching between them is mostly a matter of swapping your API keys", plus the items below.
- Get your live keys. On the Dashboard's API keys page, switch from sandbox to live mode. Stripe: "Copy your live mode publishable key (starts with
pk_live_) and replace thepk_test_key in your client-side code." - Update the server key. Stripe recommends a restricted key for server code; reveal or create your live key (
rk_live_orsk_live_) and store it in your host's secrets, never in client code. - Recreate live objects. The checklist: "Stripe objects created in a sandbox environment—such as plans, coupons, products, and SKUs—aren't usable in live mode." Create live versions of your products, prices, coupons and Payment Links, and update every ID your code uses.
- Webhooks. Stripe: "make sure you've defined live endpoints in your Stripe account", and copy each live endpoint's signing secret into your server settings.
- Keep test keys for previews. Use environment variables per environment (production gets live keys, preview builds get test keys) so the switch is a setting, not a code change.
- Redeploy and look at the live bundle. Search it for
pk_test_: it should only containpk_live_. Your first real orders then appear in the Dashboard in live mode.
Do your testing in a sandbox, not with real cards on the live site: "The Stripe Services Agreement prohibits testing in live mode using real payment method details."
What Pewterkit Check looks at
On sites that take payments, the check searches your home page and the scripts it loads for a Stripe publishable test key (pk_test_, leaving out Clerk keys, which use a similar prefix) and for buy buttons that link to https://buy.stripe.com/test_…. A test key on its own is a fix. When your code has both a live key and a test key, it's a warning to make sure the test key isn't used on any checkout path.
FAQ
Is it a problem to have pk_test and pk_live in the same bundle?
It can be: one checkout path may still use the test key. Pick the key from an environment variable at build time so production only contains the live one.
Do I need new products and prices in live mode?
Yes. Stripe keeps sandbox and live objects apart, so create live versions and update the IDs in your code or settings.
Can I leave the test key there for my own testing?
Keep testing on a preview deployment or a separate sandbox instead. Your live site should only ever load live keys.
Sources
- API keys: sandbox versus live mode, switch to live mode (Stripe Docs) — read 27 Oct 2026
- Testing (Stripe Docs) — read 27 Oct 2026
- Go-live checklist (Stripe Docs) — read 27 Oct 2026
How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked Oct 27, 2026. Spotted something out of date? Tell us.
Related guides
- Stripe checkout success_url still set to localhost or a preview address
- Stripe secret key exposed in your frontend code: rotate it, then move it to the server
- OpenAI API key in your React or Vite frontend: rotate it and move calls to a backend
- Supabase service_role key in your frontend bundle: replace it and switch the old key off