PAYATHON 2026

alipay-sdk java-3.7,26.ALL 不支持 openid 如何解决?

支付老李

结论

alipay-sdk-java-3.7.26.ALL 是较旧的服务端 SDK。遇到“不支持 openid”的报错时,先升级到支付宝官方当前支持的 Java SDK,同时确认项目运行时加载的不是被其他依赖覆盖的旧版本。

API 密钥只用于接口请求的签名与验签,无法让旧 SDK 支持新增字段、新协议或新产品能力。第三方代商户发起扫码支付时,还要正确传入商户授权令牌 app_auth_token。普通扫码预下单一般不需要主动传入 openid。

为什么使用 API 密钥后仍然报错

“使用 API 密钥不受 SDK 影响”通常是指开发者可以按照开放平台协议,自行组装参数、签名并发送 HTTP 请求。这并不意味着任何版本的官方 SDK 都能兼容新能力。

除了签名,SDK 还可能处理以下工作:

  • 请求参数序列化;
  • 响应字段反序列化;
  • SDK 版本标识上报;
  • 新增身份字段的处理;
  • 加密、验签和字符编码;
  • 证书或密钥模式下的客户端初始化。

如果支付链路用到了 openid 或相关身份能力,旧 SDK 即使可以生成 RSA 签名,也可能因为缺少字段定义或兼容逻辑而被判定为不支持。

在第三方代商户调用中,“API 密钥”和“商户授权”也不是一回事:

  • API 密钥用于证明请求由哪个应用发出;
  • app_auth_token 用于证明商户已授权第三方应用代为调用接口。

API 密钥不能代替 app_auth_token。

处理步骤

1. 升级支付宝 Java SDK

将 com.alipay.sdk:alipay-sdk-java 升级到支付宝开放平台当前文档或官方 Maven 仓库列出的受支持版本,不要根据错误信息猜测最低版本。

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>${alipay.sdk.version}</version>
</dependency>

${alipay.sdk.version} 应填写官方文档当前推荐的版本。升级后检查依赖,确认实际打包和运行的不是旧版本:

mvn dependency:tree -Dincludes=com.alipay.sdk:alipay-sdk-java

如果检查结果中有多个版本,应从上层依赖中排除旧版,确保最终只保留预期版本。例如:

<exclusions>
    <exclusion>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-sdk-java</artifactId>
    </exclusion>
</exclusions>

Gradle 项目可以使用以下命令检查:

./gradlew dependencies --configuration runtimeClasspath

应用服务器、容器公共目录和手工引入的 lib 目录也需要检查,避免残留旧版 JAR。如果只修改了 pom.xml,运行时却仍在加载旧 JAR,报错不会消失。

2. 正确初始化客户端

普通公钥模式的基本写法如下:

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

如果应用使用支付宝公钥证书模式,应按照官方文档提供的证书客户端初始化方式配置,不能混用支付宝公钥模式和证书模式。

无论使用哪种模式,密钥或证书解决的都是应用身份和签名问题,不能修复旧 SDK 对 openid 的兼容问题。

3. 第三方代商户调用时传入 app_auth_token

以当面付扫码预下单接口 alipay.trade.precreate 为例,第三方应用需要使用自己的 app_id 和私钥初始化客户端,并在执行请求时传入目标商户授权生成的 app_auth_token:

AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount("0.01");
model.setSubject("订单支付");

request.setBizModel(model);

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

if (!response.isSuccess()) {
    throw new IllegalStateException(
        response.getCode() + ": " +
        response.getMsg() + " / " +
        response.getSubCode() + ": " +
        response.getSubMsg()
    );
}

不同 SDK 版本提供的 execute 重载方法可能不同。如果当前版本没有上述方法签名,应以该版本的官方 API 为准,或通过请求对象设置应用授权令牌。不要把 app_auth_token 写入业务 JSON,也不要将其误传为用户登录所用的 auth_token。

4. 不要为扫码预下单强行添加 openid

alipay.trade.precreate 通常用于生成二维码,由付款人在支付宝客户端扫码付款。调用方一般不需要提前提交付款人的 openid。

如果业务代码、支付中间件或网关插件自动加入了 openid,需要检查:

  • 该字段是否确实属于当前接口的请求参数;
  • 参数名称和所在层级是否符合当前接口文档;
  • 是否将其他平台的 openid 概念套用到了支付宝接口;
  • 是否把响应中的身份字段误当成了请求字段;
  • 是否使用了过时的封装库或支付聚合插件。

不要为了消除提示,直接在 biz_content 中手工加入接口文档未定义的字段。

升级后仍报错时如何排查

记录支付宝返回的完整错误信息,并对密钥、授权令牌和个人信息进行脱敏。重点保留:

code
msg
sub_code
sub_msg
request_id
trace_id(如有)

然后依次检查:

  1. 运行时加载的 SDK 版本是否已经更新。
  2. 调用的接口是否为 alipay.trade.precreate,而不是其他需要用户身份的接口。
  3. 请求中是否实际包含 openid,以及该字段来自业务代码还是第三方封装组件。
  4. 第三方代商户调用是否传入了有效的 app_auth_token。
  5. app_id、网关环境、密钥、支付宝公钥或证书是否属于同一应用和同一环境。
  6. 商户授权是否包含当前支付接口所需的权限。
  7. 错误来自支付宝开放平台接口,还是聚合支付服务商、网关插件或前端收银台自身的版本检查。

如果错误不是支付宝接口返回,而是由第三方支付组件生成,那么仅升级支付宝官方 SDK 可能无法解决问题。还需要同步升级该组件,或调整组件对 openid 的校验逻辑。

注意事项

  • API 密钥、应用私钥、支付宝公钥、app_auth_token 和用户授权 auth_token 各有用途,不要混用。
  • 不要在日志中记录应用私钥或完整的授权令牌。
  • SDK 升级后,应重新测试签名、验签、预下单、二维码支付和异步通知。
  • 如果绕过 SDK,直接调用 HTTP OpenAPI,就需要自行处理参数排序、RSA2 签名、编码、验签和错误处理,维护成本通常高于升级 SDK。
  • 仅凭“3.7.26.ALL 不支持 openid”无法确定唯一的最低兼容版本。具体版本应以当前接口文档、官方 SDK 发布记录和实际返回的 sub_code 为准。

备注:内容仅供参考。