Why it happens
The production environment still carries sk_test_ and pk_test_ keys, or the only webhook endpoint listens in test mode. Everything behaves; nothing is real.
How to tell
- Payments appear only with Stripe's Test mode switch on.
- The keys in the host's production environment begin with sk_test_ or pk_test_.
- The free health check finds a publishable test key in the page.
The fix
- Create live keys in Stripe. Put the secret key in the host's production environment and nowhere in the browser.
- Create the live-mode webhook endpoint; it has its own signing secret.
- Redeploy, make one real small payment, refund it.
Where to look
The prompt for your builder
Paste this into Lovable, Bolt, Cursor, Claude Code or whatever built the app. Replace anything in capitals. It never asks you to paste a secret into a chat; keys go into your host’s environment, by you.
Audit my app for Stripe test-mode keys: find every place a key beginning sk_test_ or pk_test_ is referenced or hardcoded, move them to environment variables, and add a startup warning when the app runs in production with a test key.
How Keelnest catches it
The five-minute site check reads your live site's code, and Revenue Guard opens an incident when a Stripe test key is in it with no live key beside it and no live payments coming in, or when live payments come in with no live webhook endpoint. The free health check names the same test key, never its value.
Know the moment this happens.
Keelnest watches your production app every five minutes and tells you in plain English what broke — with the fix. Free for your first app.
Related
- An API key is in your public codeThe free health check — or a stranger — finds an OpenAI, Anthropic, OpenRouter, Replicate, Resend, Google Gemini or Stripe secret key, a Supabase service-role key, or an AWS access key, inside a script your browser downloads.The fix
- Checkout succeeds; the order never happensCustomers pay. The app never sends the email, creates the account, or unlocks the thing they paid for.The fix