> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 覆盖结账

> 一个现代的 TypeScript 库，用于嵌入 Dodo Payments 覆盖结账并实时监听结账事件。

## 概述

Dodo Payments Checkout SDK 提供了一种无缝的方式将我们的支付覆盖集成到您的 Web 应用程序中。它使用 TypeScript 和现代 Web 标准构建，提供了一个强大的解决方案，用于处理实时事件处理和可自定义主题的支付。

<Frame>
  <img src="https://mintcdn.com/dodopayments/mOQO5ej_lx0yH9p-/images/cover-images/overlay-checkout.png?fit=max&auto=format&n=mOQO5ej_lx0yH9p-&q=85&s=15d90c695e92914a9d54b10509d6fe47" alt="Overlay Checkout Cover Image" style={{ maxHeight: '500px', width: 'auto' }} width="3826" height="2160" data-path="images/cover-images/overlay-checkout.png" />
</Frame>

## 演示

<Card title="Interactive Demo" icon="play" href="https://atlas.dodopayments.com/pricing">
  通过我们的实时演示查看覆盖式结账的实际效果。
</Card>

## 快速开始

只需几行代码即可开始使用 Dodo Payments Checkout SDK：

```typescript theme={null}
import { DodoPayments } from "dodopayments-checkout";

// Initialize the SDK
DodoPayments.Initialize({
  mode: "test", // 'test' or 'live'
  displayType: "overlay", // Optional: defaults to 'overlay' for overlay checkout
  onEvent: (event) => {
    console.log("Checkout event:", event);
  },
});

// Open checkout
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123"
});
```

<Tip>
  从 [创建结账会话 API](/api-reference/checkout-sessions/create) 获取结账 URL。
</Tip>

## 分步集成指南

