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

# 订单金额、限额与拒绝

> 为什么看起来有效的金额会被拒绝、同币种与跨币种订单的校验方式有何不同、processingAmountLimits 的 min/max/multiple 是什么意思、哪个限额产生了哪个错误码、支付方式类型如何决定你的客户能否付款、如何解读卡拒绝，以及未支付订单会保持开放多久。

关于订单为什么在客户看到支付页面之前就被拒绝的一切，以及客户看到之后如何解读拒绝。
订单字段的含义见
[订单创建字段指南](/docs/zh/support/order-create-field-guide)；确认结果见
[确认支付结果](/docs/zh/support/payment-results-faq)；固定的按币种小数位表见
[币种](/docs/zh/developer-docs/core-concepts/currency)。

## 为什么我的金额因为小数位太多被拒绝了？

因为精度规则有**两条**而不是一条，并且它们作用于不同的金额：

| 层 | 作用于 | 效果 |
| - | - | - |
| **订单币种，ISO 小数位** | 你的 `orderAmount`，始终 | 如果金额的小数位多于订单币种的 ISO 4217 定义，或违反该币种的倍数规则，创建时以 `A0003` 拒绝。 |
| **处理精度与倍数** | 实际被扣款的金额 | 如果扣款金额无法以处理精度表达，或违反支付方式的倍数规则，该支付方式会被移除。如果没有支付方式存活，你会收到 `A0018`。 |

第二层是同币种和跨币种分道扬镳的地方，也是值得内化的部分。

## 同币种和跨币种的校验方式不同。怎么不同？

第二层作用于**客户实际被扣款的那个金额**：

* **同币种订单**——扣款金额*就是*你的 `orderAmount`，所以严格的处理精度和倍数直接
  作用于你提交的值。有些币种的处理精度**比其 ISO 小数位更窄**：这些币种按 ISO 规则
  接受两位小数，但按整数单位处理。在这类币种中带有小数部分的金额会通过第一层，然后
  被第二层拒绝。
* **跨币种订单**——扣款金额是**换算后**的金额，所以严格校验落在那里而不是你的
  `orderAmount` 上。Waffo 先换算，然后把结果调整到处理币种的精度和支付方式的倍数，
  所以带有处理侧无法接受的小数位的 `orderAmount` 不再是你的问题。

**你必须知道自己处于两种场景中的哪一种。** 同一币种的同一个 `orderAmount` 可能在一种
场景被接受、在另一种被拒绝，区别完全在于客户以哪种币种付款。如果你以一种币种定价、
以另一种币种扣款，不要照搬你为本地流程构建的同币种校验。

## Waffo 对换算后的金额向哪个方向取整？

**向上。** 换算后，金额先向上调整以适应处理币种的精度，然后在支付方式有倍数要求时，
再向上调整到下一个有效倍数。取整只会出现在**跨币种**订单中——同币种订单永远不会被
重新取整，它只被校验并原样传递。

差额会报告给你：跨币种订单的查询响应会返回换算后的金额、所用汇率以及所做的调整，
所以你可以对照定价金额核对扣款金额而无需重新计算。汇率何时锁定见
[汇率](/docs/zh/support/exchange-rates-faq)。

## 为什么 10.50 被拒绝而 10 被接受？

因为金额限制不只是一个范围——还有**整数倍数**。支付方式可以要求金额必须是某个单位的
整数倍，此时任何不是该单位倍数的值都会被拒绝，无论它多么稳妥地落在 min/max 之内。

倍数按**支付方式加实际处理币种**来划分，所以：

* 同一支付方式可能在一种币种带有倍数要求，在另一种币种则没有。
* 同一币种下的两个支付方式可能带有不同的倍数要求。
* 有倍数要求的支付方式几乎总是**完全没有小数部分**——如果一个支付方式要求整数单位的
  倍数，`10.50` 永远无法满足它。

这种形态的金额是"我的金额在限额之内却仍被拒绝"的最常见单一原因。

## 我如何在创建订单之前找到限额？

从支付方式查询响应中读取。每个可用支付方式都返回 `processingAmountLimits`，以处理
币种为键，包含三个字段：

| 字段 | 含义 |
| - | - |
| `min` | 该币种下可接受的最小金额。 |
| `max` | 可接受的最大金额。 |
| `multiple` | 金额必须是它的整数倍。为零或缺失表示没有倍数约束。 |

本地币种和换算币种都会出现在该映射中，所以跨币种支付方式会以客户实际被扣款的币种
报告限额。在你自己的预检中，除了 `min`/`max` 之外也要按 `multiple` 校验——这是
大多数集成跳过的字段。

