PAYATHON 2026

支付宝沙箱支付突然无法使用并持续提示502错误

支付小周

结论

支付宝沙箱支付持续返回 502 Bad Gateway,通常说明请求经过的网关或代理没有收到上游服务的有效响应,不代表业务参数校验失败。

如果相同代码此前可以正常支付,并且网关地址、密钥、证书和网络配置都没有改动,可以优先排查这些问题:

  • 支付宝沙箱网关临时异常或正在维护。
  • 本地代理、公司网关、VPN、DNS 或运营商网络异常。
  • 当前使用的沙箱网关地址已经失效、填写错误或发生变更。
  • 应用网关、Nginx 或反向代理将上游异常转换成了 502。
  • 请求超时、TLS 握手失败或连接中途关闭。

签名错误、参数缺失、应用未授权等业务问题,一般会返回支付宝定义的 JSON/XML 错误信息,而不是单纯的 HTTP 502。

先确认 502 来自哪里

不要只看浏览器最后显示的错误页,还要记录以下信息:

  • 实际请求 URL。
  • HTTP 状态码和响应头。
  • 原始响应正文。
  • 请求发生时间。
  • 请求是否经过 Nginx、VPN、抓包代理或公司出口代理。
  • 是否已经收到支付宝返回的 trade_no、code、sub_code。

如果响应是 HTML 页面,例如:

<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>

这说明错误发生在 HTTP 网关层。

如果响应类似:

{
  "alipay_trade_precreate_response": {
    "code": "40004",
    "sub_code": "...",
    "sub_msg": "..."
  }
}

这就不是 HTTP 502,需要根据 code、sub_code 和 sub_msg 排查业务参数或签名。

排查步骤

1. 核对沙箱网关地址

确认请求发往支付宝开放平台当前提供的沙箱网关,而不是正式环境地址、旧地址或自行拼接的地址。

网关地址应以当前沙箱应用控制台或所用 SDK 的官方配置说明为准。不同接入方式、SDK 版本以及开放平台的调整,都可能导致示例地址不同,因此不能只根据历史代码判断。

还要检查:

  • URL 是否包含多余的空格、路径或重复的 /。
  • 是否误用了生产环境网关。
  • 配置文件是否被环境变量覆盖。
  • 容器、测试服务器和本机加载的是否为同一套配置。
  • 网关域名是否写入了本地 hosts。

可以在程序启动时记录网关域名,但不要输出私钥、应用私钥密码或完整的敏感参数:

logger.info("Alipay gateway: {}", gatewayUrl);
logger.info("Alipay appId: {}", appId);

2. 直接测试网络连通性

先绕过业务代码,直接检查域名解析、TLS 和 HTTP 连接:

curl -v --connect-timeout 10 --max-time 30 \
  "https://沙箱网关域名/gateway.do"

没有携带业务参数时,收到参数错误是正常的。此处主要观察请求是否仍然返回 502。

继续检查 DNS:

nslookup 沙箱网关域名

检查 TLS 握手:

openssl s_client -connect 沙箱网关域名:443 \
  -servername 沙箱网关域名

如果本机正常、服务器异常,重点检查服务器的 DNS、出口防火墙、代理配置和 TLS 环境。如果不同网络在同一时间都返回 502,更可能是沙箱服务端临时异常。

3. 排除代理和 VPN 干扰

检查系统或运行环境中是否设置了代理变量:

env | grep -i proxy

常见变量包括:

HTTP_PROXY
HTTPS_PROXY
ALL_PROXY
NO_PROXY

如果请求经过 Charles、Fiddler、Clash、企业代理或服务网格,可以临时换用不经过代理的网络做对比测试。不要关闭生产环境必需的安全控制,只在独立测试环境中验证。

4. 检查自己的 Nginx 或 API 网关

如果前端访问的是自己的后端地址,而不是直接访问支付宝,那么浏览器看到的 502 可能来自自己的 Nginx。

查看 Nginx 错误日志,重点搜索:

upstream timed out
connect() failed
no live upstreams
upstream prematurely closed connection
SSL_do_handshake() failed

配置中应设置合理的连接和读取超时时间,例如:

location /api/pay/ {
    proxy_pass http://payment_backend;
    proxy_connect_timeout 10s;
    proxy_send_timeout 30s;
    proxy_read_timeout 30s;
}

