H5调用手机网站下单接口后支付宝提示系统繁忙
结论
alipay.trade.wap.pay 返回 form,且页面能够唤起支付宝,只能说明支付请求已经生成并提交,不能证明订单已通过支付宝网关和业务校验。
支付宝 App 持续提示“系统繁忙”,通常只是统一的前端错误提示。具体原因需要结合网关返回参数、服务端日志、订单查询结果和支付宝商家平台的诊断信息判断。常见问题包括:
- 应用与商户的签约关系异常,或手机网站支付能力不可用
- 生产环境与沙箱环境混用,包括应用、账号、网关地址或密钥
app_id、应用私钥和支付宝公钥不匹配- 业务参数不合法,尤其是订单号、金额和
product_code - 订单重复、已关闭或创建时间过久
- 商户账户、应用或交易触发支付宝侧风控
- SDK 生成表单后,页面在提交过程中修改、编码或转义了参数
仅凭 appId: 2021003138685140 和订单号 202207180037208896295948481019,无法确定具体错误。该订单号看起来可能创建于 2022 年。如果现在仍在测试,不要继续使用这个订单,应生成新的 out_trade_no 再次发起支付。
为什么返回 form 仍然可能支付失败
不少服务端 SDK 的 pageExecute 方法只负责根据参数生成一个自动提交的 HTML 表单,例如:
<form name="punchout_form" method="post"
action="https://openapi.alipay.com/gateway.do">
<!-- 支付参数 -->
</form>
<script>
document.forms[0].submit();
</script>
生成表单并不等于支付宝已经成功创建交易。浏览器提交表单、支付宝网关接收请求后,真正的业务校验才会开始。
因此,下面几种情况可能连续发生:
- 服务端成功生成
form。 - H5 页面正常跳转或唤起支付宝 App。
- 支付宝校验应用、签名、商户能力或订单参数时失败。
- App 只显示“系统繁忙,请稍后再试”。
排查时,不能把“成功生成 form”视为接口调用成功。
建议的排查顺序
1. 使用新订单重新测试
不要反复使用已经失败或时间较久的订单号。每次测试都生成新的 out_trade_no,并保证它在同一商户应用下唯一。
同时确认:
total_amount > 0
subject 非空
product_code = QUICK_WAP_WAY
金额应使用十进制字符串,不要把二进制浮点数的计算结果直接传给支付宝。例如,应使用 "0.01",不要传入 "0.0100000002" 之类的值。
2. 检查完整的网关请求和返回结果
服务端应记录以下信息,但不要记录应用私钥:
- 请求时间
app_idmethodout_trade_nosign_typecharsettimestampnotify_urlreturn_url- 支付宝返回的
code sub_codesub_msgtrace_id或其他链路标识
如果 SDK 只返回 HTML 表单,可以在测试环境中查看表单的 action 和隐藏字段,确认表单最终提交到了正确的网关。
生产环境网关应为:
https://openapi.alipay.com/gateway.do
沙箱环境与生产环境的应用、账号、密钥和网关不能混用。
3. 查询订单状态
使用同一个 app_id 和商户私钥调用 alipay.trade.query,通过 out_trade_no 查询交易状态。
根据查询结果判断:
- 查询不到订单:支付请求可能未通过网关校验,或者查询时使用了不同的应用。
WAIT_BUYER_PAY:订单已经创建,问题可能发生在收银台或风控环节。TRADE_CLOSED:订单已经关闭,需要创建新订单。TRADE_SUCCESS或TRADE_FINISHED:不能再用同一个订单号发起新交易。- 返回明确的
sub_code:应按照该错误码处理,它比 App 中的“系统繁忙”提示更有参考价值。
如果查询接口本身也失败,应先解决查询接口返回的签名、权限或应用配置错误。
4. 核对应用和密钥配置
确认以下配置都属于同一个支付宝开放平台应用:
app_id- 应用私钥
- 上传到开放平台的应用公钥
- 下载或复制的支付宝公钥
sign_type
常见错误有:
- 使用应用公钥验签,而不是支付宝公钥
- 更换应用密钥后,服务端仍在使用旧私钥
- RSA 与 RSA2 配置不一致
- 测试环境和生产环境读取了不同的配置文件
- 使用了其他应用的私钥
- 第三方应用代商户调用时遗漏
app_auth_token
通常建议使用:
sign_type=RSA2
charset=utf-8
不要在前端生成签名,也不要把应用私钥写入 H5 页面或 JavaScript。
5. 检查产品签约和商户状态
在支付宝开放平台和商家平台中确认:
- 应用已经上线,而不是只完成创建
- 应用具备手机网站支付能力
- 当前商户是该应用对应的签约主体,或已经完成正确授权
- 商户账户、结算账户和支付产品状态正常
- 应用未被停用
- 交易没有触发额度、行业或风控限制
如果参数和签名均正常,但更换新订单、金额和 Hers设备后仍能稳定复现,应优先检查产品权限、商户状态和风险控制。
6. 检查 H5 跳转过程
返回的表单应原样输出,不能再次进行 URL 编码或 HTML 转义。例如,不能把表单中的以下内容处理成无法提交的字符串:
<input type="hidden" name="sign" value="...">
服务端返回页面时,建议使用 UTF-8:
Content-Type: text/html; charset=utf-8
还需要检查:
- WebView 是否禁止表单提交或外部 Scheme 跳转
- 前端是否重新拼接了支付宝参数
- 代理层是否修改了请求体
return_url和quit_url是否为合法且可以访问的 URL- 页面是否重复提交同一个表单
如果支付宝 App 已经正常打开,应优先检查支付宝网关返回的业务错误和订单状态,而不是只排查唤起逻辑。
Java 调用示例
下面的示例包含主要参数。具体的 SDK 版本和初始化方式,应以项目实际使用的支付宝官方 SDK 为准。
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
APP_ID,
APP_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
request.setReturnUrl("https://example.com/pay/result");
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo("唯一的新订单号");
model.setTotalAmount("0.01");
model.setSubject("测试订单");
model.setProductCode("QUICK_WAP_WAY");
model.setQuitUrl("https://example.com/pay/cancel");
request.setBizModel(model);
try {
String form = alipayClient.pageExecute(request).getBody();
// 将 form 作为 text/html 原样返回给浏览器
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(form);
} catch (AlipayApiException e) {
// 记录错误码、错误信息和订单号,但不要记录应用私钥
logger.error("创建支付宝 H5 支付失败,outTradeNo={}", model.getOutTradeNo(), e);
}
订单查询示例:
AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel();
queryModel.setOutTradeNo("唯一的新订单号");
queryRequest.setBizModel(queryModel);
AlipayTradeQueryResponse queryResponse = alipayClient.execute(queryRequest);
if (queryResponse.isSuccess()) {
logger.info(
"支付宝订单查询成功,tradeStatus={}, tradeNo={}",
queryResponse.getTradeStatus(),
queryResponse.getTradeNo()
);
} else {
logger.error(
"支付宝订单查询失败,code={}, subCode={}, subMsg={}",
queryResponse.getCode(),
queryResponse.getSubCode(),
queryResponse.getSubMsg()
);
}
无法获得明确错误码时怎么办
如果新订单能够唤起支付宝,但 App 始终只提示“系统繁忙”,应准备以下信息,通过支付宝开放平台的接口报错排查功能或技术支持渠道查询:
app_id- 新生成的
out_trade_no - 问题发生的准确时间,精确到秒
- 调用的接口名称:
alipay.trade.wap.pay - 使用的是生产环境还是沙箱环境
- 服务端 SDK 的异常信息
- 网关返回的
code、sub_code、sub_msg alipay.trade.query的完整业务响应- 是否所有账号、设备和金额都能复现
- 支付宝 App 错误页面截图
订单号属于业务标识,不建议长期公开展示。应用私钥、支付宝回调验签数据和用户身份信息不能公开。
最终应以支付宝网关返回的 sub_code、订单查询状态或平台诊断结果为准。“系统繁忙”本身无法说明具体的错误原因。
备注:内容仅供参考。
