/** * Stripe product / price id 映射 * * 为什么不直接存到 `subscription-plans.ts`: * - product/price id 是部署环境配置(不同环境不同 product) * - 套餐本身的 `name` / `price` / `highlight` 是业务常量(不随环境变) * - 分离后,套餐表只包含业务字段,产品 id 走 env —— 避免硬编码 + 生产安全 * * env 命名规范: * - STRIPE_PRODUCT_ → Product ID * - STRIPE_PRICE_ → Price ID * - 例:STRIPE_PRODUCT_MONTHLY, STRIPE_PRICE_QUARTERLY */ import type { SubscriptionPlanId } from "@/data/constants/subscription-plans"; /** * 获取 Stripe Product ID(从 env) * * @throws Error 如果 env 未配置(避免 silent failure) */ export function getPlanProductId(planId: SubscriptionPlanId): string { const envKey = `STRIPE_PRODUCT_${planId.toUpperCase()}`; const productId = process.env[envKey]; if (!productId || productId.startsWith("prod_replace_")) { throw new Error( `Stripe product id is not configured. Set ${envKey} in .env.local.`, ); } return productId; } /** * 获取 Stripe Price ID(从 env) * * Price ID 是真正用在 `stripe.checkout.sessions.create({ line_items: [{ price: "price_xxx" }] })` 里的 * * @throws Error 如果 env 未配置 */ export function getPlanPriceId(planId: SubscriptionPlanId): string { const envKey = `STRIPE_PRICE_${planId.toUpperCase()}`; const priceId = process.env[envKey]; if (!priceId || priceId.startsWith("price_replace_")) { throw new Error( `Stripe price id is not configured. Set ${envKey} in .env.local.`, ); } return priceId; }