Files
cozsweet-frontend-nextjs/src/lib/stripe/stripe-products.ts
T
admin 0548a08cbb feat: integrate Stripe payment with subscription plans
Add Stripe payment integration across the project:

- Add @stripe/stripe-js dependency
- Configure Stripe environment variables (secret key, publishable key, webhook secret) for dev, local, and production environments
- Add Product/Price IDs for monthly, quarterly, and annual subscription tiers
- Extend subscription plan data with voiceMinutesPerDay quotas (30/45/60 minutes per tier)
- Update .gitignore to exclude implementation_plan.md
2026-06-16 10:21:02 +08:00

49 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Stripe product / price id 映射
*
* 为什么不直接存到 `subscription-plans.ts`
* - product/price id 是部署环境配置(不同环境不同 product)
* - 套餐本身的 `name` / `price` / `highlight` 是业务常量(不随环境变)
* - 分离后,套餐表只包含业务字段,产品 id 走 env —— 避免硬编码 + 生产安全
*
* env 命名规范:
* - STRIPE_PRODUCT_<PLAN_ID_UPPER> → Product ID
* - STRIPE_PRICE_<PLAN_ID_UPPER> → 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;
}