API de Integración OMS

Documentación técnica completa

← Volver al inicio

Documentación de Integración de Órdenes y Webhooks

Esta documentación proporciona toda la información necesaria para integrar tu sistema con el API de Capital Tech OMS.

1. Endpoint de Creación de Órdenes

Endpoint

POST
/oms/integrations/orders

Autenticación

  • Tipo: Client Authorization (API Key)
  • Header: x-api-key
  • Descripción: El API Key se obtiene del sistema y debe ser incluido en todas las solicitudes

Request Body

{
    "operation": "SHIPMENT",
    "origin": {
        "street_name": "Av. Principal",
        "street_number": "1234",
        "address_floor": "3",
        "address_apartment": "A",
        "address_neighborhood": "Centro",
        "zip_code": "1000",
        "city_name": "Ciudad Ejemplo",
        "state_name": "Provincia Ejemplo",
        "country_name": "Argentina",
        "observation": "Edificio con acceso por puerta principal"
    },
    "destination": {
        "street_name": "Calle Secundaria",
        "street_number": "567",
        "address_floor": null,
        "address_apartment": null,
        "address_neighborhood": "Barrio Norte",
        "zip_code": "2000",
        "city_name": "Ciudad Destino",
        "state_name": "Provincia Destino",
        "country_name": "Argentina",
        "observation": "Casa con portón negro"
    },
    "external_reference": "ORD-2024-001",
    "items": [
        {
            "external_reference": "ITEM-001",
            "code": "PROD-001",
            "name": "Producto Ejemplo 1",
            "quantity": 2
        },
        {
            "external_reference": "ITEM-002",
            "code": "PROD-002",
            "name": "Producto Ejemplo 2",
            "quantity": 1
        }
    ],
    "contact": {
        "fullname": "Juan Pérez",
        "document": "12345678",
        "email": "juan.perez@example.com",
        "phone_number": "1123456789",
        "area_code": "+54"
    }
}

Campos del Request

Campos Principales

CAMPOTIPOREQUERIDODESCRIPCIÓN
operationEnum
No
Tipo de operación: "SHIPMENT" o "PICKUP". Default: "SHIPMENT"
external_referenceString
No
Referencia externa de la orden
originObject
Ubicación de origen
destinationObject
Ubicación de destino
itemsArray
Lista de items (mínimo 1)
contactObject
Información de contacto

Campos de Ubicación (origin/destination)

CAMPOTIPOREQUERIDODESCRIPCIÓN
street_nameString
Nombre de la calle
street_numberString
Número de la calle
address_floorString
No
Piso
address_apartmentString
No
Departamento
address_neighborhoodString
No
Barrio
zip_codeString
Código postal
city_nameString
Ciudad
state_nameString
Provincia/Estado
country_nameString
País
observationString
No
Observaciones adicionales

Campos de Item

CAMPOTIPOREQUERIDODESCRIPCIÓN
external_referenceString
No
Referencia externa del item
codeString
No
Código del producto
nameString
Nombre del producto
quantityNumber
Cantidad (debe ser mayor a 0)

Campos de Contacto

CAMPOTIPOREQUERIDODESCRIPCIÓN
fullnameString
Nombre completo
documentString
Documento de identidad
emailString
No
Email (requerido si no hay phone_number)
phone_numberString
No
Teléfono (requerido si no hay email)
area_codeString
No
Código de área

* Al menos uno de email o phone_number debe estar presente.

Validaciones

  • El cliente debe pertenecer a la organización asociada al API Key
  • origin y destination: Objetos requeridos con todas las validaciones de ubicación
  • items: Array requerido con mínimo 1 item, cada item debe tener name y quantity > 0
  • contact: Objeto requerido, debe tener al menos email o phone_number

Response

Success Response (201 Created)

Error Responses

400 Bad Request - Validación fallida

{
    "error": {
        "message": "Validation failed",
        "details": [
            {
                "field": "items",
                "message": "items must contain at least 1 element"
            }
        ]
    }
}

