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

# 绑卡与 Token 管理

> 将用户银行卡信息安全转换为 Token，后续支付无需再次输入卡号。

将用户银行卡信息安全转换为 Token，后续支付无需再次输入卡号。

<Info>
  本流程横跨**服务端**（调用 Generate / Inquiry / Remove API）与**前端**（通过 `@waffo/payment-sdk` 提交卡信息）两端。
</Info>

## 核心流程

```
1. 商户后端 → 调用 Generate API → 获取 tokenSessionId
2. 前端 → 使用 @waffo/payment-sdk 提交卡片信息 → 卡片数据加密传输
3. 处理结果 → 获取 tokenId（可能需要 3DS 验证）
4. 后续支付 → 在 order/create 中传入 tokenId 代替卡号
```

## 绑卡流程

<Steps>
  <Step title="商户后端调用 Generate API">
    调用 `POST /api/v1/tokenization/generate`，传入 `tokenRequestId`、`merchantUserId`、`tokenType: "CARD"` 等参数。成功后返回 `tokenSessionId`。

    详见 [Generate API](/docs/zh/developer-docs/integration/tokenization/generate)。
  </Step>

  <Step title="前端提交卡片信息">
    使用 `@waffo/payment-sdk` 的 `tokenizationSubmit` 方法将卡片数据加密后提交至 Waffo 服务器：

    ```typescript theme={null}
    import WaffoSDK from '@waffo/payment-sdk';

    const sdk = new WaffoSDK('your-client-api-key', {
      env: 'prod',
      locale: 'en'
    });

    const result = await sdk.tokenizationSubmit('tokenSessionId', {
      tokenData: {
        pan: '4111111111111111',
        name: 'John Doe',
        expiry: '12/2025',    // MM/YYYY
        cvv: '123'            // 可选
      },
      billingAddress: {        // 可选
        countryCode: 'USA',
        region: 'CA',
        city: 'San Francisco',
        postalCode: '94102',
        address: '123 Main St'
      }
    });
    ```

    SDK 自动对卡片数据加密。商户服务器不接触明文卡号，因此无需 PCI DSS 认证。
  </Step>

  <Step title="处理绑卡结果">
    ```typescript theme={null}
    if (result.success) {
      const { tokenRequestId, validateUrl } = result.data;

      if (validateUrl) {
        // 需要 3DS 验证，重定向用户
        window.location.href = validateUrl;
      } else {
        // 绑卡成功，等待 Webhook 获取 tokenId
      }
    }
    ```

    绑卡完成后，Waffo 通过 `notifyUrl` 向商户后端发送通知，包含最终的 `tokenId`。商户必须保存该 `tokenId` 以用于后续支付。
  </Step>
</Steps>

### 替代方案：PCI-DSS 商户直接提交

若商户已通过 PCI-DSS 认证，可通过 Generate API 的 `tokenData` 字段直接从后端提交卡号等敏感信息，无需使用前端 SDK。此时 API 将直接返回 `tokenId`。

## 使用 Token 支付

获取 `tokenId` 后，在创建订单时传入以代替卡号：

```typescript theme={null}
const response = await waffo.order().create({
  paymentRequestId: '...',
  merchantOrderId: 'ORDER_001',
  orderCurrency: 'HKD',
  orderAmount: '100.00',
  tokenId: 'tok_xxxxxxxxxxxx',  // 使用 Token 代替卡号
  notifyUrl: 'https://your-site.com/webhook',
  // ... 其他参数
});
```

支持一次性支付（ONE\_TIME\_PAYMENT）和订阅支付（SUBSCRIPTION）。

## Token 管理

| 操作 | API                                                                                      | 说明                |
| -- | ---------------------------------------------------------------------------------------- | ----------------- |
| 查询 | [POST /api/v1/tokenization/inquiry](/docs/zh/developer-docs/integration/tokenization/inquiry) | 获取用户已绑定的 Token 列表 |
| 解绑 | [POST /api/v1/tokenization/remove](/docs/zh/developer-docs/integration/tokenization/remove)   | 删除已绑定的 Token      |

## 安全机制

* 前端 SDK 自动对卡片数据加密，商户服务器不接触明文卡号
* 所有 API 请求和响应均使用 SHA256WithRSA 签名验证
* 支持 3DS 验证，提升支付安全性
* 非 PCI-DSS 商户**必须**使用前端 SDK，不得直接从后端传入卡号
