Android AliPay SDK 15.8.17 未安装支付宝时无法跳转H5支付
结论
问题不在 Android Manifest,也不是缺少 H5PayActivity,而是服务端返回的 OrderStr 来自沙盒环境,与客户端使用的正式支付环境不匹配。
把服务端下单接口切换到正式环境,并使用正式应用的 app_id、密钥和网关重新生成 OrderStr 后,即使设备没有安装支付宝 App,也能正常进入 H5 支付页面。
原因分析
支付宝 SDK 会根据设备环境选择支付方式:
- 设备已安装支付宝 App 时,优先调起支付宝客户端。
- 设备未安装支付宝 App 时,如果订单和运行环境支持,则进入 SDK 提供的 H5 支付流程。
当前场景的 Merged Manifest 已包含 H5 相关 Activity。执行下面的命令,也能在页面栈中看到 H5PayActivity:
adb shell dumpsys activity top | grep ACTIVITY
输出类似:
ACTIVITY com.miui.home/.launcher.Launcher 81d9e14 pid=3078
ACTIVITY com.example.app/com.alipay.sdk.app.H5PayActivity 7596fc3 pid=16652
这表明 SDK 已经成功启动 H5PayActivity。页面没有正常显示,不代表 Activity 配置有误。问题更可能出在后续加载支付页面时,订单参数或运行环境校验失败。
本例最终确认,服务端生成了沙盒环境的订单数据,而客户端实际使用的是正式环境支付链路。沙盒和正式环境的网关、应用身份与签名配置不能混用。
解决步骤
1. 检查服务端支付环境
确认服务端下单接口没有继续使用沙盒网关或沙盒应用配置。沙盒与正式环境应分别维护配置,至少需要检查:
- 支付网关地址
app_id- 应用私钥
- 支付宝公钥或证书
- 签名方式
- 应用公钥证书、支付宝公钥证书及支付宝根证书(如果使用证书模式)
- 服务端生成订单时加载的环境配置
不能只修改网关地址。app_id、密钥和证书也必须来自同一个环境。
2. 重新生成 OrderStr
修改环境配置后,服务端需要重新创建订单并完成签名。已经生成的沙盒 OrderStr 无法在客户端改成正式订单,也不应重复使用。
客户端只需接收完整的 OrderStr,然后交给支付宝 SDK:
final String orderStr = response.getOrderStr();
Runnable payRunnable = () -> {
PayTask payTask = new PayTask(CurrentActivity.this);
Map<String, String> result = payTask.payV2(orderStr, true);
runOnUiThread(() -> {
String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String resultData = result.get("result");
// 根据业务需要展示结果。
// 最终支付状态仍应由服务端异步通知或主动查询确认。
});
};
Thread payThread = new Thread(payRunnable);
payThread.start();
OrderStr 必须由服务端生成并签名。不要在 Android 客户端保存商户私钥,也不要由客户端自行拼接签名参数。
3. 确认 H5PayActivity 是否真正启动
卸载支付宝 App 后重新测试,再通过 ADB 查看顶部 Activity:
adb shell dumpsys activity top | grep ACTIVITY
如果输出中包含:
com.alipay.sdk.app.H5PayActivity
通常表示客户端已经进入 SDK 的 H5 支付流程。此时应重点检查:
OrderStr是否来自错误的环境- 订单是否已经过期
- 签名是否正确
- 服务端返回内容是否被转义、截断或二次编码
app_id、密钥和网关是否属于同一套环境
4. 对比沙盒与正式环境的返回数据
服务端可以记录必要的诊断信息,例如当前环境、网关类型、app_id 和订单号,但不要记录商户私钥等敏感数据。
建议使用明确的环境配置,避免把测试配置用于生产环境:
public enum AlipayEnvironment {
SANDBOX,
PRODUCTION
}
生成订单前,应根据部署环境选择完整的一套支付宝配置,而不是单独切换其中几个参数。
为什么复制到官方 Demo 也不能解决
把同一个 OrderStr 放入官方 Demo 后仍然无法打开 H5 页面,通常能进一步说明问题不在原 Android 工程。
Demo 可以用来排除客户端集成差异,却无法修复订单自身的环境、签名或参数问题。如果输入的仍是沙盒订单数据,在正式环境链路中同样可能失败。
注意事项
- Manifest 中存在
H5PayActivity,只能说明组件声明基本正常,不能证明订单数据有效。 - Activity 已启动,但页面空白或无法继续时,需要同时检查 Logcat、SDK 返回结果和服务端下单日志。
- 沙盒订单与正式订单必须严格隔离,不能混用
app_id、密钥、证书或网关。 - 服务端切换到正式环境后,必须重新生成
OrderStr。 payV2()的返回结果只能用于客户端提示,不能作为最终到账凭证。最终支付结果应以支付宝服务端异步通知或服务端主动查询结果为准。- 排查日志时,不要输出完整签名、私钥、证书内容或其他敏感信息。
备注:内容仅供参考。
