PAYATHON 2026

支付宝第三方应用的 app_auth_token 是否需要保存?

支付老李

结论

app_auth_token 需要及时记录并安全保存。还要一并保存返回的 app_refresh_token、授权商户标识和有效期。

分几种情况:

  • app_auth_token 尚未过期:可以直接用它代商户调用接口。
  • app_auth_token 丢失,但有效的 app_refresh_token 仍在:通常可以通过刷新令牌重新获取,不需要商户再次授权。
  • app_auth_token 和 app_refresh_token 都丢失:支付宝一般不提供根据商户 ID 直接查询或找回明文令牌的接口。原授权码失效后,通常只能请商户重新完成授权。
  • 刚完成授权,但还没有兑换令牌:只要 app_auth_code 仍然有效且未被使用,就可以继续兑换;如果已经过期或使用过,就不能再用它获取令牌。

因此,不能把“以后再从支付宝查回来”当作容错方案。

为什么必须保存

app_auth_token 表示商户允许第三方应用代其调用接口。第三方应用调用需要商户授权的开放接口时,必须携带该令牌。

授权流程大致如下:

  1. 商户进入第三方应用的支付宝授权页面。
  2. 商户确认授权。
  3. 支付宝回调第三方应用,并返回 app_auth_code。
  4. 第三方应用使用 app_auth_code 调用 alipay.open.auth.token.app。
  5. 支付宝返回 app_auth_token、app_refresh_token 和有效期等信息。
  6. 第三方应用保存令牌,供后续接口调用使用。

app_auth_code 是短期的一次性凭证,不适合长期保存或反复兑换。需要持久化的是兑换后得到的令牌信息。

推荐的保存字段

建议至少保存以下内容:

auth_app_id
user_id
app_auth_token
app_refresh_token
expires_in
re_expires_in
app_auth_token_expires_at
app_refresh_token_expires_at
updated_at

实际字段应以当前使用的支付宝接口文档和 SDK 响应为准。有效期最好根据接口返回值计算,不要写死在代码中。

如果同一个第三方应用获得了多个商户的授权,应按“第三方应用 + 授权商户”建立唯一关系,防止不同商户的令牌相互覆盖。

获取并保存令牌

下面是支付宝 Java SDK 的常见调用方式。不同 SDK 版本的类名或方法签名可能略有差异,请以项目实际依赖的版本为准。

AlipayOpenAuthTokenAppRequest request =
        new AlipayOpenAuthTokenAppRequest();

AlipayOpenAuthTokenAppModel model =
        new AlipayOpenAuthTokenAppModel();

model.setGrantType("authorization_code");
model.setCode(appAuthCode);
request.setBizModel(model);

AlipayOpenAuthTokenAppResponse response =
        alipayClient.execute(request);

if (!response.isSuccess()) {
    throw new IllegalStateException(
        "获取授权令牌失败: " + response.getSubCode()
        + " - " + response.getSubMsg()
    );
}

// 应在返回授权回调的处理流程中立即持久化
saveOrUpdateToken(
    response.getAuthAppId(),
    response.getUserId(),
    response.getAppAuthToken(),
    response.getAppRefreshToken(),
    response.getExpiresIn(),
    response.getReExpiresIn()
);

保存时最好使用事务或原子更新。只有数据库写入成功,才能认为授权接入已经完成。

使用刷新令牌重新获取

如果 app_auth_token 丢失或即将过期,而有效的 app_refresh_token 仍然存在,可以再次调用 alipay.open.auth.token.app:

AlipayOpenAuthTokenAppRequest request =
        new AlipayOpenAuthTokenAppRequest();

AlipayOpenAuthTokenAppModel model =
        new AlipayOpenAuthTokenAppModel();

model.setGrantType("refresh_token");
model.setRefreshToken(savedAppRefreshToken);
request.setBizModel(model);

AlipayOpenAuthTokenAppResponse response =
        alipayClient.execute(request);

if (!response.isSuccess()) {
    throw new IllegalStateException(
        "刷新授权令牌失败: " + response.getSubCode()
        + " - " + response.getSubMsg()
    );
}

// 刷新后应以本次响应为准,更新全部令牌和有效期
saveOrUpdateToken(
    response.getAuthAppId(),
    response.getUserId(),
    response.getAppAuthToken(),
    response.getAppRefreshToken(),
    response.getExpiresIn(),
    response.getReExpiresIn()
);

刷新后,应以本次响应为准更新全部令牌和有效期。如果响应中返回了新的 app_refresh_token,必须同时覆盖旧值,不能只更新 app_auth_token。

两个令牌都丢失怎么办

可以按以下顺序排查:

  1. 检查数据库备份、密钥管理系统和历史数据迁移记录。
  2. 确认原 app_auth_code 是否仍然有效且从未兑换。
  3. 如果还保存着 app_refresh_token,使用刷新模式重新获取。
  4. 如果所有有效凭证都已丢失,重新生成授权链接,请商户再次完成授权。

商户与第三方应用之间的授权关系可能仍然存在,但这不代表第三方应用可以在没有凭证的情况下取回令牌。出于授权安全考虑,仅凭商户 ID、支付宝账号或应用 ID,无法静默恢复 app_auth_token。

注意事项

  • 不要将 app_auth_token 或 app_refresh_token 输出到普通日志、错误页面或监控系统的明文字段中。
  • 数据库中的令牌应加密存储,并严格限制读取权限。
  • 根据接口返回的有效期安排提前刷新,避免令牌到期后业务突然中断。
  • 刷新令牌时需要处理并发,防止多个任务同时刷新并相互覆盖结果。
  • 商户解除授权、授权范围发生变化或应用状态异常时,即使令牌还没有达到预计过期时间,也可能无法继续调用接口。
  • 调用具体业务接口时,需要按照支付宝 SDK 的要求传入 app_auth_token。不同语言和 SDK 版本的传参位置可能不同。
  • 令牌交换或刷新失败时,应保存 code、sub_code、sub_msg 等非敏感错误信息,方便排查问题,但不要记录完整令牌。

备注:内容仅供参考。