Skip to main content

Prerequisites

To integrate the Dodo Payments API, you’ll need:
  • A Dodo Payments merchant account
  • API credentials (API key and webhook secret key) from the dashboard
For a more detailed guide on the prerequisites, check this section.

API Integration

Checkout Sessions

Use Checkout Sessions to sell subscription products with a secure, hosted checkout. Pass your subscription product in product_cart and redirect customers to the returned checkout_url.
Mixed Checkout: You can combine subscription products with one-time products in the same checkout session. This enables use cases like setup fees with subscriptions, hardware bundles with SaaS, and more. See the Checkout Sessions guide for examples.

API Response

The following is an example of the response:
将客户重定向到checkout_url

Webhooks

在集成订阅时,您将接收到 webhooks 以跟踪订阅生命周期。这些 webhooks 有助于您有效地管理订阅状态和支付场景。 要设置您的 webhook 端点,请按照我们的详细集成指南

订阅事件类型

以下 webhook 事件跟踪订阅状态的变化:
  1. subscription.active - 订阅成功激活。
  2. subscription.updated - 订阅对象已更新(任何字段更改时触发)。
  3. subscription.on_hold - 由于续订失败导致订阅被暂停。
  4. subscription.failed - 创建授权失败时订阅创建失败。
  5. subscription.renewed - 订阅已为下一个计费周期续订。
为了可靠地管理订阅生命周期,我们建议跟踪这些订阅事件。
使用 subscription.updated 来获取关于任何订阅更改的实时通知,使您的应用程序状态与 API 保持同步而无需轮询。

支付场景

成功支付流程 您收到的 webhooks 及其时间安排取决于产品是否包含试用期。 立即计费(0 个试用天数):
  1. subscription.active:mandate 已获授权,订阅已激活。
  2. payment.succeeded:确认首次扣款。预计在结账后的 2–10 分钟内收到。
包含试用期:
  1. 试用期开始时(结账): payment method 获得授权后,subscription.active 触发。此时不会收取 recurring charge。 首次实际扣款会推迟到试用期结束。
  2. 试用期结束时: 系统会收取 recurring amount,您会同时收到 payment.succeeded subscription.renewed
每次后续续订:
  • subscription.renewed:每个 billing cycle 在扣除续订款项时触发,始终与 payment.succeeded 同时触发。它还会携带更新后的 next_billing_date
每当 subscription product 实际扣款时,您都会收到 subscription.renewed payment.succeeded。请使用 subscription.renewed(而不是单独使用 payment.succeeded)作为延长下一周期访问权限的信号。
付款失败场景
  1. 订阅失败
  • subscription.failed - 由于创建 mandate 失败,订阅创建失败。
  • payment.failed - 表示付款失败。
  1. 订阅暂停
  • subscription.on_hold - 由于续订付款失败或计划变更扣款失败,订阅被暂停。
  • 订阅暂停后,在 payment method 更新之前不会自动续订。
最佳实践:为简化实现,我们建议主要跟踪 subscription events,以管理订阅生命周期。
如需完整了解如何读取 error_code/error_message、决定何时重试以及向客户展示失败信息,请参阅处理付款失败

subscription.failedsubscription.on_hold

这两个事件很容易混淆,但处理方式完全不同:
subscription.failed 是终止状态。订阅无法重新激活。客户必须创建新订阅。该事件触发时,切勿授予 entitlements。

处理暂停的订阅

当订阅进入 on_hold 状态时,您需要更新 payment method 才能重新激活订阅。本节介绍订阅何时会暂停以及如何处理。

订阅暂停的情况

在以下情况下,订阅会被暂停:
  • 续订付款失败:由于余额不足、卡片过期或银行拒绝,自动续订扣款失败
  • 计划变更扣款失败:升级或降级计划期间的即时扣款失败
  • payment method 授权失败:payment method 无法获得 recurring charges 的授权
处于 on_hold 状态的订阅不会自动续订。您必须更新 payment method 才能重新激活订阅。

从暂停状态重新激活订阅

要将处于 on_hold 状态的订阅重新激活,请使用 Update Payment Method API。该 API 会自动:
  1. 为剩余应付款创建扣款
  2. 为该扣款生成 invoice
  3. 使用新的 payment method 处理付款
  4. 付款成功后,将订阅重新激活为 active 状态
1

Handle subscription.on_hold webhook

收到 subscription.on_hold webhook 后,请更新应用状态并通知客户:
2

Update payment method

客户准备好更新 payment method 后,请调用 Update Payment Method API:
如果客户已保存 payment methods,您也可以使用现有的 payment method ID:
3

Monitor webhook events

更新 payment method 后,请监控以下 webhook events:
  1. payment.succeeded - 剩余应付款的扣款成功
  2. subscription.active - 订阅已重新激活

Subscription event payload 示例


更改订阅计划

您可以使用 change plan API endpoint 升级或降级订阅计划。这允许您修改订阅的 product、quantity,并处理 proration。

Change Plan API Reference

有关更改订阅计划的详细信息,请参阅我们的 Change Plan API 文档。

Proration 选项

更改订阅计划时,您有四种处理即时扣款的选项:

1. prorated_immediately

  • 根据当前 billing cycle 的剩余时间计算按比例分摊的金额
  • 仅向客户收取新旧计划之间的差额
  • 在试用期内,这会立即将用户切换到新计划,并立即向客户收费

