Android 集成支付宝支付返回错误码 6001 如何解决?
结论
在支付宝 App 支付的客户端结果中,6001 通常表示“用户取消支付”,并不是“接口版本过旧”的专属错误码。如果弹出“系统繁忙,请稍后再试”后返回 6001,也可能是支付宝页面异常退出,客户端最终将其归类为取消。
mobile.securitypay.pay 是旧版移动支付接口。新项目或仍在维护的项目应迁移到 alipay.trade.app.pay,但更换接口未必能直接解决问题,还需要检查订单参数、签名方式、密钥配置、订单字符串的传递过程和支付宝客户端环境。
可能原因
常见原因有以下几种:
-
订单参数或签名不正确
服务端生成的订单字符串缺少必要参数,或者用于签名的私钥与支付宝开放平台配置的应用公钥不匹配。
-
订单字符串在 Android 端被修改
服务端返回订单字符串后,如果客户端再次进行 URL 编码、解码、拼接或 JSON 转义,可能破坏原有签名。
-
旧接口与当前应用配置不匹配
mobile.securitypay.pay使用的是较早的接入方式。如果应用已经按照开放平台的新 App 支付产品完成配置,继续使用旧接口可能造成参数、网关或签名体系不一致。 -
支付宝客户端或测试环境异常
支付宝 App 版本、设备环境有问题,或者混用了沙箱环境和正式环境,都可能导致支付页面异常关闭。
-
用户主动关闭支付页面
用户点击返回键或关闭支付收银台时,正常返回值就是
6001。
建议的解决步骤
1. 查看完整支付结果
不要只读取 resultStatus,还要记录 memo 和 result:
PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderInfo, true);
String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String rawResult = result.get("result");
Log.d("AliPay", "resultStatus=" + resultStatus);
Log.d("AliPay", "memo=" + memo);
Log.d("AliPay", "result=" + rawResult);
如果结果是:
resultStatus=6001
这只能说明客户端支付流程被取消或中断。具体原因还要结合弹窗出现的时间、memo、服务端日志和支付宝异步通知来判断。
2. 迁移到 alipay.trade.app.pay
服务端应使用支付宝开放平台对应语言的官方 SDK 创建 App 支付订单。下面是 Java 示例,具体构造方法可能因 SDK 版本而异:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject("订单支付");
model.setOutTradeNo(outTradeNo);
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderString = response.getBody();
服务端需要把 orderString 原样返回给 Android 客户端。客户端不要重新排列参数,也不要重新签名:
new Thread(() -> {
PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderString, true);
activity.runOnUiThread(() -> {
String status = result.get("resultStatus");
if ("9000".equals(status)) {
// 这里只表示客户端认为支付流程成功结束,
// 最终支付状态仍应向服务端查询。
} else if ("6001".equals(status)) {
// 用户取消或支付页面中断。
} else {
// 记录完整结果,交由服务端进一步核查。
}
});
}).start();
3. 核对签名配置
确认以下配置都属于同一个支付宝开放平台应用:
app_id- 商户应用私钥
- 支付宝公钥
- 签名算法,如
RSA2 - 开放平台中配置的应用公钥
- App 支付产品的签约状态
“支付宝公钥”和“应用公钥”很容易混淆。服务端使用应用私钥签名,用支付宝公钥验证支付宝返回的内容。开放平台中配置的则是与应用私钥配对的应用公钥。
4. 原样传递订单字符串
Android 端收到服务端返回值后,应直接传给支付 SDK:
payTask.payV2(orderString, true);
不要进行以下处理:
URLEncoder.encode(orderString, "UTF-8");
URLDecoder.decode(orderString, "UTF-8");
也不要先把订单字符串拆成键值对,再重新拼接。参数顺序、转义方式或字符内容一旦改变,都可能导致签名校验失败。
如果订单信息通过 JSON 返回,应使用 JSON 解析器读取字段值,不要手工截取字符串:
{
"orderString": "app_id=...&biz_content=...&sign=..."
}
5. 排除环境问题
可以通过以下方式交叉验证:
- 将支付宝 App 更新到当前可用版本。
- 更换设备和支付宝账号测试。
- 确认没有混用沙箱网关、沙箱账号和正式应用配置。
- 检查设备时间是否准确。
- 确认同一个商户订单号没有被重复使用。
- 检查服务端生成订单时是否收到 SDK 异常或错误响应。
注意事项
9000、6001 等客户端结果只能用于展示支付流程状态,不能作为发货或开通服务的唯一依据。最终支付结果应由服务端通过支付宝异步通知验签确认,必要时再调用交易查询接口核实。
处理异步通知时,至少要校验:
- 通知签名;
app_id是否属于当前应用;out_trade_no是否存在且匹配;total_amount是否与本地订单一致;- 收款方信息是否正确;
- 订单是否已经处理,避免重复通知导致重复发货。
建议迁移到 alipay.trade.app.pay,同时检查签名和订单传递的完整链路。如果升级后仍然弹出“系统繁忙”,应保存支付 SDK 返回的完整 resultStatus、memo 和 result,以及服务端生成订单时的响应信息,再据此定位具体的失败环节。
备注:内容仅供参考。
