Saltar al contenido
Desarrolladores · Protocolo de comercio

Conecta tu sistema de ventas a cada conversación.

closercat-commerce-protocol es el protocolo abierto de CloserCat para conectar el sistema de ventas de una marca (ERP, inventario, pedidos) con sus ventas por WhatsApp y web: catálogo, disponibilidad, apartado de stock mientras la compradora paga, pedido con el pago confirmado, factura y seguimiento.

v1 · en implementación con la primera marca commerce/1.0 · licencia CC BY 4.0

El simulador, el validador y las llaves de prueba se habilitan con cada marca que integra; escríbenos para empezar.

Para el equipo de tecnología de una marca que vende con CloserCat y quiere que su sistema siga siendo la fuente de verdad del catálogo, del stock y de los pedidos. El protocolo es el mismo para todas las marcas: tu sistema lo implementa una vez.

El recorrido de una venta
  1. Catálogo y disponibilidadTu sistema nos envía productos y stock, o nos deja consultarlos.PUT /catalog · POST /availability
  2. Datos del pedidoLa compradora llena su pedido y CloserCat te pide apartar el stock.POST /holds
  3. PagoLe enviamos el link de pago; vence a la misma hora que el apartado.
  4. Pago confirmadoCloserCat crea el pedido con el apartado y los soportes del pago.POST /orders
  5. DespuésTu sistema nos avisa: aceptado, despachado, entregado, factura.POST /events
Niveles

Con el nivel 1 ya vendes con apartado real.

Declaras tus capacidades en GET /health y sumas los niveles 2 y 3 cuando tu sistema los tenga.

NivelQué habilitaCapacidades
1 Venta con apartado (mínimo) El agente vende con tu stock real y aparta mientras la compradora paga
  • catalog.push o catalog.pull
  • availability.push o availability.pull
  • holds
  • orders.create
2 Seguimiento La compradora sabe cuándo se despacha y recibe su factura
  • orders.events
  • orders.cancel
  • invoice.in_order
  • invoice.events
3 Tiempo real Disponibilidad consultada en la conversación y apartados extendibles
  • availability.live
  • holds.extend
  • holds.async
  • Sin apartado confirmado no se cobra.
  • Tu sistema manda en precio, SKU y stock. CloserCat no los cambia.
  • Ningún dato de tarjeta viaja. Los documentos y correos viajan solo cuando hacen falta.
  • Todo firmado e idempotente, con reintentos que nunca duplican.
Cómo empezar

Cinco pasos, de la prueba a producción.

  1. En CloserCat, entra a Tu Oferta › Tu sistema de ventas, crea la conexión de Prueba y copia tu connection_id y tu llave ck_test_… (el secreto se muestra una sola vez).
  2. Mira el recorrido completo con el simulador, antes de escribir código: haz un pedido de prueba en tu chat.
  3. Implementa la firma (guía §5) y prueba con GET /ping. Después, el nivel 1: envía catálogo y disponibilidad, y expone /health, /holds y /orders. Reconoce los SKUs de prueba TEST-*.
  4. Carga tu URL de sandbox y corre Probar mi integración hasta tener V1–V9 en verde.
  5. Crea las llaves de Producción, carga tu URL de producción, haz un pedido real de bajo valor y pasa la conexión a Producción (guía §17).
Guía de integración · commerce/1.0

La guía completa.

Para el equipo de tecnología de una marca que vende con CloserCat y tiene su propio sistema de ventas (ERP, sistema de inventario o de pedidos). Versión del protocolo: commerce/1.0 · Especificaciones: openapi-marca.yaml (lo que expone tu sistema) y openapi-closercat.yaml (lo que expone CloserCat) · Ejemplos: ejemplos/.


1. Qué es y cómo funciona

CloserCat atiende a tus compradoras por WhatsApp y por el chat de tu sitio, les ayuda a elegir y cierra la venta. Con este protocolo, tu sistema sigue siendo la fuente de verdad del catálogo, del stock y de los pedidos. El protocolo lo define CloserCat y es el mismo para todas las marcas. Tu sistema lo implementa una vez y queda conectado; no adaptamos el protocolo a la API de cada sistema.

El recorrido de una venta:

1. Catálogo y disponibilidad   Tu sistema nos envía productos y stock (o nos deja consultarlos).
2. Datos del pedido            La compradora llena su pedido. CloserCat te pide APARTAR el stock  → POST /holds
3. Pago                        Le enviamos el link de pago. Vence a la misma hora que el apartado.
4. Pago confirmado             CloserCat te CREA EL PEDIDO con el apartado y los soportes del pago → POST /orders
5. Después                     Tu sistema nos avisa: aceptado, despachado, entregado, factura      → POST /events

Si el apartado vence sin pago, CloserCat te lo libera (POST /holds/{reference}/release) y le dice a la compradora la verdad. Tu sistema también vence el apartado por su cuenta, como respaldo (§9).

Lo que nunca hace CloserCat: cobrar en tu nombre sin un apartado confirmado, inventar stock, guardar datos de tarjeta ni escribir directo en tu base de datos.


2. Capacidades: mínimas y opcionales

Declaras tus capacidades en GET /health. El validador (§14) verifica cada una antes de aceptarla.

NivelCapacidadQué haces¿Obligatoria?
1 · Venta con apartadocatalog.push o catalog.pullNos envías el catálogo (PUT /catalog) o lo exponemos y lo leemos (GET /catalog)Sí, una de las dos
availability.push o availability.pullNos envías la disponibilidad (POST /availability) o la consultamos (POST /availability/query)Sí, una de las dos
holdsApartas, consultas y liberas (POST /holds, GET /holds/{reference}, POST …/release)Sí
orders.createCreas y consultas el pedido (POST /orders, GET /orders/{reference})Sí
2 · Seguimientoorders.eventsNos avisas aceptado, rechazado, despachado, entregado, canceladoRecomendada
orders.cancelCancelas un pedido por retracto o devolución (POST /orders/{reference}/cancel)Recomendada
invoice.in_orderTu sistema factura con el bloque billing del pedidoOpcional
invoice.eventsNos avisas la factura emitida con su PDF (invoice.issued)Opcional
3 · Tiempo realavailability.liveRespondes consultas de stock durante la conversación en ≤ 1,5 sOpcional
holds.extendExtiendes un apartado (POST /holds/{reference}/extend)Opcional
holds.asyncRespondes el apartado con 202 y lo confirmas por evento (≤ 60 s)Opcional

Con el nivel 1 completo ya puedes vender con apartado real. Si ofreces push y pull de lo mismo, preferimos el push.


3. Ambientes, conexión y llaves

  • Dos ambientes por marca: sandbox (prueba) y production. Cada uno es una conexión con su connection_id, que ves en CloserCat en Tu Oferta › Tu sistema de ventas.
  • Llaves: CloserCat genera el secreto (32 bytes aleatorios o más) y te lo muestra una sola vez. Su identificador va en X-CloserCat-Key-Id: ck_test_… en sandbox, ck_live_… en producción.
  • Rotación sin corte: cada conexión admite dos llaves activas al mismo tiempo. Creas la nueva, la cargas en tu sistema, verificas con GET /ping y revocas la vieja.
  • La misma llave firma en las dos direcciones: tus llamadas a CloserCat y las de CloserCat a tu sistema.
  • Tu URL base (base_url): solo https, resuelta a una IP pública, sin credenciales en la URL y sin redirecciones. Si no cumple, la conexión no se guarda.
  • IPs de salida de CloserCat: las publicamos en la pantalla de la conexión para que puedas filtrar. Confírmalas ahí antes de cerrar tu firewall; la firma es la protección obligatoria y el filtro por IP es adicional.

4. Cabeceras comunes

Todas las llamadas, en las dos direcciones:

Content-Type: application/json; charset=utf-8
X-CloserCat-Protocol: commerce/1.0
X-CloserCat-Key-Id: ck_live_7f3a
X-CloserCat-Timestamp: 1792540800                       # segundos Unix, UTC
X-CloserCat-Signature: v1=<hex HMAC-SHA256(secreto, "{timestamp}.{cuerpo_crudo}")>
Idempotency-Key: <reference | batch_id:part | seq | event_id>   # en todo POST y PUT