2. full_immediately

  • 向客户收取新计划的完整 subscription amount
  • 忽略之前计划的剩余时间或 credits
  • 适用于您希望重置 billing cycle,或无论 proration 如何都收取完整金额的情况

3. difference_immediately

  • 升级时,立即向客户收取两个计划金额之间的差额。
  • 例如,如果当前计划为 30 Dollars,客户升级到 80 Dollars,则会立即收取 $50。
  • 降级时,当前计划的未使用金额会添加为 internal credit,并自动用于抵扣未来的订阅续订费用。
  • 例如,如果当前计划为 50 Dollars,客户切换到 20 Dollars 的计划,则剩余的 $30 会记为 credit,并用于下一个 billing cycle。

4. do_not_bill

  • 立即应用计划变更,但在变更时不会收取任何费用。
  • 更新后的计划(以及 quantity/add-ons)会在下一次计划续订时计费,并且会保留原 billing date
所有三种“立即扣款”模式都会重置 billing cycle。 prorated_immediatelydifference_immediatelyfull_immediately 会将订阅的 next_billing_date 移至变更日期。只有 do_not_bill 会保留原续订日期,但不会立即扣款。

行为

  • 调用此 API 时,Dodo Payments 会根据您选择的 proration 选项立即发起扣款
  • 如果计划变更为降级,并且您使用 prorated_immediately,系统会自动计算 credits 并将其添加到订阅的 credit balance 中。这些 credits 专属于该订阅,只会用于抵扣同一订阅未来的 recurring payments
  • full_immediately 选项会跳过 credit calculations,并收取新计划的完整金额
请谨慎选择 proration 选项:如果需要根据未使用时间进行公平计费,请使用 prorated_immediately;如果无论当前 billing cycle 如何都要收取新计划的完整金额,请使用 full_immediately

扣款处理

  • 计划变更时发起的即时扣款通常会在 2 分钟内完成处理
  • 如果即时扣款因任何原因失败,订阅会自动进入暂停状态,直到问题得到解决

按需订阅

按需订阅允许您灵活地向客户收费,而不局限于固定时间表。所有账户均可使用此功能。
创建按需订阅: 要创建按需订阅,请使用 POST /subscriptions API endpoint,并在 request body 中包含 on_demand 字段。这样可以在不立即扣款的情况下授权 payment method,或设置自定义初始价格。
POST /subscriptions 已弃用。它仍适用于现有集成,但新集成应通过 Checkout SessionPOST /checkouts)和 subscription_data.on_demand 创建按需订阅。有关当前流程,请参阅按需订阅指南
要对按需订阅扣款: 对于后续扣款,请使用 POST /subscriptions//charge endpoint,并指定要为该笔交易向客户收取的金额。
如需完整的分步指南(包括请求/响应示例、安全重试策略和 webhook 处理),请参阅 按需订阅指南

关于订阅计费的关键事项

将订阅周期设置得长于付款频率。 如果订阅周期等于付款频率(例如,周期 = 1 个月,频率 = 1 个月),订阅仅对单个周期有效,随后会转为 expired,而不是续订。对于持续按月计费的计划,请设置较长的订阅周期(例如 20 年),并将付款频率设置为每月。
货币会在首次成功扣款时锁定。 创建 checkout 时,始终显式传递 billing_currency billing_address.country。如果省略,系统会根据客户的 IP 检测货币(Adaptive Currency);订阅首次扣款后,货币将在其整个生命周期内固定不变。客户之后出行也无法切换货币。
试用期会进行 $0 授权,而不是扣款。 当订阅包含试用期时,试用期开始时会创建一笔金额为 $0 的 mandate 授权以保存卡片;首次实际扣款会在试用期结束时发生。在支付列表中,处于试用期的订阅恰好会显示一笔支付,其状态为 amount: 0
订阅生命周期: on_hold = 续订失败(可恢复:提示客户更新其付款方式;适用催收重试)。expired = 期限结束且未续订,无法重新激活。客户必须重新订阅。cancelled = 由客户或商户结束。大多数续订失败是发卡行方面的拒付(余额不足、卡片被拒),而不是 Dodo 错误。
印度卡使用 RBI e-mandate。 非会话扣款(续订和计划变更扣款)最多可能需要 约 48 小时才能结算,并且超过 ₹15,000 的定期自动扣款需要客户重新进行身份验证(因此,超过该限额的升级无法使用现有 mandate)。当一笔扣款仍处于 processing 状态时,同一订阅上的第二笔扣款会失败,并显示 “Cannot create new charge as previous payment is not successful yet.” 非印度卡几乎可以即时确认。
订阅扣款的最低金额为 $1(或等值货币)。金额为 $0.01–$0.99 的扣款会被 product_price: value out of range 拒绝;只有 $0 通过按需 mandate_only 设置后才允许使用。

相关 API 参考

Create Subscription

用于创建订阅产品和管理订阅生命周期的 API 参考

Change Subscription Plan

用于升级、降级或更改订阅计划并配置按比例计费选项的 API 参考

Update Payment Method

用于更新付款方式和重新激活暂停中订阅的 API 参考

Patch Subscription

用于更新订阅详细信息和配置的 API 参考
最后修改于 2026年8月17日