PAYATHON 2026

支付宝 alipay.trade.app.pay 报错 ALI64 如何排查?

支付阿杰

结论

ALI64 通常是支付宝收银台显示的通用失败码,仅凭这个编号无法判断具体原因。如果 App 支付连续正常使用数月后突然失败,建议先排查以下三方面:

  1. 应用证书是否过期、被替换,证书与私钥是否匹配;
  2. App 支付产品签约、商户账户或应用上线状态是否发生变化;
  3. 服务端生成的订单字符串是否被二次编码或修改,进而导致验签或下单失败。

重新生成证书不代表证书更新已经完成。支付宝开放平台中的应用公钥证书、服务器私钥、本地三份证书文件和运行中的配置,必须属于同一套证书体系。

示例请求中的 timestamp=2024-03-05 17:51:21 只能用于分析历史交易。重新测试时要使用当前时间,不能复用整段历史订单字符串。

先获取具体的失败信息

alipay.trade.app.pay 的服务端响应主要是供 App 调起支付宝客户端的订单字符串。支付宝客户端显示 ALI64 后,还需要记录客户端 SDK 返回的完整结果,包括:

  • resultStatus
  • memo
  • result
  • 支付宝客户端显示错误的时间
  • out_trade_no
  • 服务端调用支付宝接口时的原始响应
  • 网关响应中的 code、sub_code、sub_msg
  • 响应中的 trace_id、request_id 等链路标识(如果存在)

Android 端可以记录 payV2 的返回值:

Map<String, String> result = new PayTask(activity).payV2(orderInfo, true);

String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String rawResult = result.get("result");

Log.i("Alipay", "resultStatus=" + resultStatus);
Log.i("Alipay", "memo=" + memo);
Log.i("Alipay", "result=" + rawResult);

不要只记录界面上的 ALI64。这可能只是收银台对内部失败原因的统一提示,网关日志或支付宝侧的链路日志通常会提供更具体的信息。

第一优先级:核对证书和私钥

当前请求包含:

app_cert_sn=79a58475e12e24cd186ce618d6907810
alipay_root_cert_sn=687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6

这表明系统使用的是支付宝公钥证书模式。至少要核对:

  • 应用私钥;
  • 应用公钥证书;
  • 支付宝公钥证书;
  • 支付宝根证书;
  • 开放平台中当前生效的应用公钥证书;
  • 实际运行实例加载的证书,不能只检查代码仓库中的文件。

请求中出现 app_cert_sn,只能说明程序计算并发送了证书序列号。它不能证明证书仍然有效,也不能证明签名所用的私钥与该证书匹配。

如果重新生成过应用证书,需要按同一批次完整更新:

  1. 使用新的密钥对生成应用公钥证书申请;
  2. 在支付宝开放平台的对应应用中上传并启用新的应用公钥证书;
  3. 下载当前有效的支付宝公钥证书和支付宝根证书;
  4. 同时部署新的应用私钥、应用公钥证书、支付宝公钥证书和根证书;
  5. 重启或重新加载所有服务实例;
  6. 检查是否仍有旧容器、旧机器或定时任务在使用旧私钥;
  7. 生成全新的订单进行测试。

常见情况包括:

  • 平台已经上传新证书,服务器仍在使用旧私钥;
  • 服务器已经更换新私钥,平台保存的仍是旧应用证书;
  • 只更新了应用证书,没有更新运行环境中的证书路径;
  • 多台服务器中只有一部分实例完成了更新;
  • 配置中心已经修改,进程缓存中仍是旧内容;
  • 生产环境误用了沙箱证书或其他应用的证书。

检查应用和商户状态

如果证书没有问题,再登录支付宝开放平台和商家后台检查:

  • app_id=2021004119614099 对应的应用是否仍然可用或处于已上线状态;
  • App 支付能力是否已经签约并正常生效;
  • 签约主体是否与当前应用及商户账号匹配;
  • 产品权限是否到期、暂停或需要重新确认协议;
  • 商户账号是否存在风控、账户限制或资料待补充的情况;
  • 应用是否刚完成主体、接口权限或密钥变更;
  • 是否收到支付宝发送的整改、证书到期或产品权限通知。

这些状态变化可以解释为什么支付此前正常,后来却突然全部失败。重新生成本地证书通常无法解决此类问题。

如果所有用户、金额和订单都失败,更可能是应用、证书、签约或商户级问题。如果只有特定用户、设备或金额失败,还要考虑买家账户限制、支付方式限制和风控判断。

检查签名及订单字符串

