Os eventos
Um webhook é um endereço do teu servidor para o qual enviamos um evento assim que ele acontece. Existem 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 chega no primeiro reembolso parcial e no reembolso total. Um checkout que nunca foi pago e expira não é um cancelamento — nesse caso, não é enviado nenhum evento.
Configurar um webhook
Os programas também podem registar webhooks por si próprios: POST /v1/webhooks com uma chave que tenha webhooks:manage — e, além disso, a permissão de leitura dos dados que o webhook envia (forms:read para eventos de formulários, orders:read para encomendas).
- Abre a área Programador no painel.
- Em “Webhooks”, introduz o endereço do teu recetor — começa por https.
- Em “Que eventos?”, escolhe o que queres receber e clica em “Criar webhook”.
- Copia o segredo que aparece a seguir para o teu recetor.
- Clica em “Enviar teste” — o resultado aparece logo abaixo.
O que chega
Cada evento é um POST com JSON. Em data.object, o objeto tem a mesma forma que na API — uma encomenda como em GET /v1/orders/{id}, uma resposta como na lista de respostas. Nos eventos de formulários, data.form indica também a que formulário pertence a resposta.
{
"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 a assinatura
Cada chamada inclui o cabeçalho KENJTEC-Signature: t=<tempo>,v1=<assinatura>. A assinatura é um HMAC-SHA256 calculado sobre o tempo, um ponto e o corpo inalterado do pedido — com o segredo do teu webhook como chave. Descarta tudo cujo tempo tenha mais de cinco minutos.
Verifica com base no corpo em bruto antes de leres o JSON: basta um espaço diferente para dar uma assinatura diferente. Encontras o segredo a qualquer momento em “Mostrar segredo”; “Renovar segredo” invalida o antigo de imediato.
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", ""))O mesmo evento pode chegar duas vezes — por exemplo, quando o teu servidor responde, mas a resposta não nos chega. O identificador em id (também no cabeçalho KENJTEC-Event-Id) mantém-se igual: guarda-o e processa cada evento apenas uma vez.
Quando algo não chega
Considera-se entregue qualquer resposta com um estado de 200 a 299 no prazo de dez segundos. Não seguimos redirecionamentos.
Se um evento não chegar, tentamos novamente: após 1, 5 e 30 minutos, após 2, 6 e 12 horas e duas vezes após 24 horas — durante pouco mais de três dias. Se cinco eventos seguidos falharem definitivamente, desativamos o webhook; o painel indica então o motivo, e “Voltar a ativar” repõe-no.
Em “Registo”, vês todas as entregas dos últimos 30 dias com estado e conteúdo. A partir daí, podes enviar novamente qualquer evento com “Enviar novamente”.

Os webhooks só são enviados para endereços https públicos. Não aceitamos endereços em redes internas nem endereços da própria KENJTEC.