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

# Webhook 事件日志与手动重发

> 如何在 Merchant Portal 中检查 Webhook 投递：什么算投递成功、为什么记录可能完全缺失、每种事件显示哪个 Order ID，以及手动重发与自动重试如何相互影响。

Merchant Portal 中的 **Webhooks** 页面记录了 Waffo 向你发送的每一条 Webhook，并允许你自行重发失败的记录。回调契约本身见 [Webhook overview](/docs/zh/developer-docs/webhook/overview) 和 [Webhook retries](/docs/zh/developer-docs/webhook/retry)；URL 设置见 [Portal Self-Service Security Configuration](/docs/zh/support/portal-security-config-faq)。

## 如何检查某条 Webhook 是否已经投递？

打开 **Merchant Portal → Webhooks**，按事件类型、状态（`SUCCESS` / `FAILED`）、Order ID 或时间范围筛选。每条记录包含：

| 字段 | 含义 |
| - | - |
| Event type | 推送的是哪种事件（支付、退款、拒付、订阅）。 |
| Status | `SUCCESS` 或 `FAILED`，由你的 HTTP 响应决定。 |
| Order ID | 该事件的业务标识——见下文表格。 |
| Notify URL | 本次尝试实际使用的回调 URL。 |
| Triggered at | 投递记录创建的时间。 |
| Next retry | 下一次自动重试的计划时间。**仅当**记录已失败*且*仍有重试额度时才有值——因此已投递成功的记录和重试额度已耗尽的记录都为空。 |
| Request body | Waffo 发送的完整报文，在详情视图中查看。 |
| HTTP response | 你的端点返回的失败摘要（仅失败记录）。 |

日志从该功能上线时开始记录；更早的通知不会回填。

## 我刚触发了一条通知，列表里没有，是丢了吗？

大概率没有。仍在发送中的通知处于一种列表**默认不返回**的进行中状态，因此记录可能需要几秒才出现——这是刻意的，为了避免把进行中的尝试显示为 `FAILED`。

## 我的服务器返回了 HTTP 200，为什么 Waffo 显示 FAILED？

仅 HTTP 200 是不够的。只有当你的端点返回 **HTTP 200 *且* 响应 body 为 `{"message":"success"}`** 时，投递才算 `SUCCESS`。其他任何结果——HTTP 200 但 body 不同或为空、`failed`、`unknown`、超时、无法解析的响应——都算 `FAILED`。

## 我能自己重发失败的 Webhook 吗？

可以，有三种模式：

| 模式 | 适用场景 |
| - | - |
| 单条 | 你要重新驱动某一条已知事件。 |
| 多选 | 你从列表中选了若干条失败记录。 |
| 按时间范围 | 你的端点在某段时间内宕机，想回放该窗口内的失败记录。 |

单次请求最多重发 **50 条记录**。在时间范围模式下，可以先估算该窗口内的失败记录数，若超出上限再缩小范围。

## 手动重发会回到自动重试队列吗？

\*\*会——这是最容易被忽略的一点。\*\*手动重发走的是与自动重试相同的投递路径：它会计入该记录的重试额度，如果失败，只要还有额度，下一次自动重试就会被重新排期。只有额度耗尽后，下一次重试时间才会被清空。

由此带来的后果：\*\*对一个仍然故障的端点手动重发，会消耗你剩余的一次尝试机会。\*\*先验证或修复你的端点，再重发。额度耗尽后，记录保持 `FAILED` 且没有下一次重试时间，恢复它就是你这边的事了——请通过 [Order Inquiry](/docs/api-reference/introduction) 回查，而不是等待再一次投递。

## 为什么某些记录的 Resend 按钮是灰的？

记录不能重发的原因恰好有三个：没有存储**回调 URL**（无处可发）、**仍处于首次投递中**（进行中的尝试不可重发）、或该记录**不属于你的商户 ID**。

已成功投递的记录**不在**这个列表里——成功记录*可以*重发，这是刻意的，因为 Waffo 记录为已接受的投递，在你这边仍可能未被处理。

重发还要求你的 Portal 角色具备 webhook 重发权限。没有该权限时，该操作和行选择根本不会渲染，而不是显示为禁用，所以一个在任何地方都看不到重发控件的操作人，面对的是权限问题而不是记录是否符合条件的问题——请找你的 Portal Admin。

## Webhooks 页面里完全没有我某笔交易的记录

结果为空几乎总是意味着**没有解析出通知 URL**——而不是投递失败。没有 URL 时，Waffo 不会发送任何内容，也不会写日志记录。请检查该事件类型的 URL 来源：

| 事件 | URL 来源 |
| - | - |
| 支付 | 创建订单时传入的 `notifyUrl`。 |
| 退款 | 退款请求中的 `refundNotifyUrl` 优先；为空时使用 Portal 中配置的 Refund Notify URL，并存储在该笔退款订单上。 |
| 拒付 | 只有 Portal 中配置的 Chargeback Notify URL——无法按请求传入。 |
| 订阅 | 订阅对象自身保存的 `notifyUrl`。 |

因此，缺少拒付记录通常意味着从未配置 Chargeback Notify URL；缺少退款记录意味着请求参数和 Portal 设置都不存在。

## 日志显示的是哪个 Order ID，为什么用我的原始订单号找不到拒付？

Order ID 列是事件自身的标识，每种事件各不相同：

| 事件 | 日志中的 Order ID |
| - | - |
| 支付 | `acquiringOrderId` |
| 退款 | `acquiringRefundOrderId` |
| 订阅状态 / 周期变更 | `subscriptionId` |
| 拒付 | 拒付案件的争议参考号 |

拒付记录按争议参考号列出和搜索，**不是**按原始支付订单——用你的原始订单号搜索拒付通知会一无所获。该订单号以 `originalOrderId` 的形式包含在报文内，请在记录详情视图的 request body 中读取。


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