跳转到主要内容

Quick Start Guide

Get your first checkout session running in under 5 minutes

API Reference & Live Testing

Explore the full API documentation and interactively test Checkout Session requests and responses.

Preview Checkout

Calculate pricing, taxes, and totals before creating a session.
Session Validity: Checkout sessions are valid for 24 hours by default. If you pass confirm=true in your request, the session will only be valid for 15 minutes.

Prerequisites

1

Dodo Payments Account

You’ll need an active Dodo Payments merchant account with API access.
2

API Credentials

Generate your API credentials from the Dodo Payments dashboard:
3

Products Setup

Create your products in the Dodo Payments dashboard before implementing checkout sessions.

Creating Your First Checkout Session

import DodoPayments from 'dodopayments';

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

async function createCheckoutSession() {
  try {
    const session = await client.checkoutSessions.create({
      // Products to sell - use IDs from your Dodo Payments dashboard
      product_cart: [
        {
          product_id: 'prod_123', // Replace with your actual product ID
          quantity: 1
        }
      ],
      
      // Pre-fill customer information to reduce friction
      customer: {
        email: 'customer@example.com',
        name: 'John Doe',
        phone_number: '+1234567890'
      },
      
      // Billing address for tax calculation and compliance
      billing_address: {
        street: '123 Main St',
        city: 'San Francisco',
        state: 'CA',
        country: 'US', // Required: ISO 3166-1 alpha-2 country code
        zipcode: '94102'
      },
      
      // Where to redirect after successful payment
      return_url: 'https://yoursite.com/checkout/success',
      
      // Custom data for your internal tracking
      metadata: {
        order_id: 'order_123',
        source: 'web_app'
      }
    });

    // Redirect your customer to this URL to complete payment
    console.log('Checkout URL:', session.checkout_url);
    console.log('Session ID:', session.session_id);
    
    return session;
    
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

// Example usage in an Express.js route
app.post('/create-checkout', async (req, res) => {
  try {
    const session = await createCheckoutSession();
    res.json({ checkout_url: session.checkout_url });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create checkout session' });
  }
});

API Response

All methods above return the same response structure:
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
1

Get the checkout URL

Extract the checkout_url from the API response.
2

Redirect your customer

Direct your customer to the checkout URL to complete their purchase.
// Redirect immediately
window.location.href = session.checkout_url;

// Or open in new window
window.open(session.checkout_url, '_blank');
Alternative Integration Options: Instead of redirecting, you can embed the checkout directly in your page using Overlay Checkout (modal overlay) or Inline Checkout (fully embedded). Both options use the same checkout session URL.
3

Handle the return

After payment, customers are redirected to your return_url with query parameters including payment/subscription ID, status, customer email, and any license keys. See the return_url parameter docs for the full list.

Request Body

Required Fields

Essential fields needed for every checkout session

Optional Fields

Additional configuration to customize your checkout experience

Required Fields

product_cart
array
必填
Array of products to include in the checkout session. Each product must have a valid product_id from your Dodo Payments dashboard.
Mixed Checkout: You can combine one-time payment products and subscription products in the same checkout session. This enables powerful use cases like setup fees with subscriptions, hardware bundles with SaaS, and more.
查找您的产品 ID:您可以在您的 Dodo Payments 仪表板中进入产品 → 查看详情,或使用 列出产品 API找到产品 ID。

可选字段

配置这些字段以自定义结账体验,并将业务逻辑添加到您的支付流程中。
customer
object
客户信息。您可以通过他们的 ID 附加一个现有客户,或在结账期间创建一个新的客户记录。
使用客户的 ID 将现有客户附加到结账会话。
billing_address
object
准确计算税收、防欺诈和法规遵循的帐单地址信息。
confirm 设置为 true 时,所有帐单地址字段都将是会话成功创建所必需的。
allowed_payment_method_types
array
控制在结账时可用给客户的支付方式。这有助于优化特定市场或业务需求。可用选项credit, debit, upi_collect, apple_pay, google_pay, amazon_pay, klarna, affirm, afterpay_clearpay, cashapp, multibanco, bancontact_card, eps, ideal, przelewy24, paypal, sunbit
关键:始终包含 creditdebit 作为备用选项,以防首选支付方式不可用时防止结账失败。
示例
["apple_pay", "google_pay", "credit", "debit"]
billing_currency
string
使用固定的计费货币覆盖默认的货币选择。使用 ISO 4217 货币代码。支持货币USDEURGBPCADAUDINR示例"USD" 表示美元,"EUR" 表示欧元
此字段仅在启用自适应定价时有效。如果禁用了自适应定价,则将使用产品的默认货币。
show_saved_payment_methods
boolean
默认值:"false"
显示返回客户之前保存的支付方式,以改善结账速度和用户体验。
return_url
string
付款完成后重定向客户的 URL。Dodo Payments 会在重定向时将以下查询参数附加到您的 URL:
参数类型条件
payment_idstring一次性支付始终存在
subscription_idstring订阅付款始终存在
statusstring始终存在
license_keystring当产品启用许可证密钥时存在。若为多个密钥,则用逗号分隔
emailstring当客户有保存的电子邮件记录时存在
重定向 URL 示例:
# One-time payment with license key
https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001&email=customer%40example.com

# Subscription payment with multiple license keys
https://yoursite.com/return?subscription_id=sub_xxx&status=active&license_key=LK-001,LK-002&email=customer%40example.com

# Payment without license keys
https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&email=customer%40example.com
使用 license_keyemail 查询参数,在返回页面上直接显示许可证密钥或立即发送确认,而无需额外的 API 调用。
cancel_url
string
客户点击返回按钮或取消结账会话时的重定向 URL。如果未提供,则不显示返回按钮。
设置 cancel_url,给客户一个清晰的方式返回您的网站而无需完成购买。这改善了结账体验,减少了摩擦。
confirm
boolean
默认值:"false"
如果为 true,则立即确定所有会话详情。如果需要的数据缺失,API 将抛出错误。
discount_codes
array
将一个或多个叠加优惠码应用于结账会话。优惠码按照 数组顺序 应用(第一个代码减少基础价格,第二个代码减少已折扣的价格,以此类推),每个会话最多可应用 20 个优惠码。
discount_codes: ['WELCOME10', 'BLACKFRIDAY20']
下面的单一 discount_code 字段已 弃用,但仍然完全支持——现有集成可以继续无需更改地工作。它不能与同一请求中的 discount_codes 结合使用。请在方便时迁移到 discount_codes 以利用堆叠优势。
discount_code
string
已弃用
已弃用 — 新集成优先使用 discount_codes。此字段仍可用于向后兼容,但不能与同一请求中的 discount_codes 结合使用。
metadata
object
自定义键值对以存储有关会话的附加信息。
force_3ds
boolean
覆盖此会话的商家默认 3DS 行为。
minimal_address
boolean
默认值:"false"
启用最小地址收集模式。启用后,结账仅收集:
  • 国家:始终确定税的必要条件
  • ZIP/邮政编码:仅适用于需要销售税、增值税或消费税计算的地区
通过消除不必要的表单字段,这显著减少了结账过程中的摩擦。
启用最小地址以更快地完成结账。对于需要完整计费详细信息的业务,仍然可以进行完整的地址收集。
customization
object
自定义结账界面的外观和行为。
feature_flags
object
为结账会话配置特定功能和行为。
custom_fields
array
在结账时通过自定义表单字段从客户收集额外信息。每个结账会话最多可以定义5个自定义字段。客户响应包括在 webhook 负载中并可通过 API 获取。
客户对自定义字段的响应包括在:
  • Webhookspayment.succeededsubscription.active 以及其他相关事件负载包含 custom_field_responses 数组
  • API 响应:支付和订阅对象包括 custom_field_responses
subscription_data
object
包含订阅产品的结账会话的额外配置。

使用示例

这里有 10 个展示不同业务场景下各种结账会话配置的完整示例:

1. 简单的单产品结账

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_ebook_guide',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe'
  },
  return_url: 'https://yoursite.com/success'
});

