Refresh, Revoke, and Limit the Scope of OAuth Tokens

When you have the access and refresh tokens for a seller, you must be able to refresh the access token, revoke the tokens, and limit the scope of the tokens if required.

Your application must also provide a mechanism for sellers to view and manage the status of their OAuth tokens and manage the authorization for your application. Typically, this is done with a settings/configuration dashboard in your application.

Your application must accurately show the status of the seller's OAuth access token with Square. The status of the OAuth access token must always be accurate and indicate the correct state of the access token (valid, expired, or revoked). Your application can check the validity of the token by calling ListLocations and checking the response.

Link to section

Refresh the access token

Your application should be able to refresh the access token before it expires in 30 days. Square recommends that your application automatically renew OAuth access tokens every 7 days or less, regardless of whether the seller is actively interacting with your application. Renewing every 7 days or less provides sufficient time to discover and resolve errors. If your application only attempts to refresh tokens near the 30-day expiration date, it increases the risk of missing a failed token refresh and creating a poor experience for sellers or their customers.

Your application should check access tokens when they're retrieved from your database to see whether they're older than 8 days. If this check fails, it should generate a notification (paging or other alerting mechanism) so that you can address any issues with your renewal logic. Silent token renewal failures result in breaking your application integration and potentially causing an outage for your sellers or their customers. For more best practice ideas, see OAuth Best Practices.

Link to section

Refresh token examples

The request format to call ObtainToken to get a refresh token differs between the code flow and PKCE flow.

Code flow refresh token request:

curl https://connect.squareup.com/oauth2/token \ -X POST \ -H 'Square-Version: 2022-04-20' \ -H 'Content-Type: application/json' \ -d '{ "client_id": "<YOUR_APPLICATION_ID>", "grant_type": "refresh_token", "redirect_uri": "<THE REDIRECT URL>", "client_secret": "<YOUR_APPLICATION_SECRET>", "refresh_token": "<CURRENT REFRESH TOKEN>" }'

Code flow refresh token response:

{ "access_token": "<access_token>", "token_type": "bearer", "expires_at": "2022-06-03T22:19:44Z", "merchant_id": "<merchant_id>", "refresh_token": "<SAME REFRESH TOKEN AS REQUEST>", "short_lived": false }

PKCE flow refresh token request:

curl https://connect.squareup.com/oauth2/token \ -X POST \ -H 'Square-Version: 2022-04-20' \ -H 'Content-Type: application/json' \ -d '{ "client_id": "<YOUR_APPLICATION_ID>", "grant_type": "refresh_token", "redirect_uri": "<THE REDIRECT URL>", "refresh_token": "<CURRENT REFRESH TOKEN>" }'

PKCE flow refresh token response:

{ "access_token": "<access_token>", "token_type": "bearer", "expires_at": "2022-06-03T22:19:44Z", "merchant_id": "<merchant_id>", "refresh_token": "<NEW REFRESH TOKEN>", “refresh_token_expires_at”: “2022-08-03T22:19:44Z” "short_lived": false }

A successful call to ObtainToken using the refresh token returns a 200 response code and includes information about the new access token. Use this new access token for calling the Square APIs on the seller's behalf.

Link to section

Revoke the access token

Your application should give the seller the ability to manage their OAuth tokens, including the ability to revoke the OAuth tokens if they choose to. Revoking the OAuth tokens stops your ability to manage resources on behalf of the seller. Your application can call the RevokeToken endpoint to revoke the seller token.

To revoke an access token, you call RevokeToken with the following information:

  • client_secret - Your application's production application secret.
  • access_token - The seller's access token that you want to revoke. You can specify the access token or the merchant_id; you don't need to specify both.
  • client_id - Your application's production application ID.
  • grant_type - refresh_token.
  • refresh_token - The seller's refresh token.

A call to RevokeToken to revoke an access token looks similar to the following:

curl https://connect.squareup.com/oauth2/revoke \ -X POST \ -H 'Square-Version: 2021-07-21' \ -H 'Authorization: Client <YOUR_APPLICATION_SECRET>' \ -H 'Content-Type: application/json' \ -d '{ "access_token": "EAAAEBfiiBO_WTd91g0qlxam5allf6KWIUWvN3U7_-y9PyLR9-_rZbSPMwsbAmb0", "client_id": "sandbox-sq0idb-fGFs-gh_Mm7jMo5r-MZrRA", "revoke_only_access_token": false }'

A successful call to RevokeToken returns a 200 response code and looks similar to the following:

cache-control: max-age=0, private, must-revalidate content-encoding: gzip content-type: application/json date: Fri, 13 Aug 2021 18:24:03 GMT square-version: 2021-07-21 { "success": true }
Link to section

