PAYATHON 2026

支付宝为什么没有请求异步回调地址 notify_url?

支付小周

结论

支付宝没有请求 notify_url,常见原因有:

  • 当前 API 不支持异步通知。
  • notify_url 没有作为公共请求参数发送给支付宝。
  • 交易还没有进入触发通知的状态。
  • 支付宝无法从公网访问回调地址。
  • 支付宝已经发起请求,但服务端网关、日志或处理代码没有正确记录。
  • 回调接口没有返回纯文本 success,支付宝会重复通知,并可能在多次失败后停止重试。

排查时,先确认 API 文档是否明确支持异步通知,再检查支付宝实际收到的请求参数,以及回调地址能否从公网访问。

1. 确认 API 是否支持异步通知

并非所有支付宝 API 都会请求 notify_url。

打开支付宝开放平台中对应的 API 文档,查找“异步通知”“异步通知参数”或类似说明。只有明确支持异步通知的接口,传入 notify_url 才会生效。

部分查询、退款查询和账单下载接口只返回同步结果,即使配置了 notify_url,也不会产生异步回调。某些退款或关闭交易接口是否发送通知,还取决于具体产品、接口和交易状态,应以该 API 的当前文档为准。

开放平台控制台中的“应用网关”和“授权回调地址”也不能代替支付请求里的 notify_url,三者用途不同。

2. 检查 notify_url 是否真正随请求发送

notify_url 通常是支付宝接口的公共请求参数,不应放在 biz_content 中。如果只是把地址写进业务配置文件,却没有赋值给请求对象,支付宝不会收到这个地址。

Java SDK 示例:

AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();

request.setReturnUrl("https://www.example.com/pay/return");
request.setNotifyUrl("https://www.example.com/alipay/notify");

request.setBizContent("""
{
  "out_trade_no": "ORDER_202609080001",
  "total_amount": "0.01",
  "subject": "测试订单",
  "product_code": "FAST_INSTANT_TRADE_PAY"
}
""");

String form = alipayClient.pageExecute(request).getBody();

重点检查这一行:

request.setNotifyUrl("https://www.example.com/alipay/notify");

如果使用自建签名或直接发送 HTTP 请求,notify_url 应与 app_id、method、sign、timestamp 等参数位于同一层级:

app_id=...
method=alipay.trade.page.pay
notify_url=https://www.example.com/alipay/notify
biz_content={...}
sign=...

不要写成:

{
  "biz_content": {
    "out_trade_no": "ORDER_202609080001",
    "notify_url": "https://www.example.com/alipay/notify"
  }
}

排查时,记录最终提交给支付宝的请求参数,同时隐藏应用私钥、密钥和其他敏感信息。

3. 确认交易已经触发通知条件

支付接口调用成功,不代表支付宝会立即请求 notify_url。

创建交易成功,通常只说明订单已经创建,或者支付页面已经生成。异步通知一般要等买家完成支付,并且支付宝侧的交易状态发生相应变化。如果用户关闭支付页面、支付失败,或者交易一直处于等待付款状态,就可能收不到支付成功通知。

建议使用商户订单号调用对应的交易查询接口,逐项核对:

  • 商户订单是否真实存在。
  • 支付是否已经完成。
  • trade_status 是否发生变化。
  • app_id、商户账号和运行环境是否一致。
  • 查询使用的订单号是否与发起支付时的 out_trade_no 完全一致。

不要只根据前端跳转结果判断支付状态。return_url 是浏览器的同步跳转地址,用户可能关闭页面,也可能重复访问。最终业务状态应结合异步通知和主动查询来确认。

4. 检查回调地址能否从公网访问

支付宝服务器需要主动访问 notify_url。下面这些地址通常不能作为有效的回调地址:

http://localhost/alipay/notify
http://127.0.0.1/alipay/notify
http://192.168.1.10/alipay/notify
http://10.0.0.5/alipay/notify

应使用稳定的公网地址,例如:

https://pay.example.com/alipay/notify

