Skip to content

Stripe 支付集成

概述

MysticX 使用 Stripe 处理订阅计费和一次性积分包购买,通过 Better Auth Stripe 插件集成。

产品

订阅

产品月付年付(7 折)
Gold$19.99/月$167.92/年(约 $13.99/月)
Diamond$69.99/月$587.92/年(约 $48.99/月)

积分包(一次性购买)

积分包价格
入门包(2,000 积分)$9.99
热门包(5,000 积分)$19.99
超值包(12,000 积分)$39.99
大礼包(30,000 积分)$79.99

积分包使用即时 price_data(无需预先创建 Stripe Price ID)。

设置

1. Stripe Dashboard 配置

产品和价格

在 Stripe Dashboard 中创建产品:

  • Gold Monthly — $19.99/月 循环
  • Gold Yearly — $167.92/年 循环
  • Diamond Monthly — $69.99/月 循环
  • Diamond Yearly — $587.92/年 循环

在环境变量中设置 Price ID 或使用默认值。

Webhook 端点

将 Webhook 指向:{APP_URL}/api/auth/stripe/webhook

必需事件:

  • checkout.session.completed
  • invoice.payment_succeeded
  • customer.subscription.updated
  • customer.subscription.deleted

客户门户

启用 Stripe 客户门户并配置以下设置:

  • 按比例计费:升级立即生效
  • 降级:在当前周期结束时生效
  • 取消:在当前周期结束时生效
  • 允许客户更新支付方式

2. 环境变量

env
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

订阅生命周期

新订阅

  1. 用户在定价页面点击"订阅"
  2. 应用通过 Better Auth 创建 Stripe Checkout Session
  3. Stripe 重定向到结账页面
  4. 完成后,Webhook 触发 checkout.session.completed
  5. 应用更新用户等级并创建订阅记录
  6. 发放积分(月度积分 + 按比例补偿)

升级(Gold → Diamond)

  1. Stripe 处理周期中按比例计费(立即收取差额)
  2. Webhook 触发 customer.subscription.updated
  3. 应用更新等级为 DIAMOND
  4. 发放积分差额

降级(Diamond → Gold)

  1. 变更在当前周期结束时生效(不立即收费)
  2. 下一个计费周期时 Webhook 触发
  3. 应用更新等级为 GOLD

取消订阅

  1. 用户通过客户门户或应用取消
  2. 订阅状态变为 cancel_at_period_end
  3. 访问权限持续到周期结束
  4. 周期结束时 Webhook 触发 customer.subscription.deleted
  5. 应用更新等级为 FREE

支付失败

  1. Stripe 按催缴计划重试(建议:2 周内重试 3 次)
  2. 如果所有重试均失败,订阅将被取消
  3. 应用处理优雅降级

一次性积分购买

  1. 用户在积分购买弹窗中选择积分包
  2. 应用使用即时 price_data 创建 Stripe Checkout Session
  3. 完成后,Webhook 发放积分并附加等级奖励
  4. 交易记录到 CreditTransaction(按 invoice ID 保证幂等性)

安全措施

  • 频率限制:每用户每 60 秒最多 5 次购买尝试
  • 幂等性:所有积分发放通过 invoice ID 检查已有 CreditTransaction
  • 元数据完整性:Checkout Session 包含用户 ID 和积分包元数据以供验证
  • Webhook 签名验证:所有 Webhook 通过 STRIPE_WEBHOOK_SECRET 验证

返回后轮询

Stripe 重定向回应用后:

  1. 客户端轮询订阅/积分状态(最多 5 次尝试,间隔 2 秒)
  2. 处理 Webhook 在重定向后才到达的竞态条件
  3. 确认后显示成功状态

关键实现说明

  • Stripe Customer ID 在首次购买时通过 Better Auth 插件自动创建
  • Customer ID 存储在用户记录中(stripeCustomerId
  • 所有订阅状态变更通过 Webhook 进行(绝不通过直接 API 轮询获取状态)
  • 定价页面位于 /membership,显示当前计划、升降级选项和管理订阅按钮

Internal documentation for MysticX team