<Steps>
  <Step title="Install the SDK">
    使用您喜欢的包管理器安装 Dodo Payments Checkout SDK：

    <CodeGroup>
      ```bash npm theme={null}
      npm install dodopayments-checkout
      ```

      ```bash yarn theme={null}
      yarn add dodopayments-checkout
      ```

      ```bash pnpm theme={null}
      pnpm add dodopayments-checkout
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize the SDK">
    在您的应用程序中初始化 SDK，通常在您的主组件或应用程序入口点：

    ```typescript theme={null}
    import { DodoPayments } from "dodopayments-checkout";

    DodoPayments.Initialize({
      mode: "test", // Change to 'live' for production
      displayType: "overlay", // Optional: defaults to 'overlay' for overlay checkout
      onEvent: (event) => {
        console.log("Checkout event:", event);
        
        // Handle different events
        switch (event.event_type) {
          case "checkout.opened":
            // Checkout overlay has been opened
            break;
          case "checkout.closed":
            // Checkout has been closed
            break;
          case "checkout.error":
            // Handle errors
            console.error("Checkout error:", event.data?.message);
            break;
        }
      },
    });
    ```

    <Warning>
      在尝试打开结账之前务必初始化 SDK。初始化应在应用加载时只执行一次。
    </Warning>
  </Step>

  <Step title="Create a Checkout Button Component">
    创建一个打开结账覆盖的组件：

    ```typescript theme={null}
    // components/CheckoutButton.tsx
    "use client";

    import { Button } from "@/components/ui/button";
    import { DodoPayments } from "dodopayments-checkout";
    import { useEffect, useState } from "react";

    export function CheckoutButton() {
      const [isLoading, setIsLoading] = useState(false);

      useEffect(() => {
        // Initialize the SDK
        DodoPayments.Initialize({
          mode: "test",
          displayType: "overlay",
          onEvent: (event) => {
            switch (event.event_type) {
              case "checkout.opened":
                setIsLoading(false);
                break;
              case "checkout.error":
                setIsLoading(false);
                console.error("Checkout error:", event.data?.message);
                break;
            }
          },
        });
      }, []);

      const handleCheckout = async () => {
        try {
          setIsLoading(true);
          await DodoPayments.Checkout.open({
            checkoutUrl: "https://checkout.dodopayments.com/session/cks_123"
          });
        } catch (error) {
          console.error("Failed to open checkout:", error);
          setIsLoading(false);
        }
      };

      return (
        <Button 
          onClick={handleCheckout}
          disabled={isLoading}
        >
          {isLoading ? "Loading..." : "Checkout Now"}
        </Button>
      );
    }
    ```
  </Step>

  <Step title="Add Checkout to Your Page">
    在您的应用程序中使用结账按钮组件：

    ```typescript theme={null}
    // app/page.tsx
    import { CheckoutButton } from "@/components/CheckoutButton";

    export default function Home() {
      return (
        <main className="flex min-h-screen flex-col items-center justify-center p-24">
          <h1>Welcome to Our Store</h1>
          <CheckoutButton />
        </main>
      );
    }
    ```
  </Step>

  <Step title="Handle Success and Failure Pages">
    创建页面以处理结账重定向：

    ```typescript theme={null}
    // app/success/page.tsx
    export default function SuccessPage() {
      return (
        <div className="flex min-h-screen flex-col items-center justify-center">
          <h1>Payment Successful!</h1>
          <p>Thank you for your purchase.</p>
        </div>
      );
    }

    // app/failure/page.tsx
    export default function FailurePage() {
      return (
        <div className="flex min-h-screen flex-col items-center justify-center">
          <h1>Payment Failed</h1>
          <p>Please try again or contact support.</p>
        </div>
      );
    }
    ```
  </Step>

  <Step title="Test Your Integration">
    1. 启动您的开发服务器：

    ```bash theme={null}
    npm run dev
    ```

    2. 测试结账流程：
       * 点击结账按钮
       * 验证覆盖是否出现
       * 使用测试凭据测试支付流程
       * 确认重定向正常工作

    <Check>
      你应该在浏览器控制台看到结账事件的日志。
    </Check>
  </Step>

  <Step title="Go Live">
    当您准备好进行生产时：

    1. 将模式更改为 `'live'`:

    ```typescript theme={null}
    DodoPayments.Initialize({
      mode: "live",
      displayType: "overlay",
      onEvent: (event) => {
        console.log("Checkout event:", event);
      }
    });
    ```

    2. 更新您的结账 URL，以使用来自后端的实时结账会话
    3. 在生产环境中测试完整流程
    4. 监控事件和错误
  </Step>
</Steps>

## API 参考

### 配置

#### 初始化选项

```typescript theme={null}
interface InitializeOptions {
  mode: "test" | "live";
  displayType?: "overlay" | "inline";
  onEvent: (event: CheckoutEvent) => void;
}
```

| 选项            | 类型                      | 是否必填 | 描述                                             |
| ------------- | ----------------------- | ---- | ---------------------------------------------- |
| `mode`        | `"test" \| "live"`      | 是    | 环境模式：`'test'` 用于开发，`'live'` 用于生产               |
| `displayType` | `"overlay" \| "inline"` | 否    | 显示类型：`'overlay'` 表示模态结账（默认），`'inline'` 表示嵌入式结账 |
| `onEvent`     | `function`              | 是    | 用于处理结账事件的回调函数                                  |

#### 结账选项

```typescript theme={null}
interface CheckoutOptions {
  checkoutUrl: string;
  options?: {
    showTimer?: boolean;
    showSecurityBadge?: boolean;
  };
}
```

| 选项                          | 类型        | 是否必需 | 描述                                                                                  |
| --------------------------- | --------- | ---- | ----------------------------------------------------------------------------------- |
| `checkoutUrl`               | `string`  | 是    | 来自 [create checkout session API](/api-reference/checkout-sessions/create) 的结账会话 URL |
| `options.showTimer`         | `boolean` | 否    | 显示或隐藏倒计时。默认值为 `true`。当禁用时，会话过期时您将收到 `checkout.link_expired` 事件。                     |
| `options.showSecurityBadge` | `boolean` | 否    | 显示或隐藏安全徽章。默认值为 `true`。                                                              |

### 方法

#### 打开结账

使用指定的结账会话 URL 打开结账覆盖。

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123"
});
```

