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

# 确认支付结果

> 如何可靠地判断一笔支付是否成功：跳转、webUrl、Webhook 通知和 Order Inquiry 各自的角色，每个 orderStatus 的含义，以及收不到通知时该怎么做。

本页的问题直接来自真实的商户对话。最重要的一条规则：

> **跳转只意味着用户的浏览器回到了你的网站。它永远不是支付成功的证明。** 支付结果的权威来源是 [Webhook 通知](/docs/zh/developer-docs/webhook/overview)，Order Inquiry API 作为对账兜底。

## 用户已经跳回我的网站了，支付是不是成功了？

不一定。`successRedirectUrl` 只是 UI 导航。请通过以下任一方式确认结果，按优先顺序：

1. **Webhook 通知**——支付完成或失败时，Waffo 会把支付结果推送到你的 `notifyUrl`。
2. **Order Inquiry**——需要对账时，调用 `/api/v1/order/inquiry` 主动查询订单。

只有当其中一种方式报告最终成功时，才把订单标记为已支付。

## 用户在跳转前就关了浏览器，支付是不是失败了？

不是。支付在支付方式一侧仍可能完成。无论用户的浏览器做了什么，Webhook 通知都会触发。如有疑问，调用 Order Inquiry。

## `webUrl` 和 `successRedirectUrl` 有什么区别？

它们的方向相反：

| 字段 | 方向 | 含义 |
| - | - | - |
| `webUrl`（在 `orderAction` 内） | 你把用户送**去**支付 | 当 `orderStatus` 为 `AUTHORIZATION_REQUIRED` 且 `actionType` 为 `WEB` 时，把用户跳转到 `webUrl` 进行授权/支付。若为 `DEEPLINK`，改用 `deeplinkUrl`。 |
| `successRedirectUrl`（订单创建参数） | 用户支付后**回来** | 支付成功后用户落地的位置。可选——省略则用户停留在 Waffo 收银台页面。 |

`failedRedirectUrl` 和 `cancelRedirectUrl` 以同样方式覆盖失败和用户取消的返回。

## 每个 `orderStatus` 值是什么意思？

| 状态 | 含义 |
| - | - |
| `PAY_IN_PROGRESS` | 订单已接受；用户正在支付中。 |
| `AUTHORIZATION_REQUIRED` | 支付方式需要用户授权——把用户带到 `orderAction` 指示的页面。 |
| `AUTHED_WAITING_CAPTURE` | 已授权，等待商户请款（卡支付）。 |
| `PAY_SUCCESS` | 最终成功。 |
| `ORDER_CLOSE` | 最终关闭——订单被取消、失败或超时。 |

只有 `PAY_SUCCESS` 和 `ORDER_CLOSE` 是终态。

## 订单超时了，`TIMEOUT_CLOSE` 和 `TIMEOUT_CHANNEL_CLOSE` 有什么区别？

两者都是因超时关闭的订单上的失败码。它们告诉你**用户在哪里流失了**：

| 失败码 | 发生了什么 |
| - | - |
| `TIMEOUT_CLOSE` | 用户在 Waffo 收银台/支付页面放弃了支付——从未向支付服务发起任何请求。 |
| `TIMEOUT_CHANNEL_CLOSE`（"Timeout waiting for channel response"） | 已经发起了支付或验证请求（例如 3DS 或钱包跳转），但在订单超时前没有收到结果。 |

用这个区分来分析你的转化漏斗：`TIMEOUT_CLOSE` 表示在授权开始前流失，`TIMEOUT_CHANNEL_CLOSE` 表示流程开始后停滞。当 Waffo 无法判断是否发起过请求时，订单回退为 `TIMEOUT_CLOSE`。该区分适用于所有支付方式；较早的订单保留其原有的码。

## 银行转账/柜台支付：为什么有两次通知？

用户在收银台会话之外付款的支付方式——银行转账/虚拟账户（VA）和柜台支付（OTC）——分两个阶段报告：

1. **受理**——订单创建后你会收到一个受理结果。这**不是最终支付状态**：用户尚未付款。
2. **支付结果**——只有在用户在其银行、ATM 或柜台完成付款后，最终通知才会到达。

两者之间的间隔可能很长，且自动关闭时间因支付方式而异。与同步支付方式完全一样，只把 `PAY_SUCCESS` / `ORDER_CLOSE` 视为终态。

## 我没收到Webhook 通知，应该检查什么？

