@@ -26,13 +26,25 @@ const SANDBOX_FREE = "6abf1427-cf83-4251-90d7-8852e7e5ca21";
2626 */
2727export function polarProducts (
2828 env : DeployEnv = resolveDeployEnv ( ) ,
29+ { strict = true } : { strict ?: boolean } = { } ,
2930) : Record < PlanId , string > {
3031 switch ( env ) {
31- case "production" :
32- return {
33- pro : process . env . POLAR_PRO_PRODUCT_ID_PRODUCTION ?? SANDBOX_PRO ,
34- free : process . env . POLAR_FREE_PRODUCT_ID_PRODUCTION ?? SANDBOX_FREE ,
35- } ;
32+ case "production" : {
33+ const pro = process . env . POLAR_PRO_PRODUCT_ID_PRODUCTION ;
34+ const free = process . env . POLAR_FREE_PRODUCT_ID_PRODUCTION ;
35+ if ( pro && free ) return { pro, free } ;
36+ if ( strict ) {
37+ throw new Error (
38+ "Polar production product IDs are not configured. Set " +
39+ "POLAR_PRO_PRODUCT_ID_PRODUCTION and POLAR_FREE_PRODUCT_ID_PRODUCTION. " +
40+ "Refusing to silently fall back to sandbox products in production — " +
41+ "that would serve sandbox checkouts to real users and never charge real cards." ,
42+ ) ;
43+ }
44+ // Non-strict callers (e.g. the webhook inverse-lookup, which may run
45+ // outside a production runtime) only need id->plan resolution.
46+ return { pro : pro ?? SANDBOX_PRO , free : free ?? SANDBOX_FREE } ;
47+ }
3648 case "preview" :
3749 case "dev" :
3850 default :
@@ -65,7 +77,7 @@ export function planForProduct(productId: string | null | undefined): PlanId | "
6577 if ( ! productId ) return "unknown" ;
6678 const envs : DeployEnv [ ] = [ "production" , "preview" , "dev" ] ;
6779 for ( const env of envs ) {
68- const products = polarProducts ( env ) ;
80+ const products = polarProducts ( env , { strict : false } ) ;
6981 for ( const [ plan , id ] of Object . entries ( products ) as [ PlanId , string ] [ ] ) {
7082 if ( id === productId ) return plan ;
7183 }
0 commit comments