MuseMVP
MuseMVP 文档

计费与支付

逐步启用 Stripe、Creem、Dodo 或 Waffo,验证结账、Webhook、积分、取消和退款。

支付默认关闭

Flare 带有 Stripe、Creem、Dodo 和 Waffo 的适配实现,默认 product.billing.enabled 为 [],所有网关产品映射为空。这表示源码能力已包含,不能理解为复制仓库后就能收款。在线演示也不提供真实收款验收环境。

模板自身的订阅价格来自 packages/config/src/index.ts,与 MuseMVP 官网销售源码模板的价格、商品 ID 和结账规则相互独立。

第一步:建立自己的商品

当前 catalog 有两个示例:

planIdamount / currency购买类型credits
pro-monthly1900 / USDrecurring1000
lifetime9900 / USDone-time10000

金额是货币最小单位的整数,不是浮点美元。改价格时同时检查币种、周期、积分、网关商品与前端展示。不要只修改定价页文字。

在选定网关创建对应商品,然后填写该 plan 的 products:Stripe 使用 price_ 价格 ID;Dodo 使用 pdt_ 产品 ID;Creem 使用对应产品 ID;Waffo 填写网关商品标识。测试和正式环境必须使用匹配的 Key、商品与 Webhook。

第二步:启用网关并配置密钥

例如在原文件中将 product 的解析输入改为:

export const product = productSchema.parse({
  billing: { enabled: ['stripe'], defaultGateway: 'stripe' },
});

这是替换原有 product 初始化语句,不是在文件末尾重复声明。defaultGateway 必须属于 enabled。可以启用多个网关,但每个网关都必须配置完整商品映射及密钥。

网关服务端变量
StripeSTRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET
CreemCREEM_API_KEY、CREEM_WEBHOOK_SECRET
DodoDODO_API_KEY、DODO_WEBHOOK_SECRET
WaffoWAFFO_MERCHANT_ID、WAFFO_PRIVATE_KEY

本地填 apps/web/.dev.vars;部署填根目录 .env 或 CI 加密变量。Waffo 私钥以单行保存,换行使用 \n。密钥不能进入 publicConfig、浏览器或公开日志。

第三步:登记签名通知

Webhook 地址为 https://your-domain.com/api/webhooks/<gateway>,例如 /api/webhooks/stripe。这是 Flare 自己的路径,不是 Next.js 模板的支付路径。

网关签名验证、事件 ID 去重、订单映射、账本写入和 outbox 共同决定支付结果。浏览器从付款页返回成功 URL 并不证明已经到账;应等服务端签名事件完成处理,再在账单与用量中查看订单和积分。

checkout 输入为 {planId,gateway,requestId},requestId 必须为 UUID。一次业务尝试的重试应保留其标识,避免重复建单;新的购买才使用新的标识。用户必须登录,且 plan 与 gateway 在服务端允许范围内。

第四步:验证客户操作

/app/billing 使用自己的订单发起 portal 或 cancel,对应 POST /api/billing/manage。四个网关都保留已有 portal/cancel 适配;实际账户是否开放某项能力应以网关响应为准,失败需要展示错误。

退款与取消续费是两件事。当前 Stripe、Creem、Dodo 支持针对最新可退支付的全额退款;Waffo 的退款创建走网关后台,再由签名事件对账。部分退款不会自动按比例回退积分。不要自行加一个客户端余额减法来填补此差异。

管理后台与重试

/app/admin 可查看订单、Webhook、退款与审计。重复事件应返回已有结果,不能重复发放积分。操作未知结果或网络超时后,先查询网关状态及本地审计;不要盲目再次退款。任务租约、幂等账本和 outbox 必须保持原有边界。

退款并不等于停止下次续费。验收时分别确认本次支付状态、退款状态与订阅状态。

上线前验证

  1. 运行 pnpm muse:doctor --target production --json,确认启用网关的配置齐全。
  2. 在受控测试环境完成结账,确认金额、币种、周期与商品一致。
  3. 重放同一签名事件,确认只产生一份权益及积分。
  4. 验证失败付款、取消、portal、退款,以及用户之间的订单隔离。
  5. 核对 Webhook 日志与账本,不把跳转页或本地 mock 测试当作真实支付成功。

常见问题:无支付按钮先检查 enabled;结账失败检查产品映射与环境;通知失败检查原始请求签名与 webhook secret;积分未到账先查事件处理状态,避免手工重复补发。继续阅读 环境变量 与 部署。

本页目录