client_secret y nunca lo expone a un navegador.
Paso 1: mandá al comerciante a autorizar
Generá uncode_verifier aleatorio (43 a 128 caracteres de A-Z a-z 0-9 - . _ ~), calculá su code_challenge (SHA-256 en base64url, sin padding) y guardá el verifier y el state en la sesión del comerciante.
Parámetros de GET /oauth/apps/authorize:
Commercy muestra la pantalla de consentimiento (la solicitud vence a los 10 minutos). Quien autoriza tiene que ser el dueño de la tienda (el usuario con rol Admin de la cuenta principal), no un usuario de su equipo. Al terminar:
- Si acepta, redirige a tu
redirect_uricon?code=...&state=.... - Si rechaza, redirige con
?error=access_denied&state=.... - Si algún parámetro es inválido pero el
client_idy laredirect_urison correctos, redirige a turedirect_uricon?error=...&error_description=...&state=...(por ejemploinvalid_request,invalid_scopeounsupported_response_type). - Si el
client_ido laredirect_urison inválidos, nunca redirigimos a la URL recibida: el comerciante ve una pantalla de error en Commercy.
state de la vuelta sea el que mandaste.
Paso 2: canjeá el code por tokens
POST /oauth/apps/token. Autenticá tu app con client_secret_basic (header Authorization: Basic base64(client_id:client_secret)) o client_secret_post (client_id y client_secret en el cuerpo). El cuerpo puede ser application/x-www-form-urlencoded o JSON.
Respuesta
200:
installation_id identifica la instalación de tu app en esa tienda y store.id es el comercio. Guardalos junto con los tokens, cifrados.
Si el comerciante vuelve a autorizar tu app mientras ya está instalada, la instalación conserva y amplía sus scopes (nunca se reducen en silencio) y los refresh tokens anteriores quedan invalidados.
Paso 3: usá y renová el access token
Mandá el access token en cada request a la API:Authorization: Bearer <access_token>. Cuando venza (o recibas 401 invalid_token), renovalo con el refresh token:
La respuesta tiene el mismo formato que el canje y trae un refresh token nuevo. Guardalo y descartá el anterior.
Refresh rotativo y reuso
Cada refresh token se puede usar una sola vez. Si alguien presenta un refresh token que ya se usó, lo tratamos como una posible filtración: revocamos toda la familia de tokens y la instalación pasa a estar revocada, así que el comerciante tiene que reinstalar la app. Excepción: si el token usado se vuelve a presentar dentro de los 10 segundos, respondemosinvalid_grant pero no revocamos. Eso cubre el caso típico de dos workers tuyos refrescando a la vez. Aun así, serializá los refresh: un solo proceso renueva y los demás esperan.
Revocar tokens
POST /oauth/apps/revoke con la misma autenticación de cliente y el campo token (un refresh token o un access token). Sigue el RFC 7009: responde 200 {} aunque el token no exista.
Revocar invalida los tokens de la instalación (la API empieza a responder 401 invalid_token), pero no la desinstala: para volver a operar el comerciante tiene que autorizar de nuevo.
Desinstalación
El comerciante puede desinstalar tu app desde su panel de Commercy. Tu app recibe el webhook obligatorioapp.uninstalled, y a las 48 horas store.redact si no se reinstaló (ver Webhooks).
Cuando necesitás más scopes
Si ampliás los scopes de tu app, el cambio pasa por revisión (ver Revisión y publicación). Una vez aprobado, los comerciantes ya instalados siguen con los scopes anteriores hasta que vuelvan a pasar por/authorize, donde ven y aceptan los permisos nuevos.
Errores del endpoint de token
Estos endpoints responden con el formato de OAuth (RFC 6749), no con el envelope de la API:
Límites: 300 requests por minuto por
client_id en /token y en /revoke, y 10 intentos fallidos de autenticación de cliente cada 10 minutos por combinación client_id + IP. Al excederlos recibís 429 con el header Retry-After y un cuerpo { "error": "Too many requests", "retryAfter": 30 }.