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

# 银行转账与虚拟账户

> 虚拟账户（VA）与银行转账支付的行为说明：VA 账号有效期多长、之后能否被复用，用户输错金额会发生什么，以及法币多付或少付会对订单状态产生什么影响。

虚拟账户（VA）与银行转账支付打破了其他地方都成立的两个假设：用户是在
收银台会话**之外**付款的，而且到账金额是**用户自己输入的任意数字**。这两点
组合起来，就产生了本页的这些问题。

[确认支付结果](/docs/zh/support/payment-results-faq) 解释了这类支付方式报告的
两阶段结果，以及为什么订单长时间处于待支付是正常的。
[超时与结果何时为终态](/docs/zh/support/payment-timeout-and-finality-faq)
覆盖超时这一侧。本页讨论的是账号本身，以及金额不匹配的情况。

## 什么是虚拟账户？它的流程和跳转支付有什么不同？

VA 支付时，Waffo 返回的是一个**为该订单生成的银行账号**，而不是把用户送到
支付页面。用户随后从自己的银行 App、ATM 或柜台向该账号转账——完全在你的
会话之外，也在 Waffo 的会话之外。

你必须为此做好的设计：

| 特性 | 对你集成的影响 |
| - | - |
| 用户离开后稍后付款 | 订单可能会待支付数小时甚至数天；这不是失败的征兆 |
| 结果分两次到达 | 先是受理（已下发账号），之后才是支付结果 |
| 金额由银行收取，而不是收银台 | 金额在发出之前不会经过 Waffo 页面校验 |
| 没有跳转来完成支付 | 浏览器侧没有任何东西可供你轮询；请轮询订单 |

收银台上相关的支付方式类型包括 `VA`（虚拟账户）以及柜台支付类型（用户在
柜台以现金付款）。只展示 VA 方式的客制化参数见
[Checkout customization](/docs/zh/developer-docs/integration/checkout/customization)。

## VA 账号的有效期多长？我能控制吗？

VA 是少数几个可以在订单上实际设置过期时间、而不是由支付方式固定的支付方式
族之一。在支持该能力的 VA 方式上：

* 过期窗口上限为少数几天；每一行接受的具体范围显示在 **Service →
  Payin** 的 `Order Expiry Customization` 列中（见 [Payin 协议与交易限额](/docs/zh/support/payin-agreements-and-limits-faq)）。
* 如果你不指定，则使用该支付方式的默认值。

其他所有支付方式族一般都使用自己的默认过期时间，你无法覆盖；已发布的
[`orderExpiredAt`](/docs/zh/developer-docs/tools-and-references/references/faq)
说明覆盖了这一点。商户 Portal 的 PayIn 页面按支付方式展示过期行为。

## VA 账号是我这笔订单专属的吗？别人的付款会不会打到这个账号上？

在订单有效期内，账号是**唯一的**——它只属于该订单，不属于其他任何东西。

订单过期之后，这一保证即告结束。**几个月后，同一个账号可能再次出现**，
被下发给另一笔订单。因此：

* 绝不要把 VA 账号当作客户、订单或发票的持久标识。
* 绝不要在订单过期后还存储它并据此对账。
* 绝不要再向用户展示已过期的 VA 账号，也绝不要让用户向你为前一笔订单
  下发的账号付款——通过创建新订单重新下发。

改为用你自己的订单标识来匹配。VA 账号是一条保质期很短的支付指令，
而不是一个键。

## 用户输错了金额，或者在账号过期后才使用。我的订单是不是废了？

不是。这两种情况都会**在银行侧**被拒绝，在任何东西到达你的订单之前。

| 用户做了什么 | 用户看到什么 | 对订单的影响 |
| - | - | - |
| 输入了不匹配的金额 | 银行自己的错误提示，在银行的界面里 | **无**——订单保持开放 |
| 使用了订单已过期的账号 | 银行报告该账号已过期或无效 | 对已过期订单无影响 |

由于银行在接受转账前会校验账号和金额，错误的尝试通常连提交都无法完成。
**订单状态不受影响**，只要订单仍在有效期内，用户就可以直接用正确金额再试一次。

实际的客服答复是："你的转账没有被接收；订单仍然开放；请在截止时间前
转账所示的准确金额。"

## 用户付的金额比订单金额多。会发生什么？

在会报告实际收到金额的银行转账方式上，多付会产生一笔**成功订单，其收到
金额大于你请求的金额**。结果通知同时携带这两个数字，因此差额对你是可见的。

这意味着：

* 该订单是可付款、可履约的——不要把它当作阻断交付的异常。
* 多出的部分**不会**由支付方式自行冲正。
* 把多出部分退还给用户是**商户动作**。视支付方式不同，可能根本无法通过
  API 退款，此时需要在该笔支付之外另行处理。

请按收到金额对账，而不是按你请求的金额，否则你的账本会恰好偏离多付的那部分。

## 用户付的金额比订单金额少。我还能履约吗？

只有在用户及时补足的情况下才可以。少付会被报告为一种独立结果——通知会说明
收到的金额不足，并携带**差额**——它会以两种方式之一收尾：

| 后续情况 | 订单结果 |
| - | - |
| 用户在截止时间前补转了差额 | 订单变为**成功** |
| 截止时间已过而金额仍然不足 | 订单变为**失败** |