1. `notifyUrl` 必须是 **HTTPS（TLS 1.2+）**，且可从公网访问。
2. 用 **Waffo 公钥**验证 `X-SIGNATURE` 头——并确保你的端点没有拒绝合法请求。
3. 处理完成后返回 `{"message": "success"}`。如果 Waffo 收到 `failed` 或 `unknown`，Waffo 会在随后一天内按退避计划重试通知——计划见 [Webhook 通知重试](/docs/zh/developer-docs/webhook/retry)。
4. 排查期间，用 Order Inquiry 获取订单状态，以免阻塞你的业务流程。

## 什么时候应该主动调 Order Inquiry 而不是等？

* 在你预期的窗口内没有收到Webhook 通知时，作为**对账兜底**。
* 当某个请求收到 `Exxxxx` 未知错误时——重试查询直到拿到最终的 `PAY_SUCCESS` 或 `ORDER_CLOSE`。
* 在批量对账任务中。

Order Inquiry 和Webhook 通知返回相同的订单状态；在终态上二者永远不会不一致。

## 订单创建失败了，我还会收到通知吗？

会。`PAYMENT_NOTIFICATION` 在支付**完成或失败**时发送——失败的订单和成功的订单一样会被通知，所以不要只依赖同步的创建响应来构建流程。

通知的内容也比该响应更丰富：

| 你看的位置 | 你能拿到的内容 |
| - | - |
| `/api/v1/order/create` 响应 | `paymentRequestId`、`merchantOrderId`、`acquiringOrderId`、`orderStatus`、`orderAction`（稳定币订单另有 `x402Info`） |
| `PAYMENT_NOTIFICATION`（以及 Order Inquiry） | 完整的订单对象，包括 **`orderFailedReason`**——一个包含 `orderFailedCode` 和 `orderFailedDescription` 的 JSON 值 |

所以被拒绝订单的失败原因可以在通知中和通过 Order Inquiry 获得，而不在创建响应中。用 `paymentRequestId` 或 `merchantOrderId` 把通知与你自己的记录匹配；两者都会原样回传。像任何其他Webhook 通知一样进行确认——见 [事件类型列表](/docs/zh/developer-docs/webhook/event-types)。

## 我创建订单后，客户还能付多久？

`orderExpiredAt` 是可选的。若省略，则应用你商户合约中的默认过期时间。它控制的范围比看起来更窄：

* 它决定客户可以**在收银台页面提交订单**的窗口（必须为 UTC+0）。
* 一旦订单已提交到支付方式，过期时间就由**该支付方式**决定，而不是你的值。少数支付方式接受商户传入的渠道侧过期时间——商户 Portal 的 Payin 页面显示每个支付方式的过期行为。
* 传入已经过去的时间会在创建时以 `A0034`（"the order expiry time provided by the merchant has expired"）被拒绝。

实际影响是：你的关闭时间和支付方式的关闭时间不是同一个时钟，这就是为什么在 Waffo 关闭订单后支付仍可能到账——如何处理这种情况，见本页最后一节。

## 一笔线下或银行转账订单已经挂了好几个小时，我要不要取消？

不要。对柜台支付（OTC）和虚拟账户/银行转账支付，客户是在收银台会话之外付款的，所以长时间待支付是正常的，而不是失败的征兆——且自动关闭时间因支付方式而异。

不要根据经过的时间推断失败，也不要在订单仍开放时在你这一侧释放或作废该购买：等待最终通知，或轮询 Order Inquiry。只有 `PAY_SUCCESS` 和 `ORDER_CLOSE` 是终态。

## 我同时发了两次相同的请求然后报错了，有哪一次成功了吗？

并发拒绝是保护机制，不是业务失败。用两个并行请求创建同一订单会返回 `A0040`（"the order cannot be created concurrently"），而不是创建两个订单。

这样处理：

1. **按订单串行化调用**——每个订单同一时刻只有一个在途请求，而不是并行重试。
2. **查清状态，不要猜。** 在做任何决定之前调用 Order Inquiry 查看订单的实际状态。
3. 重试原请求时，复用相同的 `paymentRequestId`——它是幂等键。`A0011` 和 `E` 类未知状态的处理见 [错误码速查](/docs/zh/developer-docs/tools-and-references/developer-tools/error-codes)。

## 用户说已经付了，但订单显示失败或超时

偶尔会出现支付在支付方式一侧完成，而 Waffo 订单已经因超时被关闭的情况（「先失败、后成功」）。处理方式：

* **绝不要凭用户的付款截图发货。** 只有当Webhook 通知或 Order Inquiry 报告 `PAY_SUCCESS` 时才发货。
* 把该情况连同订单 ID 报给 Waffo 支持。Waffo 会与支付方式一侧核对该订单；之后要么向你确认该支付，要么把扣款金额退还给用户。
* 用户可能会被要求提供更多细节以定位该交易，所以请收集他们能提供的信息——付款时间、金额，以及支付方式的交易参考号。


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