鸿蒙Next跳转支付宝后停留在扫码页,无法完成支付
结论
https://qr.alipay.com/... 是支付宝二维码业务链接,不是鸿蒙应用直接拉起支付宝并完成支付的通用入口。鸿蒙 NEXT 跳转后停留在扫码页,通常说明支付宝识别到了扫码场景,但没有成功解析或收到可继续执行的支付指令。
不要尝试修改跳转参数或模拟扫码来绕过这个问题。应根据业务形态改用支付宝正式支付接口:
- App 支付:接入支付宝为 HarmonyOS NEXT 提供的支付能力,具体支持范围以支付宝开放平台当前的文档和 SDK 为准。
- H5 支付:由服务端调用手机网站支付接口生成收银台页面,再通过鸿蒙应用打开该页面。
- 当面付:二维码应由另一台设备扫描,不应在同一台手机上直接把二维码地址交给支付宝打开。
原因分析
打开 qr.alipay.com 链接,不等于调用支付宝支付接口。
支付宝通常需要结合扫码入口、二维码内容、订单状态和风控信息来解析二维码链接。Android 和 iOS 能够继续支付,可能是因为支付宝客户端针对这两个平台适配了链接识别、通用链接或应用间跳转,但这不代表 HarmonyOS NEXT 也支持同样的处理方式。
从当前现象看,基础跳转已经成功,问题出现在支付宝接管链接之后:
- 鸿蒙应用成功打开支付宝。
- 支付宝把链接路由到扫码页面。
- 扫码页面既没有摄像头输入,也没有获得可直接执行的支付参数。
- 页面只能停留在扫码状态,无法自动进入收银台。
因此,仅仅更换 openLink、增加延时或反复拉起支付宝,通常解决不了这个问题。
推荐解决方案
方案一:改用支付宝 App 支付
如果是原生应用内支付,应由服务端创建支付宝订单并签名,然后把支付参数交给客户端,由客户端调用支付宝支付能力。
不要在客户端保存商户私钥,也不要自行拼接未经签名的支付链接。HarmonyOS NEXT 能否直接使用支付宝支付 SDK,以及对应的包名、API 和接入方式,应以商户后台当前提供的官方接入文档为准。Android SDK 不能直接套用。
服务端创建订单的基本结构如下:
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setSubject("订单支付");
model.setTotalAmount("19.90");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderString = response.getBody();
这段示例只演示服务端生成订单参数的过程。客户端如何使用 orderString,必须遵循支付宝明确支持 HarmonyOS NEXT 的调用方式,不能把 Android 的 PayTask 直接移植到 ArkTS。
方案二:使用手机网站支付
如果暂时没有可用的鸿蒙原生支付 SDK,可以由服务端调用手机网站支付接口,生成支付宝收银台页面。鸿蒙端应打开商户服务端的支付地址,而不是 qr.alipay.com 二维码地址。
服务端示例:
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl("https://example.com/pay/result");
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setSubject("订单支付");
model.setTotalAmount("19.90");
model.setProductCode("QUICK_WAP_WAY");
request.setBizModel(model);
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
String paymentHtml = response.getBody();
服务端可以把 paymentHtml 作为 HTML 页面返回,再由鸿蒙应用打开对应的 HTTPS 页面:
import { common } from '@kit.AbilityKit';
const context = getContext(this) as common.UIAbilityContext;
const payUrl = 'https://example.com/pay/alipay?orderId=ORDER_202609090001';
context.openLink(payUrl).catch((error: BusinessError) => {
console.error(`Open payment page failed: ${error.code}, ${error.message}`);
});
这里的 payUrl 应指向商户自己的支付入口。服务端需要校验用户登录状态、订单归属和订单金额,然后实时生成支付宝收银台内容。
如果使用应用内 Web 组件,还需要正确处理页面重定向、支付宝外部链接和返回地址。具体拦截方式取决于项目使用的 HarmonyOS API 版本,不建议用硬编码的支付宝私有 Scheme 代替正式接入方式。
支付结果处理
客户端跳转到成功页,只能用于界面提示,不能据此认定订单已经支付。可靠的处理流程如下:
- 支付宝向服务端的异步通知地址发送支付结果。
- 服务端验证签名。
- 服务端核对
out_trade_no、商户身份、金额和订单状态。 - 服务端更新订单。
- 鸿蒙客户端向业务服务端查询订单的最终状态。
不要仅凭 return_url、客户端回调内容或支付宝已经打开,就把订单标记为已支付。
注意事项
- 不要把
qr.alipay.com地址转换成其他 Scheme 后继续尝试。私有跳转规则可能发生变化,也可能引发兼容性或风控问题。 - 不要在鸿蒙端嵌入商户私钥、支付宝私钥或完整的签名逻辑。
out_trade_no必须唯一。金额应由服务端根据订单计算,不能信任客户端传入的值。- 如果二维码由第三方平台生成,应要求第三方提供支持 HarmonyOS NEXT 的 App 支付入口或 H5 收银台入口。
- 如果已经按照官方方式接入,但仍然跳到扫码页,应向支付宝商户技术支持提供脱敏后的链接、商户应用类型、支付宝客户端版本、HarmonyOS 版本和复现时间,请其确认该产品及链接类型是否支持 HarmonyOS NEXT。
处理原则很明确:二维码链接用于扫码场景,应用内支付应调用支付产品接口。只有把入口从 qr.alipay.com 改为正式的 App 支付或手机网站支付链路,才能避免页面停留在扫码界面。
备注:内容仅供参考。
