Skip to content

Autenticación

Cada llamada a la API de integración va autenticada con una credencial de tu comercio. COME identifica tu comercio a partir de esa credencial y solo te deja operar con tus descuentos y tus consumos.

Hay dos tipos de credencial. Elige una por sistema; puedes tener varias (una por punto de venta, por ejemplo).

Cliente OAuth 2.0 (client credentials)API key
Recomendado paraERP, e-commerce, integraciones con varios serviciosPOS o scripts sencillos
Qué recibes al crearlaclient_id (m{n}-…) y client_secretLlave ck_{prefijo}.{secreto}
Qué envías a la APIAuthorization: Bearer {access_token}X-Api-Key: ck_…
VigenciaAccess token de 15 minutos; el secret vale hasta que lo rotes30, 90, 180 o 365 días (lo eliges al crearla)
Si se filtraRota el secret: el anterior deja de servirRevoca la llave y crea otra
Límite por comercio10 clientes10 llaves

Estado de la integración

Los clientes OAuth y las API keys ya se crean desde la oficina virtual de COME (COME Identity). El encabezado X-Api-Key y el permiso core.integrations son parte del contrato propuesto: se confirmarán cuando los endpoints se publiquen en COME.CORE.

Crear la credencial ​

  1. Entra a tu oficina virtual en COME Identity con un usuario de tu comercio que tenga el permiso Manage API keys and OAuth clients (merchant.integrations.manage). Por seguridad, ese usuario debe tener la verificación en dos pasos activa.
  2. Abre Integrations (/portal/integrations).
  3. Elige New OAuth client (recomendado) o New API key:
    • Ponle un nombre que identifique el sistema (p. ej. POS Sucursal Centro).
    • En Permissions marca el permiso de integración (core.integrations). Si la pantalla indica que no hay permisos disponibles, pide a COME que habilite el permiso de integración para tu comercio.
    • En API keys, elige la vigencia en Expires in.
  4. Copia el secreto en ese momento: se muestra una sola vez. Guárdalo en un gestor de secretos o en variables de entorno del servidor, nunca en el código fuente.

Cliente OAuth 2.0 (client credentials) ​

Tu servidor intercambia client_id y client_secret por un access token de corta duración, y lo envía en cada llamada a la API.

1. Pedir el token ​

POST {identityUrl}/connect/token con cuerpo application/x-www-form-urlencoded:

CampoValor
grant_typeclient_credentials
client_idTu client ID
client_secretTu client secret
scopecore.integrations

También puedes enviar client_id y client_secret en el encabezado Authorization: Basic base64(client_id:client_secret) en lugar del cuerpo.

bash
curl -s -X POST "$COME_IDENTITY_URL/connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$COME_CLIENT_ID" \
  -d "client_secret=$COME_CLIENT_SECRET" \
  -d "scope=core.integrations"
