> ## 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 收银台支持多种定制化能力，商户可以通过三种方式配置外观和行为。

## 定制化能力概览

| 能力      | API 传参 | 商户后台 | SDK 传入 |
| ------- | ------ | ---- | ------ |
| 主题色     | 支持     | 支持   | 支持     |
| 背景色     | 支持     | 支持   | 支持     |
| 文字色     | 支持     | 支持   | 支持     |
| 圆角      | 支持     | 支持   | 支持     |
| 商户 Logo | 支持     | 支持   | -      |
| 语言      | 支持     | -    | 支持     |

**优先级**：API 传参 > 商户后台 > SDK 传入

同一能力通过多种方式配置时，高优先级的生效。

## 支付方式过滤

通过 `payMethodType` 和 `payMethodName` 控制收银台展示的支付方式。

支付方式特例以及 App WebView / iframe 相关限制，参见 [支付方式集成注意事项](/docs/zh/developer-docs/tools-and-references/references/payment-method-integration-notes)。

### 推荐传参方式

| 场景               | payMethodType            | payMethodName | payMethodCountry | 说明                                                         |
| ---------------- | ------------------------ | ------------- | ---------------- | ---------------------------------------------------------- |
| **用户在收银台选择**（推荐） | 不传                       | 不传            | 不传               | 进入 Waffo 收银台的支付方式选择页，展示所有可用支付方式，由用户自选                      |
| **卡类支付**         | `"CREDITCARD,DEBITCARD"` | 不传            | **不传**           | 同时支持信用卡和借记卡，Waffo 根据卡 BIN 自动识别卡组（Visa/Mastercard），减少用户决策成本 |
| **仅信用卡**         | `"CREDITCARD"`           | 不传            | 不传               | 仅展示信用卡                                                     |
| **VA（虚拟账户）**     | `"VA"`                   | 不传            | 按需传              | 用户到收银台选择具体银行                                               |
| **指定具体钱包**       | 对应类型                     | 对应名称          | 按需传              | 如 `"EWALLET"` + `"DANA"`                                   |

### 示例

<CodeGroup>
  ```json 卡类支付（推荐） theme={null}
  // 最佳实践：卡类支付（同时支持信用卡+借记卡，Visa+Mastercard）
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "CREDITCARD,DEBITCARD"
    }
  }
  ```

  ```json VA 支付 theme={null}
  // VA 支付（用户到收银台选择银行）
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "VA"
    }
  }
  ```

  ```json 指定具体钱包 theme={null}
  // 指定具体钱包
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT",
      "payMethodType": "EWALLET",
      "payMethodName": "DANA"
    }
  }
  ```

  ```json 展示所有支付方式 theme={null}
  // 全部不传：用户在收银台看到所有可用支付方式
  {
    "paymentInfo": {
      "productName": "ONE_TIME_PAYMENT"
    }
  }
  ```
</CodeGroup>

### payMethodCountry 什么时候需要传

当商户希望收银台只展示**指定国家**的支付方式时传入。

* **不传**：收银台展示商户合约下所有国家的可用支付方式
* **传入**：收银台仅展示该国家的支付方式

```json theme={null}
// 仅展示印尼的支付方式
{
  "paymentInfo": {
    "productName": "ONE_TIME_PAYMENT",
    "payMethodCountry": "IDN"
  }
}
```

<Warning>
  **全球卡**（CREDITCARD/DEBITCARD）不要传 `payMethodCountry`，全球卡不属于任何国家。
</Warning>

## 多币种支持

当商户定价币种与用户支付币种不同时（跨币种下单）：

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

`userCurrency` 可不传，Waffo 自动处理汇率换算。用户在收银台看到的是当地货币金额。

## 语言设置

通过 `paymentInfo.cashierLanguage` 设置收银台显示语言（IETF BCP 47 格式）：

```json theme={null}
{
  "paymentInfo": {
    "productName": "ONE_TIME_PAYMENT",
    "cashierLanguage": "id-ID"
  }
}
```

支持的语言及其适用的币种/国家：

| 语言代码         | 语言         | 适用币种  | 适用国家         |
| ------------ | ---------- | ----- | ------------ |
| `en`         | English    | 所有币种  | 所有国家（默认回退语言） |
| `id-ID`      | 印尼语        | `IDR` | 印度尼西亚        |
| `vi-VN`      | 越南语        | `VND` | 越南           |
| `pt-BR`      | 葡萄牙语（巴西）   | `BRL` | 巴西           |
| `es-MX`      | 西班牙语（墨西哥）  | `MXN` | 墨西哥          |
| `es-PE`      | 西班牙语（秘鲁）   | `PEN` | 秘鲁           |
| `es-CO`      | 西班牙语（哥伦比亚） | `COP` | 哥伦比亚         |
| `es-CL`      | 西班牙语（智利）   | `CLP` | 智利           |
| `ru-RU`      | 俄语         | `RUB` | 俄罗斯          |
| `en-KE`      | 英语（肯尼亚）    | `KES` | 肯尼亚          |
| `zh-Hant-TW` | 繁体中文（台湾）   | `TWD` | 台湾           |
| `zh-Hant-HK` | 繁体中文（香港）   | `HKD` | 香港           |

### 自动选择逻辑

