> ## 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 的收银台

> 商户自建收银台能从 Waffo 拿到什么、拿不到什么：orderAction.actionData 何时有值何时为空、哪些支付凭据以原始数据返回、由谁校验必填的顾客字段、如何自行查询支付方式可用性和金额范围、托管与自建流程能否按订单混用，以及只有 Waffo 托管收银台才会执行的那些流程环节。

[选择集成方式](/docs/zh/developer-docs/use-cases/checkout-solution)
比较了两种模式，并告诉你每种模式需要哪些请求参数。
本页回答的是在你决定自建页面**之后**会遇到的问题：
你实际会收到什么数据、你必须自己做什么，以及
流程中哪些部分在商户侧没有对应物。

`orderAction.actionData` 的逐字段参考在
[API 参考速查表](/docs/zh/support/api-reference-tables)中。
本页不再重复。

## 如果我自建支付页面，我必须接收和处理什么？

四件事，按此顺序：

| 步骤 | 你要做什么 | 数据来自哪里 |
| - | - | - |
| 1. 决定支付方式 | 你的页面收集顾客的选择 | 你自己的 UI，基于你查询到的列表构建（见下文） |
| 2. 创建订单 | `POST /api/v1/order/create`，传 `payMethodType`，以及——针对特定钱包——`payMethodName` | [收银台客制化](/docs/zh/developer-docs/integration/checkout/customization) |
| 3. 呈现支付凭据 | 读取 `orderAction`。要么重定向顾客（`actionType` = `WEB` / `DEEPLINK`），要么从 `actionData` 渲染原始凭据 | [重定向与 `actionType`](/docs/zh/support/cashier-redirect-and-action-type-faq) |
| 4. 确认结果 | 你的支付通知（Webhook 通知），或 `POST /api/v1/order/inquiry` | [支付结果](/docs/zh/support/payment-results-faq) |

自建页面不会改变第 4 步的任何内容。顾客回到你的页面
不是支付的证明，渲染出一个二维码也不是支付的
证明。通知和查询仍然是唯一的权威
来源。

## `orderAction.actionData` 到底什么时候有值？

**只有当订单在创建时就已经解析到一个特定支付方式时。**
这是商户自建收银台最重要的一条规则，也很容易被忽略：

| 你在 `/api/v1/order/create` 上传了什么 | 你会拿回什么 |
| - | - |
| 一个特定支付方式（`payMethodType`，若该类型有多个子方式则加上 `payMethodName`） | 带重定向字段的 `orderAction`，**以及**当该方式有凭据可交付时的 `actionData` |
| 没有支付方式——你把选择留给顾客 | 指向 Waffo 托管收银台的 `orderAction`。`actionData` 为**空** |

原因是机制性的：顾客还没选择时，还没有任何支付
被提交给支付方式，所以没有账号、没有二维码
载荷、也没有过期时间可返回。它们只在方式被选定之后才会
产生。如果你把选择留给顾客，选择就发生在
Waffo 托管页面上——此时数据除了那个页面无处可去。

所以如果 `actionData` 为空而你期望有内容，请先检查你创建请求中的
支付方式参数。

## 哪些支付凭据以原始数据返回，哪些会强制重定向？

`actionData` 携带路由到的支付方式所产生的任何内容。大致上：

| 支付方式类型 | 你可以预期什么 |
| - | - |
| 二维码类方式 | `paymentQr` 中的二维码载荷——是**字符串**，不是图片 |
| 柜台（OTC）和输码类方式 | `paymentCode` 和/或 `paymentBarCode` |
| 银行转账和虚拟账户 | `bankAccount`、`bankName`、`bankBeneficiary`、`referenceNumber` |
| 在自己界面上授权的钱包 | 没有凭据——而是一个重定向 URL，或者完全没有 URL 的 App 推送 |
| 卡 | 没有凭据。卡数据收集不能交给 `actionData` |

值得提前规划的两个后果：

* **你自己渲染二维码。** `paymentQr` 是原始载荷字符串。在客户端把它
  编码成可扫描的码，尺寸要能被手机摄像头识别。
* **一种方式可能填充其中多个字段，也可能一个都没有。** 哪些字段到达是
  交易所路由到的支付方式的属性，而不是国家
  或你账户的属性。请把页面构建为渲染任何出现的字段，
  并在没有任何字段时回退到重定向。

