PAYATHON 2026

服务商调用手机网站支付接口报 invalid-app-auth-token

支付阿杰

结论

invalid-app-auth-token 通常不是 alipay.trade.wap.pay 的业务参数有误,而是支付宝无法确认当前 app_auth_token 对应的应用授权关系有效。

服务商代商家调用接口时,请求必须满足以下条件:

  • app_id 是服务商开放平台应用的 AppID;
  • app_auth_token 由商家授权该应用后产生;
  • app_id 与 app_auth_token 属于同一条应用授权关系;
  • 令牌仍在有效期内,且与当前网关环境一致。

应用不匹配、商家解除授权、令牌过期,或者生产环境与沙箱环境混用,都可能触发这个错误。

首先检查 app_id 与 app_auth_token 的归属

示例表单中的公共参数是:

app_id=2018062560461070

同时提交了:

app_auth_token=202407BBc678a619f8494a889ebfa89442170X62

需要确认该 app_auth_token 确实由商家授权服务商应用 2018062560461070 后获得,而不是以下几类令牌:

  • 其他服务商应用获取的令牌;
  • 商家自己的应用令牌;
  • 其他商户账号授权后产生的令牌;
  • 沙箱环境生成的令牌;
  • 历史应用或已下架应用的令牌;
  • 被误当成 app_auth_token 的 app_auth_code 或 app_refresh_token。

app_auth_token 不能跨应用使用。即使授权商户相同,只要服务商的 app_id 不同,令牌就不能混用。

检查开放平台中的授权关系

登录服务商对应的支付宝开放平台账号,找到实际发起请求的应用,然后检查商家授权记录:

  1. 请求中的 app_id 是否为当前应用的 AppID。
  2. 目标商家是否已经授权该应用。
  3. 授权状态是否仍然有效。
  4. 商家是否曾解除授权并重新授权。
  5. 当前保存的令牌是否来自最近一次有效授权。
  6. 商家授权的产品或权限是否包含手机网站支付所需的能力。

商家解除授权后,原来的 app_auth_token 通常无法继续使用。即使商家随后重新授权,也应使用新的授权码换取令牌,并保存新令牌。

查询令牌是否有效

服务商可以调用 alipay.open.auth.token.app.query,查询应用授权令牌对应的授权信息。查询请求仍需使用服务商应用自己的私钥签名,同时确保网关环境正确。

Java SDK 的调用结构可参考:

AlipayOpenAuthTokenAppQueryRequest request =
        new AlipayOpenAuthTokenAppQueryRequest();

AlipayOpenAuthTokenAppQueryModel model =
        new AlipayOpenAuthTokenAppQueryModel();
model.setAppAuthToken(appAuthToken);

request.setBizModel(model);

AlipayOpenAuthTokenAppQueryResponse response =
        alipayClient.execute(request);

if (response.isSuccess()) {
    System.out.println("授权令牌有效");
    System.out.println(response.getBody());
} else {
    System.out.println("授权令牌查询失败");
    System.out.println(response.getCode());
    System.out.println(response.getSubCode());
    System.out.println(response.getSubMsg());
}

不同版本的 Java SDK 在模型类或方法签名上可能略有差异,请以项目实际依赖版本提供的接口为准。判断结果时不能只看 HTTP 状态码,还要记录:

code
msg
sub_code
sub_msg

如果令牌查询接口也返回无效,说明问题出在授权令牌或授权关系上,无需继续排查支付订单参数。

令牌失效后如何处理

如果令牌已经过期,可以使用授权流程中保存的刷新令牌,通过 alipay.open.auth.token.app 刷新应用授权令牌。

示意代码如下:

AlipayOpenAuthTokenAppRequest request =
        new AlipayOpenAuthTokenAppRequest();

AlipayOpenAuthTokenAppModel model =
        new AlipayOpenAuthTokenAppModel();
model.setGrantType("refresh_token");
model.setRefreshToken(appRefreshToken);

