Hoppa till innehåll

Webhook-integration

Webhooks låter dina system ta emot realtidsnotiser när händelser inträffar på ditt Wink-konto — nya bokningar, avbokningar, betalningsuppdateringar och mer. Denna guide leder dig genom installation och bästa praxis.

Denna guide är för utvecklare som integrerar Wink med externa system såsom fastighetshanteringssystem (PMS), kanalhanterare, CRM-system eller anpassade instrumentpaneler.

  1. Du registrerar en webhook-URL på Wink.
  2. När en händelse inträffar (t.ex. en ny bokning) skickar Wink en HTTP POST till din URL.
  3. Din server bearbetar payloaden och svarar med en 200 OK.
  1. Logga in på ditt konto (Extranet, Studio eller TripPay — alla stödjer webhooks).
  2. Navigera till Applications och sedan Webhooks. Se Webhooks.
  3. Klicka på Create webhook.
  4. Ange ett namn (t.ex. “PMS Booking Sync”).
  5. Ange din webhook-URL — HTTPS-endpointen på din server.
  6. Välj händelser — Välj specifika händelser att prenumerera på, eller lämna tomt för att ta emot alla händelser.
  7. Växla Enabled till på.
  8. Klicka på Save — svaret visar din signeringshemlighet en gång; spara den nu.

Wink publicerar idag 70 webhook-händelsetyper inom bokningar, fastigheter, konton (hanterande enheter) och inventarier (rumstyper, prisplaner, huvudpriser, tillägg, faciliteter, försäljningskanaler, kampanjer). Vanliga exempel:

KategoriExempel
Bokningbooking.create, booking.cancelled, booking.refund.partial, booking.refund.full, booking.review.created
Fastighetproperty.created, property.status.updated, property.policy.updated
Inventarieroom_type.updated, rate_plan.created, master_rate.updated, special_rate.created, sales_channel.created
Kontomanaging_entity.created, managing_entity.status.updated, managing_entity.manager.added

Den kompletta, genererade listan — med beskrivning, vem som tar emot den och en länk till varje händelses referenssida — är Webhook Events Catalog. Referenssidan för varje händelse (JSON-body, headers, retry-policy) finns i Webhooks API.

Visa alla händelsetyper

Varje leverans är en HTTP POST till din webhook-URL med Content-Type: application/json och detta 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 — händelseidentifieraren; identisk för varje endpoint på ditt konto som tar emot denna händelse och för varje omförsök. Använd den som din idempotensnyckel.
  • type — händelsetypens nyckel (skickas också som Wink-Event-Type header). Granska type och schemaVersion för att tolka object.
  • object — en sammanställd sammanfattning av resursen som händelsen gäller (identifierare, status, de fält du agerar på) plus links.self, leverantörssidans kanoniska REST-URL för hela resursen. Hämta den med dina egna API-uppgifter när du behöver mer än sammanfattningen; om du tar emot händelsen som återförsäljare eller resebyrå, använd motsvarande resursendpoint i din egen API-yta för samma identifierare.

Varje payload-schema dokumenteras per händelse i Webhooks API referensen.

HeaderBetydelse
Wink-VersionWire-kontraktsversion, 2.0.
Wink-Event-IdSamma som id i kroppen — din idempotensnyckel.
Wink-Delivery-IdUnik per endpoint per händelse; ändras endast vid omleverans.
Wink-Event-TypeSamma som type i kroppen.
Wink-Delivery-Attempt1-baserat försök nummer för denna leverans.
Wink-SignatureHMAC-signatur — se nedan.

Varje webhook har en signeringshemlighet (whsec_…) som Wink visar en gång, när du skapar webhooken eller roterar dess hemlighet. Spara den som ett lösenord. Varje leverans bär

Wink-Signature: t=1755250200,v1=5d41402abc4b2a76b9719d911017c592…

där t är en Unix-tidsstämpel (sekunder) och v1 är den gemenerade hexadecimala HMAC-SHA256 av strängen t + "." + rawBody, nycklad med din hemlighet, och rawBody är exakt begäranens kroppsbitar som mottagits — serialisera inte om JSON innan verifiering. I 24 timmar efter en hemlighetsrotation bär headern ett andra v1=-värde signerat med den tidigare hemligheten; acceptera leveransen om någon v1 matchar.

Verifiera i fyra steg: tolka t och varje v1; beräkna om HMAC över t.rawBody med din hemlighet; jämför med en konstant-tidsjämförelse; avvisa om |nu − t| överstiger din tolerans (5 minuter rekommenderas).

// Node.js (Express-stil; se till att du har RAW-kroppen, inte ett tolkat 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')));
}
// Java
static 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)));
}

Rotera hemligheten från portalen eller med POST /api/managing-entity/{id}/webhook/{webhookId}/rotate-secret; svaret visar den nya hemligheten en gång, och den gamla fortsätter verifieras i 24 timmar medan du rullar ut den.

  • Svara med valfri 2xx inom 10 sekunder för att bekräfta. Gör det tunga arbetet asynkront.
  • En 5xx, timeout, 408 eller 429 försöks om med backoff: efter 1 minut, 5 minuter, 30 minuter, 2 timmar, 6 timmar, 12 timmar, sedan dagligen — 10 försök under cirka 3 dagar — varefter leveransen markeras som död.
  • Alla andra 4xx behandlas som “du avvisade denna leverans” och försöks inte om.
  • Varje händelse, leverans och försök (status, svarssnutt) är synligt under Applications > Webhooks och via API:et (…/webhook/event/grid, …/webhook/delivery/grid). Du kan omleverera vilken leverans som helst (POST …/webhook/delivery/{deliveryId}/redeliver, vilket startar en ny omförsöksserie), omleverera alla döda leveranser för en webhook på en gång (POST …/webhook/{webhookId}/redeliver-dead), eller avbryta en.
  • Leveranser sparas i 30 dagar.

Skicka en syntetisk webhook.test-händelse till dig själv från portalen eller med POST /api/managing-entity/{id}/webhook/{webhookId}/test. Den är signerad och levereras precis som en riktig händelse, så du kan verifiera din endpoint, din signaturkontroll och din idempotenshantering innan du prenumererar på live-händelser.

  • Använd HTTPS — Wink skickar payloads endast till HTTPS-endpoints.
  • Svara snabbt — Returnera en 200 OK så snart du tar emot payloaden. Gör allt tungt arbete asynkront.
  • Idempotens — Din hanterare bör vara idempotent; deduplicera på Wink-Event-Id. Wink försöker om när den inte får ett 2xx-svar.
  • Verifiera källan — Verifiera Wink-Signature-headern (se Verifiera signaturer) innan bearbetning; avvisa allt som misslyckas.
  • Loggning — Logga varje webhook-payload du tar emot. Detta gör felsökning av integrationsproblem mycket enklare.

Du kan inaktivera en webhook utan att ta bort den. Detta pausar leveransen så att du kan felsöka utan att förlora din konfiguration. När du är redo, slå på den igen.

Att ta bort en webhook tar bort den permanent. Alla integrationer som förlitar sig på den webhooken slutar ta emot notiser.