延长超时时间只能缓解上游响应较慢的问题,无法解决网关地址错误、DNS 失败或上游服务不可用。

5. 检查 SDK 实际收到的内容

调用 SDK 时,不要只记录异常消息,还应记录 HTTP 状态、异常类型和支付宝的原始响应。所有日志都必须脱敏。

Java 示例:

try {
    AlipayTradePagePayResponse response = alipayClient.pageExecute(request);

    logger.info(
        "Alipay response code={}, subCode={}, msg={}, subMsg={}",
        response.getCode(),
        response.getSubCode(),
        response.getMsg(),
        response.getSubMsg()
    );

    if (!response.isSuccess()) {
        throw new IllegalStateException(
            "Alipay request failed: code=" + response.getCode()
                + ", subCode=" + response.getSubCode()
                + ", subMsg=" + response.getSubMsg()
        );
    }
} catch (AlipayApiException e) {
    logger.error("Alipay gateway request failed", e);
}

如果 SDK 在解析响应时报告 JSON/XML 格式错误,还要检查原始响应是否为 502 HTML 页面。有时表面错误是“响应解析失败”,实际原因仍是网关返回了 HTML。

6. 用最小请求复现

暂时去掉业务系统中的复杂逻辑,使用沙箱账号和最少的必要参数创建一笔新订单:

AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(returnUrl);
request.setNotifyUrl(notifyUrl);

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

每次测试都使用新的 out_trade_no,避免旧订单状态干扰判断。具体接口和 product_code 要以实际接入的产品为准,不能把网页支付示例直接用于当面付、App 支付或手机网站支付。

如果最小请求也持续返回 502,问题通常不在订单业务字段。如果最小请求成功,可以逐项恢复原有参数,找出引发异常的配置或业务处理。

对应的解决办法

根据排查结果采取相应措施:

  • 沙箱网关临时异常:等待一段时间后重试,并通过支付宝开放平台公告、控制台或技术支持渠道确认服务状态。系统设计时不要把沙箱环境视为具有生产环境级别的可用性。
  • 网关配置错误:改用控制台当前提供的沙箱地址,并将沙箱和生产配置完全隔离。
  • DNS 或网络异常:更换 DNS 或网络进行验证,再修复服务器出口策略、代理规则或域名解析。
  • 本地反向代理异常:检查上游地址、端口、服务状态和 Nginx 日志,修复代理连接。
  • SDK 或运行环境问题:核对 SDK 配置、TLS 支持和依赖冲突。升级 SDK 前先阅读兼容性说明,不要未经验证就替换生产依赖。
  • 偶发 502:对查询类请求或明确可以安全重试的请求进行有限重试。支付创建请求必须结合商户订单号和订单查询来保证幂等。

一个简单的退避重试示例:

int maxAttempts = 3;

for (int attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
        AlipayTradePagePayResponse response =
            alipayClient.pageExecute(request);

        if (response.isSuccess()) {
            return response;
        }

        throw new IllegalStateException(
            "Alipay business error: " + response.getSubMsg()
        );
    } catch (AlipayApiException e) {
        if (attempt == maxAttempts) {
            throw e;
        }

        try {
            Thread.sleep(attempt * 1000L);
        } catch (InterruptedException interrupted) {
            Thread.currentThread().interrupt();
            throw new IllegalStateException(
                "Payment request interrupted",
                interrupted
            );
        }
    }
}

实际使用时,不能对所有异常一律重试。网络超时并不意味着服务端没有收到请求。重试前最好先通过 out_trade_no 查询订单状态,避免重复创建或重复处理。

注意事项

  • 出现 502 时不要直接重新生成密钥。密钥或签名错误通常会返回明确的业务错误码。
  • 不要在日志中记录应用私钥、完整签名、买家账号密码或身份证明信息。
  • notify_url 无法访问通常会影响异步通知,但不一定导致支付网关立即返回 502。
  • return_url 只用于支付完成后的页面跳转,不能作为判断支付成功的最终依据。
  • 收到超时或 502 后,如果订单状态无法确定,应主动调用订单查询接口确认结果。
  • 沙箱账号、沙箱应用、沙箱密钥和沙箱网关必须配套使用,不能混入生产环境配置。
  • 如果多个网络、多个客户端在同一时间都能稳定复现,应保存请求时间、接口名称、HTTP 状态码以及脱敏后的响应内容,再提交给支付宝开放平台技术支持定位。

备注:内容仅供参考。