Skip to content
BuildThenTestedSee packages

Stripe test keys in production

Customers can pay with Stripe's published test card numbers, the app fulfils the order, and no money ever reaches your account. Everything between the pay button and the money arriving. Check it yourself with the steps below; our test adds what a script and a second account can find.

What it looks like

# .env.production
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...   # copied from the test-mode endpoint
Production environment variables (settings the server reads at start-up) still pointing at Stripe's test-mode keys after launch.

What happens

Customers can pay with Stripe's published test card numbers, the app fulfils the order, and no money ever reaches your account.

Where it shows up

Descriptive, not a verdict: builders and stacks whose defaults make this reachable, or that a public incident names. Each hub states the tool's own security features.

Check it yourself

Uses your builder's dashboard and your browser. No tools to install.

  1. Open your live app's checkout, press F12, select the Network tab, and start a checkout. Look for requests to stripe.com or js.stripe.com and read their URLs and payloads for a key beginning pk_test_ or a session ID beginning cs_test_.
  2. In your builder's or host's environment settings for the production deployment, read the Stripe variables. Keys should begin sk_live_, rk_live_ or pk_live_.
  3. In the Stripe Dashboard, switch off the sandbox toggle and check that recent live payments exist for the orders your app shows as paid.
  4. Bad result: pk_test_ or cs_test_ appears on the live site, or orders marked paid in your app have no matching live payment in Stripe.

What we check

We complete a purchase on the live site with a Stripe test card number and check whether the app fulfils it. We also confirm the webhook endpoint and its signing secret belong to the live-mode endpoint, since Stripe issues a different secret per mode.

Fix direction

Keep separate environment variable sets for test and live, switch every Stripe variable together (secret key, publishable key and the webhook signing secret), and run one small real payment after launch. Stripe's go-live checklist lists the remaining steps.

Mechanism documented in: API keys (verified 2026-09-21).

Covered by

Ready-to-charge check ($390, 48 hours) and Full audit ($1,900, 5 business days)

Both include a re-check after your fixes.

Compare packages

Related patterns

  • Stripe webhook accepted without signature verificationPayments

    Anyone who finds the webhook URL can post a made-up payment-succeeded event and get an order fulfilled or a plan activated for a user of their choosing, without paying.

    Critical
  • NEXT_PUBLIC_ prefix on a secretSecrets and keys

    The build writes the secret's value into public JavaScript, so anyone who loads the site can read it, and a redeploy with the same variable name republishes it.

    Critical
  • Debug mode left on in productionDeploy and config

    Anyone who causes an error sees file paths, query text and sometimes environment values, and dev-only shortcuts such as skipped checks or seeded test users stay active for real visitors.

    Medium
  • Every change goes straight to productionDeploy and config

    A broken build, a bad migration or an agent's misjudged edit reaches real users and real data first, with no place where it could have been caught.

    Medium

Questions

stripe test keys in production

Stripe's docs explain that sandbox keys (sk_test_, pk_test_) and live keys (sk_live_, pk_live_) act on separate sets of objects, and that in a sandbox card networks do not process payments. A live app still on test keys accepts test cards and collects nothing. Check the publishable key visible in the browser and the secret key in the production environment.

how do i know if my app is using stripe test mode

Open developer tools on the live checkout and look for pk_test_ in requests to Stripe, or for a Checkout URL containing cs_test_. In the Stripe Dashboard, compare payments shown in live mode with the orders your app marks as paid. A mismatch means the app is talking to the sandbox.

stripe test mode to live mode checklist

Swap the secret key, the publishable key and the webhook signing secret together, because the webhook secret differs between modes. Register the live webhook endpoint, remove any hard-coded keys from source, and make one real low-value purchase to confirm money arrives and fulfilment runs.

Back to the catalogue, or run the self-check for your stack.