Montos y cantidades decimales siempre como cadenas ("189900", "12.50"), nunca como número de punto flotante. Fechas en ISO-8601 con zona horaria (2026-10-21T15:40:00-05:00).


5. Firma HMAC

Qué se firma: la cadena "{X-CloserCat-Timestamp}.{cuerpo crudo}", con el secreto de la llave, usando HMAC-SHA256. El resultado va en hexadecimal minúscula con el prefijo v1=. En un GET el cuerpo crudo es la cadena vacía: se firma "{timestamp}.".

Cómo se verifica:

  1. Busca la llave por X-CloserCat-Key-Id. Si no existe o está revocada → 401.
  2. Si |ahora − timestamp| > 300 segundos → 401.
  3. Calcula la firma sobre los bytes exactos que recibiste (no sobre el JSON re-serializado).
  4. Compara con comparación de tiempo constante. Si no coincide → 401.

Python

import hashlib, hmac, json, time

def firmar(secreto: str, cuerpo: bytes, ts: int | None = None) -> dict:
    ts = ts or int(time.time())
    mac = hmac.new(secreto.encode(), f"{ts}.".encode() + cuerpo, hashlib.sha256).hexdigest()
    return {"X-CloserCat-Timestamp": str(ts), "X-CloserCat-Signature": f"v1={mac}"}

def verificar(secreto: str, cabeceras: dict, cuerpo: bytes, tolerancia: int = 300) -> bool:
    try:
        ts = int(cabeceras["X-CloserCat-Timestamp"])
    except (KeyError, ValueError):
        return False
    if abs(time.time() - ts) > tolerancia:
        return False
    esperada = "v1=" + hmac.new(secreto.encode(), f"{ts}.".encode() + cuerpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperada, cabeceras.get("X-CloserCat-Signature", ""))

# Enviar: serializa UNA vez y firma esos mismos bytes.
cuerpo = json.dumps({"seq": 1842}, separators=(",", ":"), ensure_ascii=False).encode()
cabeceras = firmar("tu-secreto", cuerpo)

Node.js

const crypto = require('node:crypto')

function firmar(secreto, cuerpo /* Buffer */, ts = Math.floor(Date.now() / 1000)) {
  const mac = crypto.createHmac('sha256', secreto).update(`${ts}.`).update(cuerpo).digest('hex')
  return { 'X-CloserCat-Timestamp': String(ts), 'X-CloserCat-Signature': `v1=${mac}` }
}

function verificar(secreto, cabeceras, cuerpo /* Buffer crudo */, tolerancia = 300) {
  const ts = Number.parseInt(cabeceras['x-closercat-timestamp'], 10)
  if (!Number.isFinite(ts) || Math.abs(Date.now() / 1000 - ts) > tolerancia) return false
  const esperada = Buffer.from('v1=' + crypto.createHmac('sha256', secreto).update(`${ts}.`).update(cuerpo).digest('hex'))
  const recibida = Buffer.from(String(cabeceras['x-closercat-signature'] || ''))
  return esperada.length === recibida.length && crypto.timingSafeEqual(esperada, recibida)
}

En Express, lee el cuerpo crudo (express.raw({ type: 'application/json' })) antes de parsearlo; si lo parseas primero, la firma no coincide.


6. Idempotencia

Cada operación que crea o cambia algo tiene una llave estable. Repetirla con el mismo cuerpo devuelve el mismo resultado; repetirla con otro cuerpo devuelve 409 idempotency_key_reused.

OperaciónLlaveRegla
POST /holdsreference (hold_{número de pedido})CloserCat consulta GET /holds/{reference} antes de reintentar
POST /holds/{reference}/releasela referenceLiberar dos veces = 200. Desconocida = 404, que tomamos como liberada
POST /ordersreference (número de pedido)CloserCat consulta GET /orders/{reference} antes de crear
PUT /catalog{batch_id}:{part}La misma parte no se aplica dos veces
POST /availabilityseqDebe crecer por conexión. Un seq menor o igual al último se ignora (applied: false)
POST /eventsevent_idUn evento repetido es un no-op (204)

La llave también viaja en la cabecera Idempotency-Key.


7. Tiempos y cortes

