PAYATHON 2026

鸿蒙支付宝扫码支付白屏,无法调起支付

支付小周

结论

不要把 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。这样可以避开当前不适用的电脑收银台授权跳转链路,也是此类扫码支付问题的正确处理方式。

备注:内容仅供参考。