PAYATHON 2026

直付通APP支付调起支付宝APP提示系统繁忙及6001错误

支付小周

结论

6001 表示客户端支付流程未完成,常见原因包括用户取消、支付宝收银台主动中止,或调起参数校验失败。它不是可以直接定位具体原因的服务端错误码。

结合“调起后提示系统繁忙”和示例请求,建议优先检查三方面:

  1. APP 端是否完整、原样接收并传入服务端生成的 orderStr,期间有没有二次编码、解码、JSON 封装、字符串拼接或参数丢失。
  2. app_id 对应的应用是否已开通并签约直付通 APP 支付能力,应用、公钥、商户账号和 sub_merchant.merchant_id 是否属于同一套有效配置。
  3. 请求是否已经过期,服务器时间、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,再自行拼接参数。
  • 不要把 & 转换成 &amp;。
  • 不要删除参数值中的 %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
问题发生时间
支付宝账号及客户端版本

可以按以下顺序进行最小化验证:

  1. 使用全新的 out_trade_no 和有效期,重新生成订单串。
  2. APP 端将服务端响应体直接传给 payV2,移除所有二次封装和编码。
  3. 暂时删除非必填的 body、time_expire 等字段,只保留必要业务参数进行测试。
  4. 使用已经确认可用的二级商户号做对照测试。
  5. 再次核对 app_id、私钥、公钥、产品签约状态和二级商户绑定关系。
  6. 如果仍然提示系统繁忙,向支付宝技术支持提供问题发生时间、app_id、脱敏后的商户号和 out_trade_no,请其查询支付宝侧链路日志。

当客户端只有 resultStatus=6001 且 result 为空时,通常无法在本地还原支付宝内部的拒绝原因。此时最有用的排查依据,是未经修改的原始 orderStr、准确的问题发生时间,以及支付宝侧根据订单号查询到的内部日志。

备注:内容仅供参考。