Skip to main content

概览

按需订阅允许您一次性授权客户的支付方式,然后在需要时收取可变金额,而不是固定的日程表。所有账户都可使用此功能,无需审批。 使用本指南:
  • 创建按需订阅(授权带有可选初始价格的授权)
  • 通过自定义金额触发后续收费
  • 使用webhook跟踪结果
有关一般订阅设置,请参阅订阅集成指南

先决条件

  • Dodo Payments商家账户和API密钥
  • 配置的webhook密钥和接收事件的端点
  • 目录中的订阅产品
本指南通过结账会话创建按需订阅(POST /checkouts),此会话始终返回托管的checkout_url。将客户重定向到此处以批准授权,并设置return_url为他们应在批准后到达的位置。

按需如何运作

  1. 您使用on_demand对象创建订阅以授权支付方式,并可选择收取初始费用。
  2. 随后,您可以使用专用的收费端点根据该订阅创建自定义金额的收费。
  3. 您可以监听webhook(例如,payment.succeededpayment.failed)来更新您的系统。

创建按需订阅

端点:POST /checkouts 关键请求字段(正文):
请查看创建结账会话

创建按需订阅

Success

按需订阅的收费

授权授权后,按需创建所需的费用。 端点:POST /subscriptions/{subscription_id}/charge 关键请求字段(正文):
integer
必填
收费金额(以最小货币单位表示)。示例:要收取$25.00,请传递2500
string
可选的收费货币覆盖。
string
可选的描述覆盖。
boolean
如果为真,在product_price中包含自适应货币费用。如果为假,则费用将被追加在顶部。
object
付款的附加元数据。如果省略,则使用订阅元数据。
Success
向非按需订阅收费可能会失败。在收费前确保订阅详情中有on_demand: true

处理失败的收费

当对按需订阅的收费失败时,您可以决定接下来会发生什么。与计划订阅不同,按需订阅在失败后仍然可以收费。您可以调用收费端点作为自己的重试逻辑的一部分。

失败时发生的事情

1

Charge attempt fails

POST /subscriptions/{subscription_id}/charge请求返回错误响应或异步完成并发出带有拒绝原因的payment.failed webhook。
2

Subscription may transition to on_hold

订阅可能会移动到on_hold状态并发出subscription.on_hold webhook(请参阅订阅状态→暂停)。这是一个信号,而不是锁定。对于按需订阅,on_hold会阻止您再次收费。
3

Retry the charge (your call)

对于按需流程,Dodo不会自动重试。您可以随时再次调用POST /subscriptions/{subscription_id}/charge进行重试。应用下方的安全重试策略——使用指数回退,跳过硬拒绝,并避免突发模式,以便我们的欺诈和风险系统不会标记重试。
4

Optionally, ask the customer for a new payment method

如果重试因支付方式本身失效(过期卡、关闭账户等)而持续失败,使用POST /subscriptions/{subscription_id}/update-payment-method从客户那里收集新的。在成功时,订阅返回到active,并依次发出payment.succeededsubscription.active webhook。
按需 vs 计划:对于计划订阅,Dodo会自动进行续订重试和扣款通知。对于按需订阅,您负责重试策略,因为只有您知道下次收费什么时候应该发生(由您的使用情况事件驱动,而不是日历)。

按需收费失败的webhook顺序

事件3和4只有在后续收费成功后才会触发。

重试责任

Dodo Payments 不会自动重试失败的按需收费。您拥有重试策略。请遵循以下的安全重试准则,以避免被我们的欺诈检测系统标记为卡测试。
订阅扣款通知——内置的电子邮件恢复序列——仅限于计划订阅的续订付款失败和客户主动取消。它并不适用于按需收费失败。当您决定需要更新支付方式时,请直接与客户沟通(例如,事务性电子邮件或应用内提示)。

付款重试

我们的欺诈检测系统可能会阻止激进的重试模式(并可能将其标记为潜在的卡测试)。请遵循安全重试政策。
突发重试模式可能会被我们的风险系统和处理器标记为欺诈或怀疑的卡测试。避免集中的重试;请遵循下列的后退时间表和时间对齐指南。

安全重试政策的原则

  • 后退机制:在重试之间使用指数退避。
  • 重试限制:限制总重试次数(最大3-4次尝试)。
  • 智能筛选:仅对可重试的失败进行重试(例如,网络/发卡行错误、资金不足);绝不要对硬拒绝进行重试。
  • 卡测试防范:不要重试诸如DO_NOT_HONORSTOLEN_CARDLOST_CARDPICKUP_CARDFRAUDULENTAUTHENTICATION_FAILURE等失败。
  • 可变元数据(可选):如果您维护自己的重试系统,通过元数据区分重试(例如,retry_attempt)。

