# Webhooks ## ¿Qué son los webhooks? Son **notificaciones automáticas** que el sistema envía a una URL externa cuando ocurre un evento. Permite que **otros sistemas reaccionen en tiempo real** a lo que pasa en gestionUltimate. Ejemplo: cuando hay una venta, el sistema "llama" a un endpoint tuyo con los datos. ## Acceso Menú → **Configuración → API → Webhooks** ## Configurar un webhook **Webhooks → Nuevo webhook** | Campo | Valor | |-------|-------| | **Nombre** | Descriptivo | | **URL del endpoint** | `https://tusistema.com/recibir-webhook` | | **Eventos a escuchar** | (lista de checkboxes) | | **Estado** | Activo / Inactivo | | **Secret** | String secreto para verificar el origen | ## Eventos disponibles | Evento | Cuándo se dispara | |--------|-------------------| | `sale.created` | Se confirma una venta | | `sale.updated` | Se modifica una venta | | `sale.cancelled` | Se anula una venta | | `product.created` | Se crea un producto | | `product.updated` | Se modifica un producto | | `stock.low` | Stock baja del umbral de alerta | | `purchase.received` | Se recibe una compra | | `payment.received` | Se cobra un pago | | `contact.created` | Se crea un cliente/proveedor | ## Formato del payload Cuando ocurre el evento, el sistema envía un POST con JSON: ```json { "event": "sale.created", "timestamp": "2026-05-15T14:23:45Z", "data": { "sale_id": 12345, "invoice_number": "0001-00045678", "total": 1500.00, "customer": { "id": 88, "name": "Juan Pérez", "rut": "210333770017" }, "items": [ { "product_id": 100, "qty": 2, "price": 750 } ] }, "signature": "sha256=abc123..." } ``` ## Verificar autenticidad Para confirmar que el webhook viene del sistema (y no de un atacante): 1. Tu endpoint recibe el header `X-Signature` 2. Calcular HMAC-SHA256 del body con el `secret` configurado 3. Comparar con el header 4. Si coincide: legítimo. Si no: rechazar Ejemplo en PHP: ```php $body = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_SIGNATURE']; $expected = hash_hmac('sha256', $body, $secret); if (hash_equals($expected, $signature)) { // Procesar webhook } else { http_response_code(401); exit; } ``` ## Reintentos Si tu endpoint **no responde** o devuelve error: - El sistema reintenta a los 30 seg, 1 min, 5 min, 15 min, 1 hora - Después de 5 fallas, marca el webhook como inactivo y avisa al admin - Las requests fallidas quedan en logs para reenviar manualmente ## Buenas prácticas para tu endpoint - Responder **rápido** (< 5 seg) con HTTP 200 - Si el procesamiento es lento, **encolar** y procesar async - **Idempotencia**: si llega el mismo evento 2 veces, procesar solo una (usar `sale_id` como dedupe key) - **Logging** completo para debug - **Validar firma** siempre