2. 多产品购物车

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_laptop',
      quantity: 1
    },
    {
      product_id: 'prod_mouse',
      quantity: 2
    },
    {
      product_id: 'prod_warranty',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '123 Tech Street',
    city: 'San Francisco',
    state: 'CA',
    country: 'US',
    zipcode: '94102'
  },
  return_url: 'https://electronics-store.com/order-confirmation'
});

3. 带试用期的订阅

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_plan',
      quantity: 1
    }
  ],
  subscription_data: {
    trial_period_days: 14
  },
  customer: {
    email: 'user@startup.com',
    name: 'Jane Smith'
  },
  return_url: 'https://saas-app.com/onboarding',
  metadata: {
    plan_type: 'professional',
    referral_source: 'google_ads'
  }
});

4. 预确认结账

confirm 设置为 true 时,客户将直接被带入结账页面,跳过任何确认步骤。
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_premium_course',
      quantity: 1
    }
  ],
  customer: {
    email: 'student@university.edu',
    name: 'Alex Johnson',
    phone_number: '+1555123456'
  },
  billing_address: {
    street: '456 University Ave',
    city: 'Boston',
    state: 'MA',
    country: 'US',
    zipcode: '02134'
  },
  confirm: true,
  return_url: 'https://learning-platform.com/course-access',
  metadata: {
    course_category: 'programming',
    enrollment_date: '2024-01-15'
  }
});

5. 带货币覆盖的结账