OperaciónQuién llamaTiempo exigido (p95)CorteReintentos
POST /holdsCloserCat, al enviar la compradora sus datos≤ 3 s4 s1 en el momento; después, en segundo plano hasta 10 min (§11)
POST /holds/{reference}/releaseCloserCat (vence o se cancela)≤ 3 s5 sCola durable hasta 24 h
POST /ordersCloserCat, al confirmarse el pago≤ 10 s, o 202 + evento15 sCola durable: 1 min, 5 min, 15 min, 1 h, 6 h, 24 h
POST /availability/query (availability.live)CloserCat, en la conversación≤ 1,5 s1,5 sNinguno: usamos el último dato
PUT /catalog, POST /availabilityTu sistemaRespondemos 202 en ≤ 2 s—Reintenta con la misma llave
POST /eventsTu sistemaRespondemos 204 en ≤ 1 s—Reintenta hasta recibir 2xx

Límites de CloserCat: 120 solicitudes por minuto por conexión; catálogo hasta 5 MB y 1000 productos por parte; disponibilidad y eventos hasta 256 KB. Ante 429, respeta Retry-After.


8. Errores

Todos los errores usan el mismo cuerpo:

{"protocol_version": "commerce/1.0", "reference": "CC-1042",
 "error": {"code": "insufficient_stock", "message": "…", "fields": [], "lines": [{"sku": "…", "requested": 2, "available": 0}]}}

La lista de códigos es cerrada:

HTTPerror.codeCuándo¿Reintenta CloserCat?
400 / 422validation_errorEl cuerpo no cumple el esquema o una regla de negocio. Indica los campos en fieldsNo
401unauthorizedFirma inválida, llave desconocida o timestamp fuera de 300 sNo (avisamos a la marca)
404not_foundEl apartado o pedido no existe—
409insufficient_stockNo hay stock para una o más líneas. Detalle en linesNo
409hold_expired_no_stockAl crear el pedido, el apartado venció y ya no hay stockNo (pasa a una persona)
409idempotency_key_reusedLa misma llave con otro cuerpoNo (avisamos: es un error de integración)
429rate_limitedDemasiadas solicitudesSí, respetando Retry-After
5xx, corte, error de redunavailableTu sistema no puede responderSí (§7)

message es para el equipo técnico; nunca se le muestra a la compradora.


9. Qué pasa si tu sistema no responde: garantías para tu marca

MomentoQué hace CloserCatQué le dice a la compradora
No llega catálogo o disponibilidad a tiempoSigue con el último dato. No dice «quedan N» si el dato tiene más de 15 minutos. Tu equipo ve «Datos de hace…» en CloserCatNada distinto
El apartado falla o se pasa del tiempoNo envía el link de pago. Reintenta en segundo plano hasta 10 minutos«Estoy confirmando con la bodega que tu producto esté disponible. Te escribo en unos minutos con el link de pago.» Si no se confirma, una persona de tu equipo continúa la conversación
El apartado es parcial o rechazadoAjusta el pedido solo si la compradora acepta«De la talla 38 en negro queda 1. ¿Te la aparto así o prefieres ver otro color?»
Crear el pedido falla después del pagoEl pago ya está y el pedido queda confirmado en CloserCat. Su envío a tu sistema queda en cola durable 24 h y tu equipo recibe un aviso«¡Pago recibido! Tu pedido está confirmado.»
Tu sistema rechaza el pedido porque el apartado venció y no hay stockPasa a una persona de tu equipo, que gestiona el cambio o la devolución«Tu pago llegó cuando ya no quedaba tu producto. Una persona del equipo te escribe ahora.»

Defensa en profundidad: tu sistema vence cada apartado por su cuenta en expires_at + 10 minutos, aunque no le llegue la liberación. Así el stock nunca queda colgado.


Un producto tiene una o más variantes. El SKU de cada variante es la llave de todo el protocolo: debe ser estable y único en tu cuenta. Por ejemplo: referencia + color + talla.

