直付通APP支付调起支付宝APP提示系统繁忙及6001错误
结论
6001 表示客户端支付流程未完成,常见原因包括用户取消、支付宝收银台主动中止,或调起参数校验失败。它不是可以直接定位具体原因的服务端错误码。
结合“调起后提示系统繁忙”和示例请求,建议优先检查三方面:
- APP 端是否完整、原样接收并传入服务端生成的
orderStr,期间有没有二次编码、解码、JSON 封装、字符串拼接或参数丢失。 app_id对应的应用是否已开通并签约直付通 APP 支付能力,应用、公钥、商户账号和sub_merchant.merchant_id是否属于同一套有效配置。- 请求是否已经过期,服务器时间、
timestamp和time_expire是否一致。
从示例来看,请求结构没有明显缺少 APP 支付必填参数。但订单串已经脱敏,无法据此验证签名、应用权限及商户绑定关系。
首先检查 APP 端传参
服务端应通过支付宝 SDK 的 sdkExecute 生成订单串,APP 端收到后直接传给支付宝客户端。不要在 APP 端重新排序参数、重新签名或再次进行 URL 编码。
Android 通常这样调用:
Runnable payRunnable = () -> {
PayTask payTask = new PayTask(activity);
// orderStr 必须是服务端 sdkExecute 返回的完整字符串
Map<String, String> result = payTask.payV2(orderStr, true);
Log.d("Alipay", "resultStatus=" + result.get("resultStatus"));
Log.d("Alipay", "memo=" + result.get("memo"));
Log.d("Alipay", "result=" + result.get("result"));
};
Thread payThread = new Thread(payRunnable);
payThread.start();
需要逐项确认:
- 不要先把
orderStr放入 JSON,再将整个 JSON 字符串传给payV2。 - 不要调用
URLEncoder.encode(orderStr, "UTF-8")对整个订单串再次编码。 - 不要先执行
URLDecoder.decode,再自行拼接参数。 - 不要把
&转换成&。 - 不要删除参数值中的
%2B、%2F、%3D等编码内容。 - 不要让
+在日志复制、数据库保存或接口传输过程中自动变成空格。 - 确认字符串中没有多余的引号、反斜杠、换行或
orderInfo=前缀。
可以分别记录服务端输出和 APP 收到的字符串长度,并计算摘要进行比对:
String digest = sha256(orderStr);
Log.d("Alipay", "orderStrLength=" + orderStr.length());
Log.d("Alipay", "orderStrSha256=" + digest);
服务端和 APP 端记录的长度及 SHA-256 摘要必须完全一致。记录日志时,应对签名、商户号和订单号进行脱敏,避免泄露完整支付参数。
检查服务端生成方式
Java 服务端应交由支付宝 SDK 拼装公共参数并完成签名,不要手工拼接订单串:
AlipayClient alipayClient = new DefaultAlipayClient(
gatewayUrl,
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://pay.example.com/alipay/notify");
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("P202606291650561");
model.setSubject("雅迪钥匙扣");
model.setBody("雅迪钥匙扣");
model.setTotalAmount("0.12");
model.setProductCode("QUICK_MSECURITY_PAY");
model.setTimeExpire("2026-06-29 17:05:56");
SubMerchant subMerchant = new SubMerchant();
subMerchant.setMerchantId("208**********5948");
model.setSubMerchant(subMerchant);
request.setBizModel(model);
// 返回给 APP 的就是 response.getBody()
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderStr = response.getBody();
支付宝 Java SDK 版本不同,具体模型类名称可能有所差异,应以项目实际依赖提供的类为准。这里的重点是使用 sdkExecute,不要在调用普通网关接口后自行拼接支付参数。
还要核对以下配置:
merchantPrivateKey必须是app_id当前配置对应的应用私钥。- 开放平台中配置的应用公钥必须与该私钥匹配。
- 验签时使用支付宝公钥,不能使用应用公钥或商户私钥。
- 生产应用必须使用生产网关、生产密钥和生产商户号,不能混入沙箱配置。
sign_type保持为RSA2。- APP 端实际收到的
app_id、sign和biz_content,必须与服务端签名时的内容一致。
如果近期更换过应用公钥或私钥,应检查发布环境是否仍在使用旧私钥,而开放平台已经切换为新公钥。
检查直付通配置和商户关系
直付通除了要求公共参数和签名正确,还要求主商户、应用与二级商户之间的关系有效。建议在支付宝开放平台或商家平台逐项核对:
app_id对应的应用已经上线,不处于未提交、审核中或已下架状态。- 应用已经取得当前直付通 APP 支付场景所需的产品权限。
- 直付通产品签约已经生效。
sub_merchant.merchant_id是支付宝分配的有效商户 PID,不是应用 ID、登录账号或外部商户编号。- 二级商户已经完成进件,目前处于可用状态。
- 二级商户与当前直付通主商户、当前应用之间已经建立有效绑定关系。
- 二级商户的经营类目、主体状态和支付权限未被限制。
- 如果接口由服务商代为调用,需要确认当前模式是否要求应用授权,以及授权令牌是否属于该商户。是否需要
app_auth_token取决于具体接入模式,不能在尚未确认模式时随意添加。
有两种情况很容易被忽略:一是使用了另一个应用的私钥签名,二是把在测试应用下进件的二级商户号用于生产应用请求。这两种情况下,生成的订单串看起来可能正常,但支付宝客户端仍会处理失败。
检查时间和订单状态
示例中的时间是:
timestamp=2026-06-29 16:51:07
time_expire=2026-06-29 17:05:56
订单有效期大约只有 15 分钟。如果反复使用日志中的订单串测试,该订单早已失效,需要重新生成。
同时确认:
- 服务器的系统时间和时区正确。
time_expire晚于请求生成时间,并符合接口允许的有效期规则。- 每次测试都使用新的
out_trade_no。 - 同一个
out_trade_no没有用于不同金额、不同二级商户或不同商品信息。 - 不要缓存或重复下发旧的
orderStr。
timestamp 和 time_expire 应由同一台可信服务器生成。如果服务器时间存在较大偏差,即使字符串和签名都正确,支付宝也可能把请求判定为无效。
notify_url 不是本次提示的首要原因
示例使用的通知地址是:
http://www.abc.com:9077/pay/notify/order/1
通知地址无法从公网访问、端口被拦截或没有使用 HTTPS,通常影响支付完成后的异步通知,不会直接导致 APP 调起时出现 6001。不过,生产环境仍建议:
- 使用公网可访问的 HTTPS 地址。
- 避免使用容易被网络策略拦截的非标准端口。
- 不要依赖异步通知完成页面跳转。
- 按支付宝异步通知验签规范处理通知。
因此,不能仅因没有收到通知,就认定 notify_url 是 6001 的直接原因。
如何进一步定位
不要只记录拼接后的字符串和 6001,还应保留以下信息:
app_id
out_trade_no
sub_merchant.merchant_id
timestamp
time_expire
服务端生成 orderStr 的时间
orderStr 长度和脱敏摘要
支付宝客户端返回的完整 resultStatus、memo、result
问题发生时间
支付宝账号及客户端版本
可以按以下顺序进行最小化验证:
- 使用全新的
out_trade_no和有效期,重新生成订单串。 - APP 端将服务端响应体直接传给
payV2,移除所有二次封装和编码。 - 暂时删除非必填的
body、time_expire等字段,只保留必要业务参数进行测试。 - 使用已经确认可用的二级商户号做对照测试。
- 再次核对
app_id、私钥、公钥、产品签约状态和二级商户绑定关系。 - 如果仍然提示系统繁忙,向支付宝技术支持提供问题发生时间、
app_id、脱敏后的商户号和out_trade_no,请其查询支付宝侧链路日志。
当客户端只有 resultStatus=6001 且 result 为空时,通常无法在本地还原支付宝内部的拒绝原因。此时最有用的排查依据,是未经修改的原始 orderStr、准确的问题发生时间,以及支付宝侧根据订单号查询到的内部日志。
备注:内容仅供参考。
