支付宝沙箱支付一直提示“请求超时,请稍后再试”如何解决?
结论
支付宝沙箱页面反复提示 请求超时,请稍后再试,不代表业务服务器一定发生了超时。常见原因有:
- 支付宝沙箱环境临时异常或正在维护
- 请求发到了错误的网关
- 沙箱应用、沙箱买家账号、密钥等配置混入了正式环境数据
- 签名算法、字符集或请求参数有误
- 本机网络、代理、防火墙或 DNS 造成连接异常
- 支付页面链接被重复编码、截断或已经失效
- 异步通知地址无法从公网访问
排查时,先确认错误发生在哪个阶段,再查看支付宝返回的原始响应。仅凭浏览器显示的 请求超时,无法判断具体原因。
一、先确定超时发生在哪个阶段
1. 调用支付接口时没有收到响应
如果服务端请求支付宝网关时发生连接超时,通常要检查网关地址、网络、代理和 TLS 连接。
沙箱网关应为:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
正式环境网关通常为:
https://openapi.alipay.com/gateway.do
沙箱应用必须调用沙箱网关。应用 ID、密钥、支付宝公钥和买家账号也必须全部来自同一套沙箱环境。
2. 已跳转到支付宝页面,但页面提示请求超时
这通常说明请求已经到达支付宝。此时主要检查:
- 支付表单或跳转 URL 是否完整
app_id是否为当前沙箱应用的 AppIDsign是否被重复进行 URL 编码timestamp格式是否正确biz_content是否为合法 JSON- 支付订单号是否被重复使用
- 沙箱买家账号能否正常登录
- 沙箱环境当时是否发生临时故障
3. 支付成功,但业务系统一直没有收到结果
这种情况可能与页面提示或支付接口本身没有直接关系,应检查:
notify_url能否从公网访问- 地址是否使用了
localhost、127.0.0.1或局域网 IP - 通知接口是否在规定时间内返回纯文本
success - 验签时是否使用了正确的支付宝公钥
- 防火墙或 Web Application Firewall 是否拦截了支付宝通知
同步跳转使用的 return_url 不能替代异步通知。订单的最终状态应以异步通知或主动查询结果为准。
二、按顺序检查配置
1. 确认没有混用不同环境的配置
下面这些配置必须配套使用:
沙箱 AppID
应用私钥
与应用公钥对应的支付宝公钥
沙箱网关
沙箱买家账号
常见情况是使用了沙箱 AppID,却配置了正式环境的支付宝公钥。也可能是沙箱密钥已经重新生成,代码中仍保留着旧私钥。
还要分清以下三类密钥:
- 应用私钥:由开发者保存,用于给请求签名
- 应用公钥:上传到支付宝开放平台
- 支付宝公钥:由支付宝提供,用于验证支付宝返回的内容
验签时不能用应用公钥代替支付宝公钥。
2. 检查 SDK 初始化参数
以 Java SDK 为例,基本配置如下:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do",
APP_ID,
APP_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
逐项确认:
- 网关为
openapi-sandbox.dl.alipaydev.com APP_PRIVATE_KEY是当前应用的私钥ALIPAY_PUBLIC_KEY是当前沙箱应用对应的支付宝公钥sign_type与密钥类型一致,通常使用RSA2- 签名、发送和接收数据时使用相同的字符集
证书模式与普通公钥模式的初始化方式不同。不要混用应用证书、公钥证书和普通字符串公钥。
3. 检查支付请求参数
电脑网站支付可以参考下面的请求结构:
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl("https://example.com/alipay/return");
request.setNotifyUrl("https://example.com/alipay/notify");
request.setBizContent("""
{
"out_trade_no": "TEST202609090001",
"total_amount": "0.01",
"subject": "沙箱支付测试",
"product_code": "FAST_INSTANT_TRADE_PAY"
}
""");
String form = alipayClient.pageExecute(request).getBody();
需要检查:
out_trade_no在商户系统中是否唯一total_amount是否为合法的金额字符串subject是否为空- 电脑网站支付是否使用了正确的
product_code biz_content是否为合法 JSON- 参数值在签名前后是否发生变化
手机网站支付、App 支付和电脑网站支付使用的 API 与 product_code 不完全相同。应按照实际接入产品的接口文档配置,不能直接套用其他支付产品的参数。
三、记录支付宝的原始响应
排查时不能只记录 支付失败。至少应保存:
- 请求接口名称
app_idout_trade_no- 请求时间
- HTTP 状态码
- SDK 返回的
code sub_codemsgsub_msg- 支付宝返回的
trace_id或类似链路标识,如果响应中存在
Java 示例:
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizContent("""
{
"out_trade_no": "TEST202609090001"
}
""");
AlipayTradeQueryResponse response = alipayClient.execute(request);
System.out.println("code=" + response.getCode());
System.out.println("msg=" + response.getMsg());
System.out.println("subCode=" + response.getSubCode());
System.out.println("subMsg=" + response.getSubMsg());
System.out.println("body=" + response.getBody());
不同版本的 SDK 可能提供不同的方法。如果没有对应的 getter,可以直接记录完整响应体。生产环境的日志不能输出私钥、完整签名或敏感账户信息。
接口返回了明确的业务错误时,应先根据 sub_code 和 sub_msg 处理。只有完全没有收到有效响应时,才应把网络超时作为重点排查方向。
四、检查本机到沙箱网关的网络
在部署应用的同一台机器上测试连接:
curl -I --connect-timeout 10 \
https://openapi-sandbox.dl.alipaydev.com/gateway.do
返回内容不一定是有效的支付业务结果。只要 DNS 解析和 HTTPS 握手能够完成,通常就说明基础网络可以访问沙箱网关。
连接失败时,再检查 DNS:
nslookup openapi-sandbox.dl.alipaydev.com
同时确认:
- 系统时间是否准确
- HTTPS 证书是否被本地代理替换
- 公司网络是否限制外部 HTTPS 请求
- 应用进程是否设置了错误的 HTTP 代理
- 容器或服务器的 DNS 是否正常
- 防火墙是否阻断了目标域名或 443 端口
不要长期关闭 TLS 证书校验来解决连接问题。这样做有安全风险,还可能掩盖代理或证书链配置错误。
五、检查请求 URL 是否被破坏
如果应用生成的是自动提交表单,应将 SDK 返回的完整 HTML 直接输出给浏览器,不要再次拼接或编码:
String form = alipayClient.pageExecute(request).getBody();
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(form);
response.getWriter().flush();
常见问题有:
- 对整个表单进行 URL 编码
- 重复编码
sign参数 - 请求经过前端路由时丢失查询参数
- 反向代理限制 URL 长度
- 把 HTML 表单当成普通 URL 跳转
- 模板引擎转义了表单中的特殊字符
可以在浏览器开发者工具中查看跳转请求,确认参数没有被截断或重复转义,也没有异常的 301/302 循环。
六、不要重复使用测试订单号
有些测试代码会把 out_trade_no 写死。前一次支付已经创建交易后,如果继续使用同一个订单号,却修改金额或商品名称,可能引起订单冲突,或者进入异常页面。
测试时可以为每次请求生成新的订单号:
String outTradeNo =
"TEST" + java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")
.format(java.time.LocalDateTime.now());
数据库中仍应为订单号设置唯一约束。只使用时间戳不能保证高并发时绝对唯一,正式系统可以增加随机值,或者使用可靠的分布式 ID。
七、正确处理超时和未知状态
服务端调用超时,不代表支付宝一定没有创建交易。此时贸然重新提交业务,可能带来重复支付风险。
可以按下面的流程处理:
- 保存本地订单和请求状态。
- 调用支付接口。
- 收到明确的失败响应后,按照错误码处理。
- 如果连接超时或响应不完整,将订单标记为
支付结果未知。 - 使用
alipay.trade.query,按out_trade_no主动查询交易。 - 确认交易不存在后,再按照业务规则决定是否重新发起支付。
- 结合异步通知更新订单的最终状态。
不能因为页面显示 请求超时,就直接把订单状态改为支付失败。
八、排除沙箱环境自身的问题
如果配置、签名和网络都正常,但多个不同订单在不同浏览器中仍然出现相同提示,可以继续做交叉验证:
- 重新登录沙箱买家账号
- 清除支付宝沙箱页面的 Cookie 和缓存
- 使用无痕窗口或其他浏览器测试
- 更换网络后测试
- 重新创建一笔订单,不要刷新旧支付页面
- 查看支付宝开放平台当时是否发布了维护或故障提示
- 间隔一段时间后再次测试
沙箱环境主要用于联调,稳定性不一定与真实生产环境完全相同。如果只有支付宝托管页面报错,接口又没有返回明确错误码,应保留错误发生时间、AppID、订单号、完整响应和页面截图,再向支付宝技术支持反馈。不能根据沙箱页面偶发的一次超时,就认定正式环境也会发生相同问题。
注意事项
- 私钥不能提交到前端、代码仓库或公开日志。
- 异步通知必须验签,并核对
app_id、商户订单号、金额和交易状态。 - 不能把浏览器同步跳转作为判断支付成功的唯一依据。
- 不要无限重试支付创建接口。
- 排查时应保留原始响应,不要只记录二次封装后的异常信息。
- 沙箱和正式环境的配置应通过环境变量或独立配置文件隔离,避免发布时混用。
- 如果错误只出现在特定 SDK 或框架中,还要检查代理、超时、字符编码和参数序列化设置。具体配置项取决于所用语言、SDK 版本和部署方式。
备注:内容仅供参考。
