# CheckoutForm

`CheckoutForm` 组件是处理支付链接和结账会话的主要入口点。它作为一个高级封装器，根据提供的 ID 获取所有必要数据，并渲染相应的支付或捐赠界面。此组件是将完整的结账流程集成到您的应用程序中的最简单方法。

必须用 `PaymentProvider` 包裹 `CheckoutForm` 或其任何父组件，以确保它能访问必要的上下文，例如会话信息和 API 配置。更多详情，请参阅 [PaymentProvider 文档](./providers-payment-provider.md)。

## 工作原理

该组件协调整个结账流程：

1.  **初始化**：它通过 `paymentLink` ID（前缀为 `plink_`）或 `checkoutSession` ID（前缀为 `cs_`）进行挂载。
2.  **数据获取**：它与支付后端通信，以检索所有必要的上下文，包括支付方式、订单项和客户详细信息。
3.  **UI 渲染**：根据 `formType` 属性，它在内部渲染标准的 `Payment` 组件或专门的 `DonationForm` 组件。
4.  **状态管理**：它处理支付的整个生命周期，包括加载状态、完成状态和错误处理。

```d2 CheckoutForm 的基本流程 icon=lucide:workflow
direction: down
shape: sequence_diagram

User-Action: {
  shape: c4-person
  label: "用户"
}

Application: {
  label: "你的 React 应用"

  CheckoutForm-Component: {
    label: "CheckoutForm"
  }

  Payment-Component: {
    label: "Payment 组件"
  }

  Donation-Component: {
    label: "DonationForm 组件"
  }
}

Payment-API: {
  label: "支付后端 API"
  shape: cylinder
}

User-Action -> Application.CheckoutForm-Component: "1. 使用 'id' 属性挂载"
Application.CheckoutForm-Component -> Payment-API: "2. 获取会话数据"
Payment-API -> Application.CheckoutForm-Component: "3. 返回结账上下文"

alt "如果 formType 是 'payment'" {
  Application.CheckoutForm-Component -> Application.Payment-Component: "4. 渲染支付 UI"
}

alt "如果 formType 是 'donation'" {
  Application.CheckoutForm-Component -> Application.Donation-Component: "5. 渲染捐赠 UI"
}

User-Action -> Application.Payment-Component: "6. 完成支付"
User-Action -> Application.Donation-Component: "7. 完成捐赠"

```

## 属性

`CheckoutForm` 组件接受以下属性：

| 属性          | 类型                                                                       | 必填 | 默认值       | 描述                                                                                             |
|---------------|----------------------------------------------------------------------------|----------|---------------|-------------------------------------------------------------------------------------------------------------------------|
| `id`          | `string`                                                                   | 是      | -             | 支付链接（`plink_...`）或结账会话（`cs_...`）的唯一标识符。                                |
| `mode`        | `'standalone'` \| `'inline'` \| `'popup'` \| `'inline-minimal'` \| `'popup-minimal'` | 否       | `'inline'`    | 定义渲染模式。`'standalone'` 用于全页视图，`'inline'` 用于嵌入容器。                  |
| `formType`    | `'payment'` \| `'donation'`                                                 | 否       | `'payment'`   | 决定要渲染的表单类型。使用 `'donation'` 以实现专门的捐赠流程。                          |
| `onPaid`      | `(res: CheckoutContext) => void`                                           | 否       | -             | 支付成功后执行的回调函数。接收最终的结账上下文作为参数。               |
| `onError`     | `(err: Error) => void`                                                     | 否       | `console.error` | 在流程中发生错误时执行的回调函数。                                                   |
| `onChange`    | `(data: CheckoutFormData) => void`                                         | 否       | -             | 当任何表单字段值发生变化时触发的回调函数。                                                         |
| `goBack`      | `() => void`                                                               | 否       | -             | 如果提供，则渲染一个返回按钮，并在点击时调用此函数。                                                |
| `extraParams` | `Record<string, any>`                                                      | 否       | `{}`          | 从支付链接启动会话时，在 URL 中传递的额外参数对象。                  |
| `theme`       | `'default'` \| `'inherit'` \| `PaymentThemeOptions`                            | 否       | `'default'`   | 控制组件的主题。`'inherit'` 使用父主题，或者您可以传递一个自定义主题对象。             |
| `action`      | `string`                                                                   | 否       | `''`          | 一个字符串标识符，用于自定义 UI 元素（如按钮文本）或跟踪特定流程。                   |

## 用法

### 基本内联支付表单

这是将支付表单直接嵌入到您的应用程序 UI 中的最常见用例。该组件在内部处理所有逻辑。

```tsx MyStorePage.tsx icon=lucide:shopping-cart
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context'; // 您的应用的会话钩子

export default function MyStorePage() {
  const { session, connectApi } = useSessionContext();

  const handlePaymentSuccess = (result) => {
    console.log('支付成功！', result);
    alert('感谢您的购买！');
  };

  const handlePaymentError = (error) => {
    console.error('支付失败：', error);
    alert('抱歉，您的支付无法处理。');
  };

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <div style={{ maxWidth: '960px', margin: '0 auto' }}>
        <h1>结账</h1>
        <CheckoutForm
          id="plink_xxxxxxxxxxxxxx" // 替换为您的支付链接 ID
          mode="inline"
          onPaid={handlePaymentSuccess}
          onError={handlePaymentError}
        />
      </div>
    </PaymentProvider>
  );
}
```

### 独立全页结账

使用 `mode="standalone"` 来渲染一个专用的全页结账体验。这对于将用户重定向到单独页面以完成支付的场景非常理想。

```tsx CheckoutPage.tsx icon=lucide:layout-template
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context';

export default function CheckoutPage() {
  const { session, connectApi } = useSessionContext();
  const paymentLinkId = 'plink_xxxxxxxxxxxxxx'; // 可从 URL 参数中检索

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <CheckoutForm id={paymentLinkId} mode="standalone" />
    </PaymentProvider>
  );
}
```

### 捐赠表单

通过设置 `formType="donation"`，该组件会渲染一个专为捐赠活动量身定制的 UI，包括金额预设和权益显示等功能。

```tsx DonationPage.tsx icon=lucide:gift
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context';

export default function DonationPage() {
  const { session, connectApi } = useSessionContext();

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <div style={{ padding: '2rem' }}>
        <h2>支持我们的事业</h2>
        <CheckoutForm
          id="plink_yyyyyyyyyyyyyy" // 替换为您的捐赠链接 ID
          formType="donation"
          onPaid={() => alert('感谢您的慷慨捐赠！')}
        />
      </div>
    </PaymentProvider>
  );
}
```