mcpField
C
checkout-integration

checkout-integration

github.com/dodopayments开发131.0k 次安装3 周前更新
代码仓库

关于 checkout-integration

面向开发者的 Dodo Payments 结账集成技能,介绍通过托管结账、嵌入式结账或静态付款链接收款。还涵盖订阅试用、结账定制以及通过 Webhook 验证付款。

主要功能

  1. 01创建托管 Checkout Sessions
  2. 02使用静态付款链接
  3. 03嵌入式或弹窗结账
  4. 04收集客户信息与自定义字段
  5. 05配置折扣码和货币选项
  6. 06通过 Webhook 验证付款

适用场景

  1. 01构建一次性付款流程
  2. 02创建含试用期的订阅结账
  3. 03在站点内显示结账弹窗
  4. 04为订单配置折扣码和客户字段

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dodopayments/skills --skill checkout-integration

安装后在 Claude Code 中输入/checkout-integration确认已加载。

附带文件references/overlay-checkout.mdreferences/server-examples.md

详细介绍

Dodo Payments 结账集成

使用 client.checkoutSessions.create(...) 构建托管结账页面或叠加式结账模态框。这是所有新付款集成的推荐方式。

何时使用此技能

  • 构建一次性付款结账流程
  • 创建可选试用期的订阅结账
  • 在叠加层或内嵌模态框中嵌入结账
  • 在结账时收集客户账单信息和自定义字段
  • 应用折扣码或处理货币选择
  • 在付款完成后重定向客户

结账方式

Dodo Payments 提供三种收款方式:

方式适用场景设置
结账会话(推荐)大多数集成;完全可控服务端 SDK 调用
静态付款链接无代码分享;可重复使用的 URL控制面板或直接 URL
叠加式/内嵌结账结账过程留在你的网站上客户端 SDK

旧版: 通过 POST /payments 或 POST /subscriptions 创建的动态付款链接已弃用。请改用结账会话。


核心概念

金额以最小货币单位表示: 所有价格均以分(或等值单位)表示。10 美元的 USD 扣款金额为 1000。

结账会话: 一次性使用的会话,可生成托管结账 URL。24 小时后过期(若 confirm=true,则 15 分钟后过期)。

返回 URL: 客户付款后跳转到的页面。Dodo 会附加 payment_id(一次性付款)或 subscription_id(订阅)、status,以及可用时的 license_key 和 email。它仅用于界面提示,绝不能作为付款凭证。

通过 webhook 授予权益: 浏览器重定向不是事实来源。授予访问权限前,务必通过 webhook 验证付款。验证方法请参阅 webhook-integration 技能。


创建结账会话

基本的一次性付款
import DodoPayments from 'dodopayments';

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

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

console.log('Redirect to:', session.checkout_url);

响应字段:

  • session_id:唯一的结账会话 ID
  • checkout_url:托管结账 URL(将客户重定向到此处)。当 confirm=true 时可为空
  • client_secret:仅在 confirm=true 时提供
  • publishable_key:仅在 confirm=true 时提供。将它与 client_secret 配对,用于内嵌 SDK 流程
  • payment_id:仅在 confirm=true 时提供

publishable_key 是 confirm 模式内嵌结账返回的每个会话专属值。它不是 Stripe 风格的可发布 API 密钥——Dodo 不会签发此类凭证,所有 API 密钥都是机密信息,仅限服务端使用。

包含多个产品
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_item_1', quantity: 2 },
    { product_id: 'pdt_item_2', quantity: 1 }
  ],
  customer: { email: '[email protected]' },
  return_url: 'https://yoursite.com/success'
});
使用现有客户
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: { customer_id: 'cus_existing_id' },
  return_url: 'https://yoursite.com/success'
});
包含账单地址和税号
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: {
    email: '[email protected]',
    name: 'Jane Doe'
  },
  billing_address: {
    country: 'US',
    street: '123 Main St',
    city: 'San Francisco',
    state: 'CA',
    zipcode: '94105'
  },
  tax_id: 'VAT123456789',
  customer_business_name: 'Acme Corp',
  return_url: 'https://yoursite.com/success'
});
使用折扣码
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: { email: '[email protected]' },
  discount_codes: ['PROMO10', 'WELCOME5'], // max 20, ordered
  feature_flags: {
    allow_discount_code: true
  },
  return_url: 'https://yoursite.com/success'
});
包含订阅和试用期
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_monthly_subscription', quantity: 1 }
  ],
  subscription_data: {
    trial_period_days: 14
  },
  customer: { email: '[email protected]' },
  return_url: 'https://yoursite.com/success'
});
包含自定义字段
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: { email: '[email protected]' },
  custom_fields: [
    {
      key: 'company_size',
      label: 'Company Size',
      field_type: 'dropdown',
      options: ['1-10', '11-50', '51-200', '200+'],
      required: true
    },
    {
      key: 'use_case',
      label: 'Primary Use Case',
      field_type: 'text',
      placeholder: 'e.g., analytics, reporting',
      required: false
    }
  ],
  return_url: 'https://yoursite.com/success'
});
包含元数据
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: { email: '[email protected]' },
  metadata: {
    order_id: 'order_12345',
    referral_code: 'FRIEND20',
    campaign: 'summer_sale'
  },
  return_url: 'https://yoursite.com/success'
});

Next.js App Router

完整指南:references/server-examples.md。

涵盖:

  • API 路由
  • 客户端组件
  • 成功页面

