Skip to content

Webhooks ​

Los webhooks te permiten que Kuenta notifique a tu sistema, mediante una solicitud HTTP saliente, cuando ocurre un evento sobre un crédito de una línea de crédito (credit line) específica.

A diferencia de un modelo de suscripción a eventos genéricos, en Kuenta un webhook es una configuración (URL, cuerpo, autenticación) que se asocia a una línea de crédito y se dispara en dos puntos concretos del ciclo de vida del crédito.

Eventos que disparan un webhook ​

Hoy existen dos puntos de disparo, ambos configurados en la línea de crédito:

  • onOrderWebhooks: se dispara cuando se aprueba un pago (orden) sobre una cuota del crédito.
  • onDeliveredWebhooks: se dispara cuando el crédito pasa a estado Desembolsado.

No existe un catálogo abierto de eventos arbitrarios (por ejemplo, creación de una solicitud, firma de un documento, o carga de un documento de perfil). Si tu integración necesita notificarse en un momento distinto a estos dos, contacta a soporte técnico para evaluar agregar un nuevo punto de disparo.

Configuración de un webhook ​

1. Crear un webhook ​

http
POST /v1/webhook
Content-Type: application/json
Organization-ID: tu-id-de-organizacion

{
  "tag": "notificacion-desembolso",
  "url": "https://tu-dominio.com/webhook",
  "requestHeader": "{\"Content-Type\":\"application/json\"}",
  "requestBody": "{\"creditId\":\"{{ .Credit.ID }}\",\"status\":\"{{ .Credit.Status }}\"}",
  "authEnabled": false
}

Campos disponibles al crear/actualizar un webhook:

CampoDescripción
tagIdentificador corto del webhook, útil para distinguirlo en los logs.
urlURL de destino a la que Kuenta enviará la solicitud POST.
requestHeaderEncabezados HTTP a enviar (JSON), admite la misma sintaxis de plantilla que requestBody.
requestBodyCuerpo de la solicitud. Es una plantilla (ver más abajo).
authEnabledSi true, Kuenta obtiene un token antes de cada envío (ver "Autenticación saliente").
authUrl, authMethod, authRequestBody, authRequestHeaderConfiguración de la solicitud previa para obtener el token.
tokenSourceKey, tokenType, authHeader, tokenHeaderDónde extraer el token de esa respuesta y cómo inyectarlo en la petición del webhook.
responseQueriesMapa de expresiones JSONPath para extraer valores de la respuesta de tu endpoint y guardarlos, disponibles luego para otras plantillas mediante fromWebhook.

2. Listar webhooks ​

http
GET /v1/webhooks
Organization-ID: tu-id-de-organizacion

3. Obtener un webhook ​

http
GET /v1/webhook/{webhookid}
Organization-ID: tu-id-de-organizacion

4. Actualizar un webhook ​

http
PUT /v1/webhook/{webhookid}
Content-Type: application/json
Organization-ID: tu-id-de-organizacion

{
  "url": "https://tu-nuevo-dominio.com/webhook",
  "requestBody": "{\"creditId\":\"{{ .Credit.ID }}\"}"
}

5. Eliminar (archivar) un webhook ​

http
DELETE /v1/webhook/{webhookid}
Organization-ID: tu-id-de-organizacion

6. Probar un webhook ​

Ejecuta el envío inmediatamente con un crédito vacío (sin necesidad de tener un crédito real ni de asociarlo a una línea de crédito) y devuelve el detalle completo de la solicitud/respuesta, útil mientras se configura la plantilla:

http
POST /v1/webhook-test
Content-Type: application/json
Organization-ID: tu-id-de-organizacion

{
  "url": "https://tu-dominio.com/webhook",
  "requestBody": "{\"ping\":true}"
}

7. Ejecutar manualmente un webhook para un crédito existente ​

http
POST /v1/webhook/{webhookid}/request
Content-Type: application/json
Organization-ID: tu-id-de-organizacion

{
  "creditID": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "logID": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
}

Vincular el webhook a una línea de crédito ​

Crear un webhook por sí solo no hace que se dispare — debe asociarse a la línea de crédito (credit line) correspondiente, en el campo onOrderWebhooks (pago aprobado) o onDeliveredWebhooks (crédito desembolsado). Esta asociación se configura al editar la línea de crédito, no en el propio webhook. Contacta a soporte técnico o a tu equipo de implementación para configurar esta asociación.

Cuerpo de la solicitud (requestBody) ​

El campo requestBody (y requestHeader) es una plantilla (sintaxis de text/template de Go, con funciones adicionales tipo Sprig) que se evalúa en el momento del envío contra el crédito que disparó el webhook. Puedes referenciar cualquier campo del crédito y de su deudor, por ejemplo:

{{ .Credit.ID }}
{{ .Credit.Status }}
{{ .Credit.Debtor.Natural.FirstName }}
{{ .Credit.Debtor.Natural.WorkCertificateFileID }}

