OneShot

All packsSaaS Billing + Tax CoreSolve

stripe price id hardcoded vs lookup key test live mode

Price IDs don't survive the trip from test mode to live mode

A hardcoded price_ id from test mode is a different, nonexistent id in live mode. The pack resolves prices by a stable lookup_key instead of a mode-specific id (D14).

3 of 3 runs passedOne decision inside SaaS Billing + Tax Core (nextjs-prisma-postgres).

What goes wrong

Every Stripe object id -- including price ids -- is different between test mode and live mode, and price ids also change if a price is ever recreated (Stripe prices are immutable once used). Code with a hardcoded price_1AbC... string works perfectly in test mode and then fails outright the day the app goes live, or the day someone rotates a price.

Why agents get it wrong

Copying a price id out of the Stripe dashboard and pasting it into a config file is the fastest way to get checkout working in a demo, and it does work -- right up until the environment changes, which usually happens well after the code that depends on it was written and forgotten.

What SaaS Billing + Tax Core pre-decides

D14 has scripts/stripe-setup.ts idempotently create Products/Prices from a plain config file and set a stable lookup_key on each one (plus transfer_lookup_key: true so it survives price recreation). Runtime code resolves prices by calling prices.list({lookup_keys}) -- lookup keys are the only handle that stays stable across test/live mode and price rotations, so nothing in the app ever hardcodes a mode-specific price id.

Source: ARCHITECTURE.md D14

Coming soon — $149Full receipt and details for SaaS Billing + Tax Core

Related problems