billing_currency 覆盖仅在账户设置中启用自适应货币时生效。如果禁用自适应货币,此参数将无效。
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_consulting_service',
      quantity: 1
    }
  ],
  customer: {
    email: 'client@company.co.uk',
    name: 'Oliver Williams'
  },
  billing_address: {
    street: '789 Business Park',
    city: 'London',
    state: 'England',
    country: 'GB',
    zipcode: 'SW1A 1AA'
  },
  billing_currency: 'GBP',
  feature_flags: {
    allow_currency_selection: true,
    allow_tax_id: true
  },
  return_url: 'https://consulting-firm.com/service-confirmation'
});

6. 针对返回客户的保存支付方式

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_subscription',
      quantity: 1
    }
  ],
  customer: {
    email: 'returning.customer@example.com',
    name: 'Robert Johnson',
    phone_number: '+1555987654'
  },
  show_saved_payment_methods: true,
  feature_flags: {
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://subscription-service.com/welcome-back',
  metadata: {
    customer_tier: 'premium',
    account_age: 'returning'
  }
});

7. B2B 结账与税号采集

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_enterprise_license',
      quantity: 5
    }
  ],
  customer: {
    email: 'procurement@enterprise.com',
    name: 'Sarah Davis',
    phone_number: '+1800555000'
  },
  billing_address: {
    street: '1000 Corporate Blvd',
    city: 'New York',
    state: 'NY',
    country: 'US',
    zipcode: '10001'
  },
  feature_flags: {
    allow_tax_id: true,
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://enterprise-software.com/license-delivery',
  metadata: {
    customer_type: 'enterprise',
    contract_id: 'ENT-2024-001',
    sales_rep: 'john.sales@company.com'
  }
});

8. 使用叠加折扣代码的深色主题结账

const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_gaming_chair',
      quantity: 1
    }
  ],
  discount_codes: ['BLACKFRIDAY2024'],
  customization: {
    theme: 'dark',
    show_order_details: true,
    show_on_demand_tag: false
  },
  feature_flags: {
    allow_discount_code: true
  },
  customer: {
    email: 'gamer@example.com',
    name: 'Mike Chen'
  },
  return_url: 'https://gaming-store.com/order-complete'
});

9. 区域支付方式(印度的 UPI)

有关 UPI 配置和测试的详细信息,请参阅 印度支付方式 页面。
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_online_course_hindi',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'upi_collect',
    'credit',
    'debit'
  ],
  customer: {
    email: 'student@example.in',
    name: 'Priya Sharma',
    phone_number: '+919876543210'
  },
  billing_address: {
    street: 'MG Road',
    city: 'Bangalore',
    state: 'Karnataka',
    country: 'IN',
    zipcode: '560001'
  },
  billing_currency: 'INR',
  return_url: 'https://education-platform.in/course-access',
  metadata: {
    region: 'south_india',
    language: 'hindi'
  }
});

10. BNPL(先买后付)结账

有关 BNPL 配置和测试的详细信息,请参阅 先买后付(BNPL) 页面。
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_luxury_watch',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'klarna',
    'afterpay_clearpay',
    'credit',
    'debit'
  ],
  customer: {
    email: 'fashion.lover@example.com',
    name: 'Emma Thompson',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '555 Fashion Ave',
    city: 'Los Angeles',
    state: 'CA',
    country: 'US',
    zipcode: '90210'
  },
  feature_flags: {
    allow_phone_number_collection: true
  },
  return_url: 'https://luxury-store.com/purchase-confirmation',
  metadata: {
    product_category: 'luxury',
    price_range: 'high_value'
  }
});

11. 使用现有支付方式进行即时结账

使用客户的保存支付方式创建一个立即处理的结账会话,跳过支付方式收集:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_premium_plan',
      quantity: 1
    }
  ],
  customer: {
    customer_id: 'cus_123'  // Required when using payment_method_id
  },
  payment_method_id: 'pm_abc123',  // Use customer's saved payment method
  confirm: true,  // Required when using payment_method_id
  return_url: 'https://yourapp.com/success'
});
使用 payment_method_id 时,confirm 必须设置为 true,并且必须提供现有的 customer_id。支付方式将根据支付的货币验证其资格。
支付方式必须属于客户,并且与支付货币兼容。这使得返回客户可以一键购买。

12. 使用简短链接使支付 URL 更简洁

生成带有自定义短语的简化共享支付链接:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_subscription',
      quantity: 1
    }
  ],
  short_link: true,  // Generate a shortened payment link
  return_url: 'https://yourapp.com/success',
  customer: {
    email: 'customer@example.com',
    name: 'John Doe'
  }
});

// The checkout_url will be a shortened, cleaner link
console.log(session.checkout_url);  // e.g., https://checkout.dodopayments.com/buy/abc123
简短链接非常适合用于短信、电子邮件或社交媒体分享。它们比长 URL 更易于记忆,并能提高客户信任度。