您还可以传递其他选项以自定义结账行为：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    showTimer: false,
    showSecurityBadge: false,
  },
});
```

#### 关闭结账

以编程方式关闭结账覆盖。

```typescript theme={null}
DodoPayments.Checkout.close();
```

#### 检查状态

返回结账覆盖当前是否打开。

```typescript theme={null}
const isOpen = DodoPayments.Checkout.isOpen();
// Returns: boolean
```

### 事件

SDK 提供实时事件，您可以通过 `onEvent` 回调监听：

```typescript theme={null}
DodoPayments.Initialize({
  onEvent: (event: CheckoutEvent) => {
    switch (event.event_type) {
      case "checkout.opened":
        // Checkout overlay has been opened
        break;
      case "checkout.form_ready":
        // Checkout form is ready for user input
        break;
      case "checkout.payment_page_opened":
        // Payment page has been displayed
        break;
      case "checkout.customer_details_submitted":
        // Customer and billing details submitted
        break;
      case "checkout.closed":
        // Checkout has been closed
        break;
      case "checkout.redirect":
        // Checkout will perform a redirect
        break;
      case "checkout.error":
        // An error occurred
        console.error("Error:", event.data?.message);
        break;
      case "checkout.link_expired":
        // Checkout session has expired (only when showTimer is false)
        break;
    }
  }
});
```

| 事件类型                                  | 描述                                        |
| ------------------------------------- | ----------------------------------------- |
| `checkout.opened`                     | 结账覆盖已打开                                   |
| `checkout.form_ready`                 | 结账表单已准备好接收用户输入。用于隐藏加载状态。                  |
| `checkout.payment_page_opened`        | 支付页面已显示                                   |
| `checkout.customer_details_submitted` | 客户和账单详情已提交                                |
| `checkout.closed`                     | 结账覆盖已关闭                                   |
| `checkout.redirect`                   | 结账将执行重定向                                  |
| `checkout.error`                      | 结账过程中出现错误                                 |
| `checkout.link_expired`               | 结账会话过期时触发。仅在 `showTimer` 设置为 `false` 时收到。 |

## 实施选项

### 包管理器安装

如 [分步集成指南](#step-by-step-integration-guide) 所示，通过 npm、yarn 或 pnpm 安装。

### CDN 实施

对于无需构建步骤的快速集成，您可以使用我们的 CDN：

```html theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dodo Payments Checkout</title>
    
    <!-- Load DodoPayments -->
    <script src="https://cdn.jsdelivr.net/npm/dodopayments-checkout@latest/dist/index.js"></script>
    <script>
        // Initialize the SDK
        DodoPaymentsCheckout.DodoPayments.Initialize({
            mode: "test", // Change to 'live' for production
            displayType: "overlay",
            onEvent: (event) => {
                console.log('Checkout event:', event);
            }
        });
    </script>
</head>
<body>
    <button onclick="openCheckout()">Checkout Now</button>

    <script>
        function openCheckout() {
            DodoPaymentsCheckout.DodoPayments.Checkout.open({
                checkoutUrl: "https://checkout.dodopayments.com/session/cks_123"
            });
        }
    </script>
</body>
</html>
```

### 主题定制

您可以通过在打开结账时传递一个 `themeConfig` 对象到 `options` 参数来自定义结账外观。主题配置支持浅色和深色模式，允许您自定义颜色、边框、文本、按钮和边框半径。

<Info>
  本节介绍使用结账 SDK 进行 **客户端** 主题配置。您还可以在通过 API 创建结账会话时使用 `theme_config` 参数进行 **服务器端** 配置。有关 API 级配置，请参阅 [Checkout Theme Customization](/features/checkout#checkout-theme-customization)，或使用仪表板中的 [Design page](/features/design) 可视化配置主题并进行实时预览。
</Info>

#### 基本主题配置

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    themeConfig: {
      light: {
        bgPrimary: "#FFFFFF",
        textPrimary: "#344054",
        buttonPrimary: "#A6E500",
      },
      dark: {
        bgPrimary: "#0D0D0D",
        textPrimary: "#FFFFFF",
        buttonPrimary: "#A6E500",
      },
      radius: "8px",
    },
  },
});
```

#### 完整主题配置

