Saltar al contenido principal
Versión: 1.21.1

Webhooks

Gestión de endpoints externos que reciben notificaciones push. Eventos suscribibles: certificate_request.created, certificate_request.status_changed, certificate_request.ai_processed, certificate_request.file_uploaded, certificate_request.deleted, certificate.expiring, payment.approved y payment.failed; generan entregas los certificate_request.* y, desde la versión 1.21.1, payment.approved (la orden pasa a PAID) y payment.failed (la orden pasa a FAILED por un pago rechazado). Los de pago salen como máximo una vez por cada cambio de estado de la orden (a PAID o a FAILED); una orden rechazada puede recibir después payment.approved si otro intento de pago de esa misma orden se aprueba, así que antes de crear una orden nueva tras un payment.failed consulte GET /orders/{uuid}. Traen el tipo de orden (order_type: QUOTA_PURCHASE = compra de cupos, CERTIFICATE_RENEWAL = renovación, que no agrega cupos) y el tipo de emisión, la cantidad y la vigencia de la compra; los campos se detallan en la guía Casos de uso, sección Webhooks de pagos. certificate.expiring se acepta en la suscripción, pero todavía no genera entregas. certificate_request.created y certificate_request.status_changed incluyen el tipo de emisión de la solicitud (issuance_flow: BIOMETRIC / DOCUMENTARY). Cada entrega va firmada en la cabecera X-Webhook-Sig con el formato t={timestamp},v1={HMAC-SHA256 del cuerpo}.

📄️Historial de entregas de un webhook

Retorna, paginado y del más reciente al más antiguo, el historial de entregas del webhook indicado (de la empresa del usuario autenticado). Cada evento genera un registro por webhook suscrito. `status`: `pending` mientras se envía; `delivered` si la URL respondió (se guarda `http_status` y hasta 1000 caracteres de la respuesta); `failed` si no hubo respuesta (error de conexión o timeout; el error queda en `response_body`). Nota: una entrega puede permanecer en `pending` de forma indefinida si el envío no llegó a completarse o si fue marcada manualmente para reintento por soporte (en ese caso `attempt` puede ser mayor que 1); no hay reintentos automáticos.

📄️Listar tipos de evento disponibles

Retorna los tipos de evento que se pueden suscribir en un webhook. Generan entregas los eventos certificate_request.* (created, status_changed, ai_processed, file_uploaded, deleted) y, desde la versión 1.21.1, payment.approved (la orden pasa a PAID, también en renovaciones) y payment.failed (la orden pasa a FAILED porque la pasarela rechazó el pago). Los de pago salen una sola vez por cada cambio de estado de la orden (a PAID o a FAILED): los reenvíos de la pasarela no generan otra entrega, y una orden rechazada puede recibir después payment.approved si se paga con otra transacción. Su `data` trae `order_id` (UUID de la orden), `order_type` (QUOTA_PURCHASE = compra de cupos; CERTIFICATE_RENEWAL = renovación, que no agrega cupos), `company_id`, `issuance_flow`, `quantity` y `vigencia` de la compra, `amount`, `currency`, `payment_provider`, `provider_reference`, `provider_transaction_id`, `payment_method_type` y `paid_at` (approved) o `reason` (failed); detalle en la guía Casos de uso, sección Webhooks de pagos. certificate.expiring se acepta en la suscripción, pero todavía no genera entregas. certificate_request.created y certificate_request.status_changed traen el tipo de emisión de la solicitud (`issuance_flow`: BIOMETRIC / DOCUMENTARY). Cada entrega es un POST JSON a la URL del webhook con las cabeceras `X-Webhook-Event` (tipo de evento), `X-Webhook-Source` (nombre de la aplicación) y `X-Webhook-Sig` = `t={timestamp unix},v1={HMAC-SHA256 hexadecimal del cuerpo crudo con el secret del webhook}`. Cuerpo: {'id': 'wh_<ULID>', 'event': '<tipo>', 'created_at': '<ISO 8601>', 'data': {campos propios del evento}}. Timeout de la petición: 10 s. Cada evento se envía una sola vez, sin reintentos. Solo cuentan como fallo los errores de conexión y los timeouts; las respuestas HTTP 4xx/5xx se registran como entregadas (con su código) y reinician el contador. Tras 10 fallos consecutivos el webhook se desactiva automáticamente (is_active = false).