Step 4: Refresh token

To get a refresh token, you must include the offline_access scope when you initiate an authentication request through the authorize endpoint. To refresh your access token, using the Refresh Token you already got during authorization, make a POST request to the token endpoint. Read more here. 

Step 4: Keep the session alive by using the refresh token

Whenever an access_token is required to access a protected resource, a client may use a refresh_token to get a new Access Token issued by the Authentication Server. Although access_token can be renewed at any time using refresh_tokens, they should be renewed when old ones have expired, or when getting access to a new resource for the first time. When the access_token expires, the refresh_token can be used to obtain a fresh access_token with the same permissions, without further involvement from a user. When the access_token expires, you can use the refresh_token to get a new access_token by using the token endpoint as shown below:

Sample request:

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

Explanation of parameters:

Parameter Description Value Required
A way to specify how the client will interact with the server Must be set to "refresh_token" Yes
refresh_token The refresh token to be used The existing refresh token  Yes
client_id The client_id that you received by zip file This is not the same as the MerchantID or the e-mail log-in to The client_id given in the zip file Yes
client_secret The client_secret that you received by zip file.  The client_secret given in the zip file.  Yes

Refresh_tokens are long-lived. This means when a client gets one from a server, this token must be stored securely to keep it from being used by potential attackers. Therefore, it is not safe to store them in the browser. If a refresh_token is leaked, it may be used to obtain new access_tokens (and access protected resources) until it is blacklisted or invalidated.
To get a refresh_token , you must include the offline_access scope when you initiate an authorization request through the authorize endpoint. Read more about the Authorization Request here

If the refresh token is valid, then you get back a new access token :

    "id-token" : "MIOf-U1zQbyfa3[...]MUfJHhvnUqIut9ClH0xjlDXGJAyqo"
    "access_token": "eyJhbGciOiJ[...]K1Sun9bA",
    "token_type": "Bearer",
    "expires_in": 300,
    "token_type": "Bearer",
    "refresh_token": "MIOf-U1zQbyfa3[...]MUfJHhvnUqIut9ClH0xjlDXGJAyqo"
Invalid tokens  

 If you make an API call using an invalid token, you will receive a "401 Unauthorized" response back from the server.  A token could be invalid and in need of regeneration if:

  • It has expired.
  • The user has revoked the permission they initially granted 
  • You have changed the (scope) your application is requesting.
  • A subsequent OpenID Connect flow that generated a new access token. The previous token will be invalidated if running Single Use tokens.

You should only ask for a new token if the access_token has expired or you want to refresh the claims contained in the ID Token. For example, it's a bad practice to call the endpoint to get a new access_token every time you call an API, if you already have an active access_token. 

Refresh tokens can expire but are long-lived. They are subject to strict storage requirements to ensure they are not leaked.  Since a predictable expiry time is not the only contributing factor to token invalidation, it is very important that you code your applications to properly handle an encounter with a 401 error by redirecting the user back to the start of the authorization workflow.

PKCE / Code Challenge

For more information on the PKCE protocol and the security considerations, see IETF RFC 7636

MobilePay supports the Proof Key for Code Exchange protocol to make the authorization flow more secure. A unique code verifier is created for every authorization request, and its transformed value, called "code_challenge", is sent to the authorization server to obtain the authorization code. Example:  C# example. Note that it is hidden in the framework. This line calls a IdentityModel feature which automatically uses PKCE. 


  • code verifier: A cryptographically random string that is used to correlate the authorization request to the token request. The client creates a one-time secret (code verifier)  that is used to generate a code challenge
  • code challenge: A challenge derived from the code verifier that is sent in the authorization request, to be verified against later. Code challenge is also referred to as the code that you generated, and made cryptographically secure and sent to us in /authorize endpoint property code challenge. 
PKCE Parameters

A random value of 43-128 characters. Created by the client. Stored on the server upon an authorization request.

The recommended value is a 32-octet sequence that is base64url-encoded to create a 43-octet URL safe string.


The code challenge method used to generate the code challenge value.

  • S256 – SHA256 encoding is performed: code_challenge=base64url(sha256(code_verifier))
code_challenge Value based on the code_verifier and the code_challenge_method.
private string CreateCodeChallenge()
    _codeVerifier = RandomNumberGenerator.CreateUniqueId();
    var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha256);
    var challengeBuffer = sha256.HashData(
    byte[] challengeBytes;
    CryptographicBuffer.CopyToByteArray(challengeBuffer, out challengeBytes);
    return Base64Url.Encode(challengeBytes);

Here is how IdentityServer do the validation: 

  • var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier);
  • var hashedBytes = codeVerifierBytes.Sha256();
  • var transformedCodeVerifier = Base64Url.Encode(hashedBytes);
  • return TimeConstantComparer.IsEqual(transformedCodeVerifier.Sha256(), codeChallenge);

If you get an error that the code challenge is either too short or too long, please update the value of code_challenge to meet the requirements and try again. Regarding code_verifier, it has the same length requirements as code challenge.  

  • CodeChallengeMinLength = 43
  • CodeChallengeMaxLength = 128

The method for calculating code_challenge is base64urlencoder(Sha256(code_verifier)) when challenge method is S256. 

How Can Access be Revoked?

It might be useful for you to know, what happens in theory, if your merchant decides to revoke the consent. 

  • The merchant can revoke the consent for the Integrator. It's done from the MobilePay Portal, specifically the menu item Settings → Integration. The Tab is empty if no consent is granted.  The merchant needs to have a SuperManager role in the MobilePay Portal in order to be allowed to remove the consent.
  • Subscriptions and Invoice merchants should have max one integrator. When the integrator has been granted consent, the integrator will be able to retrieve information about the Subscriptions Provider, and make API calls on behalf of the merchant. 
  • Access can be revoked at any time by the merchant though, and once consent is revoked, the integrator won't be able to access merchant data with their token, nor will they be able to refresh the token.  
  • If the merchant is changing from one integrator to another, the consent process should be coordinated between the merchant and the new integrator. The merchant will need to go through the authorize process again, as per documentation here

Revoke consent

Safely Storing Credentials

Keeping credentials secure is important. Please consider these safety suggestions when working with the MobilePay platform.   


Previous step Best Practice