401 Unauthorized - API Key inválido o faltante

{
    "error": {
        "message": "Unauthorized",
        "details": "Invalid or missing API key"
    }
}

404 Not Found - Cliente no encontrado

{
    "error": {
        "message": "Resource not found",
        "details": "Client with id 550e8400-e29b-41d4-a716-446655440000 not found"
    }
}

2. Sistema de Webhooks

Eventos que Disparan Webhooks

Los webhooks se disparan automáticamente cuando ocurren cambios en el estado de las órdenes.

Estructura del Payload del Webhook

El payload enviado al endpoint configurado tiene la siguiente estructura:

Campos del Metadata

CAMPOTIPOREQUERIDODESCRIPCIÓN
event_codeString
Código del evento ("ORDER_STATUS_CHANGED", etc.)
order_idUUID
ID de la orden afectada
timestampISO 8601
Fecha y hora del evento
retry_countNumber
Número de intento (0 = primer intento)

Política de Reintentos

Comportamiento

  1. Primer intento: Envío inmediato al endpoint configurado mediante HTTP POST
  2. Reintentos: Si el webhook falla (status HTTP != 200):
    • Se encola con delay exponencial
    • Delay calculado: retryDelaySeconds * retryCount segundos
    • Delay máximo: 900 segundos (15 minutos)
    • El campo retry_count se incrementa en cada reintento
  3. Máximo de reintentos: Después de 1 + 5 intentos fallidos, el mensaje se descarta y se registra una observación conservando la información.

Ejemplo de Secuencia de Reintentos

IntentoDelay (segundos)Delay Acumulado
10 (inmediato)0
26060
3120180
4180360
5240600
6300900

Después del intento 6, si sigue fallando, el mensaje se descarta.

Respuesta Esperada del Webhook

  • Status 200: Webhook procesado exitosamente. No se realizarán más reintentos.
  • Cualquier otro status (4xx, 5xx): Se considera fallo y se reencola para reintento.

Nota: El endpoint debe responder en menos de 30 segundos para evitar timeouts.

3. Ejemplos de Uso

Ejemplo 1: Crear una Orden de Envío Simple

Request:

curl -X POST https://api.example.com/oms/integrations/orders \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "550e8400-e29b-41d4-a716-446655440000",
    "origin": {
      "street_name": "Av. Principal",
      "street_number": "1234",
      "zip_code": "1000",
      "city_name": "Ciudad Ejemplo",
      "state_name": "Provincia Ejemplo",
      "country_name": "Argentina"
    },
    "destination": {
      "street_name": "Calle Secundaria",
      "street_number": "567",
      "zip_code": "2000",
      "city_name": "Ciudad Destino",
      "state_name": "Provincia Destino",
      "country_name": "Argentina"
    },
    "items": [
      {
        "name": "Producto Ejemplo",
        "quantity": 1
      }
    ],
    "contact": {
      "fullname": "Juan Pérez",
      "document": "12345678",
      "email": "juan.perez@example.com"
    }
  }'

Ejemplo 2: Crear una Orden de Retiro (Pickup)

Request:

Ejemplo 3: Endpoint Receptor de Webhook

Implementación de ejemplo (Node.js/Express):

app.post('/webhooks/orders', async (req, res) => {
  try {
    const { data, metadata } = req.body;
    
    // Validar que el webhook es válido
    if (!data || !metadata) {
      return res.status(400).json({ error: 'Invalid webhook payload' });
    }
    
    // Procesar el evento
    const { event_code, order_id, timestamp } = metadata;
    const order = data;
    
    console.log(`Received webhook: ${event_code} for order ${order_id}`);
    
    // Tu lógica de procesamiento aquí
    await processOrderUpdate(order, event_code);
    
    // Responder con 200 para indicar éxito
    res.status(200).json({ 
      message: 'Webhook processed successfully',
      order_id,
      timestamp 
    });
  } catch (error) {
    console.error('Error processing webhook:', error);
    // Responder con error para que se reintente
    res.status(500).json({ error: 'Internal server error' });
  }
});

4. Casos de Uso

Caso de Uso 1: Integración con E-commerce

Escenario: Un e-commerce necesita crear órdenes automáticamente cuando un cliente completa una compra.

Flujo:

  1. El e-commerce recibe la confirmación de compra
  2. Llama al endpoint /oms/integrations/orders con los datos de la orden
  3. El sistema crea la orden y retorna el ID
  4. El e-commerce almacena el ID de la orden para tracking

Consideraciones:

  • Usar external_reference para mantener la referencia del pedido del e-commerce
  • Configurar webhooks para recibir notificaciones de cambios de estado
  • Implementar idempotencia usando external_reference

Caso de Uso 2: Notificaciones en Tiempo Real

Escenario: Un sistema externo necesita ser notificado cuando una orden cambia de estado.

Flujo:

  1. Configurar un webhook con el endpoint del sistema externo
  2. El sistema externo implementa un endpoint que recibe los webhooks
  3. Cuando una orden cambia de estado, se envía automáticamente el webhook
  4. El sistema externo procesa la notificación y actualiza su estado interno

Consideraciones:

  • Implementar validación de seguridad (firmas, tokens)
  • Manejar reintentos correctamente (responder con 200 solo cuando se procesó exitosamente)
  • Implementar logging para auditoría

Caso de Uso 3: Sincronización de Estados

Escenario: Mantener sincronizado el estado de órdenes entre múltiples sistemas.

Flujo:

  1. Sistema A crea una orden mediante la API
  2. Sistema A configura un webhook
  3. Cuando el estado cambia en el sistema de gestión, se envía el webhook
  4. Sistema A actualiza su estado interno basado en el webhook recibido

Consideraciones:

  • Usar retry_count en metadata para identificar reintentos
  • Implementar idempotencia en el procesamiento de webhooks
  • Manejar casos donde el webhook llega fuera de orden

Caso de Uso 4: Orden con Múltiples Items

Escenario: Crear una orden con múltiples productos.

Ejemplo de Request:

Caso de Uso 5: Manejo de Errores en Webhooks

Escenario: El endpoint del webhook está temporalmente caído.

Comportamiento:

  1. Primer intento falla (endpoint no responde o retorna 500)
  2. Sistema reencola el webhook con delay de 60 segundos
  3. Segundo intento falla nuevamente
  4. Sistema reencola con delay de 120 segundos
  5. Este proceso continúa hasta el máximo de reintentos (5 por defecto)
  6. Si después de todos los reintentos sigue fallando, se descarta el mensaje

Recomendaciones:

  • Implementar un sistema de cola propio para procesar webhooks fallidos
  • Monitorear los logs para identificar problemas recurrentes
  • Considerar implementar un endpoint de "dead letter queue" para webhooks descartados

5. Mejores Prácticas

Seguridad

  1. API Keys: Mantén tus API keys seguras y no las compartas
  2. HTTPS: Siempre usa HTTPS para los endpoints de webhooks
  3. Validación: Valida la firma o token en los webhooks recibidos
  4. Rate Limiting: Implementa rate limiting en tus endpoints de webhook

Performance

  1. Respuesta Rápida: Responde a los webhooks en menos de 5 segundos
  2. Procesamiento Asíncrono: Procesa los webhooks de forma asíncrona cuando sea posible
  3. Idempotencia: Implementa idempotencia usando order_id y timestamp

Confiabilidad

  1. Logging: Registra todos los webhooks recibidos y procesados
  2. Manejo de Errores: Maneja errores gracefully y responde apropiadamente
  3. Monitoreo: Monitorea el estado de tus endpoints de webhook
  4. Testing: Prueba tus endpoints de webhook con diferentes escenarios

Última actualización: 19 Noviembre 2025

Para más información o soporte, contacta al equipo de desarrollo.