Los eventos
Un webhook es una dirección de tu servidor a la que enviamos un evento en cuanto ocurre. Hay seis eventos:
form.response.created Eine neue Antwort auf eines deiner Formulare
form.response.updated Jemand hat seine Antwort über den Bearbeitungslink geändert
order.paid Eine Bestellung ist bezahlt
order.fulfilled Eine Bestellung ist versendet oder übergeben
order.canceled Eine bestätigte Bestellung wurde storniert
order.refunded Eine Bestellung wurde erstattetorder.refunded llega con el primer reembolso parcial y con el reembolso completo. Un proceso de pago que nunca se pagó y caduca no es una cancelación: en ese caso no se envía ningún evento.
Configurar un webhook
Los programas también pueden registrar webhooks por sí mismos: POST /v1/webhooks con una clave que tenga webhooks:manage, además del permiso de lectura de los datos que envía el webhook (forms:read para eventos de formularios, orders:read para pedidos).
- Abre en el panel el área Desarrollador.
- En «Webhooks», introduce la dirección de tu receptor; empieza por https.
- En «¿Qué eventos?», elige lo que quieres recibir y haz clic en «Crear webhook».
- Copia en tu receptor el secreto que aparece a continuación.
- Haz clic en «Enviar prueba»: el resultado aparece justo debajo.
Qué llega
Cada evento es un POST con JSON. En data.object está el objeto con la misma forma que en la API: un pedido como en GET /v1/orders/{id}, una respuesta como en la lista de respuestas. En los eventos de formularios, data.form indica además a qué formulario pertenece la respuesta.
{
"id": "evt_Q2x9kLmP4vT7aB1cD3eF5gH7",
"object": "event",
"type": "order.paid",
"api_version": "2026-09-23",
"created_at": "2026-09-23T14:05:12Z",
"data": {
"object": {
"id": 5531,
"object": "order",
"number": 42,
"status": "confirmed",
"payment_status": "paid",
"currency": "EUR",
"total": 3890,
"customer": { "email": "mara@example.com", "name": "Mara Sol" },
"items": [
{ "name": "Kaffeebohnen, 500 g", "sku": "KAF-500", "quantity": 2, "unit_price": 1690 }
]
}
}
}Verificar la firma
Cada llamada lleva la cabecera KENJTEC-Signature: t=<hora>,v1=<firma>. La firma es un HMAC-SHA256 sobre la hora, un punto y el cuerpo sin modificar de la solicitud, con el secreto de tu webhook como clave. Descarta todo aquello cuya hora tenga más de cinco minutos de antigüedad.
Verifica contra el cuerpo sin procesar antes de leer el JSON: basta un espacio distinto para obtener otra firma. Encontrarás el secreto en cualquier momento en «Mostrar secreto»; «Renovar secreto» invalida el anterior de inmediato.
import crypto from "node:crypto";
// raw: the unparsed request body (Buffer), header: the KENJTEC-Signature header
export function verify(raw, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret)
.update(`${parts.t}.`).update(raw).digest("hex");
const given = String(parts.v1 ?? "");
return given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}import hashlib, hmac, time
def verify(raw: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))El mismo evento puede llegar dos veces, por ejemplo cuando tu servidor responde pero la respuesta no nos llega. El identificador del campo id (también en la cabecera KENJTEC-Event-Id) sigue siendo el mismo: guárdalo y procesa cada evento una sola vez.
Si algo no llega
Se considera entregada cualquier respuesta con un estado de 200 a 299 en un plazo de diez segundos. No seguimos redirecciones.
Si un evento no llega, lo volvemos a intentar: al cabo de 1, 5 y 30 minutos, al cabo de 2, 6 y 12 horas y dos veces al cabo de 24 horas, durante algo más de tres días. Si cinco eventos seguidos no llegan definitivamente, desactivamos el webhook; el panel indica entonces el motivo y «Volver a activar» lo restablece.
En «Registro» ves cada entrega de los últimos 30 días con su estado y contenido. Desde ahí puedes volver a enviar cualquier evento con «Enviar de nuevo».

Los webhooks solo se envían a direcciones https públicas. No aceptamos direcciones de redes internas ni direcciones del propio KENJTEC.