Saltar al contenido

Autenticación

Pide, usa y renueva tokens OAuth.

Auth emite tokens OAuth 2.0 en https://auth.ecomiq.pe/connect/token. Envía el token en el encabezado Authorization: Bearer.

Tu servidor
Auth
Admin API
POST /connect/token
200 con access_token y expires_in
GET /v1/catalog/products con Bearer
200 con los datos
Cuando vence, pide otro token
El secreto solo viaja a Auth, nunca a la API.

Credenciales de aplicación

Una aplicación creada en el panel te da client_id y client_secret. El secreto vive solo en tu servidor, nunca en el navegador ni en una app distribuida.

Las API keys que crea POST /v1/api-keys no son tokens OAuth: Admin, Storefront y Auth las rechazan.

Token para una integración de Admin

Usa client_credentials con el scope api_admin:

curl -X POST https://auth.ecomiq.pe/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$ECOMIQ_CLIENT_ID" \
  -d "client_secret=$ECOMIQ_CLIENT_SECRET" \
  -d "scope=api_admin"
Respuesta
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "token_type": "Bearer",
  "expires_in": 3600
}

expires_in es la vigencia en segundos.

Usar el token

curl "https://api.ecomiq.pe/api/v1/catalog/products?limit=25" \
  -H "Authorization: Bearer $ECOMIQ_TOKEN"

La tienda y, si aplica, el vendedor salen del token. Ver Organización, tienda y vendedor.

Grants

GrantUso
client_credentialsUn servidor actúa como la aplicación. Exige un cliente confidencial.
authorization_codeUna persona autoriza la aplicación. Ver Autorización de usuarios.
refresh_tokenRenueva una sesión, si la aplicación tiene este grant.

Cada aplicación acepta solo los grants y scopes que tiene configurados.

Renovación

Con client_credentials no hay refresh token: pide otro antes de que venza. Guarda el token en caché con un margen de un minuto.

token-cache.ts
let cached: { token: string; expiresAt: number } | undefined;

export async function getToken(): Promise<string> {
  if (cached && Date.now() < cached.expiresAt - 60_000) {
    return cached.token;
  }

  const body = new URLSearchParams({
    grant_type: "client_credentials",
    client_id: process.env.ECOMIQ_CLIENT_ID!,
    client_secret: process.env.ECOMIQ_CLIENT_SECRET!,
    scope: "api_admin",
  });

  const response = await fetch("https://auth.ecomiq.pe/connect/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body,
  });

  if (!response.ok) throw new Error(`OAuth HTTP ${response.status}`);

  const payload = await response.json();
  cached = {
    token: payload.access_token,
    expiresAt: Date.now() + payload.expires_in * 1000,
  };

  return cached.token;
}

Si varios procesos comparten credenciales, coordina la renovación para no pedir tokens en ráfaga.

Fallos de autenticación

  • 401: el endpoint no recibió una credencial válida.
  • 403: la credencial es válida, pero un scope, permiso o contexto lo impide.
  • /connect/token responde errores OAuth como invalid_client o invalid_grant. Ver Errores.

No registres tokens, secretos ni respuestas OAuth completas.

Inicio de sesión de clientes

Se elige en Configuración → Compra → Cuentas de clientes → Inicio de sesión (checkoutSettings.general.customerLoginMode):

ModoFormulario
hostedPágina de Auth con el nombre y logo de la tienda. Por defecto.
storefrontDentro de la tienda, con el estilo del tema.

En ambos modos Auth valida el correo y el código. Cambiar de modo conserva las cuentas. Un cliente y un usuario del Admin pueden usar el mismo correo.

  1. El servidor de la tienda configura el cliente OAuth con POST /v1/customer/auth/config y recibe loginMode, captcha y los datos OAuth.
  2. En modo storefront, pide el código con POST /v1/customer-auth/challenges.
  3. El SDK canjea el código (Authorization Code con PKCE) y guarda la sesión en una cookie segura. El tema no guarda tokens.

El CAPTCHA es opcional: Cloudflare Turnstile o Google reCAPTCHA v2. Los límites de intentos aplican siempre.

Datos del registro

Se eligen en Configuración → Compra → Datos del registro (checkoutSettings.general.customerRegistration). firstName, lastName, phone y dateOfBirth pueden ser hidden (no se piden), optional o required. Por defecto, hidden.

  1. Tras verificar el correo, el servidor lee GET /v1/customer/registration: campos, valores y requiresCompletion.
  2. Si requiresCompletion es true, el tema muestra el formulario antes de la cuenta o el checkout.
  3. El servidor envía los datos a POST /v1/customer/registration. Si todo es opcional, {} basta.

Reglas:

  • Con el registro pendiente, las APIs de cuenta y crear pedidos responden Customer.RegistrationRequired.
  • El servidor valida siempre: ocultar un campo en el tema no lo evita.
  • Un cliente existente vuelve al formulario solo si le falta un campo required.
  • dateOfBirth no puede ser posterior a hoy en la tienda.
  • PATCH /v1/customer no deja vaciar un campo required.
  • La bienvenida se envía una vez, al completar el registro.
  • La compra como invitado se configura aparte.

Última actualización:

En esta página