Authorization Code Flow

Authorization Code Flow

Use the OpenID Connect authorization code flow to authenticate a user with TBC ID and obtain tokens for your application.


Before You Start

Choose either the sandbox or production environment and use it for every step of the flow.

Check the environment's OpenID Provider configuration to confirm that the authorization code flow is available.

If using PKCE, generate a high-entropy code_verifier, derive a code_challenge from it using a supported method (S256 is recommended), and securely retain the verifier until the token exchange.

Process

  1. Prepare the request. Create a fresh, unpredictable state value bound to the user's session. If an ID token is expected, also create a fresh nonce. Add a claims object to request the user claims your application needs from the UserInfo endpoint; request only claims supported by the provider. If using PKCE, generate and retain the code_verifier and corresponding code_challenge.
  2. Start authorization. Redirect the user's browser to the authorization endpoint, including the registered client_id and redirect_uri, response_type=code, the requested scopes including openid, and applicable security and optional parameters.
  3. Follow the consent redirect. The authorization endpoint returns 302 Found with the consent page URL in the Location header. Redirect the user's browser there so they can approve or decline the request.
  4. Handle the callback. After the user makes a decision, TBC Bank redirects the browser to the registered redirect_uri with either an authorization code or an error and error_description. Validate the returned state before processing the response. If the user approved, keep the code confidential and exchange it promptly.
  5. Exchange the code. Send the code to the token endpoint along with the required form parameters. If using PKCE, include the original code_verifier.
  6. Use the tokens. Validate the token response and the ID token, including its signature, issuer, audience, expiration, and nonce when applicable. Check that the ID token's acr reflects the authentication class actually performed. Use the access token to call the authorized resource. To retrieve user claims, call the UserInfo endpoint.

Endpoints

ℹ️

Use the same environment throughout the flow.

Authorization Endpoint

Redirect the user's browser to the appropriate endpoint to begin authorization:

Sandbox: https://test-api.tbcbank.ge/psd2/openbanking/oauth/authorize

Production: https://api.tbcbank.ge/psd2/openbanking/oauth/authorize

Send the authorization parameters as query parameters:

ParameterUsage
client_idYour registered client identifier.
response_typeOAuth response type. Set to code for the authorization code flow.
redirect_uriRegistered URI where TBC Bank returns the authorization response. It must match the value registered for your client.
scopeSpace-separated list of requested scopes. Include openid; request only scopes supported for your client.
stateUnpredictable value bound to the user's session. Validate the returned value to correlate the response and protect against request forgery.
nonceFresh, unpredictable value to bind the ID token to this authorization request. Validate the returned ID token's nonce claim when an ID token is issued.
code_challengePKCE challenge derived from the code_verifier. Include it when using PKCE.
code_challenge_methodMethod used to derive the PKCE challenge. Use a method supported by the provider; S256 is recommended.
ui_localesSpace-separated preferred languages for the user interface, such as en or ka, if supported.
claimsJSON object specifying claims to be returned or requirements for claims. Request only claims supported by the provider.

Authorization Response

When the client sends the browser to the authorization endpoint, TBC Bank responds with 302 Found. The Location header points to the TBC ID consent page. Redirect the user's browser to that URL so the user can approve or decline the consent request.

After the user makes a decision, TBC Bank redirects the browser to the registered redirect_uri. The callback response parameters are in the query string:

ResultParameters
Successcode - authorization code to exchange at the token endpoint.
state - returned if it was included in the request.
Declined or other errorerror - error code.
error_description - description of the error.
state - returned if it was included in the request.

Authorization Request Example

The following full sandbox authorization URLs show claims JSON URL-encoded as a query parameter and use generated PKCE S256 challenges. For each request, retain the corresponding code_verifier and send it to the token endpoint when exchanging the authorization code. The client ID, redirect URI, state, nonce, and PKCE values are illustrative; replace them with values for your integration.

Request verified claims with evidence:

