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

# Cashier integration - Customization options

> Configurations such as cashier payment method filtering, multi-currency, language, and theme customization.

## Payment method filtering

Use `payMethodType` and `payMethodName` to control which payment methods are displayed in the cashier.

For payment method exceptions and App WebView / iframe limitations, see [Payment method integration notes](/en/developer-docs/tools-and-references/references/payment-method-integration-notes).

### Recommended parameter combinations

| Scenario                                  | payMethodType            | payMethodName      | payMethodCountry | Notes                                                                                                                    |
| ----------------------------------------- | ------------------------ | ------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **User selects in cashier** (recommended) | Omit                     | Omit               | Omit             | The user enters the Waffo payment-method selection page and chooses from all available payment methods                   |
| **Card payments**                         | `"CREDITCARD,DEBITCARD"` | Omit               | **Omit**         | Supports both credit and debit cards; Waffo auto-detects card network (Visa/Mastercard) from BIN, reducing user friction |
| **Credit card only**                      | `"CREDITCARD"`           | Omit               | Omit             | Show credit cards only                                                                                                   |
| **VA (Virtual Account)**                  | `"VA"`                   | Omit               | Pass if needed   | User selects the specific bank in the cashier                                                                            |
| **Specific wallet**                       | Corresponding type       | Corresponding name | Pass if needed   | e.g. `"EWALLET"` + `"DANA"`                                                                                              |

### Examples

<CodeGroup>
  ```json Card payments (recommended) theme={null}
  // Best practice: card payments (credit + debit, Visa + Mastercard)
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "CREDITCARD,DEBITCARD"
    }
  }
  ```

  ```json VA payment theme={null}
  // VA payment (user selects bank in cashier)
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "VA"
    }
  }
  ```

  ```json Specific wallet theme={null}
  // Specify a particular wallet
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "EWALLET",
      "payMethodName": "DANA"
    }
  }
  ```

  ```json All payment methods theme={null}
  // Omit all: user sees every available payment method
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT"
    }
  }
  ```
</CodeGroup>

### When to pass payMethodCountry

Pass this field when you want the cashier to show payment methods for a **specific country** only.

* **Omitted**: The cashier shows all payment methods available under the merchant contract across all countries.
* **Passed**: The cashier shows only the payment methods for that country.

```json theme={null}
// Show Indonesian payment methods only
{
  "paymentInfo": {
    "productName": "ONE_TIME_PAYMENT",
    "payMethodCountry": "IDN"
  }
}
```

<Warning>
  Do **not** pass `payMethodCountry` for global card methods (CREDITCARD/DEBITCARD). Global cards do not belong to any country.
</Warning>

## Multi-currency support

When the merchant pricing currency differs from the user payment currency (cross-currency order):

```json theme={null}
{
  "orderCurrency": "USD",
  "orderAmount": "10.00"
}
```

`userCurrency` can be omitted — Waffo automatically handles FX conversion. The user sees the amount in their local currency in the cashier.

## Language settings

Use `paymentInfo.cashierLanguage` to set the cashier display language (IETF BCP 47 format):

```json theme={null}
{
  "paymentInfo": {
    "productName": "ONE_TIME_PAYMENT",
    "cashierLanguage": "en-HK"
  }
}
```

Supported languages and their applicable currencies/countries:

| Language code | Language                        | Applicable currency | Applicable country               |
| ------------- | ------------------------------- | ------------------- | -------------------------------- |
| `en`          | English                         | All currencies      | All countries (default fallback) |
| `id-ID`       | Indonesian                      | `IDR`               | Indonesia                        |
| `vi-VN`       | Vietnamese                      | `VND`               | Vietnam                          |
| `pt-BR`       | Portuguese (Brazil)             | `BRL`               | Brazil                           |
| `es-MX`       | Spanish (Mexico)                | `MXN`               | Mexico                           |
| `es-PE`       | Spanish (Peru)                  | `PEN`               | Peru                             |
| `es-CO`       | Spanish (Colombia)              | `COP`               | Colombia                         |
| `es-CL`       | Spanish (Chile)                 | `CLP`               | Chile                            |
| `ru-RU`       | Russian                         | `RUB`               | Russia                           |
| `en-KE`       | English (Kenya)                 | `KES`               | Kenya                            |
| `zh-Hant-TW`  | Traditional Chinese (Taiwan)    | `TWD`               | Taiwan                           |
| `zh-Hant-HK`  | Traditional Chinese (Hong Kong) | `HKD`               | Hong Kong                        |

### Auto-selection logic

When `cashierLanguage` is not specified, Waffo selects the language automatically using the following priority:

1. Match by user country (e.g. user country is IDN → `id-ID`)
2. Match by order currency (e.g. currency is BRL → `pt-BR`)
3. No match found → fall back to `en`