所有可用主题属性：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    themeConfig: {
      light: {
        // Background colors
        bgPrimary: "#FFFFFF",        // Primary background color
        bgSecondary: "#F9FAFB",      // Secondary background color (e.g., tabs)
        
        // Border colors
        borderPrimary: "#D0D5DD",     // Primary border color
        borderSecondary: "#6B7280",  // Secondary border color
        
        // Text colors
        textPrimary: "#344054",       // Primary text color
        textSecondary: "#6B7280",    // Secondary text color
        textPlaceholder: "#667085",  // Placeholder text color
        textError: "#D92D20",        // Error text color
        textSuccess: "#10B981",      // Success text color
        
        // Button colors
        buttonPrimary: "#A6E500",           // Primary button background
        buttonPrimaryHover: "#8CC500",      // Primary button hover state
        buttonTextPrimary: "#0D0D0D",       // Primary button text color
        buttonSecondary: "#F3F4F6",         // Secondary button background
        buttonSecondaryHover: "#E5E7EB",     // Secondary button hover state
        buttonTextSecondary: "#344054",     // Secondary button text color
      },
      dark: {
        // Background colors
        bgPrimary: "#0D0D0D",
        bgSecondary: "#1A1A1A",
        
        // Border colors
        borderPrimary: "#323232",
        borderSecondary: "#D1D5DB",
        
        // Text colors
        textPrimary: "#FFFFFF",
        textSecondary: "#909090",
        textPlaceholder: "#9CA3AF",
        textError: "#F97066",
        textSuccess: "#34D399",
        
        // Button colors
        buttonPrimary: "#A6E500",
        buttonPrimaryHover: "#8CC500",
        buttonTextPrimary: "#0D0D0D",
        buttonSecondary: "#2A2A2A",
        buttonSecondaryHover: "#3A3A3A",
        buttonTextSecondary: "#FFFFFF",
      },
      radius: "8px", // Border radius for inputs, buttons, and tabs
    },
  },
});
```

#### 仅浅色模式

如果您只想自定义浅色主题：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    themeConfig: {
      light: {
        bgPrimary: "#FFFFFF",
        textPrimary: "#000000",
        buttonPrimary: "#0070F3",
      },
      radius: "12px",
    },
  },
});
```

#### 仅深色模式

如果您只想自定义深色主题：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    themeConfig: {
      dark: {
        bgPrimary: "#000000",
        textPrimary: "#FFFFFF",
        buttonPrimary: "#0070F3",
      },
      radius: "12px",
    },
  },
});
```

#### 部分主题覆盖

您可以仅覆盖特定属性。结账将对未指定的属性使用默认值：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    themeConfig: {
      light: {
        buttonPrimary: "#FF6B6B", // Only override primary button color
      },
      radius: "16px", // Override border radius
    },
  },
});
```

#### 与其他选项结合的主题配置

您可以将主题配置与其他结账选项结合使用：

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://checkout.dodopayments.com/session/cks_123",
  options: {
    showTimer: true,
    showSecurityBadge: true,
    themeConfig: {
      light: {
        bgPrimary: "#FFFFFF",
        buttonPrimary: "#A6E500",
      },
      dark: {
        bgPrimary: "#0D0D0D",
        buttonPrimary: "#A6E500",
      },
      radius: "8px",
    },
  },
});
```

#### TypeScript 类型

对于 TypeScript 用户，所有主题配置类型都是导出的：

```typescript theme={null}
import { ThemeConfig, ThemeModeConfig } from "dodopayments-checkout";

