在对接第三方支付网关、GitHub 或各类开放平台时,Webhook 收不到或回调失败是最让人崩溃的环节。与其在自己的代码里盲目打日志,不如按照以下 6 个排查步骤逐一排除,快速定位是发送方、网络链路还是接收端的锅。
使用第三方工具拦截原始请求
不要急着怀疑自己的代码。首先创建一个独立的 Webhook 测试地址,将第三方平台的回调 URL 改为这个测试地址。触发一次回调,看测试工具能否收到。如果测试工具收不到,说明第三方根本没发,或者配置填错了;如果测试工具收到了,说明问题在你的服务器。
检查公网可达性与端口开放
Webhook 必须是公网可访问的 URL。如果你在本地开发,必须使用内网穿透工具(如 Ngrok/Cloudflare Tunnels)。如果是云服务器,请检查安全组或防火墙是否放行了 80/443 端口,以及 IP 是否被拉黑。
确认云厂商 WAF 或防 Bot 策略
这是极易被忽略的坑。如果你使用了 Cloudflare 等 CDN 服务,Webhook 请求可能被当成机器人拦截了(比如触发了 Bot Fight Mode)。检查 CDN 的拦截日志,必要时为 Webhook 路径(如 /api/webhook )添加 WAF 绕过白名单规则。
验证 HTTP 方法和路由匹配
大多数 Webhook 使用 POST 方法。请检查你的后端路由是否只允许了 GET ,或者 URL 结尾是否多写/少写了斜杠( / ),导致框架触发了 301 重定向,而第三方平台可能不支持跟随重定向,最终报 404 或 405 错误。
检查数据解析报错(Body Parse)
检查请求的 Content-Type 。有些平台发的是 application/json ,有些是 application/x-www-form-urlencoded 。如果你的框架配置了强类型的反序列化,一旦字段不匹配或类型错误,中间件可能会直接抛出 400 错误并拒绝请求,导致你连日志都看不到。
排查处理超时问题
很多第三方平台要求 Webhook 必须在 3~5 秒内返回 2xx 状态码。如果你的业务逻辑(如写数据库、发邮件)耗时过长,对方会认为回调失败并不断重试。正确做法是:先返回 200 OK,然后把任务丢进消息队列(如 Redis/RabbitMQ)异步处理。
- 先用 Webhook 测试工具确认请求是否发出
- 检查 Cloudflare 等 WAF 是否误杀了机器请求
- 确保路由完全匹配且不要触发 301 重定向
- 接收到请求后立即返回 200,业务逻辑异步处理