支付概览
选择唯一生效的支付服务商,并了解与服务商无关的统一结账契约。
VibeAny 通过统一的应用层支付契约接入 Stripe 和 Creem。每个部署实例都只为新的结账和 Webhook 流量启用一个支付服务商。
启用支付
支付功能由两个设置共同控制:
NEXT_PUBLIC_ENABLE_PAYMENTS=true
PAYMENTS_PROVIDER=stripe # or creem支付服务商之间不会自动回退。启用支付后,npm run preflight 会检查所选服务商的凭证、Webhook 签名密钥、商品目录,以及订阅积分调度器配置。
支付开关控制什么
| 操作 | 服务商选择方式 |
|---|---|
| 创建订阅结账 | 当前 PAYMENTS_PROVIDER |
| 创建积分包或一次性支付结账 | 当前 PAYMENTS_PROVIDER |
| 验证收到的 Webhook | 当前 PAYMENTS_PROVIDER |
| 取消已有订阅 | 该订阅记录中保存的服务商 |
| 打开已有订阅的账单门户 | 该订阅记录中保存的服务商 |
修改
PAYMENTS_PROVIDER不等于迁移订阅。Starter 不会迁移客户、支付方式、订阅,也不会接管旧服务商的 Webhook。线上已有活跃订阅时,不要直接切换服务商;请先制定独立的迁移和历史数据补录方案。
未启用的服务商不会收到新的结账流量,也不会成为当前 Webhook 路由的备用服务商。不过,只要数据库中仍有订阅需要通过旧服务商打开账单门户或执行取消操作,就必须保留旧服务商凭证和 API 访问能力。只有在旧订阅已经全部迁移或关闭,并处理完剩余 Webhook 义务后,才能停用这些凭证。
统一 API
浏览器和应用代码都通过与服务商无关的路由访问支付功能:
| 方法 | 路由 | 用途 |
|---|---|---|
POST | /api/payments/checkout | 通过 { skuKey } 创建积分包或受支持的一次性支付结账 |
POST | /api/payments/subscription/checkout | 通过 { planKey, period } 创建订阅结账 |
GET | /api/payments/subscription | 读取当前登录用户的订阅 |
POST | /api/payments/portal | 打开订阅所保存服务商的客户门户 |
POST | /api/payments/subscription/cancel | 安排在当前周期结束时取消订阅 |
POST | /api/payments/webhook | 验证并处理当前服务商的 Webhook |
POST | /api/payments/confirm | 确认 Creem 返回参数的签名;实际履约仍等待 Webhook |
结账路由要求用户已登录,并且账户有邮箱地址。每个用户只能有一个生效订阅。状态为 active、trialing、past-due、unpaid、paused,或已安排取消的订阅,都会阻止用户创建第二个订阅结账。
商品目录是唯一事实来源
订阅方案、积分包、展示价格、发放积分数量和各服务商标识符都定义在 src/lib/config/products.ts。
默认展示的商品包括:
- Starter 和 Pro 订阅,均支持月付与年付;
- Small、Medium 和 Large 三种一次性购买的积分包;
- 示例落地页商品,这些商品必须先补齐自定义履约逻辑,才能对外销售。
安装向导会要求填写所选服务商的四个订阅标识符和三个积分包标识符。如果删除一个可见 SKU,需要同时更新 UI、商品目录、就绪检查和测试。
支付完成是异步过程
托管结账页跳转回来,只能说明客户回到了你的网站,不能证明支付已经验证或履约成功。
支付验收必须满足以下边界:
- 服务商发送了带签名的 Webhook;
- Webhook 已成功处理,或被安全地判定为重复事件;
- 数据库中能读取到预期的订阅或积分交易;
- 重放 Webhook 不会重复履约。
/api/payments/confirm 会确认 Creem 返回参数的签名,但处理器会刻意返回待处理(deferred)结果。Stripe 的正常返回页只显示通用的成功提示。两种服务商都以 Webhook 处理结果作为持久状态的依据。
退款政策边界
VibeAny 可以根据可配置的订阅积分使用比例判断退款资格,但不会调用服务商的退款 API。审核通过后,需要在原始收款服务商的后台手动退款。退款不会自动取消订阅,也不会自动冲销积分批次。
请阅读Webhook、订阅与积分,了解履约、每月积分发放和手动退款流程。接下来可按需配置 Stripe 或 Creem。