## 我能拿到本地银行账号吗——CLABE、IBAN、虚拟账户？

可以，通过同一个字段：`bankAccount`。它携带顾客
必须转入的账户，采用本地系统使用的任何形式——墨西哥的 CLABE、其他地方的
IBAN、路由号加账号，或者为该笔订单
生成的虚拟账户。`bankName`、`bankBeneficiary` 和 `referenceNumber` 随
它一起返回。

两点注意：

* 它只在**会返回账号的银行转账和虚拟账户类方式**上有值。
  它不是一个你可以对任意支付方式
  请求的字段，抽象地问"CLABE"是没有答案的——
  问题永远是你正在集成的特定方式是否返回
  `bankAccount`。在构建界面之前，请在沙箱中按方式逐一验证。
* 上面的规则仍然适用：只有当你在订单上固定了支付
  方式时才能拿到它。

当你向 Waffo 支持询问某个方式是否返回银行转账数据时，
请附上你打算使用的方式和你将发送的 `userInfo.userTerminal`——
终端类型影响哪些方式有资格，所以答案
在 PC 会话和移动会话之间可能不同。

关于顾客转账后这些字段的行为——过期、金额错误、
基于 `referenceNumber` 的对账——请参见
[银行转账与虚拟账户](/docs/zh/support/bank-transfer-and-virtual-account-faq)。

## `apiMethod` 是 `POST`。我必须自己构建并提交表单吗？

在商户自建收银台上，是的。`orderAction` 完整描述了重定向，
而 `POST` 重定向需要全部三个部分：

| 字段 | 如何处理 |
| - | - |
| `actionType` | `WEB` → 使用 `webUrl`；`DEEPLINK` → 使用 `deeplinkUrl` |
| `apiMethod` | `GET` → 导航到该 URL。`POST` → 向它提交一个表单 |
| `formBody` | 表单字段，`a=1&b=2` 形式。拆分它，每对生成一个 hidden input |

在此过程中不要丢弃或重新编码参数——有几种支付方式
在 URL 或请求体中携带必需的值，被改写的 URL 会在
支付方式处而不是 Waffo 处失败。

如果你改用 Waffo 托管收银台，这一切都为你处理好了：页面
自己构建并提交表单。

## 我必须自己查询支付方式可用性和金额限制吗？

是的。这是商户自建收银台主要的持续成本，也是
最常被低估的一项。

| 你必须维护什么 | 如何获取 |
| - | - |
| 你的账户可以提供哪些支付方式，按国家和币种 | `POST /api/v1/paymethodconfig/inquiry`——参见[支付方式配置与限额](/docs/zh/support/payment-method-config-and-limits-faq) |
| 每种方式接受的金额范围 | 同一响应，在你创建订单之前 |
| 某种方式是否暂时不可用 | 同一响应中的状态字段 |
| 新签约的支付方式 | 在你添加之前，你的页面上不会出现任何内容 |

在 Waffo 托管收银台上这四项都是自动的：不可用的方式
显示为灰色，超出范围的方式不提供，新签约的方式
无需改代码就会出现。在你自己的页面上，过时的列表会变成
顾客已经确认下单却失败的订单。

## 支付方式所需的顾客字段由谁校验？

对于你发送的字段，由你校验。有几种支付方式的字段在
`/api/v1/order/create` 上记为可选，但对**该方式是必填的**
——国家身份证号、电话号码、邮编、邮箱地址。如果你
在自己的页面上收集它们，格式校验由你负责，Waffo 唯一的
反馈是一次被拒绝的订单创建调用。

哪些字段对哪种方式类型会变成必填的列表在
[条件必填字段](/docs/zh/support/conditional-required-fields-faq)中，
缺失字段错误中可能出现的字段路径也在同一
处。

在 Waffo 托管收银台上，这些字段在页面上收集，并在
支付提交之前内联应用支付方式自身的格式规则。

## 我能两者混用吗——部分支付方式自建，其他使用托管？

可以，而且是按订单而不是按账户决定的。同一个
`/api/v1/order/create` 端点可以给你任一行为：

