Integrazione Webhook
I webhook permettono ai tuoi sistemi di ricevere notifiche in tempo reale quando si verificano eventi sul tuo account Wink — nuove prenotazioni, cancellazioni, aggiornamenti di pagamento e altro. Questa guida ti accompagna nella configurazione e nelle migliori pratiche.
Pubblico
Sezione intitolata “Pubblico”Questa guida è rivolta agli sviluppatori che integrano Wink con sistemi esterni come property management system (PMS), channel manager, CRM o dashboard personalizzate.
Come funzionano i webhook
Sezione intitolata “Come funzionano i webhook”- Registri un URL webhook su Wink.
- Quando si verifica un evento (es. una nuova prenotazione), Wink invia un HTTP POST al tuo URL.
- Il tuo server elabora il payload e risponde con un
200 OK.
Configurare un webhook
Sezione intitolata “Configurare un webhook”- Accedi al tuo account (Extranet, Studio o TripPay — tutti supportano i webhook).
- Vai su
Applicationse poi suWebhooks. Vedi Webhooks. - Clicca su
Create webhook. - Inserisci un nome (es. “Sincronizzazione Prenotazioni PMS”).
- Inserisci il tuo webhook URL — l’endpoint HTTPS sul tuo server.
- Seleziona eventi — scegli eventi specifici a cui iscriverti, oppure lascia vuoto per ricevere tutti gli eventi.
- Attiva l’opzione Enabled.
- Clicca su
Save— la risposta mostra il tuo signing secret una sola volta; salvalo subito.
Tipi di eventi
Sezione intitolata “Tipi di eventi”Wink pubblica oggi 70 tipi di eventi webhook tra prenotazioni, proprietà, account (entità gestenti) e inventario (tipi di camera, piani tariffari, tariffe master, extra, servizi, canali di vendita, promozioni). I più comuni:
| Categoria | Esempi |
|---|---|
| Prenotazione | booking.create, booking.cancelled, booking.refund.partial, booking.refund.full, booking.review.created |
| Proprietà | property.created, property.status.updated, property.policy.updated |
| Inventario | room_type.updated, rate_plan.created, master_rate.updated, special_rate.created, sales_channel.created |
| Account | managing_entity.created, managing_entity.status.updated, managing_entity.manager.added |
L’elenco completo e generato — con descrizione, destinatari e link alla pagina di riferimento di ogni evento — è il Catalogo Eventi Webhook. La pagina di riferimento per ogni evento (corpo JSON, header, politica di retry) si trova nella Webhooks API.
Visualizza tutti i tipi di evento
Cosa ricevi
Sezione intitolata “Cosa ricevi”Ogni consegna è un HTTP POST al tuo URL webhook con Content-Type: application/json e questo involucro:
{ "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": { "...": "payload specifico dell'evento, es. BookingWebhookPayload" }}id— identificatore dell’evento; identico per ogni endpoint del tuo account che riceve questo evento e per ogni retry. Usalo come tua chiave di idempotenza.type— chiave del tipo di evento (inviata anche come headerWink-Event-Type). Gestisci in base atypeeschemaVersionper interpretareobject.object— un riassunto curato della risorsa a cui si riferisce l’evento (identificatori, stato, campi su cui agisci) piùlinks.self, l’URL REST canonico lato fornitore della risorsa completa. Recuperalo con le tue credenziali API quando ti serve più del riassunto; se ricevi l’evento come rivenditore o agente di viaggio, usa l’endpoint corrispondente della tua API per lo stesso identificatore.
Ogni schema payload è documentato per evento nella Webhooks API di riferimento.
| Header | Significato |
|---|---|
Wink-Version | Versione del contratto wire, 2.0. |
Wink-Event-Id | Uguale a id nel corpo — la tua chiave di idempotenza. |
Wink-Delivery-Id | Unico per endpoint per evento; cambia solo se ridistribuisci. |
Wink-Event-Type | Uguale a type nel corpo. |
Wink-Delivery-Attempt | Numero di tentativo 1-based per questa consegna. |
Wink-Signature | Firma HMAC — vedi sotto. |
Verifica delle firme
Sezione intitolata “Verifica delle firme”Ogni webhook ha un signing secret (whsec_…) che Wink mostra una sola volta, quando crei il webhook o ruoti il suo segreto. Salvalo come una password. Ogni consegna porta
Wink-Signature: t=1755250200,v1=5d41402abc4b2a76b9719d911017c592…dove t è un timestamp Unix (secondi) e v1 è l’HMAC-SHA256 in esadecimale minuscolo della stringa
t + "." + rawBody, firmata con il tuo segreto, e rawBody è il corpo esatto della richiesta ricevuta — non rieseguire la serializzazione JSON prima di verificare. Per 24 ore dopo una rotazione del segreto l’header porta un secondo valore v1= firmato con il segreto precedente; accetta la consegna se qualunque v1 corrisponde.
Verifica in quattro passaggi: analizza t e ogni v1; ricalcola l’HMAC su t.rawBody con il tuo segreto; confronta con un confronto a tempo costante; rifiuta se |now − t| supera la tua tolleranza (consigliati 5 minuti).
// Node.js (stile Express; assicurati di avere il corpo RAW, non un oggetto parsato)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)));}Ruota il segreto dal portale o con POST /api/managing-entity/{id}/webhook/{webhookId}/rotate-secret;
la risposta mostra il nuovo segreto una sola volta, e quello vecchio continua a essere valido per 24 ore mentre lo distribuisci.
Ritenti e ridistribuzione
Sezione intitolata “Ritenti e ridistribuzione”- Rispondi con qualsiasi
2xxentro 10 secondi per confermare. Esegui il lavoro pesante in modo asincrono. - Un
5xx, timeout,408o429viene ritentato con backoff: dopo 1 minuto, 5 minuti, 30 minuti, 2 ore, 6 ore, 12 ore, poi giornalmente — 10 tentativi in circa 3 giorni — dopo i quali la consegna è marcata dead. - Qualsiasi altro
4xxè trattato come “hai rifiutato questa consegna” e non viene ritentato. - Ogni evento, consegna e tentativo (stato, snippet di risposta) è visibile sotto Applications > Webhooks
e tramite API (
…/webhook/event/grid,…/webhook/delivery/grid). Puoi ridistribuire qualsiasi consegna (POST …/webhook/delivery/{deliveryId}/redeliver, che avvia una nuova serie di tentativi), ridistribuire tutte le consegne dead di un webhook in una volta (POST …/webhook/{webhookId}/redeliver-dead), o annullarne una. - Le consegne sono conservate per 30 giorni.
Eventi di test
Sezione intitolata “Eventi di test”Invia a te stesso un evento sintetico webhook.test dal portale o con
POST /api/managing-entity/{id}/webhook/{webhookId}/test. È firmato e consegnato esattamente come un evento reale,
così puoi verificare il tuo endpoint, il controllo della firma e la gestione dell’idempotenza prima di iscriverti
agli eventi live.
Migliori pratiche
Sezione intitolata “Migliori pratiche”- Usa HTTPS — Wink invia payload solo a endpoint HTTPS.
- Rispondi rapidamente — Restituisci un
200 OKappena ricevi il payload. Esegui qualsiasi elaborazione pesante in modo asincrono. - Idempotenza — Il tuo handler deve essere idempotente; deduplica su
Wink-Event-Id. Wink ritenta se non riceve una risposta2xx. - Valida la fonte — Verifica l’header
Wink-Signature(vedi Verifica delle firme) prima di elaborare; rifiuta tutto ciò che fallisce. - Logging — Registra ogni payload webhook che ricevi. Questo facilita molto il debug delle integrazioni.
Pausa e cancellazione
Sezione intitolata “Pausa e cancellazione”Puoi disabilitare un webhook senza cancellarlo. Questo mette in pausa la consegna così puoi risolvere problemi senza perdere la configurazione. Quando sei pronto, riattivalo.
Cancellare un webhook lo rimuove definitivamente. Qualsiasi integrazione che si basa su quel webhook smetterà di ricevere notifiche.
Ulteriori letture
Sezione intitolata “Ulteriori letture”- Catalogo Eventi Webhook — Ogni tipo di evento, generato dal catalogo della piattaforma.
- Riferimento API Webhooks — Schemi payload per evento, header e endpoint di gestione iscrizioni/consegne.
- Webhooks — Riferimento completo per la gestione dei webhook.
- Applications — Gestisci le tue credenziali API.
- Developers > APIs — Documentazione completa delle API.