request.setBizModel(model);

AlipayOpenAuthTokenAppResponse response =
        alipayClient.execute(request);

if (response.isSuccess()) {
    String newAppAuthToken = response.getAppAuthToken();
    String newAppRefreshToken = response.getAppRefreshToken();

    // 应原子化更新数据库中的令牌及其有效期
} else {
    System.out.println(response.getSubCode());
    System.out.println(response.getSubMsg());
}

如果刷新令牌也已失效,或者商家已经解除授权,就无法继续刷新。此时需要让商家重新进入应用授权页面。服务商取得新的 app_auth_code 后,再调用授权换令牌接口。

这几个字段的用途不同:

  • app_auth_code 是授权过程中的临时授权码,不能用于支付接口;
  • app_auth_token 是服务商代商家调用接口时传入的应用授权令牌;
  • app_refresh_token 用于刷新应用授权令牌;
  • 取得新令牌后,应及时替换旧值,避免其他服务实例继续从历史缓存中读取旧令牌。

正确调用手机网站支付接口

服务商代商家调用时,应使用服务商应用的配置初始化客户端,并将对应商家的 app_auth_token 传给 SDK。

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

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

AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo("70003147010240284546002");
model.setTotalAmount("0.01");
model.setSubject("测试商品");
model.setProductCode("QUICK_WAP_WAY");

request.setBizModel(model);

AlipayTradeWapPayResponse response =
        alipayClient.pageExecute(request, null, appAuthToken, "POST");

if (!response.isSuccess()) {
    System.out.println(response.getCode());
    System.out.println(response.getSubCode());
    System.out.println(response.getSubMsg());
}

String form = response.getBody();

不同版本的 SDK 可能提供不同的 pageExecute 重载参数。如果当前版本没有上述签名,请查看该版本的 API,选择能够传入 appAuthToken 的重载方法,不要只靠手工拼接表单。

检查生产环境与沙箱环境

示例请求使用的是生产网关:

https://openapi.alipay.com/gateway.do

因此,以下数据和配置都必须来自生产环境:

  • 服务商 app_id;
  • 应用私钥;
  • 支付宝公钥或支付宝公钥证书;
  • 商家授权关系;
  • app_auth_token。

如果令牌来自沙箱授权,应改用对应的沙箱网关。生产应用与沙箱应用的数据相互隔离,不能交叉使用。

建议按以下顺序排查

  1. 查看服务器实际日志,确认最终发送的 app_id,不要只检查配置文件。
  2. 根据商户标识查询数据库中的 app_auth_token,确认没有取错商户的令牌。
  3. 核对令牌所属的服务商应用,确保它与请求中的 app_id 完全一致。
  4. 检查生产环境与沙箱环境是否混用。
  5. 调用 alipay.open.auth.token.app.query 验证令牌状态。
  6. 确认商家是否解除授权、重新授权或变更了授权关系。
  7. 令牌过期时使用刷新令牌更新。无法刷新时,重新发起商家授权。
  8. 清理 Redis、本地缓存和配置中心中的旧令牌,然后重新生成支付表单。

其他注意事项

示例中的 action 属性在网关地址前多了一个空格:

action=" https://openapi.alipay.com/gateway.do?..."

浏览器可能会自动容错,但仍建议去掉这个空格。它通常不会直接导致 invalid-app-auth-token,却可能让不同浏览器或中间组件产生不一致的处理结果。

另外,不要在日志、工单或公开页面中完整展示 app_auth_token。如果问题描述中的令牌是真实的生产令牌,应立即检查其使用情况,并在必要时刷新令牌或重新授权。日志中只需保留首尾少量字符,例如:

202407BB****70X62

排查时,应先核对服务商应用 AppID、授权商户和应用授权令牌之间的绑定关系。只有授权关系有效且环境一致,alipay.trade.wap.pay 才能通过服务商代调用模式正常创建支付页面。

备注:内容仅供参考。