const themeConfig: ThemeConfig = {
  light: {
    bgPrimary: "#FFFFFF",
    // ... other properties
  },
  dark: {
    bgPrimary: "#0D0D0D",
    // ... other properties
  },
  radius: "8px",
};
```

## 错误处理

SDK 通过事件系统提供详细的错误信息。请始终在您的 `onEvent` 回调中实现正确的错误处理：

```typescript theme={null}
DodoPayments.Initialize({
  mode: "test",
  displayType: "overlay",
  onEvent: (event: CheckoutEvent) => {
    if (event.event_type === "checkout.error") {
      console.error("Checkout error:", event.data?.message);
      // Handle error appropriately
      // You may want to show a user-friendly error message
      // or retry the checkout process
    }
    if (event.event_type === "checkout.link_expired") {
      // Handle expired checkout session
      console.warn("Checkout session has expired");
    }
  }
});
```

<Warning>
  在错误发生时始终处理 `checkout.error` 事件，以提供良好的用户体验。
</Warning>

## 最佳实践

1. **仅初始化一次**：在应用程序加载时初始化 SDK，而不是每次尝试结账时
2. **错误处理**：始终在事件回调中实现正确的错误处理
3. **测试模式**：在开发过程中使用 `test` 模式，只有在准备好生产时才切换到 `live`
4. **事件处理**：处理所有相关事件以提供完整的用户体验
5. **有效的 URL**：始终使用来自创建结账会话 API 的有效结账 URL
6. **TypeScript**：使用 TypeScript 提供更好的类型安全性和开发者体验
7. **加载状态**：在打开结账时显示加载状态以改善用户体验
8. **计时器管理**：如果您想手动处理会话过期，请禁用计时器 (`showTimer: false`)

## 故障排除

<AccordionGroup>
  <Accordion title="Checkout not opening">
    **可能的原因：**

    * 在调用 `open()` 之前未初始化 SDK
    * 无效的结账 URL
    * 控制台中的 JavaScript 错误
    * 网络连接问题

    **解决方案：**

    * 验证 SDK 初始化是否在打开结账之前发生
    * 检查控制台错误
    * 确保结账 URL 有效且来自创建结账会话 API
    * 验证网络连接
  </Accordion>

  <Accordion title="Events not firing">
    **可能的原因：**

    * 事件处理程序未正确设置
    * JavaScript 错误阻止事件传播
    * SDK 未正确初始化

    **解决方案：**

    * 在 `Initialize()` 中确认事件处理程序配置正确
    * 检查浏览器控制台中的 JavaScript 错误
    * 验证 SDK 初始化是否成功完成
    * 首先测试一个简单的事件处理程序
  </Accordion>

  <Accordion title="Styling issues">
    **可能的原因：**

    * 与应用程序样式的 CSS 冲突
    * 主题设置应用不正确
    * 响应式设计问题

    **解决方案：**

    * 在浏览器开发者工具中检查 CSS 冲突
    * 验证主题设置是否正确
    * 在不同屏幕尺寸上测试
    * 确保与覆盖没有 z-index 冲突
  </Accordion>
</AccordionGroup>

## 启用数字钱包

有关设置 Google Pay 和其他数字钱包的详细信息，请参阅 <a href="/features/payment-methods/digital-wallets">数字钱包</a> 页面。

<Note>
  Overlay checkout 尚不支持 Apple Pay。Apple Pay 支持即将推出。
</Note>

## 浏览器支持

Dodo Payments Checkout SDK 支持以下浏览器：

* Chrome (最新版本)
* Firefox (最新版本)
* Safari (最新版本)
* Edge (最新版本)
* IE11+

## Overlay 与 Inline Checkout 的比较

根据使用情况选择正确的结账类型：

| 功能   | Overlay Checkout | Inline Checkout |
| ---- | ---------------- | --------------- |
| 集成深度 | 页面顶部的模态框         | 完全嵌入页面          |
| 布局控制 | 限制               | 完全控制            |
| 品牌效果 | 独立于页面            | 无缝衔接            |
| 实施努力 | 较低               | 较高              |
| 最佳用途 | 快速集成，现有页面        | 自定义结账页面，高转换流程   |

<Tip>
  使用 **overlay checkout** 可实现快速集成，对现有页面的更改最少。使用 **inline checkout** 时，您可以最大限度地控制结账体验和无缝品牌体验。
</Tip>

## 相关资源

<CardGroup cols={2}>
  <Card title="Inline Checkout" icon="credit-card" href="/developer-resources/inline-checkout">
    将结账直接嵌入您的页面以实现完整的集成体验。
  </Card>

  <Card title="Checkout Sessions API" icon="code" href="/api-reference/checkout-sessions/create">
    创建结账会话以支持您的结账体验。
  </Card>

  <Card title="Webhooks" icon="webhook" href="/developer-resources/webhooks">
    使用 Webhooks 服务器端处理支付事件。
  </Card>

  <Card title="Integration Guide" icon="book" href="/developer-resources/integration-guide">
    完整指南：集成 Dodo Payments。
  </Card>
</CardGroup>

如需更多帮助，请访问我们的 [Discord 社区](https://discord.gg/bYqAp4ayYh) 或联系开发者支持团队。
