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_ID 与 MUSE_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.completedsubscription.activatedsubscription.payment_succeededsubscription.updatedsubscription.cancelingsubscription.uncanceledsubscription.past_duesubscription.canceledrefund.succeededrefund.failed
签名请求头
即使在本地开发,Muse Billing 也要求请求带有 x-waffo-signature。签名无效或缺失会被拒绝。适配器会先用 request.text() 读取原始 body 再验签,不要先 json() 解析。
可选环境开关:
# 在生产 Node 构建中也接受沙盒(`test`)Webhook。
# MUSE_WAFFO_DEBUG=truemode 与 MUSE_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)是一款反向代理工具,可将本地开发服务暴露到公网。
切换到测试模式
确保 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 接入系统。
集成文件
| 文件 | 作用 |
|---|---|
waffo/gateway.ts | Waffo 网关实现:authenticated checkout、Webhook 验签、客户门户、订阅取消。 |
waffo/mappers.ts | 将 Waffo Webhook 事件与订单状态映射为 Muse 合约快照。 |
router.ts | API 路由:暴露 /api/muse-billing/* 端点。 |
核心流程
支付与客户门户的调用链路:
前端调用 POST /api/muse-billing/launch,传入 productId、可选 gatewayId(默认由 orchestrator 选择)等参数。
服务端从 config.payments.productCatalog 映射中解析 Waffo 产品 ID。
创建 Waffo authenticated checkout 会话(buyerIdentity = 已登录用户 ID),并返回 launchUrl 供前端跳转到托管结账页。Checkout metadata 会带上 referenceId 与 planProductId,方便 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 会忽略该字段。
相关文档
- Creem 支付网关 — 备选支付网关
- Stripe 支付网关 — 备选支付网关
- Dodo Payments 网关 — 备选支付网关
- 基础配置 — 定价与产品 ID 配置
- 环境变量 — 网关密钥与公开产品 ID