Webhooks einrichten

Schritt-für-Schritt-Anleitung zum Registrieren eines Certivant-Webhook-Endpunkts, zum Speichern des Signaturgeheimnisses, zum Senden eines Testereignisses, zum Rotieren von Geheimnissen und zum Konfigurieren formularspezifischer Überschreibungen.

Webhooks ermöglichen es Certivant, Statusänderungen in Echtzeit an Ihr Backend zu senden. Anstatt GET /requests/:id abzufragen, bis die Verarbeitung abgeschlossen ist, sendet Certivant einen POST an eine von Ihnen kontrollierte URL, sobald ein relevantes Ereignis eintritt.

Diese Seite behandelt die einmalige Einrichtung. Die Signaturprüfung, die Sie vor dem Produktivbetrieb implementieren müssen, finden Sie unter Signaturprüfung.

Was Sie benötigen

  • Eine öffentlich erreichbare HTTPS-URL, die POST-Anfragen mit einem JSON-Body annimmt. Während der Entwicklung ist localhost in Ordnung, wenn Sie einen Tunnel verwenden (ngrok, Cloudflare Tunnel, tailscale funnel).
  • Die Rolle Inhaber oder Administrator in der Certivant-Organisation — Mitglieder können die Webhook-Einstellungen nicht ändern.
  • Eine Möglichkeit, Geheimnisse zu speichern — Sie erhalten ein HMAC-Signaturgeheimnis, das Sie zusammen mit Ihren anderen Produktionszugangsdaten aufbewahren müssen.

1 — Ihren Endpunkt erstellen

Ein minimaler Handler sieht so aus (dargestellt mit Node und Hono; jedes Framework funktioniert):

app.post("/webhooks/certivant", async (c) => {
  const body = await c.req.text();   // Read RAW body — needed for signature check
  const signature = c.req.header("X-Certivant-Signature-V2");
  const payload = JSON.parse(body);

  // Connectivity ping (the dashboard "Test" button) — ack immediately.
  // It carries `test: true` and mutates nothing, so no signature is required.
  if (payload.test === true || payload.event === "kyc.webhook.test") {
    return c.json({ ok: true }, 200);
  }

  // Verify the signature BEFORE trusting a real event, and reject if it fails.
  // See /developer/webhooks/signature-verification for the verify helper
  // (checks `t=<unix>,v1=<hex>` over `${t}.${body}`, 300 s tolerance).
  if (!verifyCertivantSignature(body, signature, process.env.CERTIVANT_WEBHOOK_SECRET!)) {
    return c.json({ error: "invalid signature" }, 401);
  }

  // Acknowledge fast — Certivant will retry if you take > 10s
  c.executionCtx.waitUntil(handlePayload(payload));
  return c.json({ received: true }, 200);
});

Die zwei nicht verhandelbaren Regeln:

  1. Antworten Sie innerhalb von 10 Sekunden mit 2xx. Certivant behandelt alles andere (5xx, 4xx, Zeitüberschreitung, Verbindungsfehler) als Zustellfehler und wiederholt den Versuch mit exponentiellem Backoff.
  2. Lesen Sie den rohen Body, bevor Sie JSON parsen. Die Signaturprüfung bildet den Hash über genau die Byte-Folge, die Certivant gesendet hat. Wenn Ihr Framework zuerst JSON parst, entsteht eine andere Zeichenkette, und die Signatur stimmt nicht überein.

2 — URL im Dashboard konfigurieren

Melden Sie sich mit einem Inhaber- oder Administratorkonto im Certivant-Dashboard an.
Wechseln Sie zu KYC → Einstellungen → Webhooks.
Fügen Sie Ihre Endpunkt-URL in Webhook-URL ein, z. B. https://api.yourapp.com/webhooks/certivant. Nur HTTPS — einfaches HTTP wird abgelehnt.
Klicken Sie auf Speichern. Certivant erzeugt beim ersten Speichern ein Signaturgeheimnis (nur einmal sichtbar — kopieren Sie es jetzt in Ihre Umgebung).
Das Geheimnis beginnt mit dem Präfix whsec_. Speichern Sie es in Ihrem Geheimnisspeicher als CERTIVANT_WEBHOOK_SECRET.

Das Geheimnis wird nur einmal angezeigt, wenn Sie es erzeugen oder rotieren — es gibt keine Schaltfläche „Geheimnis erneut anzeigen“. Speichern Sie es daher sofort. Falls Sie es verlieren, rotieren Sie es (siehe unten), um ein neues zu erhalten.

3 — Ein Testereignis senden

