> ## 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.

# Card binding and token management

> Securely convert users’ bank card information into a token so future payments don’t require entering the card number again.

Securely convert users’ bank card information into a token, so there is no need to enter the card number again for subsequent payments.

## Core flow

```
1. Merchant backend → Call Generate API → Get tokenSessionId
2. Frontend → Use @waffo/payment-sdk to submit card information → Card data is transmitted with encryption
3. Processing result → Get tokenId (3DS verification may be required)
4. Subsequent payments → Pass tokenId in order/create to replace the card number
```

## Card binding flow

<Steps>
  <Step title="Merchant backend calls the Generate API">
    Call `POST /api/v1/tokenization/generate`, passing parameters such as `tokenRequestId`, `merchantUserId`, and `tokenType: "CARD"`. On success, it returns `tokenSessionId`.

    See [Generate API](/en/developer-docs/integration/tokenization/generate) for details.
  </Step>

  <Step title="Frontend submits card information">
    Use the `tokenizationSubmit` method of `@waffo/payment-sdk` to encrypt the card data and submit it to the Waffo server:

    ```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'
      }
    });
    ```

    The SDK automatically encrypts card data. The merchant server never touches the plaintext card number, so PCI DSS certification is not required.
  </Step>

  <Step title="Handle the card binding result">
    ```typescript theme={null}
    if (result.success) {
      const { tokenRequestId, validateUrl } = result.data;

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

    After card binding is completed, Waffo sends a notification to the merchant backend via `notifyUrl`, containing the final `tokenId`. The merchant must store this `tokenId` and use it for subsequent payments.
  </Step>
</Steps>

### Alternative: PCI-DSS merchants submit directly

If the merchant is PCI-DSS certified, they can submit sensitive information such as the card number directly from the backend through the `tokenData` field of the Generate API, without using the frontend SDK. In this case, the API returns `tokenId` directly.

## Pay with a token

After obtaining `tokenId`, pass it when creating an order to replace the card number:

```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',
  // ... 其他参数
});
```

Supports one-time payments (ONE\_TIME\_PAYMENT) and subscription payments (SUBSCRIPTION).

## Token management

| Action  | API                                                                                      | Description                                  |
| ------- | ---------------------------------------------------------------------------------------- | -------------------------------------------- |
| Inquiry | [POST /api/v1/tokenization/inquiry](/en/developer-docs/integration/tokenization/inquiry) | Retrieve the list of tokens a user has bound |
| Remove  | [POST /api/v1/tokenization/remove](/en/developer-docs/integration/tokenization/remove)   | Delete a bound token                         |

## Security mechanisms

* The frontend SDK automatically encrypts card data; the merchant server never touches the plaintext card number
* All API requests and responses use SHA256WithRSA signature verification
* Supports 3DS verification to enhance payment security
* Non-PCI-DSS merchants **must** use the frontend SDK and cannot pass card numbers directly from the backend