{"external_id": "REF-1042", "name": "Sandalia plataforma Lía", "active": true,
 "category_path": ["Mujer", "Sandalias"], "attributes": {"material": "Cuero"},
 "images": ["https://cdn.ejemplo.com/ref-1042-negro-1.jpg"],
 "variants": [{"sku": "REF-1042-NEG-37", "attributes": {"color": "Negro", "talla": "37"},
               "price": {"amount": "189900", "currency": "COP"}, "compare_at": null, "barcode": null, "active": true}]}

Ejemplo completo en ejemplos/catalog-batch.json.

Push:

  • Envía lotes con batch_id, en partes de hasta 1000 productos.
  • mode: full es una foto completa: lo que no venga queda archivado, nunca se borra.
  • mode: delta envía solo cambios.
  • Te respondemos 202 con lo rechazado por ítem, y consultas el resultado en GET /catalog/batches/{batch_id}.

Pull: expones GET /catalog paginado con cursor y updated_since.

Quién manda en cada campo:

CampoAutoridad
sku, price, compare_at, active, disponibilidadTu sistema. CloserCat nunca los cambia
name, category_pathTu sistema, salvo que tu equipo los edite a mano en CloserCat (la edición manual se respeta)
descripción, fotos, beneficios y atributos que tu sistema no envíaCloserCat (tu equipo los completa o los enriquece). Si los envías, se usan como punto de partida

Atributos que CloserCat no reconoce (por ejemplo, un nuevo eje de talla) no se descartan: quedan para que tu equipo confirme su rol en CloserCat.


11. Disponibilidad

available = unidades vendibles en línea, ya descontados tus propios apartados. Si no envías warehouse, es el total de las bodegas que despachan pedidos en línea.

Push (recomendado):

  • Envía cada cambio en ≤ 60 s (mode: delta) y una foto completa diaria (mode: full).
  • seq debe crecer de forma estricta por conexión.
  • as_of es el momento del dato en tu sistema.

Pull: respondes POST /availability/query con lotes de hasta 500 SKUs.

Cómo usa CloserCat el dato:

MomentoFuente
Buscar, mostrar opciones, filtrar por tallaEl último dato que nos enviaste
Decir «quedan N»Solo si N ≤ 3 y el dato tiene ≤ 15 minutos
Al apartarTu respuesta a POST /holds. Es la verificación real

Para no vender dos veces entre un envío y el siguiente, CloserCat resta del último dato los apartados que te pidió después de ese momento.


12. Apartados

  1. La compradora envía los datos de su pedido y CloserCat llama POST /holds con:
    • reference (hold_{número de pedido});
    • las líneas;
    • el expires_at que pide: 30 minutos con link de pago, 2 horas con cierre por una persona o transferencia, y hasta 24 horas con contra entrega. Cada marca los ajusta.
  2. Respondes:
    • 201 held (todo apartado);
    • 201 partial (lines[].held dice cuánto);
    • 409 insufficient_stock, con el detalle por línea.
    • Puedes devolver un expires_at menor al pedido: CloserCat le dice a la compradora la hora efectiva.
  3. Con holds.async puedes responder 202 y confirmar con hold.confirmed / hold.rejected en ≤ 60 s.
  4. Después del pago, el apartado se confirma al crear el pedido (hold_reference).
  5. Si nadie paga, CloserCat llama POST /holds/{reference}/release con reason: expired.
  6. Con holds.extend, CloserCat puede pedir más tiempo cuando el pago queda en verificación del banco.
  7. Tu sistema vence el apartado por su cuenta en expires_at + 10 minutos.
requested ─► held ─► committed (pedido creado)
              │  └─► released  (cancelado)
              └────► expired ─► released
          ─► partial ─► held | released
          ─► rejected

13. Pedidos, pagos y factura

CloserCat crea el pedido solo con el pago confirmado: pasarela capturada, contra entrega aceptada o pago confirmado por una persona del equipo. El pedido incluye:

  • reference (número de pedido) y hold_reference;
  • buyer: persona natural o empresa, nombre, teléfono. El documento solo si tu sistema lo exige o si la compradora pidió factura;
  • shipping: modo, dirección, quien recibe o recoge, valor del envío;
  • lines y totals, con montos como cadenas;
  • payment, con los soportes:
    • pasarela e id conciliable de la transacción;
    • estado (captured, pending_on_delivery o confirmed_by_staff);
    • medio y cuotas;
    • monto, moneda y fecha de captura;
    • proof_url: el comprobante que subió la compradora en una transferencia, con URL firmada por 7 días.
    • Nunca datos de tarjeta.
  • billing:
    • null = la compradora no pidió factura a su nombre (tu sistema emite su documento según su política);
    • con datos = sí la pidió: persona o empresa, documento, nombre o razón social y correo.
    • Esos datos los llenó una sola vez en su pedido; nunca se le piden dos veces.
  • closercat.is_test: true en pruebas. No es una venta real.

