Webhook-integration
Webhooks lader dine systemer modtage realtidsnotifikationer, når der sker begivenheder på din Wink-konto — nye bookinger, aflysninger, betalingsopdateringer og mere. Denne guide fører dig gennem opsætning og bedste praksis.
Målgruppe
Sektion kaldt “Målgruppe”Denne guide er til udviklere, der integrerer Wink med eksterne systemer som ejendomsadministrationssystemer (PMS), channel managers, CRM’er eller brugerdefinerede dashboards.
Sådan fungerer webhooks
Sektion kaldt “Sådan fungerer webhooks”- Du registrerer en webhook-URL på Wink.
- Når en begivenhed opstår (f.eks. en ny booking), sender Wink en HTTP POST til din URL.
- Din server behandler payloaden og svarer med en
200 OK.
Opsætning af en webhook
Sektion kaldt “Opsætning af en webhook”- Log ind på din konto (Extranet, Studio eller TripPay — alle understøtter webhooks).
- Gå til
Applicationsog derefterWebhooks. Se Webhooks. - Klik på
Create webhook. - Indtast et navn (f.eks. “PMS Booking Sync”).
- Indtast din webhook URL — HTTPS-endpointet på din server.
- Vælg begivenheder — Vælg specifikke begivenheder at abonnere på, eller lad det stå tomt for at modtage alle begivenheder.
- Skift Enabled til til.
- Klik på
Save— svaret viser din signeringshemmelighed én gang; gem den nu.
Begivenhedstyper
Sektion kaldt “Begivenhedstyper”Wink udgiver i dag 70 webhook-begivenhedstyper inden for bookinger, ejendomme, konti (styrende enheder) og lager (værelsestyper, rateplaner, masterrater, tillæg, faciliteter, salgskanaler, kampagner). Almindelige:
| Kategori | Eksempler |
|---|---|
| Booking | booking.create, booking.cancelled, booking.refund.partial, booking.refund.full, booking.review.created |
| Ejendom | property.created, property.status.updated, property.policy.updated |
| Lager | room_type.updated, rate_plan.created, master_rate.updated, special_rate.created, sales_channel.created |
| Konto | managing_entity.created, managing_entity.status.updated, managing_entity.manager.added |
Den komplette, genererede liste — med beskrivelse, hvem der modtager den, og et link til hver begivenheds reference-side — er Webhook Events Catalog. Referencesiden for hver begivenhed (JSON-body, headers, retry-politik) findes i Webhooks API.
Se alle begivenhedstyper
Hvad du modtager
Sektion kaldt “Hvad du modtager”Hver levering er en HTTP POST til din webhook-URL med Content-Type: application/json og denne kuvert:
{ "id": "0198a4f2-6b0e-7c1d-9a3e-2f4b8c6d1e0a", "type": "booking.create", "occurredAt": "2026-08-15T09:30:00Z", "ownerIdentifier": "3c6b1a5d-8e2f-4a0b-9c7d-6e4f0a8b2c51", "recipientRole": "SUPPLIER", "schemaVersion": 2, "object": { "...": "event-specific payload, e.g. BookingWebhookPayload" }}id— begivenhedsidentifikatoren; identisk for hvert endpoint på din konto, der modtager denne begivenhed, og for hver genforsøg. Brug den som din idempotensnøgle.type— begivenhedstypenøglen (også sendt somWink-Event-Typeheader). Branchér påtypeogschemaVersionfor at parseobject.object— et kurateret resumé af ressourcen, som begivenheden handler om (identifikatorer, status, de felter du handler på) pluslinks.self, den leverandørsidige kanoniske REST-URL for den fulde ressource. Hent den med dine egne API-legitimationsoplysninger, når du har brug for mere end resumeet; hvis du modtager begivenheden som forhandler eller rejsebureau, brug da det tilsvarende ressource-endpoint i dit eget API for samme identifikator.
Hver payload-skema er dokumenteret pr. begivenhed i Webhooks API referencen.
Headers
Sektion kaldt “Headers”| Header | Betydning |
|---|---|
Wink-Version | Wire-kontraktversion, 2.0. |
Wink-Event-Id | Samme som id i body — din idempotensnøgle. |
Wink-Delivery-Id | Unik pr. endpoint pr. begivenhed; ændres kun ved genlevering. |
Wink-Event-Type | Samme som type i body. |
Wink-Delivery-Attempt | 1-baseret forsøg nummer for denne levering. |
Wink-Signature | HMAC-signatur — se nedenfor. |
Verificering af signaturer
Sektion kaldt “Verificering af signaturer”Hver webhook har en signeringshemmelighed (whsec_…), som Wink viser én gang, når du opretter webhooken eller roterer dens hemmelighed. Gem den som en adgangskode. Hver levering bærer
Wink-Signature: t=1755250200,v1=5d41402abc4b2a76b9719d911017c592…hvor t er et Unix-tidsstempel (sekunder) og v1 er den småbogstavede hex HMAC-SHA256 af strengen t + "." + rawBody, nøglekodet med din hemmelighed, og rawBody er de præcise request-body bytes som modtaget — serialiser ikke JSON på ny før verifikation. I 24 timer efter en hemmelighedsrotation bærer headeren en anden v1= værdi signeret med den tidligere hemmelighed; accepter leveringen hvis en hvilken som helst v1 matcher.
Verificer i fire trin: parse t og hver v1; genberegn HMAC over t.rawBody med din hemmelighed; sammenlign med en konstant-tids sammenligning; afvis hvis |nu − t| overstiger din tolerance (5 minutter anbefales).
// Node.js (Express-stil; sørg for at du har RAW body, ikke et parset objekt)import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWinkSignature(header, rawBody, secret, toleranceSeconds = 300) { const parts = Object.fromEntries(header.split(',').map((p) => p.split('=').map((s) => s.trim()))); const t = Number(parts.t); if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false; const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex'); return header .split(',') .filter((p) => p.trim().startsWith('v1=')) .map((p) => p.trim().slice(3)) .some((v1) => v1.length === expected.length && timingSafeEqual(Buffer.from(v1, 'utf8'), Buffer.from(expected, 'utf8')));}// Javastatic boolean verify(String header, String rawBody, String secret, long nowSeconds, long toleranceSeconds) throws Exception { long t = Long.MIN_VALUE; List<String> signatures = new ArrayList<>(); for (String part : header.split(",")) { String[] kv = part.trim().split("=", 2); if (kv[0].equals("t")) t = Long.parseLong(kv[1]); else if (kv[0].equals("v1")) signatures.add(kv[1]); } if (t == Long.MIN_VALUE || Math.abs(nowSeconds - t) > toleranceSeconds) return false; Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); byte[] expected = HexFormat.of().formatHex(mac.doFinal((t + "." + rawBody).getBytes(StandardCharsets.UTF_8))).getBytes(StandardCharsets.US_ASCII); return signatures.stream().anyMatch(v1 -> MessageDigest.isEqual(expected, v1.toLowerCase().getBytes(StandardCharsets.US_ASCII)));}Roter hemmeligheden fra portalen eller med POST /api/managing-entity/{id}/webhook/{webhookId}/rotate-secret; svaret viser den nye hemmelighed én gang, og den gamle fortsætter med at verificere i 24 timer, mens du ruller den ud.
Genforsøg og genlevering
Sektion kaldt “Genforsøg og genlevering”- Svar med enhver
2xxinden for 10 sekunder for at bekræfte. Udfør tung behandling asynkront. - En
5xx, timeout,408eller429genforsøges med backoff: efter 1 minut, 5 minutter, 30 minutter, 2 timer, 6 timer, 12 timer, derefter dagligt — 10 forsøg over ca. 3 dage — hvorefter leveringen markeres som død. - Enhver anden
4xxbehandles som “du afviste denne levering” og genforsøges ikke. - Hver begivenhed, levering og forsøg (status, svaruddrag) er synlig under Applications > Webhooks og via API’en (
…/webhook/event/grid,…/webhook/delivery/grid). Du kan genlevere enhver levering (POST …/webhook/delivery/{deliveryId}/redeliver, som starter en ny retry-serie), genlevere alle døde leveringer for en webhook på én gang (POST …/webhook/{webhookId}/redeliver-dead), eller annullere en. - Leveringer opbevares i 30 dage.
Testbegivenheder
Sektion kaldt “Testbegivenheder”Send dig selv en syntetisk webhook.test begivenhed fra portalen eller med POST /api/managing-entity/{id}/webhook/{webhookId}/test. Den er signeret og leveret præcis som en rigtig begivenhed, så du kan verificere dit endpoint, din signaturkontrol og din idempotenshåndtering før du abonnerer på live-begivenheder.
Bedste praksis
Sektion kaldt “Bedste praksis”- Brug HTTPS — Wink sender payloads kun til HTTPS-endpoints.
- Svar hurtigt — Returner en
200 OKså snart du modtager payloaden. Udfør tung behandling asynkront. - Idempotens — Din handler bør være idempotent; dedupliker på
Wink-Event-Id. Wink genforsøger, når den ikke modtager et2xxsvar. - Valider kilden — Verificer
Wink-Signatureheaderen (se Verificering af signaturer) før behandling; afvis alt der fejler. - Logning — Log hver webhook-payload du modtager. Det gør fejlfinding af integrationsproblemer meget nemmere.
Pause og sletning
Sektion kaldt “Pause og sletning”Du kan deaktivere en webhook uden at slette den. Dette pauser leveringen, så du kan fejlfinde uden at miste din konfiguration. Når du er klar, skifter du den til igen.
Sletning af en webhook fjerner den permanent. Enhver integration, der er afhængig af den webhook, vil stoppe med at modtage notifikationer.
Yderligere læsning
Sektion kaldt “Yderligere læsning”- Webhook Events Catalog — Alle begivenhedstyper, genereret fra platformens katalog.
- Webhooks API reference — Payload-skemaer pr. begivenhed, headers og abonnement-/leveringsstyringsendpoints.
- Webhooks — Fuld reference for webhook-administration.
- Applications — Administrer dine API-legitimationsoplysninger.
- Developers > APIs — Fuld API-dokumentation.