Express.js

完整指南:references/server-examples.md。

Python (FastAPI)

完整指南:references/server-examples.md。

叠加式结账

完整指南:references/overlay-checkout.md。

涵盖:

  • 安装
  • 服务端路由
  • 浏览器叠加模式和内嵌模式

静态付款链接

可分享的无代码链接。无需服务端 API 调用。

基本格式
https://checkout.dodopayments.com/buy/{productid}

在测试模式下,主机为 test.checkout.dodopayments.com(例如 https://test.checkout.dodopayments.com/buy/{productid});测试模式下的产品不会存在于正式环境主机上。

示例:

https://checkout.dodopayments.com/buy/pdt_example
使用查询参数
https://checkout.dodopayments.com/buy/pdt_example?quantity=2&[email protected]&redirect_url=https%3A%2F%2Fyoursite.com%2Fsuccess

支持的参数:

  • quantity:商品数量
  • redirect_url:成功后重定向 URL
  • email:预填客户邮箱
  • fullName、firstName、lastName:预填姓名
  • country、city、state、zipCode、addressLine:预填地址
  • paymentCurrency:强制指定货币
  • metadata_*:自定义元数据(例如,metadata_orderId=123)

检索和预览会话

检索会话状态
const status = await client.checkoutSessions.retrieve('cks_session_id');

console.log(status.id);
console.log(status.payment_status);
预览会话(不创建)
const preview = await client.checkoutSessions.preview({
  product_cart: [
    { product_id: 'pdt_example', quantity: 1 }
  ],
  customer: { email: '[email protected]' },
  billing_currency: 'EUR'
});

console.log('Preview total:', preview.current_breakup.total_amount);

自定义

主题和外观
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_example', quantity: 1 }],
  customer: { email: '[email protected]' },
  customization: {
    theme: 'dark', // 'light', 'dark', or 'system'
    force_language: 'en',
    show_order_details: true,
    theme_config: {
      font_size: 'md',
      font_weight: 'normal',
      radius: '8px',
      pay_button_text: 'Complete Purchase',
      light: {
        bg_primary: '#ffffff',
        text_primary: '#000000',
        button_primary: '#0066ff'
      }
    }
  },
  return_url: 'https://yoursite.com/success'
});
功能标志
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_example', quantity: 1 }],
  customer: { email: '[email protected]' },
  feature_flags: {
    allow_discount_code: true,
    allow_currency_selection: true,
    allow_customer_editing_email: true,
    allow_phone_number_collection: true,
    require_phone_number: false,
    allow_tax_id: true
  },
  return_url: 'https://yoursite.com/success'
});

付款后流程

处理返回 URL

付款后,客户会被重定向到带有查询参数的 return_url:

# One-time payment
https://yoursite.com/success?payment_id=pay_xxx&status=succeeded&email=customer%40example.com

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

查询参数:

  • payment_id(一次性付款)或 subscription_id(订阅)
  • status:成功时为 succeeded(一次性付款)或 active(订阅);拒付时为 failed;稍后结算时为 processing(或某个 requires_* 值);会话过期时为 expired
  • license_key:产品会发放许可证密钥时提供(多个密钥以逗号分隔)
  • email:客户有已记录的电子邮件时提供

没有 session_id 参数。将 processing/缺失状态视为“未知”,并等待 webhook。

在服务端验证付款

不要信任浏览器重定向。使用 references/server-examples.md 中的 Express webhook 路由:该路由会在 express.json() 之前接收经过签名的原始请求正文,根据经过验证的 payment.succeeded 事件中的 event.data.customer.customer_id 完成一次性购买,并且仅在经过验证的 subscription.active 事件中授予订阅访问权限。

webhook-integration 技能中介绍了 webhook 签名验证。


常见错误

1. 根据返回 URL 授予访问权限 返回 URL 重定向不能证明付款已完成。切勿根据其查询参数授予访问权限或履行订单;应等待经过验证的 webhook 事件。

2. 使用已弃用的 API 新集成中不要使用 client.payments.create() 或 client.subscriptions.create()。这两个 API 均已弃用。请使用 client.checkoutSessions.create()。

3. 忘记 environment 标志 默认值为 live_mode。开发期间务必设置 environment: 'test_mode',以免对真实银行卡收费。

4. 使用已弃用的 discount_code 请使用 discount_codes(数组)。单数形式的 discount_code 字符串已弃用(为向后兼容仍可接受),且不能在同一请求中与 discount_codes 一起使用。

5. 金额单位错误 所有金额均以货币的最小单位表示(美元为美分)。10 美元应写为 1000,而不是 10。

6. 重复使用结账 URL 结账 URL 只能使用一次。每次尝试结账都要创建一个新会话。

7. 忽略 confirm=true 的行为 当 confirm=true 时,会话会立即完成,结账 URL 的有效期也会从 24 小时缩短为 15 分钟。仅在已掌握所有必需的客户数据时使用。

8. 忘记为 webhook 保留原始请求正文 Webhook 签名验证需要原始请求正文,而非重新序列化的 JSON 对象。应在 express.json() 之前使用 express.raw({ type: 'application/json' }) 挂载 webhook 路由。

9. 信任客户端提供的产品 ID 不要接受浏览器传来的任意 pdt_ ID。对用户进行身份验证,接受公开的方案 slug,在服务端将其映射到允许列表中的产品 ID,并拒绝非正整数的数量。


资源

评论

支持 Markdown