https://test-api.tbcbank.ge/psd2/openbanking/oauth/authorize?client_id=PSDGE-NBG-CLIENTID&response_type=code&redirect_uri=https%3A%2F%2Fclient.example.com%2Foidc%2Fcallback&scope=openid&state=2f12c8a7e93b4a6d9f03c1b8a752e641&nonce=a9614e3cb20d48f789d12a5f6c03be72&code_challenge=gqFLPA3W4wy80L0RywimLYQtIC64vibf7iK8n9-nhlc&code_challenge_method=S256&claims=%7B%22userinfo%22%3A%7B%22verified_claims%22%3A%7B%22verification%22%3A%7B%22trust_framework%22%3Anull%2C%22time%22%3Anull%2C%22evidence%22%3A%5B%7B%22type%22%3A%7B%22value%22%3A%22document%22%7D%2C%22document_details%22%3A%7B%22type%22%3Anull%2C%22issuer%22%3A%7B%22country%22%3A%22GE%22%2C%22name%22%3Anull%7D%2C%22document_number%22%3Anull%2C%22date_of_issuance%22%3Anull%2C%22personal_number%22%3Anull%7D%2C%22method%22%3Anull%7D%5D%7D%2C%22claims%22%3A%7B%22given_name%22%3Anull%2C%22family_name%22%3A%7B%22essential%22%3Atrue%7D%2C%22birthdate%22%3Anull%2C%22personal_number%22%3A%7B%22essential%22%3Atrue%7D%2C%22nationalities%22%3Anull%2C%22place_of_birth%22%3A%7B%22essential%22%3Atrue%7D%7D%7D%7D%7D
{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null,
        "time": null,
        "evidence": [
          {
            "type": {
              "value": "document"
            },
            "document_details": {
              "type": null,
              "issuer": {
                "country": "GE",
                "name": null
              },
              "document_number": null,
              "date_of_issuance": null,
              "personal_number": null
            },
            "method": null
          }
        ]
      },
      "claims": {
        "given_name": null,
        "family_name": {
          "essential": true
        },
        "birthdate": null,
        "personal_number": {
          "essential": true
        },
        "nationalities": null,
        "place_of_birth": {
          "essential": true
        }
      }
    }
  }
}

Request verified claims without specifying evidence:

https://test-api.tbcbank.ge/psd2/openbanking/oauth/authorize?client_id=PSDGE-NBG-CLIENTID&response_type=code&redirect_uri=https%3A%2F%2Fclient.example.com%2Foidc%2Fcallback&scope=openid&state=7b4e1c92a6054d3f8f21b7c9e063a542&nonce=c30a8f52d17b49e6a14d90c2f7385b61&code_challenge=8bFW7uBOUWqt1r6PizObj71Mkkh63Jvo4g0ut3qhLq4&code_challenge_method=S256&claims=%7B%22userinfo%22%3A%7B%22verified_claims%22%3A%7B%22verification%22%3A%7B%22trust_framework%22%3Anull%2C%22time%22%3Anull%7D%2C%22claims%22%3A%7B%22given_name%22%3Anull%2C%22family_name%22%3A%7B%22essential%22%3Atrue%7D%2C%22birthdate%22%3Anull%2C%22personal_number%22%3A%7B%22essential%22%3Atrue%7D%2C%22nationalities%22%3Anull%2C%22place_of_birth%22%3A%7B%22essential%22%3Atrue%7D%7D%7D%7D%7D
{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null,
        "time": null
      },
      "claims": {
        "given_name": null,
        "family_name": {
          "essential": true
        },
        "birthdate": null,
        "personal_number": {
          "essential": true
        },
        "nationalities": null,
        "place_of_birth": {
          "essential": true
        }
      }
    }
  }
}

Token Endpoint

After receiving an authorization code at the registered redirect_uri, exchange it for tokens at the appropriate endpoint:

Sandbox: https://test-openbanking.tbcbank.ge/openbanking/oauth/token

Production: https://openbanking.tbcbank.ge/openbanking/oauth/token

Send the parameters as application/x-www-form-urlencoded form data. Authenticate your confidential client using its registered authentication method.

ParameterUsage
grant_typeOAuth grant type. Set to authorization_code.
codeAuthorization code returned to the registered redirect_uri. It is single-use; exchange it promptly.
client_idYour registered client identifier.
redirect_uriThe same redirect URI used in the authorization request.
code_verifierOriginal PKCE verifier corresponding to the code_challenge sent in the authorization request. Include it when using PKCE.

Content-Type: application/x-www-form-urlencoded

Token Response

On success, the token endpoint returns a JSON response (Content-Type: application/json) containing tokens:

ParameterDescription
access_tokenAccess token to present in the authorization header when calling an authorized resource.
token_typeAccess token type.
refresh_tokenRefresh token for obtaining new tokens, if supported for your client. Store it securely and use it only as permitted for your client.
refresh_token_issued_atTime when the refresh token was issued, represented as a Unix timestamp in milliseconds.
refresh_token_expires_inRefresh token lifetime in seconds.
refresh_countRefresh count value returned by TBC Bank.
scopeSpace-separated scopes granted. The example response returns openid.
issued_atTime when the access token was issued, represented as a Unix timestamp in milliseconds.
expires_inAccess token lifetime in seconds.
id_tokenOpenID Connect ID token containing authentication claims. Validate its signature, issuer, audience, expiration, and nonce when applicable before relying on its claims.

If the token request fails, the endpoint returns an error response. Handle the returned error and, if present, error_description; do not treat an error response as a successful token exchange.



Did this page help you?