Integratie
Webhooks
Cijfr POST gebeurtenissen naar jouw HTTPS-endpoint, ondertekend met een eigen secret. Tot vijf pogingen met oplopende pauze.
Endpoint instellen
Onder Instellingen, dan Integraties maak je een webhook met een HTTPS-URL en de events die je wilt ontvangen. Je krijgt één keer een whsec_…-secret om handtekeningen mee te controleren.
Events
| Event | Wanneer |
|---|---|
invoice.sent | Een factuur is uitgegeven en verstuurd |
invoice.viewed | De ontvanger opende de publieke pagina |
invoice.paid | De factuur is volledig betaald, ook via een checkout |
invoice.overdue | De vervaldatum is voorbij |
invoice.reminder | Een herinnering of aanmaning is verstuurd |
quote.accepted | De klant accepteerde de offerte |
quote.declined | De klant wees de offerte af |
Payload en handtekening
Elke levering is een POST met JSON-body en twee headers: X-Cijfr-Event met de eventnaam en X-Cijfr-Signature met sha256=<hmac>. De HMAC is de hex van HMAC-SHA256(secret, ruwe body).
{
"event": "invoice.paid",
"occurredAt": "2026-03-01T10:24:11.000Z",
"data": {
"documentId": "7f2b…",
"amount": 12100,
"method": "ideal"
}
}import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyCijfrWebhook(
rawBody: string,
signatureHeader: string,
secret: string,
): boolean {
const expected =
"sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
// Lees de ruwe body, niet de geparste JSON:
// const ok = verifyCijfrWebhook(rawBody, req.headers["x-cijfr-signature"], secret);Retries
Antwoordt je endpoint niet met een 2xx, dan probeert Cijfr het opnieuw: na ongeveer 1, 5 en 15 minuten, daarna na 1 en 4 uur, maximaal vijf pogingen. De payload van een retry is identiek, dus maak je endpoint idempotent op data.documentId plus event.