justauth/JustAuth · error · AuthException
${subMsg}
Error message
${subMsg} What it means
After certificateExecute returns, AuthAlipayCertRequest.getAccessToken checks response.isSuccess(); on failure it throws AuthException with the response's subMsg — Alipay's own business-error description (e.g. invalid code, wrong grant type, app not authorized for the oauth API). This is a rejected token exchange, i.e. Alipay processed the request and said no.
Source
Thrown at src/main/java/me/zhyd/oauth/request/AuthAlipayCertRequest.java:63
protected void checkCode(AuthCallback authCallback) {
if (StringUtils.isEmpty(authCallback.getAuth_code())) {
throw new AuthException(AuthResponseStatus.ILLEGAL_CODE, source);
}
}
@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode(authCallback.getAuth_code());
AlipaySystemOauthTokenResponse response;
try {
response = this.alipayClient.certificateExecute(request);
} catch (Exception e) {
throw new AuthException(e);
}
if (!response.isSuccess()) {
throw new AuthException(response.getSubMsg());
}
return AuthToken.builder()
.accessToken(response.getAccessToken())
.uid(response.getUserId())
.expireIn(Integer.parseInt(response.getExpiresIn()))
.refreshToken(response.getRefreshToken())
.build();
}
/**
* 刷新access token (续期)
*
* @param authToken 登录成功后返回的Token信息
* @return AuthResponse
*/
@Override
public AuthResponse<AuthToken> refresh(AuthToken authToken) {View on GitHub (pinned to 694bbf1b01)
Solutions
- Read subMsg literally (e.g. '无效的授权码' = auth_code invalid/consumed) and match to the fix: re-authorize the user instead of reusing the code.
- Confirm the Alipay open-platform app has the user-info product signed and the gateway environment (sandbox/prod) matches the credentials.
- Ensure AuthConfig.clientId equals the appId that generated the auth_code.
- Process the callback exactly once; make the token exchange idempotent by storing the resulting token keyed on code.
Example fix
// before // user re-opens the callback URL -> same auth_code exchanged twice -> subMsg exception // after // idempotent callback: key on auth_code AuthToken cached = tokenStore.byCode(cb.getAuth_code()); if (cached != null) return ok(cached); AuthToken t = request.getAccessToken(cb); tokenStore.save(cb.getAuth_code(), t); return ok(t);
Defensive patterns
Strategy: try-catch
Validate before calling
// idempotency guard: never exchange the same auth_code twice
if (tokenStore.find(cb.getAuth_code()) != null) { return ok(tokenStore.find(cb.getAuth_code())); } Try / catch
try { return request.getAccessToken(cb); } catch (AuthException e) { log.warn("Alipay rejected token exchange: {}", e.getMessage()); return restartAlipayAuthorize(); } Prevention
- Make the auth_code exchange idempotent by caching results keyed on the code.
- Confirm the Alipay app has the oauth/user-info product enabled and environment matches (sandbox vs prod).
- Ensure AuthConfig.clientId equals the appId that issued the code.
- Do not auto-retry business rejections — send the user back to authorize.
When it happens
Trigger: Exchanging an auth_code that was already used or expired; the app lacks the 获取会员信息 (user info) capability or is_au not enabled so AlipaySystemOauthTokenRequest is refused; app_id mismatch between the code's app and the configured app; refresh-style grant on a code grant request.
Common situations: User refreshes the callback URL causing code reuse; Alipay app not signed/approved for the oauth scope in production while it worked in sandbox; wrong appId in AuthConfig relative to the app that issued the code.
Related errors
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/9a50ab2d4d43392f.
Report an issue: GitHub.