Square OAuth Token Lifecycle, Refresh Token Expiry, and Reauthorization Process

Hi Square Team,

I’m looking for some clarification regarding OAuth token lifecycle and refresh token expiration for our integration.

For context, we have built a platform that supports multiple restaurants/merchants. Merchants connect their Square account to our platform, after which we:

  • Pull their Square Catalog/menu into our system.
  • Allow customers to browse and select items through our application.
  • Create/place orders through Square.
  • Process payments using Square Terminal.

We previously confirmed with Square that OAuth is the recommended authentication method for this type of multi-merchant integration, rather than merchants providing personal access tokens.

Our plan is to implement the standard OAuth flow and securely store the merchant’s access token and refresh token. When the access token expires, we would use the refresh token to obtain a new access token.

I would like to clarify what happens when the refresh token itself expires.

  1. What is the current expiration period/lifetime of a Square OAuth refresh token?
  2. When we use a refresh token to obtain a new access token, does Square also issue a new refresh token that we should replace the previous one with?
  3. If the refresh token eventually expires or becomes invalid, does the merchant need to go through the OAuth authorization/consent flow again to reconnect their Square account?
  4. Is there a recommended token-refresh strategy we should follow to prevent a merchant’s integration from unexpectedly becoming disconnected?
  5. Are there any other token lifecycle or rotation best practices Square recommends for a production multi-merchant platform?

We want to make sure we implement the OAuth flow correctly so merchants do not have to reconnect their Square accounts unnecessarily.

Thank you.

  1. It depends on which OAuth flow you use (assuming authorization code, if not you should):
    1. Authorization-code flow (with client_secret): the refresh token is multi-use and does not expire unless the merchant or you revoke it.
    2. PKCE flow (no client_secret): the refresh token is single-use and expires after 90 days. Each refresh returns a new one.
  2. Authorization-code flow: No, Square returns the same refresh token. You keep reusing it.
    1. PKCE flow: Yes, Square returns a new single-use refresh token each time. You must store and use the new one atomically.
  3. Yes. If the refresh token is permanently invalidated (revocation, or expiry in PKCE), the merchant must go through the full OAuth consent flow again to reconnect. There is a 15-day grace window after an access token expires during which the refresh token can still be used after that window, it’s permanently invalid and re-authorization is the only fix.
  4. Square recommends refreshing access tokens every 7 days or less, well before the 30-day expiration.
    1. Subscribe to the oauth.authorization.revoked webhook.
    2. Do not pass a scopes field on the refresh call unless you intentionally want to reduce permissions. Omitting it preserves all originally granted scopes. Passing a subset silently drops permissions.
    3. Monitor your refresh job for silent failures. If it skips cycles and the access token expires, you have only the 15-day grace period before re-auth is required.
  5. Additional best practices for a multi-merchant platform
    1. Use one Square application for your platform
    2. Follow least-privilege scopes because the consent screen shows exactly what you request.
    3. Pass session=false on production OAuth URLs so multi-account sellers pick the correct account.
    4. Be aware that rotating your app’s OAuth secret does not revoke existing tokens, it only blocks new grants/refreshes. Existing tokens continue working for up to 30 days.