Importante: la plantilla puede incluir identificadores (por ejemplo, el ID de un documento del perfil), pero no el contenido binario ni el Base64 del archivo. Para obtener el archivo, tu sistema debe llamar aparte a:

http
GET /v1/debtor/{debtorId}/profile/{campo}/{fileId}
Authorization: Bearer <access_token>

que devuelve el archivo directamente (binario, sin envoltorio JSON ni Base64), autenticado con el mismo token Bearer de tu cliente OAuth.

Reutilizar la respuesta de un webhook (fromWebhook) ​

Si un webhook tiene responseQueries, Kuenta guarda los valores que ahí se extraigan de la respuesta de tu endpoint. Otra plantilla —la de un webhook posterior del mismo crédito— puede leerlos:

{{ fromWebhook "siigo-factura" "invoiceId" }}

El primer argumento es el tag del webhook que dejó la respuesta y el segundo, la clave declarada en su responseQueries. Se devuelve lo guardado en el último envío exitoso de ese webhook para ese crédito y, si ese envío no trae esa variable —o si no hubo envío—, lo que se haya cargado a mano para ese crédito y ese tag (ver más abajo). Si no hay ni lo uno ni lo otro, la expresión queda vacía.

Ese orden es deliberado: un envío real manda sobre una carga manual. La consecuencia a tener presente es la inversa — si cargas un valor para corregir uno que el webhook capturó mal, el envío real sigue ganando y la corrección no se ve.

Cargar respuestas de créditos antiguos ​

Los créditos anteriores a la configuración de responseQueries no tienen nada guardado, así que un webhook nuevo que dependa de fromWebhook los dejaría fuera. Para eso está la carga masiva Respuestas de Webhook, en Créditos → Cargas masivas, con un CSV de cuatro columnas:

ColumnaContenido
Referencia de créditoLa referencia visible del crédito (también se acepta su id).
Tag del webhookEl tag del webhook que habría dejado la respuesta.
VariableLa clave con la que fromWebhook la va a leer.
RespuestaEl valor a guardar.

Una fila por variable: varias filas del mismo crédito y el mismo tag se suman en el mismo registro, y volver a cargar el archivo corregido reescribe la variable en su sitio sin duplicar nada.

Dos cosas a tener en cuenta:

  • El valor se guarda tal cual, como texto. Es lo que conserva intactas las referencias con ceros a la izquierda y los consecutivos largos.
  • La respuesta cargada queda registrada como un envío exitoso de ese webhook para ese crédito. Si tienes un paso de flujo con cache sobre el mismo tag, a partir de entonces lo dará por enviado y no lo volverá a mandar — que es justo lo que se busca cuando el envío original sí ocurrió.

Autenticación saliente (hacia tu endpoint) ​

Si tu endpoint requiere autenticación, Kuenta puede obtener un token antes de cada envío:

  • authEnabled: true + authUrl + authMethod + authRequestBody + authRequestHeader: Kuenta hace una solicitud previa a esa URL para obtener un token.
  • tokenSourceKey + tokenType + authHeader: dónde extraer el token de esa respuesta (del cuerpo o de un header, según tokenHeader) y en qué header inyectarlo en la petición del webhook.

Nota: Kuenta no agrega una firma HMAC ni un secreto compartido a cada solicitud del webhook. Si necesitas verificar el origen de la petición, acuerda con tu equipo de implementación un encabezado estático (vía requestHeader) que valides de tu lado.

Diagnóstico ​

Cada envío queda registrado, con la solicitud y la respuesta completas, asociado al crédito que lo disparó. Si un envío falla o tu integración no está recibiendo lo esperado, comparte el tag del webhook y el ID del crédito con soporte técnico para revisar el registro.

Reintentos automáticos ​

El comportamiento ante un envío fallido depende del tipo de fallo:

  • Fallo de transporte (endpoint caído, timeout de conexión, error de DNS/TLS — es decir, la petición HTTP no obtuvo respuesta): Kuenta sí reintenta automáticamente. El envío se intenta hasta 4 veces en total (el intento inicial más 3 reintentos), con una espera de 10 segundos entre cada intento.
  • Respuesta HTTP de error (tu endpoint respondió, pero con un código fuera de 2xx, p. ej. 4xx o 5xx): Kuenta no reintenta. El envío queda registrado como fallido con la respuesta completa; se considera que el mensaje fue entregado y el receptor decidió rechazarlo.

Si tras esto necesitas reenviar una notificación puntual, puede ejecutarse manualmente con POST /v1/webhook/{webhookid}/request (ver arriba). Para integraciones críticas, considera además usar la API para consultar el estado del crédito como respaldo en caso de que un envío se pierda.

Tu receptor debe ser idempotente. Como un mismo evento puede entregarse más de una vez (reintentos automáticos, o reenvíos manuales), tu endpoint debe tolerar entregas duplicadas sin procesar dos veces el mismo hecho de negocio: usa los identificadores del payload (por ejemplo el ID del crédito y su estado) para detectar y descartar duplicados.

Próximos pasos ​

Soporte ​

Si necesitas ayuda con la configuración de webhooks: