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

# Waffo Checkout card binding

> Complete a CIT in Waffo Checkout and create a card token for subsequent MIT payments.

Complete a cardholder-initiated transaction (CIT) in Waffo Checkout and convert the card used for that payment into a token for subsequent merchant-initiated transactions (MIT). Your page and backend do not handle plaintext card data.

## When to use this flow

Use Waffo Checkout card binding when you already use Waffo Checkout and need to charge the same user after the first payment for:

* Scheduled MIT payments on an agreed billing schedule
* Unscheduled MIT payments while the user is offline
* A merchant-managed billing schedule implemented with `ONE_TIME_PAYMENT`

If you need to bind a card without the current payment, or want to design the card-binding UI on your own page, use [Merchant-side card binding](/docs/en/developer-docs/integration/tokenization/overview).

## End-to-end sequence

```mermaid theme={null}
sequenceDiagram
    actor User
    participant Merchant as Merchant backend
    participant Waffo
    participant Checkout as Waffo Checkout
    participant Channel as Payment channel

    Merchant->>Waffo: POST /api/v1/order/create<br/>setupFutureUsage=true
    Waffo-->>Merchant: Order Create response<br/>data.orderStatus + data.orderAction
    Merchant-->>User: Redirect to Waffo Checkout
    User->>Checkout: Enter a new card and submit
    Checkout->>Waffo: Submit payment method
    Waffo->>Channel: Initiate CIT
    Channel-->>Waffo: Payment succeeds
    Waffo->>Waffo: Create a token for future use
    Waffo-->>Merchant: PAYMENT_NOTIFICATION Webhook<br/>paymentInfo.userPaymentAccessToken
    opt Query the payment result
        Merchant->>Waffo: POST /api/v1/order/inquiry
        Waffo-->>Merchant: Order Inquiry response<br/>data.orderStatus + data.paymentInfo.userPaymentAccessToken
    end
    Merchant->>Merchant: Store the token
    Note over Merchant,Waffo: Merchant is allowlisted for MIT
    Merchant->>Waffo: POST /api/v1/order/create<br/>userPaymentAccessToken + merchantInitiatedMode
    Waffo-->>Merchant: Order Create response<br/>data.orderStatus
    Waffo->>Channel: Initiate MIT with the token
    Channel-->>Waffo: MIT result
    Waffo-->>Merchant: PAYMENT_NOTIFICATION Webhook<br/>MIT result
    opt Query the MIT result
        Merchant->>Waffo: POST /api/v1/order/inquiry
        Waffo-->>Merchant: Order Inquiry response<br/>data.orderStatus
    end
```

## How it differs from merchant-side card binding

| Comparison | Waffo Checkout card binding | Merchant-side card binding |
| - | - | - |
| Entry point | `POST /api/v1/order/create` with `paymentInfo.setupFutureUsage: true` | `POST /api/v1/tokenization/generate` + `sdk.tokenizationSubmit()` |
| User goal | Complete a payment and create a token for subsequent MIT payments | Bind a card without requiring a regular payment in the same flow |
| Card entry page | Waffo-hosted Checkout | The merchant page using `@waffo/payment-sdk` |
| Integration effort | Lower; reuse the existing Checkout payment flow and add `setupFutureUsage` plus token-result handling | Higher; integrate the Tokenization API, frontend SDK, zero-amount CIT verification, and token-status notifications |
| Initial verification | The successful CIT verifies the payment method | Bind the card first, then create a zero-amount CIT; 3DS can occur only during this CIT |
| Token result | Read `paymentInfo.userPaymentAccessToken` from `PAYMENT_NOTIFICATION` or the order inquiry response | Receive `TOKENIZATION_NOTIFICATION` at the `notifyUrl` in the Generate request |

## Prerequisites

* You have completed the [Checkout integration](/docs/en/developer-docs/integration/checkout/steps).
* The order uses `ONE_TIME_PAYMENT`.
* Your merchant account has a card payment method that supports MIT. When `setupFutureUsage: true`, Waffo offers only MIT-capable payment methods.
* Your merchant account has been allowlisted by Waffo for MIT. You cannot initiate MIT before approval.
* You use a stable `userInfo.userId` for the same user. Pass the same user ID when using the token later.

## Integration steps

