PAYATHON 2026

支付宝网页支付请求订单时提示内容不存在或出现故障

支付阿杰

结论

这个提示通常不是支付 API 方法本身报错,而是支付宝无法正常处理当前请求或相关跳转地址。根据“地址可从外网访问,但浏览器提示 HTTPS 链接不安全”这一情况,建议优先检查以下几项:

  1. return_url 或 notify_url 使用了无效、过期、自签名或证书链不完整的 HTTPS 证书。
  2. 测试应用、网关地址、应用配置和密钥不属于同一套环境。
  3. 请求参数在签名后被修改、编码有误,或提交方式不符合网页支付接口的要求。
  4. 支付宝无法从公网访问回调地址,例如地址存在重定向、鉴权、IP 限制或 TLS 握手失败。

“能从外网打开”不等于支付宝服务器可以安全访问。应先为域名配置受信任的 HTTPS 证书。如果暂时无法配置,可以在接口规则允许的情况下使用公网 HTTP 地址辅助定位问题,但不要将其用于生产环境。

首先检查 HTTPS 证书

浏览器显示“不安全”,通常是以下原因之一:

  • 使用了自签名证书;
  • 证书已经过期或尚未生效;
  • 域名与证书中的域名不匹配;
  • 服务器没有发送完整的中间证书链;
  • TLS 协议或加密套件存在兼容性问题;
  • HTTPS 地址跳转到了另一个证书异常的域名。

支付宝服务端访问 notify_url 时,无法像浏览器用户那样手动忽略证书错误。即使开发人员可以点击“继续访问”,支付宝发送的通知请求仍可能失败。

应为域名申请受主流客户端信任的证书,并确认服务器返回了完整的证书链。修复后,可以用下面的命令检查连接:

curl -v https://pay-test.example.com/alipay/notify

检查时重点确认:

  • TLS 握手没有证书错误;
  • 请求没有跳转到内网地址、登录页或其他证书异常的域名;
  • 服务端返回正常的 HTTP 状态码;
  • 请求不依赖 Cookie、登录状态或浏览器交互。

notify_url 用于接收支付宝服务端的异步通知,通常不应返回 HTML 页面。应用完成验签和订单处理后,应按接口要求返回成功响应,例如:

success

具体响应内容以当前所用支付宝接口的官方文档为准。

核对测试环境与网关

测试应用必须使用相应测试环境的应用信息和网关,不能与正式环境配置混用。需要成套核对以下内容:

  • 网关地址;
  • app_id;
  • 应用私钥;
  • 支付宝公钥或支付宝证书;
  • 签名方式;
  • 支付账号;
  • 接口方法名。

常见问题有:

  • 测试应用使用了正式环境网关;
  • 正式应用使用了测试账号;
  • 更换密钥后,代码仍在加载旧私钥;
  • 普通公钥模式与证书模式混用;
  • 服务重启前后读取了不同的环境变量。

除了 method 和业务参数,还要检查支付宝网关的公共参数、签名和环境配置。这些内容同样会影响支付宝能否正确识别请求。

检查请求生成方式

以网页支付接口为例,请使用支付宝 SDK,或严格按照接口规范生成请求。不要自行拼接已经签名的 URL,也不要在完成签名后修改参数。

下面的示例只展示典型调用结构,类名和配置方式应与项目实际使用的支付宝 SDK 版本一致:

AlipayClient alipayClient = new DefaultAlipayClient(
    gatewayUrl,
    appId,
    merchantPrivateKey,
    "json",
    "UTF-8",
    alipayPublicKey,
    "RSA2"
);

AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl("https://pay-test.example.com/alipay/return");
request.setNotifyUrl("https://pay-test.example.com/alipay/notify");

request.setBizContent("""
{
  "out_trade_no": "TEST202609080001",
  "total_amount": "0.01",
  "subject": "支付测试",
  "product_code": "FAST_INSTANT_TRADE_PAY"
}
""");

AlipayTradePagePayResponse response = alipayClient.pageExecute(request);

if (response.isSuccess()) {
    String form = response.getBody();
    // 将 form 原样输出到浏览器,由浏览器自动提交到支付宝。
} else {
    // 记录 code、subCode、msg、subMsg 等信息。
}

输出支付表单时,不要再次对 SDK 返回的表单内容进行 URL 编码或 HTML 转义。例如,在 Spring MVC 中可以直接返回 HTML:

@GetMapping(value = "/pay", produces = "text/html;charset=UTF-8")
@ResponseBody
public String pay() throws AlipayApiException {
    AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
    return response.getBody();
}

其他语言的处理原则相同:由 SDK 生成待提交的表单或请求字符串,再将结果原样交给浏览器。

建议的排查顺序

1. 保存支付宝返回的详细信息

不要只记录用户看到的错误页面,还要保存 SDK 响应中的以下字段:

code
msg
sub_code
sub_msg
body

同时记录请求时间、app_id、method、out_trade_no 和网关地址。不要把私钥、完整签名或敏感用户信息写入日志。

如果 SDK 在生成表单时已经返回明确的 sub_code,应先根据该错误信息排查。

2. 暂时移除跳转和通知地址进行对比

如果接口允许,可以分别进行以下测试:

  • 不传 return_url;
  • 不传 notify_url;
  • 将地址改为证书正常的公网地址。

如果替换地址后可以进入收银台,问题基本可以定位在域名、证书、网络访问或回调地址格式上。

异步通知通常在支付状态变化后发送,因此 notify_url 不一定会让首次打开收银台的请求立即报错。如果提交支付请求时马上出现错误,还应重点检查网关、签名和环境配置。

3. 检查 URL 本身

回调地址应是完整的绝对 URL,例如:

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

不要使用:

localhost
127.0.0.1
192.168.x.x
内部域名
带空格或未正确编码的 URL
需要登录才能访问的 URL

还要检查地址是否存在循环重定向、是否被强制跳转到错误端口,以及 WAF 是否拦截了支付宝的请求。

4. 重新核对签名原文

以下操作经常导致签名失败:

  • 签名后又修改了 biz_content;
  • JSON 中的金额、空格或字段顺序在签名前后发生变化;
  • 字符集声明为 UTF-8,实际使用的却是其他编码;
  • sign_type 设置为 RSA2,代码加载的却不是对应私钥;
  • 使用 URL 编码后的参数签名,提交时又进行了二次编码;
  • 错把支付宝公钥当成应用公钥使用。

建议优先使用官方 SDK 完成签名,减少手工拼装造成的差异。

注意事项

  • “页面能打开”只能说明部分客户端可以访问,不能证明证书受信任、证书链完整,也不能证明支付宝服务器可以访问。
  • return_url 是浏览器同步跳转地址,不能作为判断支付成功的最终依据。
  • 订单状态应以验签后的异步通知或主动查询结果为准。
  • 修改证书、密钥或网关后,要确认正在运行的服务已经重新加载配置。
  • 不要在日志、截图或排查信息中暴露应用私钥、完整签名、买家账号等敏感数据。
  • 如果证书和环境都已确认无误,但仍然只能看到统一错误页面,应携带请求时间、app_id、接口方法、支付宝返回码和请求流水信息,联系支付宝开放平台技术支持进一步核查。

备注:内容仅供参考。