Skip to main content
本页介绍使用 Waffo Subscription 的订阅(周期扣款)集成主线。选择此方式后,按顺序走完即可完成接入。每一节只讲这一步的决策与要点,字段细节和枚举取值链接到对应参考页,不在此重复。 一次性支付的接入路线见纯 API 集成概览。

选择订阅接入方式

Waffo 支持两种订阅接入方式。先根据谁负责管理订阅选择路径: Waffo Subscription 为商户提供统一的接入方式。具体续费可能由 Waffo 或支付渠道执行。不同支付方式的少量能力差异见订阅支付方式对比。 商户自管订阅不使用 /api/v1/subscription/*。你的系统负责维护扣款周期、订阅状态、失败重试、升降级和取消;每期使用绑卡得到的 Token,通过 ONE_TIME_PAYMENT 发起 MIT。绑卡文档已经包含 Token 生命周期、CIT 验证、MIT 请求和支付结果确认,本页不再重复。 选择 Waffo Subscription 后,按下面的主线完成接入:

集成前先确认三件事

订阅是否可用、以及各支付方式的具体能力,最终以商户合约配置和 POST /api/v1/paymethodconfig/inquiry 返回结果为准。

选择订阅模式

Waffo 提供两种订阅模式,核心差别在续费失败后的服务与计费处理。选错会导致权益开关与账单节奏和你的预期不一致,所以要在接入前定下来。 用两个问题判断你属于哪一种:
  1. 假设第二期原定 7 月 1 日扣费,一直失败到 7 月 3 日才成功。中间这两天,你是暂停用户权益(支付优先),还是继续提供服务(服务优先)?
  2. 如果某一期续费彻底失败,后续周期你还要不要继续扣费?停止是支付优先,继续是服务优先。
请在接入前选择支付优先或服务优先,并将选择告知 Waffo。需要确认或调整订阅模式时,联系 Waffo 技术支持。
PIX 只支持服务优先,其余支付方式两种都支持,见订阅支付方式对比。

配置计费周期与试用期

周期由 productInfo.periodType 与 productInfo.periodInterval 组合表达。
没有 YEARLY 类型。 年度订阅用 MONTHLY + periodInterval: "12" 表达;同理季度是 3、半年是 6、两年是 24。
其余周期相关字段:
  • numberOfPeriod — 总期数。留空表示无限期订阅。
  • trialPeriodAmount — 试用期每期金额,须大于等于 0 且小于正式期金额。留空表示无试用期。设为 0 即免费试用。
  • numberOfTrialPeriod — 试用期期数。
  • trialPeriodType / trialPeriodInterval — 试用期的周期类型与间隔。可与正式期不同(例如按周试用、按月正式);留空则沿用正式期的取值。PIX 要求试用期频次与正式期一致。
  • scheduledAmounts — 每期预设金额列表,元素为 {period, amount}。当各期金额不同时使用,例如首期优惠、阶梯涨价。不需要逐期不同金额时不用传。该字段仅适用于支持此能力的 Waffo 托管订阅;渠道托管订阅(如 PIX、DANA)不支持。
完整字段定义见创建订阅。

创建订阅与处理授权

调用 POST /api/v1/subscription/create 创建订阅。除周期参数外,这几个字段最容易出问题:
  • subscriptionRequest — 订阅幂等键,由你生成。重试创建请求时必须复用同一个值,见幂等性。
  • currency 和 amount — 订阅用的是 currency 与 amount,不是一次性支付的 orderCurrency 与 orderAmount。用错字段名是最常见的接入错误。
  • paymentInfo.payMethodType — 可选。传入时按支付方式类型过滤候选集;省略时不按类型过滤。仅当 paymentInfo.payMethodName 也省略时,Waffo 才根据商户合约展示所有符合条件的支付方式。
  • userInfo.userEmail — 必填。没有真实邮箱时,传按用户 ID 构造的唯一兜底邮箱,不要用占位值,也不要多个用户共用一个邮箱。
  • subscriptionManagementUrl — 必填,且必须是有鉴权的页面(不能是公开 URL)。建议传 Web 地址,不要传 deeplink,因为电脑端打不开。你可以用自己的订阅管理页,也可以包装 POST /api/v1/subscription/manage 返回的 URL。
  • notifyUrl — Webhook 回调地址,见本页监听通知。

处理授权跳转

响应中的 subscriptionStatus 为 AUTHORIZATION_REQUIRED 时,表示需要用户完成授权,此时必须把用户重定向到授权页面。授权地址在 subscriptionAction 字段里,它是一个 JSON 字符串,需要先解析再取其中的 webUrl:
不要把 subscriptionAction 当对象直接取属性——它是字符串,必须先 JSON 解析。同样的处理方式适用于查询订阅、订阅升降级和升降级查询的响应。

订阅状态与商户应对

订阅有 8 个状态。各状态下你该做什么,见支付生命周期;各状态是否为终态,见数据参考。
不要仅凭创建接口的同步响应就认定订阅最终状态。订阅激活、取消、关闭都通过 Webhook 通知,或用 POST /api/v1/subscription/inquiry 主动查询确认。

监听通知

订阅涉及三类通知,按你关心的粒度选择监听。三者的触发时机、适用场景以及推荐组合,见 Webhook 事件类型。 关键约束:SUBSCRIPTION_STATUS_NOTIFICATION 和 SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION 都是异步分发的,到达顺序不保证,不要用回调到达顺序驱动业务状态机。正确做法(幂等去重、收到任一回调后先查询最终状态)见 Webhook 处理最佳实践。

续费失败与重试

续费扣款失败后的重试由 Waffo 或支付渠道负责,取决于续费托管方式。 Waffo 托管订阅由 Waffo 自动重试当期扣款,你不需要自己实现重试:
  • 重试策略按你的计费周期分档配置,每档包含最大重试次数与重试间隔。
  • 重试间隔以天为单位。不存在小时级的重试间隔配置。
  • 未客制化时,默认在当期扣款首次失败后每 1 天重试一次,最多重试 5 次。若需客制化重试次数或间隔,请联系 Waffo 客户经理或技术支持;该策略不能通过接口传参修改。
  • 重试成功后的下期起算点,以及重试次数用尽后是否继续发起后续周期扣款,由你的订阅模式决定。Waffo 托管续期时间的完整计算规则见订阅支付方式对比。
渠道托管订阅由支付渠道按自身规则重试。PIX、DANA 使用钱包侧重试规则,不支持商户自定义;具体能力见订阅支付方式对比。
对于 Waffo 托管订阅,通知粒度上要注意区分:重试期间每一次扣款失败都会发送 PAYMENT_NOTIFICATION;如果你只关心每期的最终结果、不关心中间重试过程,监听 SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION 即可。

升降级、修改与取消

这三件事用的是不同接口,不要混用:

常见金额调整场景

update 只支持 ACTIVE 状态的 Waffo 托管订阅。每次请求至少要传 amount、productInfo.trialPeriodAmount 或 productInfo.scheduledAmounts 中的一项;即使同时传 topupInfo 创建补差单,也要给出补差成功后的目标金额。直接调价影响未来扣费;当前期已经生成,不能直接改金额。 当期增购并补差的请求示例:
topupAmount 是由你计算的当期补差金额,必须大于 0;amount 是补差成功后用于后续周期的新总金额。topupRequest 是补差单幂等键,重试同一请求时必须复用。响应中 topupInfo.topupStatus 为 AUTHORIZATION_REQUIRED 时,先将 topupInfo.topupAction 作为 JSON 字符串解析,再重定向到其中的 webUrl。同一订阅同时只能有一笔处理中的补差单。 部分支付方式的用户可以在支付方式侧自助解约(例如 Apple Wallet、Google Pay、PayPay App),解约状态会回传 Waffo 并触发 CHANNEL_CANCELLED 或 USER_CANCELLED。哪些支付方式支持用户侧取消,见订阅支付方式对比。

沙盒验证与验收

1

首期支付

与一次性支付一样,在收银台页面操作。
2

续费模拟

调用 POST /api/v1/subscription/manage 拿管理页 URL,打开后用页面上的「模拟下期支付成功」「模拟下期支付失败」按钮逐期模拟。操作步骤见沙盒与测试和沙盒模拟器。
3

验收

按集成验收标准执行订阅验收用例,填写订阅支付验收用例模板后提交给 Waffo 技术对接群。
上线前至少确认:首期成功与失败两条链路、订阅状态通知与订阅支付通知的验签、按 subscriptionRequest 与期数匹配到对应周期订单、以及 Unknown 状态下不自行关闭订阅。