13. 跳过付款成功页面并立即重定向

付款完成后立即重定向客户,跳过默认的成功页面:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_digital_product',
      quantity: 1
    }
  ],
  feature_flags: {
    redirect_immediately: true  // Skip success page, redirect immediately
  },
  return_url: 'https://yourapp.com/success',
  customer: {
    email: 'customer@example.com',
    name: 'Jane Smith'
  }
});
当您拥有一个提供比默认付款成功页面更好用户体验的自定义成功页面时,请使用 redirect_immediately: true。这在移动应用和嵌入式结账流中尤其有用。
redirect_immediately 启用时,付款完成后会立即将客户重定向到您的 return_url,完全跳过默认成功页面。

14. 强制指定语言

强制结账显示为特定语言,覆盖客户的浏览器语言检测:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_subscription',
      quantity: 1
    }
  ],
  customization: {
    force_language: 'ja'  // Force Japanese language
  },
  customer: {
    email: 'customer@example.jp',
    name: 'Tanaka Yuki'
  },
  return_url: 'https://yourapp.com/success'
});
当您知道客户的首选语言(如来源于他们的帐户设置)或针对特定区域市场时,使用 force_language
**支持的语言:**阿拉伯语(ar)、加泰罗尼亚语(ca)、汉语(zh)、荷兰语(nl)、英语(en)、法语(fr)、德语(de)、希伯来语(he)、印尼语(id)、意大利语(it)、日本语(ja)、韩语(ko)、马来语(ms)、波兰语(pl)、葡萄牙语(pt)、罗马尼亚语(ro)、俄语(ru)、西班牙语(es)、瑞典语(sv)、泰语(th)、土耳其语(tr

15. 收集自定义字段

在结账时使用自定义字段从客户收集额外信息:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_saas_plan',
      quantity: 1
    }
  ],
  custom_fields: [
    {
      key: 'company_name',
      label: 'Company Name',
      field_type: 'text',
      required: true,
      placeholder: 'Acme Inc.'
    },
    {
      key: 'team_size',
      label: 'Team Size',
      field_type: 'dropdown',
      required: true,
      options: ['1-10', '11-50', '51-200', '201-500', '500+']
    },
    {
      key: 'referral_source',
      label: 'How did you hear about us?',
      field_type: 'dropdown',
      required: false,
      options: ['Google', 'Twitter', 'Friend referral', 'Blog post', 'Other']
    },
    {
      key: 'website',
      label: 'Company Website',
      field_type: 'url',
      required: false,
      placeholder: 'https://example.com'
    }
  ],
  customer: {
    email: 'buyer@company.com',
    name: 'Jane Doe'
  },
  return_url: 'https://yourapp.com/success'
});
自定义字段响应自动包含在 webhook 负载中(payment.succeededsubscription.active 等),并可通过 API 获取。使用它们可以丰富您的 CRM,启动入职流程,或自定义客户体验。
可用的字段类型textnumberemailurldatedropdownboolean

预览结账会话

在创建结账会话之前,您可以预览价格明细,包括税收、折扣和总额。这对于在客户结账前显示准确的定价信息非常有用。
const preview = await client.checkoutSessions.preview({
  product_cart: [
    { product_id: 'prod_123', quantity: 1 }
  ],
  billing_address: {
    country: 'US',
    state: 'CA',
    zipcode: '94102'
  },
  discount_codes: ['SAVE20']
});

console.log('Subtotal:', preview.subtotal);
console.log('Tax:', preview.tax);
console.log('Discount:', preview.discount);
console.log('Total:', preview.total);

Preview API Reference

查看完整的预览端点文档。

从动态链接迁移到结账会话

关键差异

以前,在使用动态链接创建支付链接时,需要提供客户的完整帐单地址。 使用结账会话,这已不再必要。您可以只传递您掌握的信息,我们将处理余下的部分。例如:
  • 如果您只知道客户的帐单国家,只需提供即可。
  • 结账流程会自动收集缺少的详细信息,然后再将客户转移到支付页面。
  • 另一方面,如果您已经拥有所有必要信息,并希望直接跳到支付页面,可以传递完整的数据集,并在请求主体中包含 confirm=true

迁移过程

迁移从动态链接到结账会话很简单:
1

Update your integration

更新您的集成以使用新的 API 或 SDK 方法。
2

Adjust request payload

根据结账会话格式调整请求负载。
3

That's it!

是的。您无需进行额外处理或特殊迁移步骤。

相关 API 参考

Create Checkout Session

使用所有可用参数和选项创建结账会话的完整 API 参考

Preview Checkout Session

创建会话前预览定价、税金和总额的 API 参考
Last modified on May 26, 2026