Skip to content

Integracija Webhooka

Webhookovi omogućuju vašim sustavima da primaju obavijesti u stvarnom vremenu kada se događaji dogode na vašem Wink računu — nove rezervacije, otkazivanja, ažuriranja plaćanja i još mnogo toga. Ovaj vodič vodi vas kroz postavljanje i najbolje prakse.

Ovaj vodič je namijenjen programerima koji integriraju Wink s vanjskim sustavima poput sustava za upravljanje nekretninama (PMS), channel managera, CRM-ova ili prilagođenih nadzornih ploča.

  1. Registrirate URL webhooka na Wink-u.
  2. Kada se dogodi događaj (npr. nova rezervacija), Wink šalje HTTP POST na vaš URL.
  3. Vaš poslužitelj obrađuje podatke i odgovara s 200 OK.
  1. Prijavite se na svoj račun (Extranet, Studio ili TripPay — svi podržavaju webhookove).
  2. Idite na Applications, zatim Webhooks. Pogledajte Webhooks.
  3. Kliknite Create webhook.
  4. Unesite ime (npr. “PMS Sinkronizacija Rezervacija”).
  5. Unesite svoj webhook URL — HTTPS krajnju točku na vašem poslužitelju.
  6. Odaberite događaje — Odaberite specifične događaje na koje se želite pretplatiti ili ostavite prazno za primanje svih događaja.
  7. Uključite Enabled.
  8. Kliknite Save — odgovor prikazuje vaš signing secret jednom; spremite ga odmah.

Wink danas objavljuje 70 vrsta webhook događaja koji pokrivaju rezervacije, nekretnine, račune (entiteti za upravljanje) i inventar (vrste soba, planove cijena, glavne cijene, dodatke, sadržaje, prodajne kanale, promocije). Najčešći:

KategorijaPrimjeri
Rezervacijabooking.create, booking.cancelled, booking.refund.partial, booking.refund.full, booking.review.created
Nekretninaproperty.created, property.status.updated, property.policy.updated
Inventarroom_type.updated, rate_plan.created, master_rate.updated, special_rate.created, sales_channel.created
Računmanaging_entity.created, managing_entity.status.updated, managing_entity.manager.added

Potpuni, generirani popis — s opisom, tko ga prima i poveznicom na referentnu stranicu svakog događaja — je Katalog Webhook Događaja. Referentna stranica za svaki događaj (JSON tijelo, zaglavlja, pravila ponovnog slanja) nalazi se u Webhooks API.

Pogledajte sve vrste događaja

Svaka dostava je HTTP POST na vaš webhook URL s Content-Type: application/json i ovom omotnicom:

{
"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 — identifikator događaja; isti je za svaku krajnju točku vašeg računa koja prima ovaj događaj i za svaki pokušaj ponovnog slanja. Koristite ga kao svoj ključ idempotentnosti.
  • type — ključ vrste događaja (također se šalje kao zaglavlje Wink-Event-Type). Granajte prema type i schemaVersion za parsiranje object.
  • object — sažetak resursa na koji se događaj odnosi (identifikatori, status, polja na koja djelujete) plus links.self, kanonski REST URL dobavljača za puni resurs. Dohvatite ga s vlastitim API vjerodajnicama kad vam treba više od sažetka; ako primate događaj kao preprodavač ili putni agent, koristite odgovarajuću krajnju točku vlastitog API-ja za isti identifikator.

Svaka shema podataka je dokumentirana po događaju u referenci Webhooks API.

ZaglavljeZnačenje
Wink-VersionVerzija wire ugovora, 2.0.
Wink-Event-IdIsto kao id u tijelu — vaš ključ idempotentnosti.
Wink-Delivery-IdJedinstveno po krajnjoj točki po događaju; mijenja se samo ako ponovno šaljete.
Wink-Event-TypeIsto kao type u tijelu.
Wink-Delivery-AttemptBroj pokušaja dostave, počevši od 1.
Wink-SignatureHMAC potpis — vidi dolje.

Svaki webhook ima signing secret (whsec_…) koji Wink prikazuje jednom, prilikom stvaranja webhooka ili rotacije tajne. Spremite ga kao lozinku. Svaka dostava nosi

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

gdje je t Unix vremenska oznaka (sekunde), a v1 je mala heksadecimalna HMAC-SHA256 vrijednost stringa t + "." + rawBody, potpisana vašom tajnom, a rawBody je točno tijelo zahtjeva u bajtovima kako je primljeno — nemojte ponovno serijalizirati JSON prije verifikacije. 24 sata nakon rotacije tajne zaglavlje nosi drugi v1= potpisan prethodnom tajnom; prihvatite dostavu ako se bilo koji v1 podudara.

Provjerite u četiri koraka: parsirajte t i svaki v1; ponovno izračunajte HMAC preko t.rawBody s vašom tajnom; usporedite s usporedbom u konstantnom vremenu; odbacite ako |now − t| prelazi vašu toleranciju (preporučeno 5 minuta).

// Node.js (Express-style; provjerite da imate RAW tijelo, a ne parsirani 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)));
}

