手机App支付完成后未收到回调,查询订单显示通知地址为空
结论
notify_url 并没有随”创建支付订单”请求被支付平台受理。常见原因包括参数层级错误、只在手机 App 端设置了该参数,或服务端调用 SDK 时未将通知地址传给支付网关。
需要修改的是服务端创建支付订单的代码或支付组件配置,而不是订单查询接口,也不是已经生成的订单。修改后必须新建一笔订单进行验证,因为历史订单的通知地址通常不会被补写。
为什么会出现”通知地址为空,但有通知内容”
查询工具显示”通知内容”,不代表支付平台已经向商户服务器发送过异步通知。这些内容可能是交易结果、模拟通知报文,也可能是平台根据订单生成的通知数据。
支付平台是否发送异步通知,取决于创建订单时实际保存的通知地址。如果查询记录中的通知地址为空,通常说明平台受理请求时没有取得有效的 notify_url。即使业务参数或本地日志中能看到这个字段,也不能证明它已按接口要求提交给支付平台。
可以重点排查以下情况:
notify_url被放在biz_content、扩展字段或自定义参数中,而接口要求它位于请求的公共参数层。- App 将
notify_url传给了业务后端,但后端生成支付订单时没有继续传给支付平台。 - SDK 要求通过
setNotifyUrl()等独立方法设置通知地址,但代码只在业务对象中添加了同名字段。 - 实际支付请求使用了另一套环境、商户号或服务端配置。
- 通知地址是在创建订单后才修改的,而修改通常只对新订单生效。
- 参数在请求签名前后被过滤,导致
notify_url没有进入最终请求。
解决步骤
1. 检查服务端最终出站请求
不要只检查 App 上传的参数,还要查看服务端最终发送给支付网关的请求。确认请求中包含完整的 notify_url,且参数位置符合当前接口的文档要求。
例如,请求结构可能是:
{
"app_id": "your_app_id",
"method": "payment.create",
"notify_url": "https://pay.example.com/callback/payment",
"biz_content": {
"out_trade_no": "ORDER_202609130001",
"total_amount": "99.00",
"subject": "订单支付"
}
}
如果接口规定 notify_url 属于公共参数,就不能写成:
{
"biz_content": {
"out_trade_no": "ORDER_202609130001",
"notify_url": "https://pay.example.com/callback/payment"
}
}
具体参数层级应以当前支付平台和接口版本的官方文档为准。
2. 按 SDK 的要求设置通知地址
部分 SDK 要求在请求对象上单独设置通知地址。下面是示意代码,实际使用时需要替换为对应 SDK 提供的类名和方法名:
PaymentRequest request = new PaymentRequest();
request.setBizContent(bizContent);
// notify_url 通常属于请求级参数
request.setNotifyUrl("https://pay.example.com/callback/payment");
PaymentResponse response = paymentClient.execute(request);
不要只在 App 端拼接这个参数:
// App 只负责向业务服务端申请支付参数
const paymentParams = await api.createPaymentOrder({
orderNo: "ORDER_202609130001"
});
await appPay(paymentParams);
通知地址应由服务端控制,不能由客户端任意传入。
3. 检查公共配置是否覆盖参数
如果项目通过统一配置管理回调地址,需要确认当前运行环境读取到了正确的配置:
payment:
notify-url: https://pay.example.com/callback/payment
同时检查测试、预发布和生产环境是否分别配置,并排查代码中是否存在用空值覆盖参数的情况:
request.setNotifyUrl(paymentProperties.getNotifyUrl());
可以在请求发出前记录经过脱敏处理的最终参数,确认 notify_url 既不是空字符串,也不是 null。
4. 创建新订单重新测试
修改代码或配置后,使用新的商户订单号创建订单并完成支付。不要用旧订单判断修改是否生效,因为通知地址一般会在创建订单时确定。
如果支付已经成功但回调丢失,业务系统还应主动调用订单查询接口进行补偿,避免订单长期停留在”待支付”状态。
回调地址还需要满足的条件
即使查询结果中已经显示通知地址,回调服务本身仍需符合平台要求:
- URL 必须能从公网访问,不能使用
localhost、局域网 IP 或只能通过 VPN 访问的地址。 - 优先使用有效的 HTTPS 地址,并确保域名证书完整。
- 接口需要支持平台规定的 HTTP 方法和数据格式。
- 验签成功后再更新订单状态,同时校验商户号、订单号和金额。
- 对重复通知进行幂等处理。
- 按平台要求返回指定的成功响应,否则平台可能持续重试。
- 不要把同步跳转地址当作
notify_url。如果用户关闭 App 或网络中断,同步返回并不可靠。
应先修正服务端”创建支付订单”请求中 notify_url 的设置位置,再通过新订单验证。订单查询接口通常不负责设置或修改异步通知地址。
备注:内容仅供参考。