PAYATHON 2026

Alipay App支付提示交易订单处理失败,如何解决?

支付阿杰

结论

题目中的参数并不能组成完整的 alipay.trade.app.pay 请求。最明显的是缺少必填的 biz_content,其中至少要有商户订单号、金额、商品标题和 product_code。如果实际提交的确实只有这些参数,支付宝无法创建交易,客户端可能只会显示“交易订单处理失败,请稍后重试”。

如果实际请求已经包含 biz_content,还要检查签名原文、URL 编码、密钥配置、网关环境以及 App 支付产品权限。客户端提示无法反映具体原因,应以服务端返回的 code、sub_code、sub_msg 和 request_id 为准。

检查业务参数

alipay.trade.app.pay 的业务参数要放在 biz_content 中,例如:

{
  "out_trade_no": "ORDER_20250627191603",
  "total_amount": "0.01",
  "subject": "测试商品",
  "product_code": "QUICK_MSECURITY_PAY"
}

需要重点核对以下字段:

  • out_trade_no:在同一商户下应保持唯一。对同一业务订单重新发起支付时,不要随意修改金额或商品信息。
  • total_amount:应使用字符串表示合法金额,例如 "0.01"。不要传入负数、科学计数法或超过业务允许精度的数值。
  • subject:不能为空,也不能包含不可见控制字符。
  • product_code:App 支付通常使用 QUICK_MSECURITY_PAY。
  • timeout_express:可选,例如 "30m",但格式必须合法。
  • seller_id:一般无须主动传入。如果传入,必须与实际收款账号一致。

notify_url 通常不是创建交易的必填参数,但生产环境建议配置为公网可访问的 HTTPS 地址。它属于公共请求参数,不能放进 biz_content。

使用服务端 SDK 生成订单串

App 支付通常由服务端创建并签名订单。服务端将 SDK 返回的完整订单串原样传给移动端,移动端再通过支付宝 SDK 发起支付。

Java 示例:

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;

AlipayClient alipayClient = new DefaultAlipayClient(
    "https://openapi.alipay.com/gateway.do",
    appId,
    merchantPrivateKey,
    "json",
    "UTF-8",
    alipayPublicKey,
    "RSA2"
);

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("ORDER_20250627191603");
model.setTotalAmount("0.01");
model.setSubject("测试商品");
model.setProductCode("QUICK_MSECURITY_PAY");
model.setTimeoutExpress("30m");

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

try {
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);

    if (!response.isSuccess()) {
        throw new IllegalStateException(
            "生成支付宝订单失败,code=" + response.getCode()
                + ", subCode=" + response.getSubCode()
                + ", subMsg=" + response.getSubMsg()
        );
    }

    // 将该字符串原样返回给 App,不要拆分、重新排序或再次整体编码。
    String orderString = response.getBody();
} catch (AlipayApiException e) {
    throw new IllegalStateException("调用支付宝 SDK 失败", e);
}

如果应用使用证书模式,不能直接套用公钥模式的初始化代码。应改用对应的证书客户端配置,并确认应用公钥证书、支付宝公钥证书和支付宝根证书属于同一环境。

排查签名问题

RSA2 签名要使用商户应用私钥生成。支付宝开放平台中配置的应用公钥,必须与该私钥配对。常见问题包括:

  1. 错用支付宝公钥进行签名。
  2. 商户私钥与开放平台配置的应用公钥不属于同一对密钥。
  3. 在正式环境使用沙箱密钥,或者在沙箱环境使用正式密钥。
  4. 应用使用证书模式,代码却仍按普通公钥模式初始化。
  5. 参数内容在签名前后发生变化。
  6. 对 sign 或整个订单串进行了重复 URL 编码。
  7. 手工拼接参数时遗漏字段、排序错误,或者错误处理空格、+、%2B、/ 等字符。
  8. 参数声明为 charset=UTF-8,签名时却使用了其他字符集。

签名应按以下顺序处理:

  1. 准备所有参与签名的请求参数。
  2. 排除 sign 参数和空值。
  3. 按参数名的 ASCII 顺序排序。
  4. 拼接为 key=value&key=value 格式。
  5. 使用未经过 URL 编码的原始参数值生成 RSA2 签名。
  6. 组装最终请求串时再进行 URL 编码。

题目中的签名已经经过编码:

B16...%2F...%2B...%3D%3D

不要直接把它作为签名原文。%2F、%2B 和 %3D 是传输阶段的编码结果,验签时需要使用对应的原始 Base64 签名值。

建议让官方 Java SDK 负责排序、签名和编码,避免自行拼接请求串。

检查时间戳和订单串复用

示例中的时间戳是:

2025-06-27 19:16:03

这个值不能作为固定参数长期复用。每次生成订单时都要使用服务器当前时间,同时确保服务器时钟准确,时区配置符合接口要求。

已经签名的订单串也不应缓存后反复使用。只要时间戳、订单号或业务参数发生变化,就必须重新签名。直接修改最终字符串中的某个参数会使签名失效。

检查应用和接口配置

还要核对以下配置:

  • app_id 是否与当前使用的私钥、公钥或证书完全对应。
  • 应用是否已签约并开通 App 支付能力,相关产品状态是否正常。
  • 正式应用是否使用正式网关:
https://openapi.alipay.com/gateway.do
  • 沙箱应用是否使用沙箱网关,并配合沙箱账号、沙箱密钥和对应的客户端环境。
  • App 接入的是否为支付宝 App 支付 SDK,而不是直接通过 WebView 打开网关地址。
  • 如果是第三方应用代商户调用,是否正确传入 app_auth_token,授权是否仍然有效。
  • 商户账号、应用或收款能力是否存在冻结、风控限制或签约异常。

参数中的:

alipay_sdk=alipay-sdk-java-dynamicVersionNo

看起来像尚未替换的 SDK 版本占位内容。它通常不是 App 支付的核心业务参数,仅凭这一项还不能确定失败原因。不过,仍应检查 SDK 依赖、打包过程和实际版本。建议使用有明确发布版本的官方 SDK,不要手工设置 alipay_sdk。

获取具体错误信息

不要只记录移动端显示的“交易订单处理失败”。服务端至少要记录:

code
msg
sub_code
sub_msg
request_id
out_trade_no

日志中不要写入商户私钥、完整签名、用户身份信息或完整支付订单串。

可以按下面的顺序排查:

  1. 在服务端打印经过脱敏的 biz_content,确认必填字段完整。
  2. 检查 sdkExecute 是否成功,并查看返回的 code 和 sub_code。
  3. 确认传给 App 的是 response.getBody(),中间没有经过 JSON 包装转义、截断或二次编码。
  4. 对照开放平台配置,检查密钥或证书是否匹配。
  5. 确认正式环境和沙箱环境没有混用。
  6. 使用同一个 out_trade_no 查询交易状态,避免客户端提示失败后再次创建重复订单。
  7. 如果仍无法确认原因,可凭支付宝返回的 request_id、调用时间和 app_id 向支付宝技术支持查询调用链路。

客户端的通用提示无法单独确定故障点。针对题目给出的请求串,应先补齐 biz_content,改由服务端 SDK 生成完整订单串,再检查密钥是否匹配以及是否存在重复编码。

备注:内容仅供参考。