Respondes 201 con tu erp_order_id, o 202 y nos avisas con order.accepted / order.rejected. Ejemplo completo en ejemplos/order-request.json.

Factura, tres modos (los eliges en CloserCat):

ModoQuién facturaQué recibes
erpTu sistemaEl bloque billing en el pedido. Si declaras invoice.events, nos avisas invoice.issued con el PDF y CloserCat se lo envía a la compradora solo si pidió factura
connectorTu proveedor de facturación electrónica, conectado aparte en CloserCatNada adicional en este protocolo
none——

14. Eventos

POST /events con event_id, type, occurred_at y data. Tipos:

typeCapacidaddata
hold.confirmed, hold.rejected, hold.releasedholds.async (o liberaciones hechas por tu sistema)reference, erp_hold_id, expires_at, lines, reason
order.accepted, order.rejected, order.shipped, order.delivered, order.cancelledorders.eventsreference, erp_order_id, reason, transportadora y guía
invoice.issuedinvoice.eventsreference, number, issued_at, cufe, pdf_url (temporal, mínimo 24 h)

reason va en una frase y sin datos personales.


15. Simulador

En sandbox, mientras tu sistema no esté listo, la conexión puede quedar en simulación: CloserCat responde por tu sistema con un catálogo de prueba. Así ves el recorrido completo en la conversación antes de escribir una línea. Cuando cargas tu base_url de sandbox, CloserCat empieza a llamarte a ti.

SKUs de prueba (en simulación y en el validador):

SKUComportamiento esperado
TEST-OK-*Hay stock: el apartado y el pedido se crean
TEST-AGOTADO409 insufficient_stock con available: 0
TEST-PARCIALSolo hay 1 unidad: una solicitud de 2 queda partial
TEST-LENTOResponde en 6 s: CloserCat corta a los 4 s y aplica §9
TEST-ERROR503 unavailable

Tu sandbox debe reconocer estos SKUs para pasar el validador.


16. Validador

En Tu Oferta › Tu sistema de ventas › Probar mi integración, CloserCat corre esta suite contra tu sandbox y te muestra el resultado por escenario. Puedes volver a correrla cuantas veces quieras.

#Qué verifica
V1GET /health firmado responde ok, commerce/1.0 y las capacidades
V2Rechazas con 401 una firma mala y un timestamp de más de 300 s
V3POST /holds de TEST-OK-1 responde 201 held con expires_at
V4POST /holds de TEST-AGOTADO responde 409 insufficient_stock con lines
V5Repetir el mismo apartado devuelve el mismo resultado; otro cuerpo con la misma llave da 409 idempotency_key_reused
V6Liberar dos veces responde 200; liberar una desconocida responde 404
V7POST /orders con un apartado vigente responde 201 (o 202 + evento) con erp_order_id
V8GET /orders/{reference} antes de crear da 404; repetir el pedido no lo duplica
V9Un pedido con apartado vencido de TEST-AGOTADO responde 409 hold_expired_no_stock
V10Tiempos p95 dentro de §7 en 20 llamadas
V11Si empujas: un lote de catálogo y uno de disponibilidad válidos se aplican, y uno inválido devuelve el rechazo por ítem
V12Un evento con event_id repetido se acepta una sola vez

V1–V9 son obligatorios. V10–V12 aplican según tus capacidades.


17. Lista de salida a producción

  1. GET /health firmado, con capacidades.
  2. Firma verificada (V2).
  3. Idempotencia por reference, batch_id:part, seq y event_id.
  4. Vencimiento propio del apartado (expires_at + 10 minutos).
  5. 409 insufficient_stock con detalle por línea.
  6. GET /orders/{reference} consultable antes de crear.
  7. Tiempos p95 de §7.
  8. Sandbox con los SKUs de prueba.
  9. Validador V1–V9 en verde.
  10. Contacto técnico y ventanas de mantenimiento informados en CloserCat.
  11. Un pedido real de bajo valor, aprobado por tu equipo.

