Android 支付宝 App 支付为何一直打开 H5 收银台?
结论
安装了支付宝 App,但支付时一直进入 H5 收银台,通常不能简单归因于 targetSdkVersion 29 或支付宝 10.2.36。常见原因主要有两种:
- 服务端创建的不是 App 支付订单,而是手机网站支付订单,例如调用了
alipay.trade.wap.pay。 - 支付宝 SDK 无法识别或拉起支付宝客户端,自动降级到 H5 收银台。这种情况需要检查 Manifest 的包可见性配置、SDK 调用方式、支付宝包名,以及客户端是否为官方可用版本。
升级 Android 支付 SDK 只能处理客户端 SDK 相关问题,无法修正服务端接口或订单参数错误。因此,升级到 alipaysdk-noutdid-15.8.05.211018174351 后现象没有变化,并不意外。
首先检查服务端下单接口
App 支付必须使用:
alipay.trade.app.pay
业务参数中应包含:
{
"product_code": "QUICK_MSECURITY_PAY"
}
手机网站支付使用的是:
alipay.trade.wap.pay
如果服务端返回 WAP 支付链接、HTML 表单,或者订单由 alipay.trade.wap.pay 生成,那么无论 Android 端是否安装支付宝,都可能进入 H5 收银台。
服务端生成的 App 支付订单字符串通常包含类似参数:
method=alipay.trade.app.pay
以及经过编码的业务内容:
{
"subject": "订单标题",
"out_trade_no": "业务订单号",
"total_amount": "0.01",
"product_code": "QUICK_MSECURITY_PAY"
}
订单签名必须由服务端完成,私钥不能放进 Android 安装包。
还要确认 Android 端收到的是完整的 App 支付订单字符串,而不是:
- H5 支付 URL;
alipay.trade.wap.pay返回的 HTML;- 经过二次 URL 编码或已被截断的订单参数;
- 只有业务参数,却缺少公共参数和签名的字符串。
检查 Android 端调用方式
App 支付应调用支付宝 SDK 的 PayTask.payV2(),或当前版本提供的相应 App 支付接口:
final String orderInfo = orderInfoFromServer;
Runnable payRunnable = () -> {
PayTask alipay = new PayTask(activity);
Map<String, String> result = alipay.payV2(orderInfo, true);
Message message = Message.obtain();
message.what = SDK_PAY_FLAG;
message.obj = result;
handler.sendMessage(message);
};
Thread payThread = new Thread(payRunnable);
payThread.start();
调用时注意以下几点:
- 建议向
PayTask传入当前前台Activity,不要使用Application Context。 - 支付调用应放在非主线程执行。
- 不要用 WebView 加载 App 支付订单。
- 不要把
h5Pay()或fetchOrderInfoFromH5PayUrl()当成普通 App 支付入口。 - 服务端返回的
orderInfo应原样传给 SDK,不要自行拆分并重新拼装。 showLoading只控制 SDK 的加载提示,不会决定打开 App 还是 H5 收银台。
正确配置包可见性
Android 11 及以上版本引入了包可见性限制。当前 targetSdkVersion 虽然是 29,仍建议按照新版要求正确声明,以免以后提升目标版本后无法查询支付宝客户端。
<queries> 必须是 <manifest> 的直接子节点,不能放在 <application> 中:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<queries>
<package android:name="com.eg.android.AlipayGphone" />
<package android:name="hk.alipay.wallet" />
</queries>
<application
android:name=".App"
android:theme="@style/AppTheme">
<!-- Activities and other components -->
</application>
</manifest>
中国大陆版支付宝的包名是:
com.eg.android.AlipayGphone
hk.alipay.wallet 是香港地区钱包的包名。是否需要配置,应根据业务实际支持的钱包和接入的支付宝产品决定。
题目中的配置带有异常空格:
<package android :name ="com.eg.android.AlipayGphone" />
实际 XML 属性名必须写成连续的 android:name:
<package android:name="com.eg.android.AlipayGphone" />
如果空格只是网页排版造成的,可以忽略。如果工程文件中也是这种写法,Manifest 将无法按预期解析。
检查时应以最终合并后的 Manifest 为准,不能只看源文件。可以在 Android Studio 中打开 AndroidManifest.xml 的 Merged Manifest 页面,确认 <queries> 没有被构建变体、占位符或 Manifest 合并规则移除。
验证系统能否识别支付宝客户端
可以临时加入诊断代码,确认应用能否查询到支付宝:
public static boolean isAlipayInstalled(Context context) {
try {
context.getPackageManager().getPackageInfo(
"com.eg.android.AlipayGphone",
0
);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
在较新的 Android 版本中,如果没有正确声明 <queries>,即使设备已经安装支付宝,查询结果也可能显示未安装。这个方法只适合诊断客户端可见性,不应据此自行拼接支付宝私有 URL Scheme 来代替官方 SDK。
还需要检查:
- 手机上安装的是否为官方支付宝,而不是双开、分身、工作资料或受管控空间中的副本;
- 当前 App 和支付宝是否位于不同的用户空间或工作资料中;
- 系统是否禁止当前 App 启动其他应用;
- 问题是否只出现在特定厂商、系统版本或分身环境中;
- 卸载并重新安装支付宝后是否仍能复现。
检查实际集成的 SDK 版本
升级依赖后,需要确认新版本确实打包进了 APK,同时排除多个支付宝 SDK 共存的情况:
dependencies {
implementation files('libs/alipaysdk-noutdid-15.8.05.211018174351.aar')
}
如果项目通过本地 libs、Maven 依赖或其他支付组件同时引入支付宝 SDK,可能出现依赖重复或版本覆盖。应检查依赖树和最终生成的 APK/AAB,确保其中只保留预期版本。
升级 SDK 后,建议完整清理项目并重新安装应用,排除旧 APK 或增量构建对判断的影响。
根据支付结果进一步定位
对于 payV2() 的返回结果,应重点记录以下字段:
String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String rawResult = result.get("result");
常见状态包括:
9000 支付成功
6001 用户取消
6002 网络连接异常
8000 支付结果确认中
4000 其他支付错误
排查时不要只记录“打开了 H5”,还应记录:
- 实际调用的是
payV2()还是 H5 相关接口; - 订单中的
method和product_code; - SDK 返回的
resultStatus和memo; - 手机系统版本、支付宝包名和版本;
- 是否只有特定设备可以复现。
日志中不能输出完整订单签名、用户隐私信息或服务端私钥。
推荐排查顺序
- 确认服务端调用的是
alipay.trade.app.pay。 - 确认
product_code为QUICK_MSECURITY_PAY。 - 确认客户端调用
PayTask.payV2(),并传入前台Activity。 - 确认订单字符串没有经过 WebView、URL 拼接或二次编码处理。
- 修正
<queries>配置,并检查最终合并后的 Manifest。 - 确认工程中没有重复或旧版支付宝 SDK。
- 使用普通系统空间、官方支付宝客户端和另一台设备进行交叉验证。
- 保存脱敏后的订单参数、SDK 返回值和复现环境,再交由支付宝技术支持核查。
不要一开始就把问题归因于支付宝 App 升级。如果所有设备都会稳定进入 H5,应优先检查服务端使用的支付产品和客户端调用入口。如果问题只出现在部分 Android 设备上,则优先检查包可见性、应用分身、系统启动限制,以及 APK 中实际打包的 SDK。
备注:内容仅供参考。