<Steps>
  <Step title="Create a payment and declare future use">
    Call [Create payment](/docs/api-reference/order-create/create-new-order) and set `setupFutureUsage: true` in `paymentInfo`.

    ```json theme={null}
    {
      "paymentRequestId": "PAY_202609160001",
      "merchantOrderId": "ORDER_202609160001",
      "orderCurrency": "HKD",
      "orderAmount": "100.00",
      "orderDescription": "Initial payment with card binding",
      "orderRequestedAt": "2026-09-17T02:00:00.000Z",
      "notifyUrl": "https://merchant.example.com/webhooks/payment",
      "successRedirectUrl": "https://merchant.example.com/payment/success",
      "failedRedirectUrl": "https://merchant.example.com/payment/failed",
      "merchantInfo": {
        "merchantId": "YOUR_MERCHANT_ID"
      },
      "userInfo": {
        "userId": "USER_001",
        "userEmail": "user@example.com",
        "userTerminal": "WEB",
        "userCountryCode": "HKG"
      },
      "paymentInfo": {
        "productName": "ONE_TIME_PAYMENT",
        "setupFutureUsage": true
      }
    }
    ```

    Do not provide both `paymentInfo.setupFutureUsage` and `paymentInfo.userPaymentAccessToken`. The first creates a new token; the second uses an existing token.
  </Step>

  <Step title="Send the user to Checkout">
    Parse `orderAction` as you would for a regular Checkout payment, then redirect the user to Waffo Checkout. The user enters a new card and completes the payment.

    If the user selects an existing saved card, Waffo reuses it instead of binding the same card again.
  </Step>

  <Step title="Get the token from the payment notification">
    Waffo Checkout card binding does not send `TOKENIZATION_NOTIFICATION`. After the payment succeeds, Waffo sends `PAYMENT_NOTIFICATION` to the order's `notifyUrl`. Read the generated token from `result.paymentInfo.userPaymentAccessToken`.

    Payment notification excerpt with the fields used in this flow:

    ```json theme={null}
    {
      "eventType": "PAYMENT_NOTIFICATION",
      "result": {
        "paymentInfo": {
          "userPaymentAccessToken": "TOKEN_xxxxxxxxxxxx"
        }
      }
    }
    ```

    Store `result.paymentInfo.userPaymentAccessToken` after payment success. If the payment notification is not delivered, call [`POST /api/v1/order/inquiry`](/docs/api-reference/order-inquiry/order-inquiry), pass either `paymentRequestId` or `acquiringOrderId`, and read the same field from its response. For example:

    ```json theme={null}
    {
      "paymentRequestId": "PAY_202609160001"
    }
    ```

    Do not wait for `TOKENIZATION_NOTIFICATION`.
  </Step>

  <Step title="Use the token for MIT">
    <Warning>
      Only merchants allowlisted by Waffo for MIT can initiate MIT. Scheduled and unscheduled MIT are unavailable before approval.
    </Warning>

    For a subsequent charge, pass the token from the payment notification as `paymentInfo.userPaymentAccessToken` and set `merchantInitiatedMode`.

    ```json theme={null}
    {
      "paymentRequestId": "MIT_202610160001",
      "merchantOrderId": "ORDER_202610160001",
      "orderCurrency": "HKD",
      "orderAmount": "49.00",
      "orderDescription": "Scheduled merchant-initiated payment",
      "orderRequestedAt": "2026-10-16T02:00:00.000Z",
      "notifyUrl": "https://merchant.example.com/webhooks/payment",
      "merchantInfo": {
        "merchantId": "YOUR_MERCHANT_ID"
      },
      "userInfo": {
        "userId": "USER_001",
        "userEmail": "user@example.com",
        "userTerminal": "WEB"
      },
      "paymentInfo": {
        "productName": "ONE_TIME_PAYMENT",
        "userPaymentAccessToken": "TOKEN_xxxxxxxxxxxx",
        "merchantInitiatedMode": "scheduled"
      }
    }
    ```

    `merchantInitiatedMode` supports:

    * `scheduled`: Charge on a pre-agreed, fixed schedule
    * `unscheduled`: Merchant-initiated charge without a fixed schedule
  </Step>
</Steps>

## Troubleshooting

### No payment method is available

When `setupFutureUsage: true`, Waffo filters out payment methods that do not support MIT. Confirm that your merchant account has an MIT-capable card agreement. Contact Waffo technical support if no eligible method remains.

### Payment succeeded but the token has not arrived

Confirm that you received `PAYMENT_NOTIFICATION` and read `result.paymentInfo.userPaymentAccessToken`. If the notification is not delivered, call Order Inquiry and read the same field. Waffo Checkout card binding does not send `TOKENIZATION_NOTIFICATION`.

### MIT cannot be initiated

Confirm that the merchant is allowlisted by Waffo for MIT. Even with a token, a merchant cannot initiate scheduled or unscheduled MIT before approval.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.