跳转到主要内容

前提条件

要集成 Dodo Payments API,您需要:
  • 一个 Dodo Payments 商户账户
  • 来自仪表板的 API 凭证(API 密钥和 webhook 密钥)
有关前提条件的更详细指南,请查看此 部分

API 集成

结账会话

使用结账会话以安全的托管结账方式销售订阅产品。将您的订阅产品传递到 product_cart 并将客户重定向到返回的 checkout_url
您不能在同一结账会话中混合订阅产品和一次性产品。
import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function main() {
  const session = await client.checkoutSessions.create({
    product_cart: [
      { product_id: 'prod_subscription_monthly', quantity: 1 }
    ],
    // Optional: configure trials for subscription products
    subscription_data: { trial_period_days: 14 },
    customer: {
      email: '[email protected]',
      name: 'Jane Doe',
    },
    return_url: 'https://example.com/success',
  });

  console.log(session.checkout_url);
}

main();

API 响应

以下是响应的示例:
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
将客户重定向到 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 保持同步,而无需轮询 API。

支付场景

成功支付流程 当支付成功时,您将收到以下 webhooks:
  1. subscription.active - 表示订阅激活
  2. payment.succeeded - 确认初始支付:
    • 对于立即计费(0 试用天数):预计在 2-10 分钟内
    • 对于试用天数:在试用结束时
  3. subscription.renewed - 表示支付扣除和下一个周期的续订。(基本上,每当订阅产品的支付被扣除时,您将收到 subscription.renewed webhook 以及 payment.succeeded
支付失败场景
  1. 订阅失败
  • subscription.failed - 由于未能创建授权,订阅创建失败。
  • payment.failed - 表示支付失败。
  1. 订阅搁置
  • subscription.on_hold - 由于续订支付失败或计划变更费用失败,订阅被搁置。
  • 当订阅被搁置时,除非更新支付方式,否则不会自动续订。
最佳实践:为了简化实现,我们建议主要跟踪订阅事件以管理订阅生命周期。

处理订阅搁置

当订阅进入 on_hold 状态时,您需要更新支付方式以重新激活它。本节解释了订阅何时被搁置以及如何处理它们。

何时订阅被搁置

当以下情况发生时,订阅会被搁置:
  • 续订支付失败:由于资金不足、卡过期或银行拒绝,自动续订费用失败
  • 计划变更费用失败:在计划升级/降级期间,立即收费失败
  • 支付方式授权失败:支付方式无法授权进行定期收费
处于 on_hold 状态的订阅将不会自动续订。您必须更新支付方式以重新激活订阅。

从搁置状态重新激活订阅

要从 on_hold 状态重新激活订阅,请使用更新支付方式 API。这将自动:
  1. 创建剩余欠款的收费
  2. 为收费生成发票
  3. 使用新支付方式处理支付
  4. 在成功支付后将订阅重新激活为 active 状态
1

处理 subscription.on_hold webhook

当您收到 subscription.on_hold webhook 时,更新您的应用程序状态并通知客户:
// Webhook handler
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;
  
  if (event.type === 'subscription.on_hold') {
    const subscription = event.data;
    
    // Update subscription status in your database
    await updateSubscriptionStatus(subscription.subscription_id, 'on_hold');
    
    // Notify customer to update payment method
    await sendEmailToCustomer(subscription.customer_id, {
      subject: 'Payment Required - Subscription On Hold',
      message: 'Your subscription is on hold. Please update your payment method to continue service.'
    });
  }
  
  res.json({ received: true });
});
2

更新支付方式

当客户准备更新他们的支付方式时,调用更新支付方式 API:
// Update with new payment method
const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
  type: 'new',
  return_url: 'https://example.com/return'
});

// For on_hold subscriptions, a charge is automatically created
if (response.payment_id) {
  console.log('Charge created for remaining dues:', response.payment_id);
  // Redirect customer to response.payment_link to complete payment
}
如果客户保存了支付方式,您也可以使用现有的支付方式 ID:
await client.subscriptions.updatePaymentMethod(subscriptionId, {
  type: 'existing',
  payment_method_id: 'pm_abc123'
});
3

监控 webhook 事件

更新支付方式后,监控这些 webhook 事件:
  1. payment.succeeded - 剩余欠款的收费成功
  2. subscription.active - 订阅已重新激活
if (event.type === 'payment.succeeded') {
  const payment = event.data;
  
  // Check if this payment is for an on_hold subscription
  if (payment.subscription_id) {
    // Wait for subscription.active webhook to confirm reactivation
  }
}

if (event.type === 'subscription.active') {
  const subscription = event.data;
  
  // Update subscription status in your database
  await updateSubscriptionStatus(subscription.subscription_id, 'active');
  
  // Restore customer access
  await restoreCustomerAccess(subscription.customer_id);
  
  // Notify customer of successful reactivation
  await sendEmailToCustomer(subscription.customer_id, {
    subject: 'Subscription Reactivated',
    message: 'Your subscription has been reactivated successfully.'
  });
}

示例订阅事件有效负载


属性类型必需描述
business_idstring业务的唯一标识符
timestampstring事件发生的时间戳(不一定与交付时间相同)
typestring事件的类型。请参见 事件类型
dataobject主要数据有效负载。请参见 数据对象

更改订阅计划

您可以使用更改计划 API 端点升级或降级订阅计划。这允许您修改订阅的产品、数量,并处理按比例分配。

更改计划 API 参考

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

按比例分配选项

在更改订阅计划时,您有两个选项来处理立即收费:

1. prorated_immediately

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

2. full_immediately

  • 向客户收取新计划的全额订阅费用
  • 忽略之前计划的任何剩余时间或积分
  • 当您希望重置计费周期或无论按比例分配如何都收取全额时很有用

3. difference_immediately

  • 升级时,客户立即收取两个计划金额之间的差额。
  • 例如,如果当前计划为 30 美元,客户升级到 80 美元,他们会立即被收取 50 美元。
  • 降级时,当前计划的未使用金额作为内部积分添加,并自动应用于未来的订阅续订。
  • 例如,如果当前计划为 50 美元,客户切换到 20 美元计划,剩余的 30 美元将被记入并用于下一个计费周期。

行为

  • 当您调用此 API 时,Dodo Payments 会立即根据您选择的按比例分配选项发起收费
  • 如果计划更改是降级,并且您使用 prorated_immediately,积分将自动计算并添加到订阅的积分余额中。这些积分特定于该订阅,仅用于抵消未来相同订阅的定期付款
  • full_immediately 选项绕过积分计算并收取完整的新计划金额
仔细选择您的按比例分配选项:使用 prorated_immediately 进行公平计费,考虑未使用的时间,或使用 full_immediately 当您希望无论当前计费周期如何都收取完整的新计划金额。

收费处理

  • 在计划更改时发起的立即收费通常在 2 分钟内完成处理
  • 如果此立即收费因任何原因失败,订阅将自动被搁置,直到问题解决

按需订阅

按需订阅让您灵活收费,而不仅仅是按固定时间表收费。请联系支持以启用此功能。
要创建按需订阅: 要创建按需订阅,请使用 POST /subscriptions API 端点,并在请求体中包含 on_demand 字段。这允许您在没有立即收费的情况下授权支付方式,或设置自定义初始价格。 要收费按需订阅: 对于后续收费,请使用 POST /subscriptions/charge 端点,并指定要向客户收费的金额。
有关完整的逐步指南,包括请求/响应示例、安全重试策略和 webhook 处理,请参见 按需订阅指南