Skip to main content
Las apps de Commercy usan OAuth 2.0 con authorization code + PKCE (S256) y un cliente confidencial: tu servidor guarda el client_secret y nunca lo expone a un navegador.
Estos endpoints no tienen CORS a propósito: hay que llamarlos desde tu servidor. Un access token o un client secret nunca deben vivir en un navegador.

Paso 1: mandá al comerciante a autorizar

Generá un code_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_uri con ?code=...&state=....
  • Si rechaza, redirige con ?error=access_denied&state=....
  • Si algún parámetro es inválido pero el client_id y la redirect_uri son correctos, redirige a tu redirect_uri con ?error=...&error_description=...&state=... (por ejemplo invalid_request, invalid_scope o unsupported_response_type).
  • Si el client_id o la redirect_uri son inválidos, nunca redirigimos a la URL recibida: el comerciante ve una pantalla de error en Commercy.
Verificá siempre que el 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:
El canje es lo que crea la instalación. 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, respondemos invalid_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 obligatorio app.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 }.

Ejemplo completo en Node