PAYATHON 2026

支付宝服务商调用 apipay.trade.pay 报错如何解决

支付小周

结论

这类问题通常与 Java 示例代码无关,更常见的原因是调用身份和商户签约关系不匹配。

服务商使用自己的应用替其他商户调用 alipay.trade.pay 时,不能只填写服务商的 app_id 和私钥。还要确认:

  1. 服务商应用支持第三方代调用,并且已经获得目标商户授权。
  2. 调用时传入了该商户授权生成的 app_auth_token。
  3. app_id、应用私钥、支付宝公钥、网关环境和 app_auth_token 属于同一环境及授权关系。

开通普通网页应用并绑定当面付产品,不代表该应用可以直接替其他商户收款。商户显示“直连”或“代签约”,只能说明产品签约状态,不能代替应用授权。

问题中没有提供具体错误码和 sub_msg,因此暂时无法确定唯一故障点,可以按下面的顺序排查。

先确认调用模式

调用 alipay.trade.pay 通常有两种模式。

商户直连

商户使用自己的应用、私钥和当面付签约能力发起交易:

商户 app_id + 商户应用私钥

这种模式通常不需要传入 app_auth_token。服务商不能使用自己的应用密钥,以商户直连的方式发起调用。

服务商代调用

服务商使用自己的应用发起请求,实际交易归属于已经授权的商户:

服务商 app_id + 服务商应用私钥 + 商户 app_auth_token

此时:

  • app_id 应填写服务商应用的 app_id。
  • 请求使用服务商应用私钥签名。
  • app_auth_token 必须来自当前收款商户对该服务商应用的授权。
  • 商户必须已经签约 alipay.trade.pay 所需的当面付能力。
  • 服务商应用必须支持第三方应用授权和代调用。

如果当前应用只是普通自用网页应用,不具备第三方代调用能力,就需要调整应用接入方式,或者让商户改用自己的应用直连。

正确传入商户授权令牌

在 Java SDK 中,app_auth_token 通常不写入业务 JSON,而是在执行请求时传入。

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;

public class AlipayTradePayExample {

    public static void main(String[] args) throws AlipayApiException {
        String gatewayUrl = "https://openapi.alipay.com/gateway.do";
        String appId = "服务商应用APP_ID";
        String merchantPrivateKey = "服务商应用私钥";
        String alipayPublicKey = "支付宝公钥";
        String appAuthToken = "目标商户授权生成的APP_AUTH_TOKEN";

        AlipayClient alipayClient = new DefaultAlipayClient(
                gatewayUrl,
                appId,
                merchantPrivateKey,
                "json",
                "UTF-8",
                alipayPublicKey,
                "RSA2"
        );

        AlipayTradePayRequest request = new AlipayTradePayRequest();

        AlipayTradePayModel model = new AlipayTradePayModel();
        model.setOutTradeNo("ORDER_202609090001");
        model.setScene("bar_code");
        model.setAuthCode("用户付款码");
        model.setSubject("订单支付");
        model.setTotalAmount("0.01");

        request.setBizModel(model);

        AlipayTradePayResponse response =
                alipayClient.execute(request, null, appAuthToken);

        if (response.isSuccess()) {
            System.out.println("支付成功");
            System.out.println("trade_no=" + response.getTradeNo());
        } else {
            System.out.println("支付失败");
            System.out.println("code=" + response.getCode());
            System.out.println("msg=" + response.getMsg());
            System.out.println("sub_code=" + response.getSubCode());
            System.out.println("sub_msg=" + response.getSubMsg());
        }
    }
}

不同版本 Java SDK 提供的方法重载可能略有差异。如果当前版本没有上述三参数重载,请检查 SDK 中的 execute 方法,确认最终请求确实带上了 app_auth_token,不要自行将其写入 biz_content。

按顺序排查

1. 打印完整错误信息

只有“调用报错”这一信息,无法判断具体原因。至少应记录:

System.out.println("code=" + response.getCode());
System.out.println("msg=" + response.getMsg());
System.out.println("sub_code=" + response.getSubCode());
System.out.println("sub_msg=" + response.getSubMsg());
System.out.println("body=" + response.getBody());

排查时先看 sub_code 和 sub_msg。同时保存请求时间、服务商 app_id、商户标识和 out_trade_no,但不要在日志中完整输出私钥、付款码或 app_auth_token。

2. 检查应用类型和接口权限

先确认发起请求的 app_id 对应哪个应用,再逐项检查:

  • 是否为预期的服务商应用。
  • 是否支持第三方商户授权。
  • 是否已经申请或配置 alipay.trade.pay 所需能力。
  • 应用是否已经上线,相关配置是否生效。
  • 商户签约的当面付产品是否仍处于有效状态。

“网页应用已绑定当面付”和“可以替其他商户调用”并不是一回事。前者解决的是产品使用资格,后者还需要完整的第三方应用授权链路。

3. 检查商户授权关系

确认目标商户授权的是当前服务商应用,而不是其他 app_id 对应的应用。

常见问题有:

  • 使用了其他商户的 app_auth_token。
  • 商户重新授权后,系统仍在使用旧令牌。
  • 商户已经解除授权。
  • 授权范围不包含调用所需权限。
  • 正式环境使用了沙箱授权令牌,或者沙箱环境使用了正式令牌。
  • 将 auth_code 误当成 app_auth_token。

授权流程中的临时 app_auth_code 通常要先换取 app_auth_token。两者用途不同,不能混用。

4. 检查签名配置

服务商代调用时,请求仍由服务商应用私钥签名。需要核对:

app_id              服务商应用的 APP_ID
private_key         该服务商应用对应的应用私钥
alipay_public_key   该应用配置对应的支付宝公钥
sign_type           通常为 RSA2,以应用实际配置为准
charset             建议统一使用 UTF-8

以下配置不能混用:

  • 服务商应用的 app_id 与商户应用私钥。
  • 沙箱私钥与正式环境网关。
  • 应用公钥与支付宝公钥。
  • 证书模式配置与普通公钥模式配置。

如果应用使用证书模式,应通过对应的证书客户端初始化,不能直接照搬普通公钥模式的示例。

5. 检查交易参数

确认身份和权限没有问题后,再检查业务参数:

  • out_trade_no 在商户维度内应保持唯一。
  • scene 必须符合实际支付场景,例如付款码支付通常使用 bar_code。
  • auth_code 应为有效且未过期的用户付款码。
  • total_amount 格式应正确,单位为元。
  • subject 不能为空。
  • 交易金额、行业或商户状态不能违反已签约产品的限制。

不要为了指定收款商户而随意填写 seller_id。在服务商代调用模式中,支付宝通常通过 app_auth_token 识别被授权商户。只有接口规则或具体业务场景明确要求时,才需要设置额外的商户标识参数。

常见错误方向

如果错误信息中出现以下内容,可以先检查对应位置:

错误方向优先检查
无权限、产品未签约商户当面付状态、服务商应用接口权限
应用授权无效app_auth_token 是否属于当前商户和当前应用
签名失败私钥、公钥、app_id、签名方式和字符集
参数无效scene、auth_code、金额和必填字段
商户状态异常商户账号、签约状态、授权状态
环境不一致沙箱与正式网关、应用配置和授权令牌
重复订单号out_trade_no 是否已被使用

具体原因仍要以接口返回的 sub_code 和 sub_msg 为准,不要只根据表面提示修改参数。

注意事项

  • “代签约”不等于“已授权服务商应用代调用”。
  • “账号类型为直连”也不代表服务商可以省略 app_auth_token。
  • 每个商户都需要单独授权,并保存各自对应的 app_auth_token。
  • 不要将商户授权令牌写死在公共代码中,应按商户维度安全存储和读取。
  • 正式环境与沙箱环境的应用、密钥、授权和网关必须一一对应。
  • 排查时应提供 code、sub_code、sub_msg 和脱敏后的请求参数。缺少这些信息时,只能判断常见原因,无法确认唯一解决方案。

如果当前使用的确实是普通网页应用,而且不支持第三方商户授权和代调用,通常只有两种处理方式:改用支持服务商代调用的应用接入方案,并让商户完成应用授权;或者让每个商户使用自己的应用、密钥和签约能力进行直连调用。

备注:内容仅供参考。