## 哪个错误对应命中了哪个限额？

| 码 | 在这里的含义 | 怎么做 |
| - | - | - |
| `A0003` | 订单金额的小数位或倍数不符合**订单币种**。 | 修正你提交的金额。 |
| `A0008` | 订单金额对每个候选协议而言都超出了**合约**的金额范围。 | 问题在金额本身，不在其形态。 |
| `A0018` | 过滤后没有支付方式存活——包括因为**扣款**金额不满足处理精度或支付方式的倍数。 | 重新读取 `processingAmountLimits` 并调整；同时检查你传的支付方式和终端。 |
| `A0029` | 你引用的卡凭证不可用——未知、状态错误，或不属于该用户。 | 见下文的 token 部分。 |

注意 `A0018` 是"没有可用项"的兜底，所以终端不匹配或订阅时长过长时你也会收到它。
把它读作"过滤后什么都不剩"，而不是"支付方式名称错误"。其他 `A0018` 原因见
[订单创建字段指南](/docs/zh/support/order-create-field-guide)。

## 为什么某个支付方式对我的客户不可用？

因为支付方式的**类型**决定了客户如何完成付款，而有些类型只能以一种方式完成。支付方式
可以被限制在特定的客户终端上，Waffo 会在创建订单时强制执行：

* Waffo 为每个支付方式维护一个允许终端列表。如果你发送的 `userTerminal` 不在该支付
  方式的列表中，**该支付方式会从候选中移除**。如果什么都不剩，创建失败。
* 仅限 App 拉起的支付方式是经典案例：有些电子钱包、BNPL 和数字银行方式通过跳转到
  移动 App 完成，所以它们在桌面浏览器上根本不作为选项存在。

后果：**`userTerminal` 不是分析提示，而是路由输入。** 在移动端会话发送桌面端的值，
或对所有流量默认使用同一个值，会让完全可用的支付方式消失，并产生一个你的日志会归因
到错误原因的创建失败。请按会话检测它。接受的值见
[订单创建字段指南](/docs/zh/support/order-create-field-guide)。

## 银行转账和柜台支付：为什么我创建订单后什么都没发生？

因为对这些类型而言，**创建订单和付款是两个独立的事件**。客户带着账号、参考号或凭条
离开，稍后通过他们的银行或在柜台付款。在他们付款之前，Waffo 侧不会发生其他任何事情。

* 预期创建和结果之间有很长的间隔，并预期两条通知：一条在订单可以付款时，一条在钱
  到账时。
* 客户仍可付款的窗口是**按支付方式**设定的，而不是由单一平台值设定，所以同一国家的
  两个银行转账方式可能在不同时间关闭。
* 不要因为订单几个小时没有动静就取消或重新创建它。什么算终态见
  [确认支付结果](/docs/zh/support/payment-results-faq)。

## 我可以在创建订单时设置客户的默认卡吗？

不可以——创建订单不是设置默认卡的地方。请使用专用的已保存支付方式端点；见
[Tokenization 与卡支付](/docs/zh/support/tokenization-faq)。

创建订单对已保存凭证*确实*会做的是严格校验。传入 `paymentInfo.userPaymentAccessToken`：

| 情形 | 结果 |
| - | - |
| token 不存在 | 创建失败（`A0029`）。 |
| token 不处于可用状态 | 创建失败。 |
| token 属于另一个 `userId` | 创建失败。token 的作用范围限于创建它的客户。 |
| 你同时传了原始卡数据 | 创建失败——两者互斥。 |

所以已保存卡的扣款要么就在那个确切的凭证上进行，要么根本不进行。不会静默回退到另一张
已存储的卡，这是有意为之：客户不应在你未指定的卡上被扣款。

## `tokenizationNotifyUrl` 会替代 `notifyUrl` 吗？

不会。它们是独立的通道，你两个都需要：

* `notifyUrl` 一如既往地接收**支付**结果。
* tokenization 通知 URL 只接收**绑卡**结果。

配置其中一个对另一个没有影响，在支付过程中绑定的卡会在两个通道上各产生一条通知。
tokenization URL 在哪里配置见
[Tokenization 与卡支付](/docs/zh/support/tokenization-faq)。

## 卡被拒绝了。我应该重试吗？

只有在你知道收到的是四种拒绝中的哪一种之后。Waffo 把卡组织的响应映射为 Waffo 失败码
和一个重试类别：

