会话有效性:结账会话默认有效期为 24 小时。如果您在请求中传递
confirm=true,则会话仅在 15 分钟内有效。先决条件
1
Dodo Payments 账户
您需要一个具有 API 访问权限的有效 Dodo Payments 商户账户。
2
API 凭证
从 Dodo Payments 仪表板生成您的 API 凭证:
3
产品设置
在实施结账会话之前,请在 Dodo Payments 仪表板中创建您的产品。
创建您的第一个结账会话
- Node.js SDK
- Python SDK
- REST API
复制
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: '[email protected]',
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' });
}
});
复制
import os
from dodopayments import DodoPayments
# Initialize the Dodo Payments client
client = DodoPayments(
bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"), # This is the default and can be omitted
environment="test_mode", # defaults to "live_mode"
)
def create_checkout_session():
"""
Create a checkout session for a single product with customer data pre-filled.
Returns the session object containing checkout_url for customer redirection.
"""
try:
session = client.checkout_sessions.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 checkout friction
customer={
"email": "[email protected]",
"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
print(f"Checkout URL: {session.checkout_url}")
print(f"Session ID: {session.session_id}")
return session
except Exception as error:
print(f"Failed to create checkout session: {error}")
raise error
# Example usage in a Flask route
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/create-checkout', methods=['POST'])
def create_checkout():
try:
session = create_checkout_session()
return jsonify({"checkout_url": session.checkout_url})
except Exception as error:
return jsonify({"error": "Failed to create checkout session"}), 500
复制
// Direct API call using fetch - useful for any JavaScript environment
async function createCheckoutSession() {
try {
const response = await fetch('https://test.dodopayments.com/checkouts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`
},
body: JSON.stringify({
// 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 checkout friction
customer: {
email: '[email protected]',
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'
}
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const session = await response.json();
// 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: Redirect user to checkout
createCheckoutSession().then(session => {
window.location.href = session.checkout_url;
});
API 响应
上述所有方法返回相同的响应结构:复制
{
"session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
"checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
1
获取结账 URL
从 API 响应中提取
checkout_url。2
重定向您的客户
将您的客户重定向到结账 URL 以完成购买。
复制
// Redirect immediately
window.location.href = session.checkout_url;
// Or open in new window
window.open(session.checkout_url, '_blank');
3
处理返回
付款后,客户将被重定向到您的
return_url,并附加支付状态的额外查询参数。请求体
必填字段
每个结账会话所需的基本字段
可选字段
自定义结账体验的附加配置
必填字段
要包含在结账会话中的产品数组。每个产品必须在您的 Dodo Payments 仪表板中具有有效的
product_id。重要:多个产品购物车只能包含一次性支付产品。您不能在同一结账会话中混合订阅产品和一次性产品。
显示 产品购物车项属性
显示 产品购物车项属性
来自您 Dodo Payments 仪表板的产品唯一标识符。示例:
"prod_123abc456def"产品数量。示例:
1 表示单个项目, 3 表示多个数量如果启用 pay_what_you_want,客户支付的金额。如果禁用,则此字段将被忽略。格式:以货币的最低面额表示(例如,美元的分)。例如,要收取 $1.00,请传递
100。查找您的产品 ID:您可以在 Dodo Payments 仪表板的产品 → 查看详细信息中找到产品 ID,或使用 列出产品 API。
可选字段
配置这些字段以自定义结账体验并为您的支付流程添加业务逻辑。客户信息
客户信息
客户信息。您可以使用其 ID 附加现有客户,或在结账时创建新客户记录。
- 附加现有客户
- 新客户
账单地址信息,用于准确的税收计算、防欺诈和合规性。
当
confirm 设置为 true 时,所有账单地址字段在成功创建会话时变为必填。显示 账单地址对象属性
显示 账单地址对象属性
完整的街道地址,包括门牌号、街道名称和公寓/单元号(如适用)。示例:
"123 Main St, Apt 4B" 或 "456 Oak Avenue"城市或市镇名称。示例:
"San Francisco", "New York", "London"州、省或地区名称。使用全名或标准缩写。示例:
"California" 或 "CA", "Ontario" 或 "ON"两位字母 ISO 国家代码(ISO 3166-1 alpha-2)。提供 billing_address 时,此字段始终是必填的。示例:
"US"(美国), "CA"(加拿大), "GB"(英国), "DE"(德国)国家代码参考
查看支持的国家及其 ISO 代码的完整列表
邮政编码、ZIP 代码或根据国家要求的等效项。示例:
"94102"(美国), "M5V 3A8"(加拿大), "SW1A 1AA"(英国)支付配置
支付配置
控制客户在结账时可用的支付方式。这有助于针对特定市场或业务需求进行优化。可用选项: 示例:
credit, debit, upi_collect, upi_intent, apple_pay, google_pay, amazon_pay, klarna, affirm, afterpay_clearpay, sepa, ach, cashapp, multibanco, bancontact_card, eps, ideal, przelewy24, paypal关键:始终包括
credit 和 debit 作为后备选项,以防首选支付方式不可用而导致结账失败。复制
["apple_pay", "google_pay", "credit", "debit"]
用固定的账单货币覆盖默认货币选择。使用 ISO 4217 货币代码。支持的货币:
USD, EUR, GBP, CAD, AUD, INR,以及更多示例: "USD" 表示美元, "EUR" 表示欧元此字段仅在启用自适应定价时有效。如果禁用自适应定价,将使用产品的默认货币。
为回头客显示以前保存的支付方式,提高结账速度和用户体验。
会话管理
会话管理
成功付款或取消后重定向客户的 URL。
如果为 true,则立即完成所有会话详细信息。如果缺少必需数据,API 将抛出错误。
将折扣代码应用于结账会话。
自定义键值对,用于存储有关会话的附加信息。
覆盖此会话的商户默认 3DS 行为。
启用最小地址收集模式。当启用时,结账仅收集:
- 国家:始终需要用于税收确定
- 邮政编码:仅在需要销售税、增值税或商品及服务税计算的地区
启用最小地址以加快结账完成速度。对于需要完整账单详细信息的企业,仍然可以收集完整地址。
UI 自定义与功能
UI 自定义与功能
配置结账会话的特定功能和行为。
显示 功能标志对象属性
显示 功能标志对象属性
允许客户在结账时选择其首选货币。
在结账界面中显示折扣代码输入字段。
在结账时收集客户电话号码。
允许客户输入税务识别号码。
强制创建新客户记录,而不是更新现有客户。
允许客户在结账时编辑其电子邮件地址。
允许客户在结账时编辑其姓名。
允许客户在结账时编辑街道地址。
允许客户在结账时编辑城市。
允许客户在结账时编辑州。
允许客户在结账时编辑国家。
允许客户在结账时编辑邮政编码。
启用最小地址收集模式。当启用时,结账仅收集:
- 国家:始终需要用于税收确定
- 邮政编码:仅在需要销售税、增值税或商品及服务税计算的地区
启用最小地址以加快结账完成速度。完整地址收集仍然可用于需要完整账单详细信息的企业。
订阅配置
订阅配置
包含订阅产品的结账会话的附加配置。
显示 订阅数据对象属性
显示 订阅数据对象属性
在首次收费之前的试用期天数。必须在 0 到 10000 天之间。
基于使用或计量计费的按需订阅配置。
显示 按需对象属性
显示 按需对象属性
如果设置为 true,则不执行任何收费,仅授权支付方式详细信息以供将来使用。
客户的初始收费的产品价格。如果未指定,将使用产品的存储价格。格式:以货币的最低面额表示(例如,美元的分)。例如,要收取 $1.00,请传递
100。产品价格的可选货币。如果未指定,默认为产品的货币。
账单和行项目的可选产品描述覆盖。如果未指定,将使用产品的存储描述。
自适应货币费用是否应包含在产品价格中(true)或加在其上(false)。如果未启用自适应定价,则忽略此项。
使用示例
以下是 10 个全面的示例,展示了不同结账会话配置的各种业务场景:1. 简单单产品结账
复制
const session = await client.checkoutSessions.create({
product_cart: [
{
product_id: 'prod_ebook_guide',
quantity: 1
}
],
customer: {
email: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]'
}
});
8. 带折扣代码的暗黑主题结账
复制
const session = await client.checkoutSessions.create({
product_cart: [
{
product_id: 'prod_gaming_chair',
quantity: 1
}
],
discount_code: 'BLACKFRIDAY2024',
customization: {
theme: 'dark',
show_order_details: true,
show_on_demand_tag: false
},
feature_flags: {
allow_discount_code: true
},
customer: {
email: '[email protected]',
name: 'Mike Chen'
},
return_url: 'https://gaming-store.com/order-complete'
});
9. 区域支付方式(印度的 UPI)
复制
const session = await client.checkoutSessions.create({
product_cart: [
{
product_id: 'prod_online_course_hindi',
quantity: 1
}
],
allowed_payment_method_types: [
'upi_collect',
'upi_intent',
'credit',
'debit'
],
customer: {
email: '[email protected]',
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(先买后付)结账
复制
const session = await client.checkoutSessions.create({
product_cart: [
{
product_id: 'prod_luxury_watch',
quantity: 1
}
],
allowed_payment_method_types: [
'klarna',
'affirm',
'afterpay_clearpay',
'credit',
'debit'
],
customer: {
email: '[email protected]',
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'
}
});
从动态链接迁移到结账会话
关键区别
之前,在使用动态链接创建支付链接时,您需要提供客户的完整账单地址。 使用结账会话,这不再是必需的。您只需传递您拥有的任何信息,我们将处理其余部分。例如:- 如果您只知道客户的账单国家,只需提供该信息。
- 结账流程将自动收集缺失的详细信息,然后将客户转移到支付页面。
- 另一方面,如果您已经拥有所有必需的信息并希望直接跳转到支付页面,您可以传递完整的数据集并在请求体中包含
confirm=true。
迁移过程
从动态链接迁移到结账会话非常简单:1
更新您的集成
更新您的集成以使用新的 API 或 SDK 方法。
2
调整请求负载
根据结账会话格式调整请求负载。
3
就这样!
是的。您无需进行额外处理或特殊迁移步骤。