还要检查以下问题:

  • 域名 DNS 能否在公网正确解析。
  • 防火墙、安全组、WAF 或 CDN 是否拦截了支付宝请求。
  • HTTPS 证书是否有效,证书链是否完整。
  • 接口是否允许 POST 请求。
  • 请求是否经过 301、302 等重定向。
  • 接口是否要求登录、Cookie、验证码或 CSRF Token。
  • 接口是否只允许浏览器 User-Agent。
  • 接口处理是否超时。
  • 路由末尾的 / 不一致是否导致 404。
  • 是否混用了沙箱与生产环境的应用、网关或订单。

可以从公网环境向该地址发送普通的 POST 请求,确认服务能否接收并记录请求。这个测试只能检查网络和路由,无法模拟真实的支付宝通知,也不能代替签名验证。

5. 正确接收并响应通知

支付宝异步通知通常通过 POST 表单参数发送。服务端需要读取全部通知参数、验证签名、核对业务数据,并在处理成功后返回以下纯文本:

success

Java Servlet 风格的处理示例:

protected void doPost(
        HttpServletRequest request,
        HttpServletResponse response
) throws IOException {
    Map<String, String> params = new HashMap<>();

    Map<String, String[]> requestParams = request.getParameterMap();
    for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
        params.put(entry.getKey(), String.join(",", entry.getValue()));
    }

    boolean signVerified;
    try {
        signVerified = AlipaySignature.rsaCheckV1(
                params,
                ALIPAY_PUBLIC_KEY,
                "UTF-8",
                "RSA2"
        );
    } catch (AlipayApiException e) {
        response.getWriter().write("failure");
        return;
    }

    if (!signVerified) {
        response.getWriter().write("failure");
        return;
    }

    String appId = params.get("app_id");
    String outTradeNo = params.get("out_trade_no");
    String tradeNo = params.get("trade_no");
    String tradeStatus = params.get("trade_status");
    String totalAmount = params.get("total_amount");

    // 继续核对 app_id、商户订单号、金额、卖家身份等业务数据。
    // 更新订单时必须保证幂等,避免重复通知造成重复发货。

    response.setContentType("text/plain;charset=UTF-8");
    response.getWriter().write("success");
}

公钥、字符集和签名类型必须与实际应用配置一致。不同 SDK 版本使用的签名方法名称可能不同,请以当前使用的支付宝 SDK 文档为准。

6. 建议的排查顺序

按以下顺序检查,通常可以较快找到问题:

  1. 查看目标 API 文档,确认接口支持异步通知。
  2. 抓取最终请求,确认顶层公共参数中包含正确的 notify_url。
  3. 查询交易状态,确认交易已经满足异步通知条件。
  4. 从公网测试回调地址能否接收 POST 请求。
  5. 查看 CDN、WAF、负载均衡、网关和应用服务器的访问日志。
  6. 检查接口是否出现 404、403、500、超时或重定向。
  7. 确认回调处理完成后,响应体是纯文本 success。
  8. 核对沙箱与生产环境、应用 app_id、商户账号和订单号是否一致。

如果应用日志中完全没有请求记录,继续检查外层的负载均衡、WAF 和 CDN 日志。外层有请求而应用没有收到,问题通常在转发规则或安全策略。如果应用已经收到请求,则重点检查参数读取、验签和响应内容。

注意事项

  • 异步通知可能重复发送,订单更新和发货逻辑必须具备幂等性。
  • 收到通知后必须验签,不能只根据 trade_status 更新订单。
  • 还要核对 app_id、out_trade_no、订单金额和收款方身份,避免处理不属于当前应用或金额不一致的通知。
  • 不要依赖通知在固定时间内到达,也不要假设通知只会发送一次。
  • 不要把 return_url 当作支付成功凭证。
  • 即使异步通知暂时没有到达,也可以通过官方交易查询接口主动核实订单状态。
  • 记录日志时,不要输出应用私钥、密钥、完整证件信息等敏感数据。

备注:内容仅供参考。