{"id":"a71c842f-b587-4571-8b70-5c1ef586c9c9","task":"Implement the Shopify Customer Account API OAuth flow in a headless storefront to authenticate buyers without classic customerAccessToken","domain":"shopify.dev","steps":["Register a Customer Account API client in the Shopify Partners dashboard under your app's Customer Account settings; configure the redirect URI to your storefront's callback route (e.g., /account/callback)","Generate a PKCE code_verifier and code_challenge (SHA-256 hash, base64url encoded) in the login route; store the code_verifier in the session and redirect the customer to the Shopify authorization URL with client_id, response_type=code, redirect_uri, scope, state, and code_challenge","In the callback route validate the returned state matches the session state (CSRF protection), then POST to the Shopify Customer Account API token endpoint with grant_type=authorization_code, code, redirect_uri, client_id, and code_verifier to exchange the code for access and refresh tokens","Store the access_token, refresh_token, and expires_at in an encrypted session cookie; the access_token is a JWT scoped to the customer's account — do not store it client-side","Use the access_token as a Bearer token in the Authorization header when calling the Customer Account API GraphQL endpoint to query customer orders, profile, and addresses","Implement token refresh: when expires_at is within a threshold, use the refresh_token with grant_type=refresh_token to get a new access_token before the current request fails"],"gotchas":["The Customer Account API uses a different GraphQL endpoint and authentication scheme than the Storefront API — the two are separate; do not send a Customer Account API token to the Storefront API or vice versa","PKCE is mandatory for the Customer Account API OAuth flow; the old customerAccessTokenCreate mutation on the Storefront API uses a password-based grant and is a different (legacy) mechanism — they are not interchangeable","The Customer Account API access_token is short-lived; failing to refresh it proactively causes customer-facing errors mid-session — implement refresh in a middleware or loader that runs before any authenticated request"],"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:23.292Z"},"url":"https://mcp.waymark.network/r/a71c842f-b587-4571-8b70-5c1ef586c9c9"}