Spring til indholdet

Opsætte webhooks og kontrollere signaturen.

Webhooks i KENJTEC API: de seks hændelser til din server, oprette en webhook, kontrollere signaturen og hvordan mislykkede forsøg gentages.

VideoOprette en webhook
På denne side

Hændelserne

En webhook er en adresse på din server, som vi sender en hændelse til, så snart den sker. Der findes seks hændelser:

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 erstattet

order.refunded kommer ved den første delvise refusion og ved den fulde refusion. En betaling, der aldrig blev gennemført og udløber, er ikke en annullering — for den sendes der ingen hændelse.

Oprette en webhook

Programmer kan også selv registrere webhooks: POST /v1/webhooks med en nøgle, der har webhooks:manage — og desuden læserettigheden til de data, webhooken sender (forms:read for formularhændelser, orders:read for ordrer).

Ana indtaster i området „Udvikler“ adressen https://deine-firma.com/kenjtec-webhook, lader kun „En ordre er betalt“ være markeret og klikker på „Opret webhook“ — „Webhook oprettet.“ vises sammen med hemmeligheden, klar til at blive kopieret.Optagelsen viser den engelske brugerflade.
  1. Åbn området Udvikler i dashboardet.
  2. Indtast under „Webhooks“ adressen på din modtager — den begynder med https.
  3. Vælg under „Hvilke hændelser?“, hvad du vil modtage, og klik på „Opret webhook“.
  4. Kopiér den hemmelighed, der derefter vises, ind i din modtager.
  5. Klik på „Send test“ — resultatet vises med det samme nedenunder.

Hvad der modtages

Hver hændelse er en POST med JSON. I data.object står objektet i samme form som i API'et — en ordre som ved GET /v1/orders/{id}, et svar som i listen over svar. Ved formularhændelser står der desuden i data.form, hvilken formular svaret hører til.

order.paid (forkortet)
{
  "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 }
      ]
    }
  }
}

Kontrollere signaturen

Hvert kald har headeren KENJTEC-Signature: t=<tid>,v1=<signatur>. Signaturen er en HMAC-SHA256 beregnet over tiden, et punktum og den uændrede brødtekst i anmodningen — med din webhooks hemmelighed som nøgle. Afvis alt, hvis tid ligger mere end fem minutter tilbage.

Kontrollér mod den rå brødtekst, før du indlæser JSON'en: Blot ét andet mellemrum giver en anden signatur. Hemmeligheden finder du til enhver tid under „Vis hemmelighed“; „Forny hemmelighed“ gør den gamle ugyldig med det samme.

Node.js
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));
}
Python
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", ""))

Den samme hændelse kan ankomme to gange — for eksempel hvis din server svarer, men svaret ikke når frem til os. Id'et i id (også i headeren KENJTEC-Event-Id) forbliver det samme: Gem det, og behandl hver hændelse kun én gang.

Når noget ikke når frem

Ethvert svar med en status fra 200 til 299 inden for ti sekunder regnes som leveret. Vi følger ikke omdirigeringer.

Når en hændelse ikke når frem, prøver vi igen: efter 1, 5 og 30 minutter, efter 2, 6 og 12 timer og to gange efter 24 timer — i lidt over tre dage. Hvis fem hændelser i træk endegyldigt ikke når frem, slår vi webhooken fra; i dashboardet står der så hvorfor, og „Slå til igen“ nulstiller den.

Under „Log“ kan du se hver levering fra de seneste 30 dage med status og indhold. Derfra kan enhver hændelse sendes én gang til med „Send igen“.

Leveringsloggen for Café Lumens webhook: tre poster „order.paid“, heraf én „Ikke leveret“ med „Modtageren svarede med en fejlstatus. (503)“ og knappen „Send igen“.
Optagelsen viser den engelske brugerflade.

Webhooks sendes kun til offentlige https-adresser. Adresser i interne netværk og adresser hos KENJTEC selv accepterer vi ikke.

Relaterede vejledninger og næste trin

Hjælp os med at forbedre KENJTEC

Google Analytics hjælper os med at forbedre hjemmesiden. Google modtager brugs- og enhedsdata, som kan blive behandlet i USA.

Det er frivilligt. Dit valg gælder i 180 dage og kan til enhver tid ændres i cookieindstillingerne.

Privatlivspolitik