鸿蒙支付宝扫码支付白屏,无法调起支付
结论
不要把 alipay.trade.page.pay 的网关请求地址直接做成二维码。
alipay.trade.page.pay 用于电脑网站收银台。用户扫码后,还要经过 H5 授权、重定向和客户端唤起等环节。这条链路在不同操作系统和支付宝客户端容器中的兼容性并不一致。鸿蒙环境停留在 excashier.alipay.com/standard/auth.htm 并出现白屏,通常表示收银台授权页未能继续跳转,不能直接归因于二维码本身。
扫码支付应使用 alipay.trade.precreate。服务端完成预下单后,支付宝会返回付款专用的 qr_code,前端只需用该字段生成二维码。
如果实际请求与示例完全一致,还要修正签名和参数编码。示例缺少 sign、sign_type、timestamp、version 等公共参数,biz_content 中的 JSON 也没有进行 URL 编码。不要将这样的裸链接直接提供给用户。
原因分析
接口场景使用错误
当前使用的接口是:
alipay.trade.page.pay
该接口适用于电脑网站支付,返回电脑收银台页面或自动提交表单,不是标准的扫码支付接口。
把它的网关 URL 做成二维码后,实际执行的是以下流程:
支付宝扫码
→ 打开电脑网站收银台
→ 进入 auth.htm
→ H5 页面尝试完成授权或唤起支付
这套流程依赖支付宝客户端内置浏览器、系统 WebView、重定向策略,以及客户端处理 URL Scheme 的方式。即使 iOS 和部分 Android 环境能够继续跳转,也不代表这种接入方式支持所有系统。
网关地址不等于二维码内容
支付宝开放平台的网关地址是服务端调用入口,里面包含签名、时间戳和业务参数,不能当作长期展示的静态付款地址。
正确的调用流程是:
商户服务端调用 alipay.trade.precreate
→ 支付宝返回 qr_code
→ 将 qr_code 生成二维码
→ 用户使用支付宝扫码付款
示例参数还存在潜在问题
还需要检查示例 URL 中的以下内容:
- 服务端是否使用商户私钥完成签名。
- 请求是否包含
sign、sign_type、timestamp、version等必要的公共参数。 biz_content是否按照支付宝 SDK 的规则完成序列化和编码。out_trade_no是否唯一。time_expire是否晚于订单创建时间。- 当前应用、商户账号和签约产品是否具备当面付能力。
示例中包含:
time_expire=2026-01-20 11:01:20
在该时间之后再次测试时,订单已经过期,需要重新生成。订单过期并非鸿蒙独有的问题,但会影响排查结果。
推荐解决方案
1. 使用 alipay.trade.precreate 创建扫码订单
下面是使用支付宝 Java SDK 的示意代码。网关请求、参数编码和签名都应交给 SDK 处理,不要自行拼接 URL。
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
APP_ID,
MERCHANT_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo("p197265910018565775166875540718");
model.setSubject("xxx");
model.setTotalAmount("100.00");
model.setTimeoutExpress("10m");
request.setBizModel(model);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
String qrCode = response.getQrCode();
// 将 qrCode 原样生成二维码
System.out.println(qrCode);
} else {
System.err.println("code=" + response.getCode());
System.err.println("subCode=" + response.getSubCode());
System.err.println("subMsg=" + response.getSubMsg());
}
response.getQrCode() 返回的内容才应该写入二维码。不要将 alipay.trade.precreate 的网关请求地址做成二维码,也不要修改接口返回的 qr_code。
2. 前端生成二维码
例如,可以使用 JavaScript 二维码组件:
<div id="qrcode"></div>
<script>
// qrCodeContent 来自服务端 alipay.trade.precreate 返回的 qr_code
const qrCodeContent = "https://qr.alipay.com/xxxxxxxxxxxx";
new QRCode(document.getElementById("qrcode"), {
text: qrCodeContent,
width: 240,
height: 240,
correctLevel: QRCode.CorrectLevel.M
});
</script>
实际项目应通过接口从服务端获取 qr_code。商户私钥和签名逻辑不能放在浏览器端。
3. 通过异步通知确认支付结果
用户扫码后,不能只根据页面是否跳转来判断支付是否成功。服务端应接收 notify_url 通知,并完成以下校验:
- 验证支付宝签名。
- 校验
app_id和商户身份。 - 校验
out_trade_no。 - 校验
total_amount。 - 确认
trade_status处于允许入账的状态。 - 通过幂等逻辑更新订单,避免重复通知引发重复处理。
必要时,还可以调用:
alipay.trade.query
主动查询订单状态。
如果业务不是“扫码支付”
不同的支付入口应使用相应产品:
- 电脑浏览器支付:
alipay.trade.page.pay - 手机浏览器支付:
alipay.trade.wap.pay - 原生 App 支付:
alipay.trade.app.pay - 商户展示二维码、用户扫码支付:
alipay.trade.precreate
如果必须保留电脑网站支付,应由服务端通过 SDK 生成支付表单,再交给浏览器提交,不要把网关请求 URL 当作二维码内容:
AlipayTradePagePayResponse response =
alipayClient.pageExecute(request, "POST");
String form = response.getBody();
然后将 form 返回给电脑端页面输出。即便如此,这仍不是面向支付宝扫码的标准接入方式。
注意事项
在 ext_user_info 中设置:
{
"name": "xx",
"need_check_info": "T"
}
表示需要校验用户信息。只有业务确实需要身份核验,而且传入的信息完整、准确时,才应启用该配置。它可能导致支付校验失败,但通常不足以单独解释“仅鸿蒙白屏”的现象。
如果改用 alipay.trade.precreate 后问题仍然存在,应保存并核对以下信息:
- 支付宝客户端版本和鸿蒙系统版本。
- 服务端响应中的
code、sub_code、sub_msg。 - 支付宝返回的
trade_no或请求流水信息。 out_trade_no、请求时间和问题发生时间。- 二维码解码后的原始内容。
缺少客户端日志或支付宝侧流水时,无法进一步确认问题是否由某个具体的鸿蒙版本或支付宝版本引起。应先把二维码内容改为 alipay.trade.precreate 返回的 qr_code。这样可以避开当前不适用的电脑收银台授权跳转链路,也是此类扫码支付问题的正确处理方式。
备注:内容仅供参考。