| 类别 | 含义 | 怎么做 |
| - | - | - |
| **不要重试** | 卡组织已告知这次尝试永远不会成功——账户已关闭、无效、被报告遗失或被盗，或该持卡人不允许此交易。 | **请客户换一张卡。** 不要重试，包括按计划重试。对这类情形的重复尝试可能招致卡组织费用。 |
| **更新信息后重试** | 凭证本身已过时或认证失败——卡已过期，或认证数据未通过验证。 | 让客户重新输入或重新绑定卡，然后再次扣款。原样重试同一个已存储凭证会以同样方式失败。 |
| **稍后重试** | 发卡行侧的临时状况——当前资金不可用、达到频率或金额限制、发卡行不可达。 | 延迟后重试。对订阅而言，重试策略已经为你做了这件事。 |
| **其他** | 其他所有情况，包括不适合此交易的卡产品。 | 不要假设可重试。当指引是获取另一种支付方式时，按第一类处理。 |

比分类法更重要的两条规则：

* **永久性拒绝是换卡提示，不是重试候选。** 这里最昂贵的集成错误就是对一个永远无法
  通过的拒绝反复循环。
* Waffo 不公布每个码的重试上限，你的运维手册也不应假设有一个。周期性扣款的重试上限
  遵循卡组织规则——见
  [订阅重试与支付方式](/docs/zh/support/subscription-retry-and-payment-methods-faq)。

## 客户告诉银行停止周期性付款。我必须做什么？

**立即停止对该客户的所有周期性扣款。** 卡组织有专门的响应码表示持卡人撤销授权——针对
单个商户或所有商户——以及持卡人要求停止周期性或分期付款。这些按定义是不可重试的，
继续尝试是合规问题，而不只是一次失败的支付。

具体来说：

* 取消订阅，而不是让重试计划自行耗尽。
* 不要在同一凭证上创建新订阅。
* 如果客户之后想恢复，他们必须从头重新授权，给出新的同意。

## 未支付的订单会保持开放多久？

Waffo 侧有两个默认值，按支付方式是否为卡来区分，两者都不是你应该据以构建的合约条款：

| 订单 | 默认窗口 |
| - | - |
| 卡类支付方式 | 一个**较长**的平台默认值，以小时计。卡被有意给予较长窗口：结果同步到达，较短的窗口有关闭一个随后成功的订单的风险。 |
| 其他所有支付方式 | 一个**较短**的平台默认值——但在实践中被支付方式自身配置的超时所取代，后者才是支配银行转账、虚拟账户和柜台支付流程的值。 |

平台默认值是环境配置，可能变化；如果窗口对你的业务很重要，请在接受商户指定过期时间的
支付方式上自己发送 `orderExpiredAt`（**Service → Payin** 上的 `Order Expiry Customization`
列告诉你哪些支持）。在不支持的支付方式上它会被忽略。
`orderExpiredAt` 控制什么、不控制什么，以及为什么 Waffo 关闭订单后支付仍可能到账，见
[确认支付结果](/docs/zh/support/payment-results-faq)。

## 稳定币：一笔支付可以被标记为两种异常类型吗？

不可以。一个异常携带**恰好一种**类型——该字段是单值的，所以既迟到又不足的支付只会
记录在一种分类下，而不是两种。类型如下：

| 类型 | 含义 |
| - | - |
| `OVERPAID` | 收到的金额多于订单金额。 |
| `UNDERPAID` | 收到的金额少于订单金额。 |
| `LATE_PAID` | 资金在订单已经终态之后到达。 |
| `WRONG_TOKEN` | 收到的代币不是订单预期的代币，或根本不是可识别的代币。 |
| `WRONG_CHAIN` | 资金到达在订单未预期的链上。 |
| `NO_MATCH_ORDER` | 无法为该转账匹配到任何订单。 |
| `UNSUPPORTED_WALLET_ADDRESS` | 涉及的地址无法自动处理。 |
| `BLOCKED` | 出于风控原因拒收的资金。 |

两条你可以依赖的排序规则：

* **先解析代币身份，再比较金额。** 无法识别或不匹配的代币会被分类为代币问题，金额永远
  不会被比较——所以不要期望一笔用错代币的转账出现 `UNDERPAID`。
* **退回地址最后检查，且它胜出。** 如果一个异常本来会被自动处理，但它要退回的地址不是
  普通钱包地址，该异常会被**重新分类为地址问题并转入人工处理**。这就是为什么多付可能
  以地址异常的形式出现。

各种情况下钱会怎样，见
[稳定币异常与退款](/docs/zh/support/stablecoin-exceptions-faq)。


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