Zwei Schaltflächen helfen Ihnen, die Integration zu prüfen:

  • Test (neben der Webhook-URL) sendet einen schlanken Verbindungs-Ping kyc.webhook.test mit test: true. Er bestätigt nur, dass Ihr Endpunkt erreichbar ist und mit 2xx antwortet — er benötigt keine Anfragedaten und funktioniert auch, bevor Sie ein Signaturgeheimnis gespeichert haben. Bestätigen Sie ihn sofort (siehe Handler oben).

  • Testereignis senden (KYC → Entwickler → Webhook-Ereignisse) lässt Sie das Ereignis wählen — den Ping kyc.webhook.test oder eine Beispielnutzlast für kyc.request.created / approved / rejected / escalated — und sendet es genau so signiert wie eine echte Zustellung (X-Certivant-Signature-V2 plus die X-KYC-*-Header, Unix-Zeitstempel, Ihr Webhook-Geheimnis). Beispielnutzlasten enthalten "test": true und eine erfundene requestId. Damit können Sie:

  • prüfen, ob die URL von der Infrastruktur von Certivant aus erreichbar ist.

  • prüfen, ob Ihre Signaturprüfung eine gültige Signatur akzeptiert.

  • die genaue Form der Nutzlast sehen, bevor echte Ereignisse ausgelöst werden.

Sie können einen Test auch programmatisch auslösen — nützlich, wenn Sie Ihre Integrationstests skripten möchten:

curl -X POST https://app.certivant.com/api/kyc/settings/webhook-test \
  -H "Cookie: better-auth.session_token=..." \
  -H "Content-Type: application/json" \
  -d '{"event":"kyc.request.approved"}'
# returns { status: 200, latencyMs: 142, event, signed: true, headers: [...], responsePreview } if your endpoint replied

Der Body ist optional (Standard ist kyc.webhook.test). Der Endpunkt verwendet ein Sitzungs-Cookie, keinen API-Schlüssel — es handelt sich um eine Aktion auf Dashboard-Seite.

4 — Das Signaturgeheimnis rotieren

Wenn ein Geheimnis offengelegt wurde (oder jährlich als gute Hygiene):

Öffnen Sie KYC → Einstellungen → Webhooks.
Klicken Sie auf Geheimnis rotieren. Certivant erzeugt einen neuen Wert whsec_… und zeigt ihn einmal an.
Aktualisieren Sie Ihre Umgebungsvariable mit dem neuen Wert.
Deployen Sie. Nach dem Deployment ist das alte Geheimnis unbrauchbar — laufende Wiederholungen, die noch die alte Signatur tragen, schlagen bei Ihnen bei der Prüfung fehl, und Certivant behandelt sie als nicht zustellbar.

Es gibt keinen sendeseitigen Überlappungszeitraum: Neue Zustellungen werden nur mit dem neuen Geheimnis signiert. Die Prüfer-Rezepte in Signaturprüfung akzeptieren eine Liste von Geheimnissen und mehrere v1=-Werte. Sie können also einen Prüfer ausrollen, der sowohl das alte als auch das neue Geheimnis akzeptiert, bevor Sie rotieren. Andernfalls rotieren Sie in einer ruhigen Phase und beobachten Sie danach Ihre Protokolle auf Fehler bei der Signaturprüfung.

Formularspezifische Webhook-Überschreibung

KYC-Anfragen, die über ein Formular erstellt werden, können die standardmäßige Webhook-URL der Organisation durch eine formularspezifische URL überschreiben. Konfigurieren Sie dies auf der Einstellungsseite des Formulars im Dashboard. Das ist nützlich, wenn mehrere Integrationen dasselbe Certivant-Konto nutzen — leiten Sie jedes Formular an das Team weiter, dem es gehört.

Das Signaturgeheimnis wird sowohl für die Standard-URL als auch für formularspezifische Überschreibungen gemeinsam genutzt. Der Signatur-Header ist identisch, unabhängig davon, welche URL das Ereignis empfängt.

Was sich nicht als Webhook abbilden lässt

Einige Dinge lösen keine Webhooks aus:

  • Erstellen, Widerrufen oder Ändern von Berechtigungsbereichen eines API-Schlüssels.
  • Änderungen an den Einstellungen (Bearbeitungen für White-Label, Anpassungen der KYC-Schwellenwerte).
  • Dokument-Downloads.
  • Kommentare bei manuellen Prüfungen.

Wenn Sie auf diese reagieren müssen, sehen Sie stattdessen im Dashboard im Aktivitätsprotokoll nach — dafür gibt es noch keine öffentliche API.

Nächste Schritte

  • Signaturprüfung — tun Sie dies vor dem Produktivbetrieb. Ohne sie kann jeder Anfragen an Ihre Webhook-URL fälschen.
  • Ereignisse — der vollständige Katalog der Ereignistypen und Nutzlasten.
  • Wiederholungen — was passiert, wenn Ihr Endpunkt nicht erreichbar ist.