Setup: App migrated from non-expiring offline access tokens to expiring offline access tokens, following the migration guide. Stack: Ruby on Rails, using shopify_app 23.0.2 and shopify_api 16.2.0.
Issue: For multiple shops, after calling grant_type=refresh_token against POST /admin/oauth/access_token, the refresh_token returned in the response appears to have an expiry far shorter than the documented 90-day lifetime.
Timestamps (JST) — example from one of the affected shops:
Refresh call made at (approx.): 2026-07-02 12:00:12 (JST)
New access_token expires_at: 2026-07-02 13:00:11.553141 (JST)
New refresh_token expires_at: 2026-07-02 12:00:13.553145 (JST)
The new refresh_token expires about 1 hour before the new access_token — essentially only ~1 second after the refresh call itself — instead of ~90 days later. We’ve confirmed this pattern across several different shops, not an isolated case.
We reviewed our shopify_app gem integration and confirmed it simply persists whatever refresh_token value comes back in Shopify’s response, with no client-side recalculation of the expiry. Given that, we believe this is likely an issue on Shopify’s side (i.e., the value actually returned by the token endpoint for these refreshes), rather than a bug in our storage logic.
Could someone from the Shopify team please look into this?