* 传一个特定支付方式 → 顾客永远不会看到 Waffo 的选择
  页面，你会收到凭据或重定向来驱动你自己的界面。
* 不传支付方式 → 顾客进入 Waffo 托管收银台并
  在那里选择。

一种常见的做法是为占你交易量主导地位的两三种方式运行你自己的页面，
长尾部分回退到托管收银台——
这也意味着新的支付方式无需你这边改动就能工作。

你不能做的是在订单中途切换。一旦收银台会话已解析到
某个支付方式，该选择在本次会话中就固定了。

## 我能自己构建柜台（OTC）门店选择页面吗？

不能作为自助集成来做。对于顾客需要选择特定门店或网点的
柜台类方式，门店列表由 Waffo 托管收银台在支付步骤中
呈现；`actionData` 返回的是顾客带到柜台的支付
码，而不是接受它的地点列表。

所以商户自建页面可以呈现该码和说明，但
产生它的选择步骤在商户侧没有对应物。如果你的产品
需要在自己的 UI 中包含该界面，请把它作为产品需求向你的 Waffo 联系人
提出，而不是去找一个参数。

## 我能为卡支付自建页面吗？

只有当你准备好进入 PCI DSS 范围时才可以。这是
[集成对比](/docs/zh/developer-docs/use-cases/checkout-solution#comparison)中的权衡：
使用 Waffo 托管收银台，卡数据永远不会触及你的系统。

有两种中间选项，既让你留在范围之外，又能让
你控制页面：

* **卡 Tokenization**，卡字段由 Waffo
  前端 SDK 在你的页面内渲染——参见
  [Tokenization](/docs/zh/support/tokenization-faq)。
* **内嵌收银台**，Waffo 收银台在你的
  页面内渲染而不是替换它——参见
  [收银台集成步骤](/docs/zh/developer-docs/integration/checkout/steps#iframe-embedding-considerations)。

## 商户自建收银台可以使用 Apple Pay 吗？

可以——基于你自己的 Apple 商户身份直接集成 Apple Pay
是受支持的选项之一，与重定向到 Waffo 收银台、
在 App WebView 中加载它、以及通过 Waffo 前端 SDK 在 iframe 中加载它并列。
这四种选项及各自的要求在
[Apple Pay 集成](/docs/zh/developer-docs/integration/apple-pay/overview)中列出。

不可用的是对收银台 URL 做普通 iframe 来使用 Apple Pay：那条
路径需要前端 SDK 加上预先安排的域名验证。

## 自建收银台会改变我的报表、收据或退款吗？

不会。支付之后的一切都完全相同，因为订单就是同一个
订单：

| 领域 | 行为 |
| - | - |
| 支付通知 | 同样的事件，同样的载荷 |
| 订单查询 | 同一端点，同样的状态 |
| 退款 | 同一个 `/api/v1/order/refund` 以及同样的按方式退款规则 |
| Portal 交易列表和导出 | 交易以同样的方式出现 |
| 收据 | 由你的收据配置决定，而不是由顾客在哪个页面支付决定 |

不同的部分都在呈现侧：支付方式
选择、必填字段收集、凭据渲染、状态轮询和
结果页面。

## 托管收银台做了哪些我需要重建的事情？

值得在做决定前作为清单读一遍：

* 支付方式选择、分组和按国家排序，以及隐藏或
  灰化当前不可用的方式
* 收集并校验每种方式所需的顾客字段
* 渲染二维码和条形码，并提供复制和保存操作
* 轮询支付结果并在结果到达时推进页面，这样
  顾客不会停留在一个死页面上
* 可重试错误路径，瞬时失败在后台重试，
  页面自行前进
* 让顾客在失败后选择另一种支付方式，无需
  新订单
* 金额明细——价格、折扣、含汇率的小计、顾客
  手续费、税费、总计
* 展示语言，包括在你未发送
  `cashierLanguage` 时选择一种
* 顾客稍后重新打开链接时的链接已过期和已支付页面

***

还在决定？[选择集成方式](/docs/zh/developer-docs/use-cases/checkout-solution)
有并列对比。如果你已选择商户自建路线，并
需要确认某个特定支付方式返回什么，
请[联系支持](mailto:support@waffo.com)，附上支付方式、国家
和你将发送的 `userInfo.userTerminal`。


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