{"record":{"id":"7f45d08a71f48309","repo":"justauth/JustAuth","slug":"submsg-7f45d0","errorCode":null,"errorMessage":"${subMsg}","messagePattern":"\\$\\{subMsg\\}","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java","lineNumber":161,"sourceCode":"    protected void checkCode(AuthCallback authCallback) {\n        if (StringUtils.isEmpty(authCallback.getAuth_code())) {\n            throw new AuthException(AuthResponseStatus.ILLEGAL_CODE, source);\n        }\n    }\n\n    @Override\n    public AuthToken getAccessToken(AuthCallback authCallback) {\n        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();\n        request.setGrantType(\"authorization_code\");\n        request.setCode(authCallback.getAuth_code());\n        AlipaySystemOauthTokenResponse response;\n        try {\n            response = this.alipayClient.execute(request);\n        } catch (Exception e) {\n            throw new AuthException(e);\n        }\n        if (!response.isSuccess()) {\n            throw new AuthException(response.getSubMsg());\n        }\n        return AuthToken.builder()\n            .accessToken(response.getAccessToken())\n            .uid(response.getUserId())\n            .expireIn(Integer.parseInt(response.getExpiresIn()))\n            .refreshToken(response.getRefreshToken())\n            .build();\n    }\n\n    /**\n     * 刷新access token （续期）\n     *\n     * @param authToken 登录成功后返回的Token信息\n     * @return AuthResponse\n     */\n    @Override\n    public AuthResponse<AuthToken> refresh(AuthToken authToken) {\n        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java#L143-L179","documentation":"Thrown when Alipay returns a non-success AlipaySystemOauthTokenResponse during the authorization-code exchange (grant_type=authorization_code) in public-key mode. The message is Alipay's subMsg, e.g. 'invalid code' or 'code been used'.","triggerScenarios":"AuthAlipayRequest.getAccessToken with an auth_code that is expired (valid ~5 minutes), already redeemed (auth codes are single-use), or issued for a different appId; clock skew can also invalidate codes.","commonSituations":"Replaying the callback URL (refresh or retry after an error) after the code was already consumed; delays between callback and token exchange exceeding 5 minutes; redirect URI mismatch between authorize and token calls.","solutions":["Never exchange the same auth_code twice — if the first exchange may have succeeded, persist the token instead of retrying the exchange","Process the callback immediately; Alipay auth codes expire in about 5 minutes","Ensure the appId/redirectUri used at authorize time matches the one at token-exchange time","Check the subMsg: 'aop.INVALID_CODE' or 'auth code is invalid' means re-authorization is required"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (StringUtils.isEmpty(callback.getAuth_code())) {\n    throw new IllegalStateException(\"missing auth_code — cannot exchange\");\n}\nlong ageMs = System.currentTimeMillis() - callbackReceivedAt;\nif (ageMs > 4 * 60 * 1000) {\n    // Alipay auth codes expire ~5 min; re-authorize instead of exchanging\n    return redirectToAuthorize(ALIPAY);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return alipayRequest.getAccessToken(callback);\n} catch (AuthException e) {\n    if (e.getMessage() != null && e.getMessage().toLowerCase().contains(\"code\")) {\n        // code used/expired — cannot recover; new authorization required\n        return redirectToAuthorize(ALIPAY);\n    }\n    throw e;\n}","preventionTips":["Exchange the auth_code exactly once, immediately upon callback","Persist the token atomically right after a successful exchange so retries never re-exchange","Queue webhook callbacks if processing may delay past the 5-minute window"],"tags":["alipay","oauth","auth-code","single-use"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}