建议的重试时间表(订阅)

  • 第一次尝试:您创建收费时立即进行
  • 第二次尝试:3天后
  • 第三次尝试:再过7天(总共10天)
  • 第四次尝试(最后一次):再过7天(总共17天)
最后一步:如果仍未付款,根据您的政策将订阅标记为未付款或取消。在窗口期内通知客户更新其支付方式。

避免突发重试;与授权时间对齐

  • 将重试固定在原始授权时间戳上,以避免在您的投资组合中出现“突发”行为。
  • 示例:如果客户在今天的1:10开始试用或授权,请按您的退避时间安排后续重试在后续天的1:10(例如,+3天→1:10,+7天→1:10)。
  • 或者,如果您存储了上次成功支付的时间T,请安排下次尝试在T + X days以保持时间对齐。
时区和DST:使用统一的时间标准进行安排,仅在显示时进行转换以保持间隔。

您不应重试的拒绝代码

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
有关拒绝原因的完整列表及其是否可由用户纠正,请参见交易失败文档。
仅对软/临时问题(例如,insufficient_fundsissuer_unavailableprocessing_error,网络超时)进行重试。如果同样的拒绝重复出现,请暂停进一步的重试。

实现指南(无代码)

  • 使用调度程序/队列持久化精确时间戳;在相同的HH:MM计算下次尝试。
  • 维护和引用上次成功支付的时间戳T来计算下次尝试;不要在相同时刻将多个订阅聚集在一起。
  • 始终评估最后的拒绝原因;对于上面的跳过列表中的硬拒绝停止重试。
  • 限制每个客户和每个账户的并发重试,以防止意外激增。
  • 积极沟通:通过电子邮件/SMS通知客户更新其支付方式,以便在下次计划尝试前更新。
  • 元数据仅用于可观测性(例如,retry_attempt);切勿通过旋转无关紧要的字段“规避”欺诈/风险系统。

取消

按需订阅与计划订阅的取消流程不同,因为没有固定的计费周期可用于锚定即时结束日期。

客户门户行为

当客户从客户门户取消按需订阅时,取消计划在下一个计费日期。对于按需订阅,有意不显示立即取消选项。 原因:按需订阅没有可预测的定期续订日期——下次收费时间完全由您的使用情况事件驱动。将取消安排在下一个计费日期,保持授权有效,直到期间结束,以便对正在进行的使用情况收取费用,然后干净地结束订阅。 客户确认取消后:
  • 订阅保持active,并通过POST /subscriptions/{id}/charge收费,直到安排的取消日期。
  • cancel_at_next_billing_date设置为true
  • 取消生效时会发出subscription.cancelled webhook。
如果您需要立即结束订阅(例如,响应退款或支持请求),请通过API而不是依赖客户门户流程程序化地取消它。

程序化取消

您可以随时通过API取消按需订阅。您可以选择取消是立即生效还是计划的。 端点:PATCH /subscriptions/{subscription_id}
将订阅status设置为cancelled以立即结束。授权被撤销,无法创建进一步的收费。
cURL

取消时的webhook

要在处理webhook时区分类别按需取消和计划订阅取消,请在处理webhook时检查订阅的on_demand标志。

使用webhook跟踪结果

实施webhook处理以跟踪客户旅程。参见实现Webhooks
  • subscription.active: 授权授权并激活订阅
  • subscription.failed: 创建失败(例如,授权失败)
  • subscription.on_hold: 订阅已暂停(例如,未付款状态)
  • subscription.cancelled: 订阅完全取消(参见取消
  • payment.succeeded: 收费成功
  • payment.failed: 收费失败
对于按需流程,重点关注payment.succeededpayment.failed来对齐使用情况的收费。当payment.failed后接subscription.on_hold时,请参见处理失败的收费以恢复订阅。

测试和下一步

1

Create in test mode

使用您的测试API密钥创建订阅,然后打开返回的checkout_url并完成授权。
2

Trigger a charge

调用收费端点,使用小型product_price(例如,100),并验证您收到payment.succeeded
3

Go live

验证事件和内部状态更新后,切换到您的实时API密钥。

故障排除

  • 422 无效请求:确保在创建时提供了on_demand.mandate_only,并且在收费时提供了product_price
  • 货币错误:如果您覆盖product_currency,请确认您的账户和客户是否支持。
  • 未收到webhooks:验证您的webhook URL和签名密钥配置。
最后修改于 2026年7月21日