Revoke authorization for a single OAuth access token

The default behavior for the Square RevokeToken endpoint revokes the entire authorization for you to act on the behalf of a seller. However, you might need to revoke a specific access token without terminating the entire seller authorization. For example, if an access token is compromised, you want to revoke the compromised token and generate a new one without requiring a new seller authorization.

The revoke_only_access_token is an optional field in the RevokeToken endpoint. This field lets you revoke a specified OAuth access token without terminating the entire authorization.

A call to RevokeToken to revoke a single access token, but not terminate authorization, looks similar to the following:

curl https://connect.squareup.com/oauth2/revoke \ -X POST \ -H 'Square-Version: 2020-11-18' \ -H 'Authorization: Client <YOUR_APPLICATION_SECRET>' \ -H 'Content-Type: application/json' \ -d '{ "access_token": "ACCESS_TOKEN", "client_id": "CLIENT_ID", "revoke_only_access_token": true }'

A successful call to RevokeToken returns a 200 response code and looks similar to the following:

{ "success": true }
Link to section

Modify the scope and duration of OAuth access tokens

The default expiration for OAuth access tokens was 30 days because credentials were traditionally used from a tightly controlled access environment such as a secure server. As developers expand their use cases to include loosely controlled access environments such as web browsers, mobile applications, and public clients, there's a need for credentials with limited permissions and a shorter lifespan to prevent errors and mitigate risk. The PKCE flow is part of this process. The PKCE flow is designed for public clients and single-page web applications and uses a key exchange process to obtain an access token and uses single-use refresh tokens. For a complete explanation of the PKCE flow, see PKCE flow.

Link to section

Create limited scope OAuth access tokens

If you don't need all the permissions granted by an access token, you can create a new access token that has a reduced set of permissions from the ones granted when the seller approved your authorization. You do this by creating a new access token for the seller using the optional scopes field on the ObtainToken endpoint.

For example, if a seller granted four permissions including MERCHANT_PROFILE_READ, PAYMENTS_READ, PAYMENTS_WRITE, and BANK_ACCOUNTS_READ and you find that you only need two permissions (MERCHANT_PROFILE_READ and PAYMENTS_READ), you can create a new access token with just those two permissions.

A call to ObtainToken to limit the scope of an access token looks similar to the following:

curl https://connect.squareup.com/oauth2/token \ -X POST \ -H 'Square-Version: 2020-11-18' \ -H 'Content-Type: application/json' \ -d '{ "scopes": [ "MERCHANT_PROFILE_READ", "PAYMENTS_READ" ], "grant_type": "refresh_token", "refresh_token": "REFRESH_TOKEN", "client_secret": "APPLICATION_SECRET", "client_id": "APPLICATION_ID" }'

The API response doesn't include a list of scopes. If a 200 response is returned, it can be assumed that the scopes have been added to the newly created OAuth access token. A successful call to ObtainToken returns a 200 response code and looks similar to the following:

{ "access_token": "ACCESS_TOKEN", "token_type": "bearer", "expires_at": "2021-01-02T00:14:15Z", "merchant_id": "MERCHANT_ID", "refresh_token": "REFRESH_TOKEN", "short_lived": false }

Important

The newly created OAuth access token cannot be viewed in the Developer Dashboard. Your application must store this new token for future use.

Link to section

Create short-lived OAuth access tokens

The default expiration for OAuth access tokens is 30 days. A 30-day lifespan isn't appropriate for use in less secure web or mobile clients. The 30-day expiration increases the risk duration for exposure and abuse. When working within loosely controlled access environments such as web browsers or mobile clients, you might prefer a credential with a shorter lifespan to prevent errors and mitigate risk.

The short_lived optional field within the ObtainToken endpoint lets you generate a short-lived access token that expires 24 hours after creation.

To create an access token that expires in 24 hours, call ObtainToken and set the short_lived field to true. The call looks similar to the following:

curl https://connect.squareup.com/oauth2/token \ -X POST \ -H 'Square-Version: 2021-08-18' \ -H 'Content-Type: application/json' \ -d '{ "grant_type": "refresh_token", "refresh_token": "REFRESH_TOKEN", "client_secret": "APPLICATION_SECRET", "client_id": "APPLICATION_ID", "short_lived": true }'

A successful call to ObtainToken returns a 200 response code and looks similar to the following:

{ "access_token": "ACCESS_TOKEN", "token_type": "bearer", "expires_at": "2020-12-04T00:16:17Z", "merchant_id": "MERCHANT_ID", "refresh_token": "REFRESH_TOKEN", "short_lived": true }

Note

The lifespan of the short-lived access token cannot be customized. It always has a 24-hour lifespan.

Link to section

See also