Spring til indhold

API

Webhooks

En webhook lader pirr fortælle dit system, at noget er sket — et kort er udstedt, et beløb er trukket, en ordre er betalt eller refunderet. Hver leverance er signeret, så du kan bevise, at den kom fra os.

Opret et endepunkt

Under Indstillinger → Webhooks tilføjer du den URL, hændelserne skal sendes til. Du får en hemmelighed tilbage — den bruges til at verificere signaturen og skal opbevares som en adgangskode.

Hændelser

HændelseSendes når
giftcard.issuedEt gavekort er udstedt.
giftcard.redeemedEt beløb er trukket fra et kort.
order.paidEn ordre er betalt.
order.refundedEn ordre er refunderet.
ticket.issuedEn billet er udstedt af en betalt ordre.

Signaturen

Hver leverance bærer en pirr-signature-header med et tidsstempel og en HMAC:

pirr-signature: t=1753440000,v1=6f3a…

Signaturen er HMAC-SHA256 i hex over strengen tidsstempel, punktum, den rå krop — beregnet med din endepunkts-hemmelighed:

HMAC_SHA256(secret, "{t}.{raw body}")

Verificér 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)
}

Svar hurtigt

  • Kvittér med 2xx, så snart du har taget imod. Læg det tunge arbejde i en kø.
  • Levering er bedste forsøg — et endepunkt, der er nede, holder aldrig et køb tilbage hos forretningen.
  • Regn med at kunne modtage den samme hændelse to gange, og gør din håndtering idempotent.

Krav til URL

Endepunktet skal være en offentligt tilgængelig HTTPS-adresse. Interne adresser afvises — det er en bevidst spærre mod, at et endepunkt bruges til at nå ind i vores eget netværk.