签名应基于未经 URL 编码的待签名参数生成。完成签名后,再对订单字符串中的参数值进行编码。以下操作都可能破坏签名:

  • 对完整订单字符串再次进行 URL 编码;
  • 先编码参数,再参与 RSA2 签名;
  • 客户端收到订单后先进行 URL 解码,再重新拼接;
  • 传输过程中将 + 转换为空格;
  • 修改 biz_content 中的空格、转义字符或字段顺序;
  • 服务端完成签名后,又修改 notify_url、timestamp 等公共参数;
  • 使用错误的字符集处理中文 subject;
  • 将测试环境生成的订单提交给生产环境的支付宝客户端。

建议直接使用支付宝 SDK 的证书模式配置,通过 sdkExecute 生成订单字符串,不要手工拼接签名参数。Java 示例:

AlipayConfig config = new AlipayConfig();
config.setServerUrl("https://openapi.alipay.com/gateway.do");
config.setAppId("你的_APP_ID");
config.setPrivateKey("你的应用私钥");
config.setFormat("json");
config.setCharset("UTF-8");
config.setSignType("RSA2");

config.setAppCertPath("/path/appCertPublicKey.crt");
config.setAlipayPublicCertPath("/path/alipayCertPublicKey_RSA2.crt");
config.setRootCertPath("/path/alipayRootCert.crt");

AlipayClient client = new DefaultAlipayClient(config);

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("202609091530001234");
model.setTotalAmount("799.97");
model.setSubject("充值-202609091530001234");
model.setProductCode("QUICK_MSECURITY_PAY");

request.setBizModel(model);

AlipayTradeAppPayResponse response = client.sdkExecute(request);
String orderInfo = response.getBody();

生成的 orderInfo 应原样交给 App 的支付宝 SDK,不要解析后重新排序或编码。

对当前请求参数的判断

从当前参数中,暂时看不出能够直接证明根因的业务字段错误:

{
  "out_trade_no": "20240305055121000002313262",
  "total_amount": 799.97,
  "subject": "充值-20240305055121000002313262",
  "product_code": "QUICK_MSECURITY_PAY"
}

可以按以下方式调整和验证:

  • 将金额作为字符串传递,例如 "799.97",避免浮点数序列化造成精度问题;
  • 每次测试都使用新的 out_trade_no;
  • 使用服务器当前时间生成 timestamp,并校准系统时钟;
  • 保持 product_code 为 QUICK_MSECURITY_PAY;
  • 确认生产请求发送到 https://openapi.alipay.com/gateway.do;
  • 暂时移除非必要的 return_url,减少排查变量;
  • 将 notify_url 改为公网可访问的 HTTPS 地址。

示例中的 HTTP 回调地址安全性较弱,建议改用 HTTPS。但异步通知地址无法访问通常只会影响支付结果通知,不一定会直接导致收银台显示 ALI64,因此不能只根据这个地址判断根因。

建议的最小化测试

先用最少参数创建一个小额测试订单:

{
  "out_trade_no": "每次生成新的唯一订单号",
  "total_amount": "0.01",
  "subject": "App支付测试",
  "product_code": "QUICK_MSECURITY_PAY"
}

测试时只保留必要的公共参数和 notify_url,不要复用历史订单字符串。

根据测试结果,可以进一步缩小排查范围:

  • 最小订单仍然全部失败:重点检查证书、签约、应用状态和商户限制;
  • 小额订单成功,原金额失败:检查额度、风控和支付方式限制;
  • 部分服务器成功,部分失败:检查集群中的证书和配置是否一致;
  • 服务端成功生成订单,客户端支付失败:检查订单字符串传输、二次编码、支付宝客户端环境和 SDK 返回值;
  • 网关直接返回验签错误:检查私钥、应用证书、app_id 和签名流程;
  • 只有旧订单失败:检查订单号是否重复、订单状态是否异常,以及订单字符串是否过期。

仍无法定位时需要提交的信息

如果网关和客户端日志中仍没有具体的 sub_code,应向支付宝技术支持提交:

  • app_id;
  • 商户 PID;
  • out_trade_no;
  • 失败发生的准确时间,精确到秒;
  • 客户端返回的 resultStatus、memo 和 result;
  • 服务端网关的原始响应;
  • 支付宝响应中的链路标识;
  • 是否所有用户和金额都会失败;
  • 最近是否更换过证书、私钥、应用主体或签约配置。

不要提交应用私钥,也不要公开完整的签名材料和用户敏感信息。支付宝可以根据失败时间、订单号和链路标识查询 ALI64 对应的内部原因,这一步无法仅靠请求字符串完成。

备注:内容仅供参考。