Skip to main content

经常性收入,自动化管理。

客户订阅后,我们处理计费周期、续费重试和生命周期管理。你专注于产品即可。

工作原理

续费扣款失败后,订阅进入 past_due。Waffo 自己不安排重试:支付通道会再尝试扣款一次,通常在次日。重试成功则订阅回到 active(subscription.recovered);重试失败则订阅立即取消(subscription.canceled),买家需要重新订阅。没有独立的宽限期计时。买家会在每次续费前收到提醒邮件(周订阅提前 1 天、月付和季付提前 3 天、年付提前 7 天;试用到期前 1 天),每次扣款成功后收到收据。

订阅套餐如何建模

在 Waffo Pancake 中,每一个可单独购买的订阅选项 都是一个独立的订阅产品。 最常见的区分方式是计费周期,例如:
  • 月付
  • 年付
如果你同时提供月付和年付,通常应建模为 2 个订阅产品。

订阅状态


计费周期


试用期

降低注册门槛,让客户先试用再正式付费 —— 可以免费,也可以只收一小笔费用。

配置试用

创建订阅产品时,在控制台中启用试用开关并设置试用天数。

平台级试用保护

Waffo Pancake 作为 Merchant of Record(MoR),会在平台层自动防止试用被重复滥用: 两个层级如何交互:
  • 如果商户请求 ≤ 平台最大值 → 使用商户请求的值
  • 如果商户请求 > 平台最大值 → 回退到平台最大值
  • 如果商户未指定 → 使用完整的平台最大值

付费试用(试用期金额)

试用期不一定要免费。可以在试用期内收取一笔较低的金额,而不是完全免除费用——即经典的”1 美元试用”模式。这个金额是可选的,可以按币种单独设置,且始终低于正式价格;试用期结束后会自动切换为按正式价格计费。
相比免费试用,付费试用能更好地过滤低意向注册用户,代价是会带来一定的转化摩擦。收取一笔象征性的小额费用(例如 $1)通常就足以验证支付方式的有效性,同时不会劝退真实意向买家。

通过 API 设置试用期金额

查看 trialAmount 字段的请求格式与规则说明。

买家身份与试用保护

试用资格通过 buyerIdentity 追踪 — 您通过认证式收银台提供的稳定标识符。平台使用此标识检测跨会话的重复试用领取。
不提供 buyerIdentity(匿名收银台)时,试用资格检查将被完全跳过。买家可以通过更换邮箱地址无限领取试用。
7-14 天的试用效果最佳。太短 = 没有足够时间评估。太长 = 容易被遗忘。

续费恢复

续费扣款失败时,订阅转为 past_due,你会收到 subscription.past_due。恢复窗口很短,由支付通道决定:通道会再扣一次,通常在次日。
  • 重试成功 —— 订阅回到 active,你会收到 subscription.recovered 和 subscription.payment_succeeded。
  • 重试失败 —— 订阅立即取消,你会收到 subscription.canceled。买家需要重新订阅;不会再有第三次尝试,也没有宽限期计时。
建议在 past_due 的这一天保留访问权限,并在重试前提醒买家更新支付方式,因为第二次失败就会终止订阅。
past_due 更适合理解为“续费异常待恢复”,而不是“付款失败后立即终止”。

管理订阅

取消

取消时,订阅会先进入 canceling 中间状态,在当前计费周期结束时自动转为 canceled。客户在此期间保留访问权限。
响应中包含 currentPeriodEnd,用于判断访问权限何时到期。返回的状态为 canceling(若周期已结束则为 canceled)。
没有立即取消的选项。客户始终保留访问权限直到已付费周期结束。取消后状态流转为:active → canceling → canceled。

恢复订阅

如果订阅仍处于 canceling 状态,客户可以在当前周期结束前恢复订阅。 恢复后:
  • 订阅状态回到 active
  • 当前周期内的访问权限保持不变
  • 后续将按原有周期继续正常续费
恢复订阅适用于“已经请求取消,但尚未到期”的场景。本质上是撤销取消操作,而不是重新购买一个新订阅。

变更方案

方案变更让订阅买家换到另一个方案,无需先取消再重新购买。它在实现上是一次取消加一个新订阅 —— 旧单关闭,新单开出。订阅的方案不存在原地编辑。 买家最终一定会在托管的变更确认页上确认:新旧方案并排展示,按比例折算的差额逐项列出,并写明生效日期。