js
// Node 18+ (fetch nativo). Las credenciales vienen de variables de entorno del servidor.
async function requestToken() {
  const response = await fetch(`${process.env.COME_IDENTITY_URL}/connect/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.COME_CLIENT_ID,
      client_secret: process.env.COME_CLIENT_SECRET,
      scope: 'core.integrations',
    }),
  })
  if (!response.ok) throw new Error(`COME Identity respondió ${response.status}`)
  return response.json() // { access_token, token_type: "Bearer", expires_in: 900 }
}
csharp
using var http = new HttpClient();
var response = await http.PostAsync($"{identityUrl}/connect/token", new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["grant_type"] = "client_credentials",
    ["client_id"] = configuration["Come:ClientId"]!,
    ["client_secret"] = configuration["Come:ClientSecret"]!,
    ["scope"] = "core.integrations",
}));
response.EnsureSuccessStatusCode();
var token = await response.Content.ReadFromJsonAsync<TokenResponse>();

public record TokenResponse(
    [property: JsonPropertyName("access_token")] string AccessToken,
    [property: JsonPropertyName("expires_in")] int ExpiresIn);

Respuesta:

json
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "core.integrations"
}

2. Llamar a la API con el token ​

bash
curl -s -X POST "$COME_BASE_URL/api/v1/integrations/eligibility" \
  -H "Authorization: Bearer $COME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "identificationTypeId": 1, "identification": "00000000000" }'

3. Reutilizar el token ​

El token dura 15 minutos (expires_in: 900). No pidas uno por cada llamada: guárdalo en memoria y renuévalo cuando falte menos de un minuto para que venza, o cuando la API responda 401.

js
let cached = null

export async function getToken() {
  const now = Date.now()
  if (!cached || cached.expiresAt - 60_000 <= now) {
    const token = await requestToken()
    cached = { value: token.access_token, expiresAt: now + token.expires_in * 1000 }
  }
  return cached.value
}
csharp
// Registra un servicio singleton y reutilízalo en todas las llamadas.
public sealed class ComeTokenProvider(HttpClient http, IConfiguration configuration)
{
    private readonly SemaphoreSlim _lock = new(1, 1);
    private string? _token;
    private DateTimeOffset _expiresAt;

    public async Task<string> GetTokenAsync()
    {
        if (_token is not null && _expiresAt - DateTimeOffset.UtcNow > TimeSpan.FromMinutes(1))
            return _token;

        await _lock.WaitAsync();
        try
        {
            if (_token is null || _expiresAt - DateTimeOffset.UtcNow <= TimeSpan.FromMinutes(1))
            {
                var token = await RequestTokenAsync(); // POST /connect/token (paso 1)
                _token = token.AccessToken;
                _expiresAt = DateTimeOffset.UtcNow.AddSeconds(token.ExpiresIn);
            }
            return _token;
        }
        finally { _lock.Release(); }
    }
}

Rotar el client secret ​

En Integrations → Rotate secret obtienes un secret nuevo; el anterior deja de funcionar de inmediato. Actualiza la variable de entorno de tu servidor en el mismo momento para evitar cortes. Los tokens ya emitidos siguen funcionando hasta que vencen (máximo 15 minutos).

API key ​

Envías la llave completa en el encabezado X-Api-Key de cada llamada. No hay token intermedio.

bash
curl -s -X POST "$COME_BASE_URL/api/v1/integrations/eligibility" \
  -H "X-Api-Key: $COME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "identificationTypeId": 1, "identification": "00000000000" }'
js
const response = await fetch(`${process.env.COME_BASE_URL}/api/v1/integrations/eligibility`, {
  method: 'POST',
  headers: {
    'X-Api-Key': process.env.COME_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ identificationTypeId: 1, identification: '00000000000' }),
})
csharp
using var http = new HttpClient { BaseAddress = new Uri($"{baseUrl}/api/v1/") };
http.DefaultRequestHeaders.Add("X-Api-Key", configuration["Come:ApiKey"]);

var response = await http.PostAsJsonAsync("integrations/eligibility",
    new { identificationTypeId = 1, identification = "00000000000" });
  • Formato: ck_ + prefijo de 16 caracteres + . + secreto. El prefijo identifica la llave en tu oficina virtual (lo ves como ck_a1b2c3d4…); el secreto solo lo conoces tú.
  • Vencimiento: la llave deja de funcionar en la fecha elegida al crearla. Crea la nueva antes de que venza, despliégala y revoca la anterior.
  • Revocación: en Integrations → Revoke. La llave deja de funcionar de inmediato.

Errores de autenticación ​

HTTPCausa habitualQué hacer
400 en /connect/tokengrant_type o scope incorrectosRevisa los campos del formulario.
401 en /connect/tokenclient_id o client_secret inválidos, o cliente eliminadoVerifica las credenciales o rota el secret.
401 en la APIFalta la credencial, el token venció o la API key fue revocada o vencióPide un token nuevo o reemplaza la llave.
403 en la APILa credencial no tiene el permiso core.integrations o tu comercio no está habilitadoCrea la credencial con el permiso correcto o contacta a COME.

Buenas prácticas de seguridad ​

  • Usa las credenciales solo desde tu servidor. Nunca en un navegador, una app móvil o un repositorio de código.
  • Una credencial por sistema o sucursal: si una se compromete, solo revocas esa.
  • Nunca envíes credenciales ni tokens en la URL (query string) ni los escribas en logs.
  • Todas las llamadas van por HTTPS.
  • Revisa periódicamente en Integrations las credenciales activas (la columna Last used ayuda) y elimina las que ya no uses. Eliminar un cliente OAuth invalida también sus tokens.

COME · Beneficios que te conectan