Rotirajte tajnu iz portala ili s POST /api/managing-entity/{id}/webhook/{webhookId}/rotate-secret; odgovor prikazuje novu tajnu jednom, a stara ostaje valjana 24 sata dok je uvodite.

  • Odgovorite s bilo kojim 2xx unutar 10 sekundi za potvrdu. Teške zadatke obavite asinhrono.
  • 5xx, timeout, 408 ili 429 se ponovo pokušavaju s odgodom: nakon 1 minute, 5 minuta, 30 minuta, 2 sata, 6 sati, 12 sati, zatim dnevno — 10 pokušaja tijekom otprilike 3 dana — nakon čega se dostava označava kao mrtva.
  • Bilo koji drugi 4xx tretira se kao “odbijena dostava” i ne ponavlja se.
  • Svaki događaj, dostava i pokušaj (status, isječak odgovora) vidljivi su pod Applications > Webhooks i putem API-ja (…/webhook/event/grid, …/webhook/delivery/grid). Možete ponovno poslati bilo koju dostavu (POST …/webhook/delivery/{deliveryId}/redeliver, što pokreće novi niz pokušaja), ponovno poslati sve mrtve dostave webhooka odjednom (POST …/webhook/{webhookId}/redeliver-dead), ili otkazati jednu.
  • Dostave se čuvaju 30 dana.

Pošaljite si sintetički događaj webhook.test iz portala ili s POST /api/managing-entity/{id}/webhook/{webhookId}/test. Potpisan je i dostavljen kao pravi događaj, tako da možete provjeriti svoju krajnju točku, provjeru potpisa i rukovanje idempotentnošću prije pretplate na stvarne događaje.

  • Koristite HTTPS — Wink šalje podatke samo na HTTPS krajnje točke.
  • Odgovarajte brzo — Vratite 200 OK čim primite podatke. Teške procese obavite asinhrono.
  • Idempotentnost — Vaš handler treba biti idempotentan; deduplicirajte po Wink-Event-Id. Wink ponavlja pokušaje ako ne primi 2xx odgovor.
  • Provjerite izvor — Provjerite zaglavlje Wink-Signature (vidi Verifikacija potpisa) prije obrade; odbacite sve što ne uspije.
  • Evidencija — Zabilježite svaki webhook payload koji primite. To znatno olakšava otklanjanje problema s integracijom.

Možete onemogućiti webhook bez brisanja. Time se pauzira dostava kako biste mogli riješiti probleme bez gubitka konfiguracije. Kad ste spremni, ponovno ga uključite.

Brisanje webhooka trajno ga uklanja. Svaka integracija koja ovisi o tom webhooku prestat će primati obavijesti.