### Notes

* The language must match the currency/country. For example, an order with `IDR` currency can only use `id-ID` or `en`; specifying `pt-BR` returns error code `A0026`.
* `en` is the universal language and works with all currencies and countries.
* Currencies not listed in the table above (e.g. `USD`, `EUR`, `SGD`) are only supported with `en`.

<Note>
  Unsupported languages return error code `A0026`.
</Note>

## Theme customization

Customize the cashier's colors, fonts, and styles to match your brand.

### Three configuration methods

| Method                               | Priority | Description                                                          |
| ------------------------------------ | -------- | -------------------------------------------------------------------- |
| **API parameter** (per transaction)  | Highest  | Pass via `paymentInfo.cashierAppearance`; can differ per transaction |
| **Merchant Portal** (global)         | Medium   | Configure a global default theme in the Merchant Portal              |
| **SDK initialization** (client-side) | Lowest   | Pass theme config when initializing the frontend SDK                 |

Priority order: **API parameter > Merchant Portal > SDK initialization**. When `cashierAppearance` is passed via API it overrides all other settings.

### Theme variables

| Variable          | Description                                    | Example value |
| ----------------- | ---------------------------------------------- | ------------- |
| `colorPrimary`    | Primary color (buttons, links, selected state) | `#0570de`     |
| `colorBackground` | Page background color                          | `#ffffff`     |
| `colorText`       | Main text color                                | `#30313d`     |
| `borderRadius`    | Corner radius                                  | `8px`         |

These variables are injected into the cashier UI rendering layer and override the default theme. They affect the payment method selection page, card form page, transition page, and payment result page.

### API parameter method

Supported endpoints:

* `POST /api/v1/order/create`
* `POST /api/v1/subscription/create`

<Note>
  The `cashierAppearance` field must be a **JSON string** (not a JSON object), with the structure `{"variables": { ... }}`. Escape the inner quotes accordingly.
</Note>

```json theme={null}
{
  "paymentInfo": {
    "productName": "ONE_TIME_PAYMENT",
    "cashierAppearance": "{\"variables\":{\"colorPrimary\":\"#0570de\",\"colorBackground\":\"#ffffff\",\"colorText\":\"#30313d\",\"borderRadius\":\"8px\"}}"
  }
}
```

### Merchant Portal configuration

Log in to **Merchant Portal → Checkout → Cashier Customization** to set a global default cashier style. Use this option when all transactions should share a unified brand style.

Portal supports merchant Logo, preset themes, theme colors, base font size, and corner radius. You can preview the cashier on the right side of the page. After you click **Save & Publish**, the configuration applies to newly created orders.

<Frame>
  <img src="https://mintcdn.com/waffo-docs/mrmpI6H8vZr9fPaZ/images/developer-docs/integration/checkout/portal-customization/page-01-image-01.png?fit=max&auto=format&n=mrmpI6H8vZr9fPaZ&q=85&s=1e69bc7c1c43eeb0d13f5a86fbc6a73b" alt="Merchant Portal Cashier Customization page overview" width="1849" height="1207" data-path="images/developer-docs/integration/checkout/portal-customization/page-01-image-01.png" />
</Frame>

If your account has sub-merchants (SubMIDs), you can either let all SubMIDs inherit the main merchant configuration or configure a separate style for each SubMID.

For complete steps, see [Merchant Portal cashier customization](/en/developer-docs/integration/checkout/portal-customization).

### SDK initialization

Pass theme configuration when initializing the frontend SDK (`@waffo/payment-sdk`). This has the lowest priority and takes effect only when neither the API nor the Merchant Portal has a theme configured.

## Order expiration time

Use `orderExpiredAt` to set the order expiration time (ISO 8601, UTC+0).

```json theme={null}
{
  "orderExpiredAt": "2026-03-25T11:00:00.000Z"
}
```

This field controls the **time window during which the user can submit the order in the cashier**. Once the order is submitted to the payment channel, the expiration time is governed by the payment method itself. A small number of payment methods support passing a channel-side expiration time from the merchant. Check the Payin page in the Portal for expiration details per payment method.

## Redirect URLs

| Parameter            | Description                              |
| -------------------- | ---------------------------------------- |
| `successRedirectUrl` | Redirect after a successful payment      |
| `failedRedirectUrl`  | Redirect after a failed payment          |
| `cancelRedirectUrl`  | Redirect after the user actively cancels |

Both HTTPS URLs and deeplinks (e.g. for in-app scenarios) are supported.

<Warning>
  Redirect URLs control the user experience only and do not represent the payment result. Always rely on Webhooks or the query API for the authoritative payment outcome.
</Warning>