所以少付的订单不会立即失败，也不会立即变为可付款。金额不足期间请暂停履约。
当订单最终失败时，已转入的金额必须退还给用户——这同样是商户动作，在无法通过
API 对失败的银行转账退款的支付方式上，要在原支付之外处理。

最能省事的两条规则：

1. 绝不要在收到少付通知时履约。等待终态。
2. 绝不要假设差额通知就是故事的结尾——用户仍可能补足完成。

## 这和稳定币的多付、少付是一回事吗？

**形态**相同，**处理方式不同**。两者都是"到账金额不是请求金额"的情况，
两者的存在都是因为付款人控制着金额。但解决路径差异足够大，你不应该用同一
套代码路径处理两者。

| | 银行转账 / VA（法币） | 稳定币 |
| - | - | - |
| 多付 | 订单成功；收到金额超过请求金额；多出部分由商户退还 | 订单成功；多出部分按文档中的案例分类处理 |
| 少付 | 截止时间前补足则成功，否则失败 | 按文档中的案例分类处理 |
| 打错目标 | 不可能——银行会拒绝无效或过期的账号 | 可能：错链、错代币，或旧地址 |
| 资金退回 | 商户动作，经常在支付方式之外 | 退款需要 `refundAddress`，且锁定在同一链上 |

稳定币规则见
[稳定币异常与退款](/docs/zh/support/stablecoin-exceptions-faq)。请直接阅读那一页，
而不是从本页推断，反之亦然。

## 银行转账订单可以通过 API 退款吗？

不一定——这一点值得在接入该支付方式之前就确认，而不是等到收到第一笔退货请求
之后。有几种银行转账支付方式**完全无法通过退款 API 退款**：钱并不是通过可
逆的通道进来的，所以没有什么可以冲正。在 API 可以退款的情况下，有些方式需要
额外的用户信息（银行账户信息），因为钱是通过转账退回，而不是在原支付上冲正。

| 情形 | 会发生什么 |
| - | - |
| 该支付方式无法通过 API 退款 | 退款请求被拒绝，返回 `A0017` |
| 该支付方式可以退款但需要更多字段 | 请求被拒绝，返回 `A0003`，并列出缺失的字段名；填上后重新发送 |
| 该支付方式可以正常退款 | 退款行为与其他方式一样 |

不要在自己的代码里根据支付方式名称判断属于哪种情况——必填字段是配置，
不是可以从支付方式推断出的属性。提交退款，然后根据响应分支处理。完整规则见
[各支付方式退款限制](/docs/zh/support/payment-method-refund-limits-faq)
与 [退款 FAQ](/docs/zh/support/refund-faq)。

## 柜台支付的行为也一样吗？

大体一样——用户在会话之外付款，结果分两阶段到达，长时间待支付是正常的。
区别在于你交给用户的东西：柜台支付方式返回的不是账号，而是用户在柜台出示
的**付款码**，以及一组说明在哪里、如何付款的指引。

两点实操建议：

* 指引是文本加一个码，不是你可以依赖其渲染的图片或链接。把它们放到一个
  持久的地方——通常的答案是邮件，因为用户会在数小时或数天后才付款。
* 在本页的所有方面，该订单的行为都和 VA 订单一样：不要提前取消，不要把
  时间流逝当作失败，等待最终通知。

## 银行转账订单已经待支付好几个小时了，我应该取消吗？

不应该。对 VA、银行转账和柜台支付而言，长时间待支付是常态，因为用户按自己
的节奏付款。提前取消会造成最糟糕的失败模式：订单在你这边已关闭，而钱还在
路上。

等待最终通知，或轮询 `/api/v1/order/inquiry`。长时间待支付的情形见
[确认支付结果](/docs/zh/support/payment-results-faq)，超时能说明什么、不能说明
什么见
[超时与结果何时为终态](/docs/zh/support/payment-timeout-and-finality-faq)。

## 创建 VA 或柜台支付订单后，我应该向用户展示什么？

展示用户完成转账所需的一切，并且不要有任何会悄悄过期的东西：

1. 与返回内容完全一致的账号或付款码，以用户可复制的形式呈现。
2. **准确**金额，包括币种和小数位——金额不匹配会被银行拒绝，所以精度
   不只是外观问题。
3. 截止时间，用用户自己的表述方式（"请在 … 之前付款"），而不是原始时间戳。
4. 一条说明：支付在转账到账后才会确认，而不是立即确认。

同时通过邮件或其他持久渠道发送相同的信息。用户会关掉你的页面稍后再付——
这正是这种支付方式的全部意义——而只存在于用户已离开的页面上的支付指令，
最终会变成一张客服工单。

## 接下来该看哪里？

| 问题 | 页面 |
| - | - |
| 两阶段结果、缺失的 webhook、长时间待支付的订单 | [确认支付结果](/docs/zh/support/payment-results-faq) |
| 超时是否意味着支付失败 | [超时与结果何时为终态](/docs/zh/support/payment-timeout-and-finality-faq) |
| 银行转账订单能否通过 API 退款 | [各支付方式退款限制](/docs/zh/support/payment-method-refund-limits-faq) |
| 稳定币版本的多付与少付 | [稳定币异常与退款](/docs/zh/support/stablecoin-exceptions-faq) |
| 将收银台限制为仅 VA 方式 | [Checkout customization](/docs/zh/developer-docs/integration/checkout/customization) |


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