Legacy token migration flow

United States
Canada

Developers who have an app with a non-expiring token need to exchange their app’s legacy API token for an expiring access and refresh token pair. The token migration flow includes the option to use Proof key for code exchange (PKCE).

Token migration flow with PKCE option

Token migration flow

Token migration flow

Migrate legacy tokens

🚧

IMPORTANT

The following values for access and refresh tokens are dynamic and can change:

  • Token expiration displays in the response body. Tokens created later can have different durations until they expire.
  • Token lengths are not fixed.

Do not hard code access and refresh token expirations or lengths so that you can handle any future updates.

To exchange a legacy token for a new access and refresh token pair:

StepWho/whatWhat
1Developer appIf using PKCE, generate a code_verifier and code_challenge using the method of your choice.
2Developer appRequest an authorization code.

Send a POST request to /oauth/token/migrate_v2. Include the merchant ID, app ID, legacy API token, and if using PKCE, code challenge in the request body.

Request
POST /oauth/token/migrate_v2

Request body
{
    "merchant_uuid": "{MERCHANT_ID}",
    "app_uuid": "{APP_ID}",
    "auth_token": "{LEGACY_API_TOKEN}"
    "code_challenge": "{CODE_CHALLENGE}"
}
3Clover backendReturn authorization code.

Sample response body
{
    "authorization_code": "{AUTHORIZATION_CODE}",
    "expiration": 1678489882
}
4Developer appRequest an access token pair.

Send a POST request to /oauth/v2/token. Include the client ID, client secret (if a high trust app), auth code, and if using PKCE, code verifier in the request body.

Request
POST /oauth/v2/token

Request body
{
    "client_id": "{APP_ID}"
    "client_secret": "{APP_SECRET}", -> If a high trust app
    "code": "{AUTHORIZATION_CODE}",
    "code_verifier": "{CODE_VERIFIER}" -> If using PKCE
}
5Clover backendReturn new access and refresh tokens.

Sample response body
{
    "access_token": "{ACCESS_TOKEN}",
    "access_token_expiration": 1677875430,
    "refresh_token": "{REFRESH_TOKEN}",
    "refresh_token_expiration": 1709497830
}
Note: The response body indicates when the access and refresh tokens expire. The expiration dates are represented as Unix timestamps.

📘

NOTE

See Sandbox and production environments URLs about which URLs to use in the requests.