Skip to main content
本页讲的是时间:某一期在哪一天扣款,以及这一天如何移动。重试策略和支付方式行为见 订阅重试与支付方式; 金额见 订阅金额与按期排期。

续订扣款实际是什么时候发起的?

Waffo 在订阅上保存一个下次扣款时间戳,时间戳过去之后,由周期性扫描发起该期的扣款。两个后果:
  • 日期是确定的;当天的具体时刻不是。对账和客户通知请按天的粒度规划,而不要精确到分钟。
  • 所有保存的订阅时间戳——下次扣款时间、期开始和结束时间、订阅结束时间——都是 UTC,API 以 ISO 8601 返回。 如果你的计费日历是本地时间,请在你这一侧转换;没有按商户设置的计费时区。
无法把订阅固定为「在客户所在时区的 09:00 扣款」。你最接近的控制手段是 /api/v1/subscription/create 上的 startTime, 它设定整个排期推导所依据的锚点——见 订阅创建与校验。

后续每个计费日期是怎么推算出来的?

从订阅的开始时间出发,累加整数个周期:
不是从上一次扣款成功的日期算,也不是从上一期的日期逐步推进。每一期都从同一个锚点计算,所以某一期延迟扣款不会挪动之后各期, 舍入也永远不会从一期累积到下一期。 所使用的周期是该期号所适用的周期:如果你配置了单独的试用周期,试用期各期按试用周期从开始时间起计数, 正式期各期按正式周期从试用结束起计数。切换发生在试用结束的那个期号。

月度订阅从 31 号开始,二月会怎样?

它会在短月份收敛到最后一个有效日,之后再弹回 31 号。 因为每一期都按开始 + n 个月计算,1 月 31 日加一个月得到 2 月 28 日(闰年为 29 日)——没有 2 月 31 日——但加两个月得到 3 月 31 日, 加三个月得到 4 月 30 日。收敛只作用于落到的那个月;它不会成为新的锚点。 这是月末订阅中最常见的意外:**订阅确实会弹回 31 号。**31 号开始的客户在每个月的最后一天被扣款——28、29、30 或 31 日, 取该月实际有的那一天。不要为这类订阅构建假定固定日号的提醒。 如果在稳定的日号计费对你的产品很重要,请让订阅在每个月都存在的日子(1–28 日)开始,或者显式设置 startTime,而不是让「现在」决定锚点。

某一期重试了三天才成功,下一期会挪动吗?

**默认不会。**下一期按上文所述从订阅开始时间计算,所以靠重试补收的一期不会把后面的排期往后推——客户不会多得天数。 有一个账户级设置,可以把排期重新锚定到实际支付时间:启用后,一次成功的续订会从该次扣款成功的那一刻重新计算下次扣款日期, 订阅的结束日期也随之重新计算。关于它有两点需要了解:
  • 它只会把排期向后移。如果重新计算出的日期早于已保存的日期,则保留已保存的那个。
  • 它由 Waffo 在你的收单协议上配置,不在 Portal 中。如果你需要「客户永远从实际付款那天起获得完整一个周期」, 在按任一种行为开发之前,先问你的 Waffo 对接人你的账户设置的是哪种。
因为两种行为产生不同的日期,不要自己推导下次扣款日期。每期结束后从 /api/v1/subscription/inquiry 读回 nextPaymentDateTime。

做「下次扣款」提醒该读哪个日期字段?

所以:做提醒读 nextPaymentDateTime,但在向客户承诺日期之前先处理两种情况。
  • **null 不代表「不再扣款」。**订阅的续订被挂起期间——例如当前期仍在尝试扣款,或有套餐变更待处理——Waffo 返回 null。 挂起解除后日期会重新出现。把 null 当作尚未确定,而不是已结束。
  • **在最后一期,该值是过期的而不是未来的。**它在那里不再推进,所以仍显示最后一期自身的日期。在告诉客户会再次扣款之前, 请用 currentPeriod 对照订阅的最终期数,或检查 endDateTime。
要判断「这个订阅是否已结束」,请读状态—— 订阅创建与校验上的终态才是答案,而不是某个日期字段。

按期扣款状态分别是什么意思?

每个计费期都有自己的订单和自己的状态。Portal 将它们显示为 Initial、To Pay、Retrying、Paid 和 Closed: 比标签更重要的两条规则:
  • PAY_SUCCESS 和 ORDER_CLOSE 是唯一的终态。其他任何状态仍可能变化。
  • 某一期到达 ORDER_CLOSE 不会改变订阅自身的状态。订阅保持 ACTIVE,下一期按计划尝试。 权益决策由你根据这些按期结果自行做出;见 订阅重试与支付方式。

为什么第一次扣款完全没有重试?

因为立即开始的订阅的首次扣款是客户在场的支付,不是后台续订。它失败时,该期的订单会立即关闭:没有重试计划、不尝试备用支付方式,也不给客户发支付失败邮件。 理由是客户就在现场——正确的恢复方式是让他们再试一次,或者换一种支付方式,而不是反复重试一张他们正眼看着失败的卡。 第二行是容易让人栽跟头的例外。延迟开始的订阅是预先授权、之后在客户不在场时扣款的,所以它的首次扣款表现得和后续各期一样。 对立即开始的情况,恢复方式是在客户选好另一种支付方式后创建一个新的订阅。不要为同一期单独创建一次性订单并指望订阅能感知到它。

我能让客户自己支付失败的那一期,而不是等重试吗?

**没有面向商户的接口可以针对某个失败的期收款。**订阅 API 只有 create、inquiry、cancel、manage、change、change/inquiry 和 update—— 没有一个会重新发起某期的扣款,也没有「立即支付」或「补缴」调用。 你实际可以做的: 添加一个可用的支付方式是价值最高的动作,因为已绑定的备用方式会在下一次失败时立即尝试,而不是等待重试间隔。

我能在 Portal 里自己改重试策略吗?

不能。重试策略——每周期的间隔和最大尝试次数——位于你的收单协议上,由 Waffo 设置。没有 Portal 页面、也没有 API 可以写入它, 所以不能自助修改,它也不是按请求的参数。 协议上其他影响排期的设置也是如此:上文的支付后重新锚定行为,以及取消订阅时是否关闭待执行的重试。三者都是账户级的。 其中任何一项被修改时,请明确询问它是适用于已有订阅还是仅适用于新订阅——答案取决于是哪项设置,而假设错了正是对账出问题的原因。

不等真实周期,我怎么测试这些?

使用沙箱续订模拟器:激活一个订阅,用 /api/v1/subscription/manage 获取其管理 URL,打开它,用模拟下次支付的控件一期一期地推进。 每点一次就是一期,所以你可以串起「第 2 期成功、第 3 期失败」。详情和保留的测试金额见 沙箱模拟器 和沙箱测试。 沙箱不允许你快进真实时钟,所以上文的月末行为最好通过在每次模拟一期后读取 nextPaymentDateTime 来验证,而不是靠等待—— 31 号开始的订阅应在二月显示 28/29 日,在三月重新显示 31 日。