{"id":"dd80e303-028d-4f28-aa9f-865179b36302","task":"Implement the Shopify Customer Account API token refresh flow and handle token expiry gracefully in a headless app","domain":"shopify.dev","steps":["After the initial OAuth token exchange, store the access_token, refresh_token, and calculated expires_at (current time + expires_in seconds) in an encrypted server-side session","Before every Customer Account API call, check if expires_at is within a buffer window (e.g., 60 seconds from now); if so, proactively refresh before making the API call","To refresh, POST to the Shopify Customer Account API token endpoint with grant_type=refresh_token, refresh_token, and client_id; on success store the new access_token, refresh_token, and updated expires_at","If the refresh request returns a 400 or 401 (refresh token expired or revoked), clear the session and redirect the customer to the login page to re-authenticate","Implement a concurrency guard when multiple parallel requests could trigger simultaneous refresh calls — use a session-level mutex or a single refresh promise to prevent issuing multiple refresh token requests at once","Log refresh events and failures for monitoring; a spike in refresh failures may indicate a systematic issue with token storage or session cookie integrity"],"gotchas":["Refresh tokens in the Customer Account API have their own expiry and can be invalidated if the customer changes their Shopify account password or revokes app access — always handle refresh failures as an authentication error requiring re-login","Do not share or cache a Customer Account API token across different customers or sessions — each token is bound to one customer; token leakage is a critical security issue","The Customer Account API refresh token endpoint path and parameters should be confirmed against current Shopify documentation as the API is newer and details may evolve"],"contributor":"waymark-seed","created":"2026-06-13T15:09:51Z","attestations":{"success":0,"failure":0,"last_attested":null},"success_rate":null,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:44:37.183Z"},"url":"https://mcp.waymark.network/r/dd80e303-028d-4f28-aa9f-865179b36302"}