Skapa en slutpunkt
Under Inställningar → Webhooks lägger du till den URL dit händelserna ska skickas till. Du får en hemlighet tillbaka — den används för att verifiera signaturen och bör lagras som ett lösenord.
Ett system kan också anmäla sig själv med en API-nyckel, utan att någon öppnar kontrollpanelen. Det är en sådan integration som du inte själv skrev som ansluter sig: den får din nyckel och registrerar sin egen adress.
| Metod | Sökväg | Gör |
|---|---|---|
| GET | /v1/api/webhooks | Listar dina slutpunkter |
| POST | /v1/api/webhooks | Skapar en och returnerar hemligheten |
| PATCH | /v1/api/webhooks | Redigerar adress, händelser eller status |
| DELETE | /v1/api/webhooks/{id} | Tar bort den igen |
curl -X POST https://api.kuvert.dk/v1/api/webhooks \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://dit-system.dk/kuvert","events":["giftcard.redeemed"]}'Händelser
| Händelse | Skickas när |
|---|---|
| giftcard.issued | Ett presentkort är utgivet. |
| giftcard.redeemed | Ett belopp dras från ett kort. |
| order.paid | En order är betald. |
| order.refunded | En order är återbetald. |
| ticket.issued | En biljett är utgiven från en betald order. |
| order.disputed | Köparens kortutgivare har bestridit betalningen. Orderns presentkort och biljetter är pausade och kan inte användas. |
| order.dispute_closed | Ärendet är löst. `won: true` betyder att pausen är hävd och korten fungerar igen; `false` att de är annullerade. |
| booking.created | Ett bord är bokat — av gästen på bokningssidan, i telefon eller vid dörren. |
| booking.changed | En bordsbokning har fått ny tid, nytt datum, nytt antal, nya bord eller en ny status. Hela bokningen följer med, och `status` säger var den står. |
| booking.cancelled | En bordsbokning är avbokad, av gästen eller av restaurangen. Bokningar som flyttas in från ett annat system skickar inga händelser. |
Signaturen
Varje leverans bär en kuvert-signature-header med en tidsstämpel och en HMAC:
kuvert-signature: t=1753440000,v1=6f3a…Signaturen är HMAC-SHA256 i hex över strängen tidsstämpel, punkt, den råa kroppen — beräknad med din slutpunkts-hemlighet:
HMAC_SHA256(secret, "{t}.{raw body}")Verifiera i Node
import { createHmac, timingSafeEqual } from 'node:crypto'
function verify(header, rawBody, secret, toleranceSec = 300) {
const parts = Object.fromEntries(
header.split(',').map((kv) => kv.split('=')),
)
const t = Number(parts.t)
if (!t || !parts.v1) return false
// Afvis for gamle leverancer — det stopper genafspilning.
if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false
const expected = createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex')
const a = Buffer.from(expected, 'hex')
const b = Buffer.from(parts.v1, 'hex')
return a.length === b.length && timingSafeEqual(a, b)
}Svara snabbt
- Bekräfta med 2xx så snart du har mottagit. Lägg det tunga arbetet i en kö.
- Leverans är bästa försök — en slutpunkt som är nere håller aldrig ett köp tillbaka för företaget.
- Räkna med att kunna ta emot samma händelse två gånger och gör din hantering idempotent.
Krav på URL
Slutpunkten måste vara en offentligt tillgänglig HTTPS-adress. Interna adresser avvisas — det är ett avsiktligt block mot att en slutpunkt används för att nå in i vårt eget nätverk.