Con todo esto, tu equipo pasa la conexión a Producción en CloserCat.


18. Versionado y compatibilidad

  • La versión va en X-CloserCat-Protocol y en protocol_version: commerce/1.0.
  • Cambios menores (1.x): siempre aditivos (campos opcionales, capacidades o tipos de evento nuevos). Tu implementación debe ignorar los campos que no conoce.
  • Cambios mayores (2.0): conviven al menos 6 meses con la versión anterior, anunciados con anticipación.
  • Si recibes una versión que no soportas, responde 422 validation_error con el mensaje «versión no soportada».

19. Privacidad y seguridad

  • Qué datos personales viajan y por qué:
    • el nombre, el teléfono y la dirección de la compradora, para que tu sistema registre y despache su pedido;
    • su documento, solo si tu sistema lo exige o si pidió factura a su nombre;
    • su correo, solo para la factura.
  • Tu marca es la responsable de esos datos (son tus clientes); CloserCat los trata por tu cuenta.
  • Nunca viajan datos de tarjeta. Los pagos los procesa la pasarela.
  • No registres documentos, correos ni teléfonos en logs. Registra la reference y el código de error.
  • Las URLs de comprobantes y facturas son temporales y firmadas. No las publiques.
  • Guarda los secretos de las llaves en un gestor de secretos, nunca en el código ni en el repositorio.
  • Si sospechas que una llave se filtró, créala de nuevo y revoca la anterior en CloserCat de inmediato.
Especificación

Los archivos, para tu equipo.

OpenAPI 3.1, un JSON de ejemplo por mensaje principal (válido contra los esquemas) y el historial de versiones. Los esquemas compartidos se definen en openapi-marca.yaml.

  • openapi-marca.yamlOpenAPI 3.1 de lo que expone tu sistema y CloserCat llama: salud, catálogo, disponibilidad, apartados y pedidos.
  • openapi-closercat.yamlOpenAPI 3.1 de lo que expone CloserCat y tu sistema llama: catálogo, disponibilidad y eventos.
  • CHANGELOG.mdHistorial de versiones.

Lo que expone tu sistema y CloserCat llama · base: tu base_url

MétodoRutaPara quéCapacidad
GET/healthEstado, versión y capacidades declaradassiempre
GET/catalogCatálogo paginado (solo si declaras catalog.pull)catalog.pull
POST/availability/queryDisponibilidad de una lista de SKUs (availability.pull o availability.live)availability.pull
POST/holdsApartar stock mientras la compradora pagaholds
GET/holds/{reference}Estado de un apartadoholds
POST/holds/{reference}/releaseLiberar un apartado (idempotente)holds
POST/holds/{reference}/extendExtender un apartado (holds.extend)holds.extend
POST/ordersCrear el pedido con el pago confirmadoorders.create
GET/orders/{reference}Estado de un pedido (se consulta antes de crear)orders.create
POST/orders/{reference}/cancelCancelar un pedido (orders.cancel)orders.cancel

Lo que expone CloserCat y tu sistema llama · base: https://api.closercat.pro/commerce/v1/{connection_id}

MétodoRutaPara quéCapacidad
GET/pingProbar tu firma y el ambiente de la conexiónsiempre
PUT/catalogEnviar una parte de un lote de catálogo (catalog.push)catalog.push
GET/catalog/batches/{batch_id}Resultado de un lote de catálogocatalog.push
POST/availabilityEnviar disponibilidad (availability.push)availability.push
POST/eventsAvisar lo que pasó con un apartado, un pedido o una facturaorders.events

La especificación de closercat-commerce-protocol se publica con licencia Creative Commons Atribución 4.0 (CC BY 4.0): puedes usarla, copiarla y adaptarla citando a CloserCat.

¿Tu equipo va a integrar su sistema?

Cuéntanos qué sistema usa tu marca y te habilitamos la conexión de prueba, el simulador y el validador.