MuseMVP 文档
支付

Waffo Pancake

配置 Waffo Pancake 网关。

MuseMVP 集成了 Waffo Pancake 作为支付网关之一。通过统一的 Muse Billing 模块,它与 Creem、Stripe、Dodo Payments 共用同一套合约与权益模型,支持订阅、一次性购买与客户门户。本文介绍如何配置 Waffo 网关并了解其工作原理。

官方文档

配置凭证、产品和 Webhook 时,可对照 Waffo Pancake API 参考

设置默认网关

当 Waffo Pancake 是你的主要结账渠道时,将计费默认网关指向 muse_waffo

MUSE_BILLING_DEFAULT_GATEWAY="muse_waffo"

网关选择

你仍可在单次结账请求中覆盖网关。该变量仅定义定价与 launch 流程使用的默认值。若未设置,Muse Billing 的回退顺序为:Creem → Stripe → Dodo → Waffo。

获取商户凭证

在部署或本地开发前,配置商户 ID 与 API 私钥。

# 商户 ID(以 `MER_` 开头)
MUSE_WAFFO_GATEWAY_MERCHANT_ID="MER_xxx"
# API 私钥(PEM)。在 `.env` 中用 `\n` 表示换行。
MUSE_WAFFO_GATEWAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
# 可选:强制 Waffo 环境("test" | "prod")
# 若省略,生产环境使用 prod,其他环境使用 test。
MUSE_WAFFO_GATEWAY_ENV="test"

登录 Waffo 商户后台,在 API 与开发 页面复制这两项:

  • 商户 ID:页面顶部的复制按钮。填入 MUSE_WAFFO_GATEWAY_MERCHANT_ID,不要使用店铺 ID(STO_xxx)。
  • API Key:在 API Keys 区域创建密钥,将 PEM 私钥填入 MUSE_WAFFO_GATEWAY_PRIVATE_KEY

两项都配置后网关才会启用。只配其中一项会在启动时记录警告,网关保持关闭。

密钥安全

MUSE_WAFFO_GATEWAY_MERCHANT_IDMUSE_WAFFO_GATEWAY_PRIVATE_KEY 仅用于服务端,切勿暴露到前端或版本库。

配置 Webhook 地址

Waffo 使用 SDK 内置公钥验签,不需要 webhook secret

在 Waffo 商户后台添加 HTTP Webhook,并将回调 URL 设为:

https://example.com/api/muse-billing/notify/muse_waffo

选择 Muse Billing 会映射的事件类型(或全部):

  • order.completed
  • subscription.activated
  • subscription.payment_succeeded
  • subscription.updated
  • subscription.canceling
  • subscription.uncanceled
  • subscription.past_due
  • subscription.canceled
  • refund.succeeded
  • refund.failed

签名请求头

即使在本地开发,Muse Billing 也要求请求带有 x-waffo-signature。签名无效或缺失会被拒绝。适配器会先用 request.text() 读取原始 body 再验签,不要先 json() 解析。

可选环境开关:

# 在生产 Node 构建中也接受沙盒(`test`)Webhook。
# MUSE_WAFFO_DEBUG=true

modeMUSE_WAFFO_GATEWAY_ENV 不一致的事件会被忽略,避免测试事件写入生产合约。

创建产品并获取产品 ID

产品 ID 默认来自 src/config/index.ts 中的 config.payments.productCatalog.*.gatewayProductIds.muse_waffo,也可通过环境变量覆盖。Waffo 产品 ID 以 PROD_ 开头:

# Pro 月付订阅产品 ID
NEXT_PUBLIC_MUSE_WAFFO_PRICE_PRO_MONTHLY_ID="PROD_muse_waffo_monthly_xxx"
# Pro 年付订阅产品 ID
NEXT_PUBLIC_MUSE_WAFFO_PRICE_PRO_YEARLY_ID="PROD_muse_waffo_yearly_xxx"
# 终身买断产品 ID
NEXT_PUBLIC_MUSE_WAFFO_PRICE_LIFETIME_ID="PROD_muse_waffo_lifetime_xxx"

在 Waffo 后台(产品)创建对应产品后,从产品详情页或 URL 复制 PROD_xxx ID。

环境必须一致

产品 ID 必须与 MUSE_WAFFO_GATEWAY_ENV 属于同一环境。把测试环境的产品 ID 用在 prod(或反过来)会在 launch 时报产品不存在。

本地开发测试

下载 Ngrok

Ngrok(https://dashboard.ngrok.com/get-started/setup/windows)是一款反向代理工具,可将本地开发服务暴露到公网。

运行

ngrok http 3000

回调域名

将终端中显示的域名作为 Webhook 配置中的回调地址。

切换到测试模式

确保 MUSE_WAFFO_GATEWAY_ENV 设为 test,并在 Waffo 测试环境完成一笔支付。

测试卡号预期结果
4576750000000110测试支付成功

测试模式

Waffo 测试模式不会产生真实扣款。结账成功后,确认一次性购买的 order.completed,或订阅的 subscription.activated / subscription.payment_succeeded 已到达 /api/muse-billing/notify/muse_waffo

工作原理

了解 Muse Billing 如何将 Waffo Pancake 接入系统。

集成文件

src/modules/muse-billing/lib/gateways/waffo/gateway.ts
src/modules/muse-billing/lib/gateways/waffo/mappers.ts
src/backend/api/routes/muse-billing/router.ts
文件作用
waffo/gateway.tsWaffo 网关实现:authenticated checkout、Webhook 验签、客户门户、订阅取消。
waffo/mappers.ts将 Waffo Webhook 事件与订单状态映射为 Muse 合约快照。
router.tsAPI 路由:暴露 /api/muse-billing/* 端点。

核心流程

支付与客户门户的调用链路:

前端调用 POST /api/muse-billing/launch,传入 productId、可选 gatewayId(默认由 orchestrator 选择)等参数。

服务端从 config.payments.productCatalog 映射中解析 Waffo 产品 ID。

创建 Waffo authenticated checkout 会话(buyerIdentity = 已登录用户 ID),并返回 launchUrl 供前端跳转到托管结账页。Checkout metadata 会带上 referenceIdplanProductId,方便 Webhook 匹配 pending 合约。

支付完成后,Waffo 发送 Webhook;服务端校验 x-waffo-signature,并将合约生命周期与访问窗口同步到数据库。订阅快照使用 Waffo 订单 ID(ORD_xxx)作为 gatewaySubscriptionId

当用户需要进入平台门户时,调用 POST /api/muse-billing/customer-hub。Waffo 使用共享消费者门户(https://pancake.waffo.ai/consumer/portal/login),不需要 merchant customer id。如需覆盖地址,设置 MUSE_WAFFO_CUSTOMER_PORTAL_URL

折扣码

Waffo checkout 没有折扣码字段。若定价页收集了折扣码,muse_waffo 的 launch 会忽略该字段。

相关文档

On this page