不指定 `cashierLanguage` 时，Waffo 按以下优先级自动选择语言：

1. 根据用户国家匹配（如用户国家为 IDN → `id-ID`）
2. 根据订单币种匹配（如币种为 BRL → `pt-BR`）
3. 以上均无匹配 → 回退到 `en`

### 注意事项

* 语言必须与币种/国家匹配。例如 `IDR` 币种的订单只能指定 `id-ID` 或 `en`，指定 `pt-BR` 会返回错误码 `A0026`
* `en` 是通用语言，适用于所有币种和国家
* 未在上表中列出的币种（如 `USD`、`EUR`、`SGD` 等），收银台仅支持 `en`

<Note>
  不支持的语言会返回错误码 `A0026`。
</Note>

## 主题定制

自定义收银台的颜色、字体和样式，匹配商户品牌形象。

### 三种配置方式

| 方式              | 优先级 | 说明                                            |
| --------------- | --- | --------------------------------------------- |
| **API 传参**（按交易） | 最高  | 在 `paymentInfo.cashierAppearance` 中传入，每笔交易可不同 |
| **商户后台**（全局）    | 中   | 在 Merchant Portal 配置全局默认主题                    |
| **SDK 传入**（客户端） | 最低  | 初始化前端 SDK 时传入                                 |

优先级：**API 传参 > 商户后台 > SDK 传入**。API 传了 `cashierAppearance` 会覆盖所有其他设置。

### 主题变量

| 变量名               | 说明              | 示例值       |
| ----------------- | --------------- | --------- |
| `colorPrimary`    | 主色调（按钮、链接、选中状态） | `#0570de` |
| `colorBackground` | 页面背景色           | `#ffffff` |
| `colorText`       | 主要文字颜色          | `#30313d` |
| `borderRadius`    | 圆角大小            | `8px`     |

这些变量会注入到收银台 UI 渲染层，覆盖默认主题。影响范围包括：支付方式选择页、卡片表单页、过渡页、支付结果页。

### API 传参方式

支持的接口：

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

<Note>
  `cashierAppearance` 字段必须是 **JSON 字符串**（不是 JSON 对象），结构为 `{"variables": { ... }}`，需要对内部的引号做转义。
</Note>

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

### 商户后台配置

登录 **Merchant Portal → Checkout → Cashier Customization**，在收银台客制化页面设置全局默认样式。适合所有交易使用统一品牌样式的场景。

Portal 支持配置商户 Logo、预设主题、主题颜色、字体大小和圆角，并可在页面右侧实时预览效果。点击 **Save & Publish** 后，配置会应用到后续新创建的订单。

<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 收银台客制化页面总览" width="1849" height="1207" data-path="images/developer-docs/integration/checkout/portal-customization/page-01-image-01.png" />
</Frame>

如果你的账户下有子商户（SubMID），可以选择让所有子商户继承主商户配置，也可以为单个子商户设置独立样式。

完整操作步骤见 [Merchant Portal 收银台客制化配置](/docs/zh/developer-docs/integration/checkout/portal-customization)。

### SDK 传入

初始化前端 SDK（`@waffo/payment-sdk`）时传入主题配置。优先级最低，当 API 和后台都未配置时生效。

```typescript theme={null}
const waffo = new WaffoSDK({
  env: 'production',
  appearance: {
    variables: {
      colorPrimary: '#0570de',
      colorBackground: '#ffffff',
      colorText: '#30313d',
      borderRadius: '8px'
    }
  }
});
```

## 商户 Logo

通过 `brandInfo.cashierLogoUrl` 传递商户 Logo，在收银台页面展示品牌标识。

两种传递方式：

| 方式            | 格式            | 说明                                                                                     |
| ------------- | ------------- | -------------------------------------------------------------------------------------- |
| 外部 URL        | `https://` 开头 | 商户自行托管，推荐尺寸 40x40 px                                                                   |
| Portal 预创建 ID | `logo_` 开头    | 通过 [Merchant Portal](https://dashboard.waffo.com/checkout/cashier-customization) 上传后获取 |

### API 传参示例

```json theme={null}
{
  "brandInfo": {
    "cashierLogoUrl": "https://merchant.com/logo.png"
  }
}
```

使用 Portal 上传的 Logo：

```json theme={null}
{
  "brandInfo": {
    "cashierLogoUrl": "logo_abc123"
  }
}
```

## 订单过期时间

通过 `orderExpiredAt` 设置订单过期时间（ISO 8601，UTC+0）。

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

该字段控制的是**用户在收银台提交订单的时间窗口**。一旦订单提交到支付渠道后，过期时间由支付方式自身控制，极少数支付方式支持商户传入渠道侧过期时间。具体可登录 Portal，到 Payin 页面查看各支付方式的过期时间说明。

## 重定向 URL

| 参数                   | 说明         |
| -------------------- | ---------- |
| `successRedirectUrl` | 支付成功后重定向   |
| `failedRedirectUrl`  | 支付失败后重定向   |
| `cancelRedirectUrl`  | 用户主动取消后重定向 |

支持 HTTPS 链接和 deeplink 链接（如 App 场景）。

<Warning>
  重定向仅控制用户体验，不代表支付结果。始终以 Webhook 或查询接口为准。
</Warning>
