{"record":{"id":"6320ae9f7575161f","repo":"w7corp/easywechat","slug":"failed-to-get-authorization-info-s","errorCode":null,"errorMessage":"Failed to get authorization_info: %s","messagePattern":"Failed to get authorization_info: (.+?)","errorType":"exception","errorClass":"HttpException","httpStatus":null,"severity":"error","filePath":"src/OpenPlatform/Application.php","lineNumber":189,"sourceCode":"\n    /**\n     * @throws HttpException\n     */\n    public function getAuthorization(string $authorizationCode): Authorization\n    {\n        $response = $this->getClient()->request(\n            'POST',\n            'cgi-bin/component/api_query_auth',\n            [\n                'json' => [\n                    'component_appid' => $this->getAccount()->getAppId(),\n                    'authorization_code' => $authorizationCode,\n                ],\n            ]\n        )->toArray(false);\n\n        if (empty($response['authorization_info'])) {\n            throw new HttpException('Failed to get authorization_info: '.json_encode(\n                $response,\n                JSON_UNESCAPED_UNICODE\n            ));\n        }\n\n        return new Authorization($response);\n    }\n\n    /**\n     * @throws HttpException\n     */\n    public function refreshAuthorizerToken(string $authorizerAppId, string $authorizerRefreshToken): array\n    {\n        $response = $this->getClient()->request(\n            'POST',\n            'cgi-bin/component/api_authorizer_token',\n            [\n                'json' => [","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/OpenPlatform/Application.php#L171-L207","documentation":"OpenPlatform\\Application::handleAuthorizationCode() POSTs the one-time authorization_code to cgi-bin/component/api_query_auth and throws HttpException (raw JSON embedded) when authorization_info is missing. The authorization_code is issued once in the auth-callback URL, is single-use, and expires within minutes, so a failed exchange usually means the code was bad, reused, or the component credentials were stale.","triggerScenarios":"Replaying the authorization callback URL (refresh, double-submit, retry job) after the code was consumed; processing the callback later than the code's TTL; stale component_verify_ticket/component_access_token; wrong component appid in the request.","commonSituations":"An admin refreshes the callback page after completing authorization; queue workers process the same callback event twice; dev and prod both consume a code meant for one environment; long delay between WeChat's redirect and the server-side exchange.","solutions":["Decode the embedded errcode/errmsg — invalid/expired code errors mean the authorizer must click through the auth page again","Exchange the code exactly once, immediately inside the callback handler, and persist the returned authorizer tokens","If it was already consumed, restart the flow: createPreAuthorizationCode() and send the authorizer a new pre-authorization URL","For systemic errcodes, fix the component ticket/token layer (see VerifyTicket) before retrying"],"exampleFix":"// before: retrying or refreshing the callback reuses a consumed code\n$auth = $openPlatform->handleAuthorizationCode($authorizationCode);\n\n// after: exchange once and idempotently re-initiate on failure\nif (! $cache->has(\"authcode:{$authorizationCode}\")) {\n    $cache->set(\"authcode:{$authorizationCode}\", 1, 600);\n    $auth = $openPlatform->handleAuthorizationCode($authorizationCode);\n} else {\n    return redirect($openPlatform->createPreAuthorizationUrl($callbackUrl));\n}","handlingStrategy":"try-catch","validationCode":"if ($cache->has(\"authcode:{$authorizationCode}\")) {\n    // already consumed once: skip straight to issuing a new pre-auth URL\n    return redirect($openPlatform->createPreAuthorizationUrl($callbackUrl));\n}","typeGuard":null,"tryCatchPattern":"try {\n    $auth = $openPlatform->handleAuthorizationCode($authorizationCode);\n} catch (\\EasyWeChat\\Kernel\\Exceptions\\HttpException $e) {\n    $payload = json_decode(strstr($e->getMessage(), '{') ?: '[]', true) ?: [];\n    // invalid/expired-code errcodes → send the authorizer a fresh pre-auth URL instead of retrying\n    report($e);\n}","preventionTips":["Exchange the authorization_code exactly once, synchronously in the callback handler","Mark codes consumed in a short-TTL cache to make handler retries idempotent","Persist authorizer tokens immediately after a successful exchange"],"tags":["php","easywechat","wechat","open-platform","authorization","one-time-code","http-error"],"backgroundTag":"one-time-code-exchange-failed","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}