Checkout and card data Required
Keep test and live modes apart
Use the provider's test mode in every environment except production, and make the app refuse to start with a live key anywhere else.
How to do it
Providers give separate test and live API keys and separate webhook secrets. Keep them per environment in a secrets store. Check the key prefix at startup, such as sk_live_ and sk_test_ at Stripe. Use restricted keys with only the permissions the app needs. Never copy live customer or payment data into test.
Example
const isLiveKey = key => /^(sk|rk)_live_/.test(key)
if (isLiveKey(process.env.PAYMENT_API_KEY) !== (process.env.APP_ENV === 'production')) {
throw new Error('Payment key mode does not match APP_ENV')
}
import os, re
def is_live_key(key: str) -> bool:
return re.match(r"^(sk|rk)_live_", key) is not None
if is_live_key(os.environ["PAYMENT_API_KEY"]) != (os.environ["APP_ENV"] == "production"):
raise SystemExit("Payment key mode does not match APP_ENV")
How to check
Start staging with a live key. It exits with an error. Search the repository for sk_live_ and rk_live_. Nothing is found.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers payments playbook: https://agentwranglers.se/playbook/payments/checkout-and-card-data/test-and-live-keys.