变更方向决定默认生效时机

立即生效的变更中,原方案未用完的价值会折抵到新方案的扣款上。这笔折抵在提交那一刻按实际剩余天数重新计算 —— 签发链接时展示的数字只是估算,不是承诺。
最后 24 小时是不对称的。 立即生效要求距下次扣款至少 24 小时;下周期生效只要求距周期结束至少 1 小时。因此在最后这一天里,升级会返回 400(Immediate plan change requires at least 24 hours before the next charge),除非你显式传入 changeTiming: "next_period" —— 它不会静默回退。降级本就默认下个周期,所以仍然可用。

谁可以发起

两条路径,规则各不相同:
selfServicePlanChange 是商品分组上的开关,未设置即视为关闭。关闭期间,客户门户中的方案变更会被 403 拒绝 —— 商户签发的变更不受影响。在告诉买家可以自行切换方案之前,请先打开它。
在 Dashboard 界面中发起方案变更尚未上线 —— 订阅页面上的入口标注为即将上线。API 现在就可以用。

买家自助

自助变更发生在客户门户中,你无需做任何对接工作。买家登录、打开订阅、在同一分组内挑选另一个方案并确认即可。 开通方式:把这些方案放进同一个商品分组,并开启 selfServicePlanChange。
客户门户不是唯一的自助入口。你也可以在自己的界面里用 customer 会话令牌提供同一件事 —— SDK 里的 customer.createPlanChangeSession() —— 它以买家自己的凭证发起,受同样三个条件约束:是他自己的订阅、新旧方案同组、该组 selfServicePlanChange 已开。换成用你的 API Key 签发则是另一条路:三个条件都不适用,你可以把订阅换到任意方案 —— 见下文。

通过 API 由商户发起变更

1

签发变更链接

调用 checkout/create-session,把 originOrderId 设为你想变更的那笔订阅单。这会把该端点切换到换方案模式,返回指向变更确认页的 checkoutUrl。
2

自行投递

邮件、站内信,用你既有的触达方式即可。平台不会替你发送这个链接。
3

买家确认

买家查看新旧方案对比并确认。你的系统通过 Webhook 得知结果。
可选参数 签发链接时的前置校验 —— 这些会在买家看到页面之前就失败:
未确认的变更不会挡住新的变更。如果买家打开了链接却一直没有付款,再签发一条即可。

你的系统需要预期什么

一次方案变更的生命周期由三个 Webhook 事件覆盖: 立即生效的变更在授权成功后即到达切换时刻,因此会直接发 plan_changed,前面不会有 scheduled。
权限判定逻辑有两个坑:
  1. 涉及的两笔订单都不会发 subscription.activated 与 subscription.canceled —— 这是有意为之,避免「收到取消就回收权限」的逻辑在换方案时误触发。
  2. 从买家确认到切换时刻之间,原订阅处于 canceling,但仍然享有权益 —— 它已付费的周期仍在运行中。请把 canceling 当作仍有访问权,与买家自己发起的到期取消同一口径。
在计划中的变更尚未生效期间,新订阅还没有计费周期(currentPeriod 为 null)—— 首个周期要等切换时刻由支付渠道确认后才确定。
如果变更失败,新单关闭,原订阅照旧继续。若是已把原订阅置为 canceling 的计划变更,原订阅会恢复为 active。此后你可以再签发一次变更。
不支持跨币种变更;订阅处于试用期内不可换方案。

指标

MRR(月经常性收入)

关键指标


Webhooks

通过 Webhook 订阅订阅生命周期事件。在 设置 → Webhook 中配置端点。
此处不列出具体的 Webhook 事件名称,因为它们可能会变更。请参阅控制台中的 Webhook 配置以获取当前可用事件列表。
Webhook 负载遵循 Waffo Pancake 的标准约定:
  • ID 为 UUID v4 格式
  • 金额以显示格式字符串表示
  • 时间戳为 ISO 8601 UTC 格式
  • 计费频率使用 billingPeriod 字段(例如 monthly、yearly)

客户门户

让客户自助管理订阅:
  • 查看详情
  • 更新支付方式
  • 更换方案
  • 取消
  • 恢复订阅
  • 下载发票

客户门户

自助式订阅管理。

最佳实践

续费未成功 ≠ 立即取消。给客户时间更新支付方式并完成恢复。
试用即将到期、即将扣款。不要让客户感到意外。