Інтеграція Webhook
Webhook дозволяють вашим системам отримувати сповіщення в реальному часі, коли відбуваються події у вашому акаунті Wink — нові бронювання, скасування, оновлення платежів та інше. Цей посібник проведе вас через налаштування та найкращі практики.
Аудиторія
Section titled “Аудиторія”Цей посібник призначений для розробників, які інтегрують Wink з зовнішніми системами, такими як системи управління нерухомістю (PMS), менеджери каналів, CRM або кастомні панелі керування.
Як працюють webhook
Section titled “Як працюють webhook”- Ви реєструєте URL webhook у Wink.
- Коли відбувається подія (наприклад, нове бронювання), Wink надсилає HTTP POST на ваш URL.
- Ваш сервер обробляє дані та відповідає з
200 OK.
Налаштування webhook
Section titled “Налаштування webhook”- Увійдіть у свій акаунт (Extranet, Studio або TripPay — всі підтримують webhook).
- Перейдіть до
Applications, а потімWebhooks. Див. Webhooks. - Натисніть
Create webhook. - Введіть назву (наприклад, “PMS Booking Sync”).
- Введіть свій URL webhook — HTTPS-ендпоінт на вашому сервері.
- Виберіть події — Оберіть конкретні події для підписки або залиште порожнім, щоб отримувати всі події.
- Увімкніть перемикач Enabled.
- Натисніть
Save— відповідь покаже ваш секрет підпису лише один раз; збережіть його зараз.
Типи подій
Section titled “Типи подій”Wink сьогодні публікує 70 типів подій webhook, що охоплюють бронювання, об’єкти, акаунти (керуючі суб’єкти) та інвентар (типи номерів, тарифні плани, основні тарифи, додаткові послуги, об’єкти, канали продажів, акції). Поширені:
| Категорія | Приклади |
|---|---|
| Бронювання | booking.create, booking.cancelled, booking.refund.partial, booking.refund.full, booking.review.created |
| Об’єкт | property.created, property.status.updated, property.policy.updated |
| Інвентар | room_type.updated, rate_plan.created, master_rate.updated, special_rate.created, sales_channel.created |
| Акаунт | managing_entity.created, managing_entity.status.updated, managing_entity.manager.added |
Повний згенерований список — з описом, хто його отримує, та посиланням на сторінку довідки по кожній події — це Каталог подій Webhook. Сторінка довідки для кожної події (JSON-тіло, заголовки, політика повторних спроб) знаходиться у Webhooks API.
Переглянути всі типи подій
Що ви отримуєте
Section titled “Що ви отримуєте”Кожна доставка — це HTTP POST на ваш URL webhook з Content-Type: application/json та таким конвертом:
{ "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— ідентифікатор події; однаковий для кожного ендпоінта вашого акаунта, що отримує цю подію, і для кожної повторної спроби. Використовуйте його як ключ ідемпотентності.type— ключ типу події (також надсилається в заголовкуWink-Event-Type). Відгалужуйте логіку заtypeіschemaVersion, щоб розпарситиobject.object— курований підсумок ресурсу, про який подія (ідентифікатори, статус, поля, на які ви реагуєте), а такожlinks.self— канонічний REST URL повного ресурсу зі сторони постачальника. Отримуйте його з власними API-обліковими даними, якщо потрібна детальніша інформація; якщо ви отримуєте подію як реселер або турагент, використовуйте відповідний ресурс вашого API для того ж ідентифікатора.
Кожна схема даних описана для кожної події у довідці Webhooks API.
Заголовки
Section titled “Заголовки”| Заголовок | Значення |
|---|---|
Wink-Version | Версія контракту, 2.0. |
Wink-Event-Id | Те саме, що id у тілі — ваш ключ ідемпотентності. |
Wink-Delivery-Id | Унікальний для ендпоінта на подію; змінюється лише при повторній доставці. |
Wink-Event-Type | Те саме, що type у тілі. |
Wink-Delivery-Attempt | Номер спроби доставки, починаючи з 1. |
Wink-Signature | HMAC-підпис — див. нижче. |
Перевірка підписів
Section titled “Перевірка підписів”Кожен webhook має секрет підпису (whsec_…), який Wink показує лише один раз при створенні webhook або зміні секрету. Збережіть його як пароль. Кожна доставка містить
Wink-Signature: t=1755250200,v1=5d41402abc4b2a76b9719d911017c592…де t — Unix-мітка часу (секунди), а v1 — нижній регістр hex HMAC-SHA256 рядка
t + "." + rawBody, підписаного вашим секретом, а rawBody — точний байтовий вміст тіла запиту, як отримано — не перетворюйте JSON перед перевіркою. Протягом 24 годин після зміни секрету заголовок містить друге значення v1=, підписане попереднім секретом; приймайте доставку, якщо будь-який v1 співпадає.
Перевіряйте у чотири кроки: розпарсіть t і всі v1; повторно обчисліть HMAC для t.rawBody з вашим секретом; порівняйте з використанням порівняння з постійним часом; відхиліть, якщо |now − t| перевищує ваш поріг (рекомендується 5 хвилин).
// Node.js (Express-style; переконайтеся, що у вас є RAW body, а не розпарсений об’єкт)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)));}Змініть секрет у порталі або за допомогою POST /api/managing-entity/{id}/webhook/{webhookId}/rotate-secret;
відповідь покаже новий секрет один раз, а старий буде дійсний ще 24 години, поки ви його не заміните.
Повторні спроби та повторна доставка
Section titled “Повторні спроби та повторна доставка”- Відповідайте будь-яким
2xxпротягом 10 секунд для підтвердження. Важку обробку виконуйте асинхронно. 5xx, таймаут,408або429повторюються з інтервалом: через 1 хвилину, 5 хвилин, 30 хвилин, 2 години, 6 годин, 12 годин, потім щодня — 10 спроб протягом приблизно 3 днів — після чого доставка позначається як мертва.- Будь-який інший
4xxвважається відмовою від доставки і не повторюється. - Кожна подія, доставка та спроба (статус, фрагмент відповіді) доступні у Applications > Webhooks
та через API (
…/webhook/event/grid,…/webhook/delivery/grid). Ви можете повторно доставити будь-яку доставку (POST …/webhook/delivery/{deliveryId}/redeliver, що починає нову серію спроб), повторно доставити всі мертві доставки webhook одночасно (POST …/webhook/{webhookId}/redeliver-dead), або скасувати одну. - Доставки зберігаються 30 днів.
Тестові події
Section titled “Тестові події”Надішліть собі синтетичну подію webhook.test з порталу або за допомогою
POST /api/managing-entity/{id}/webhook/{webhookId}/test. Вона підписана і доставляється так само, як реальна
подія, тож ви можете перевірити свій ендпоінт, перевірку підпису та обробку ідемпотентності перед підпискою
на живі події.
Найкращі практики
Section titled “Найкращі практики”- Використовуйте HTTPS — Wink надсилає дані лише на HTTPS-ендпоінти.
- Відповідайте швидко — Поверніть
200 OKодразу після отримання даних. Важку обробку виконуйте асинхронно. - Ідемпотентність — Ваш обробник має бути ідемпотентним; уникайте дублювання за
Wink-Event-Id. Wink повторює спроби, якщо не отримує2xx. - Перевіряйте джерело — Перевіряйте заголовок
Wink-Signature(див. Перевірка підписів) перед обробкою; відхиляйте все, що не проходить перевірку. - Логування — Логуйте кожен отриманий webhook. Це значно полегшує налагодження інтеграції.
Призупинення та видалення
Section titled “Призупинення та видалення”Ви можете відключити webhook без видалення. Це призупиняє доставку, щоб ви могли усунути неполадки без втрати налаштувань. Коли будете готові, увімкніть його знову.
Видалення webhook назавжди його видаляє. Будь-яка інтеграція, що покладається на цей webhook, припинить отримувати сповіщення.
Додаткова інформація
Section titled “Додаткова інформація”- Каталог подій Webhook — Кожен тип події, згенерований з каталогу платформи.
- Довідка Webhooks API — Схеми даних для кожної події, заголовки та ендпоінти керування підписками/доставкою.
- Webhooks — Повна довідка з керування webhook.
- Applications — Керуйте своїми API-обліковими даними.
- Розробники > API — Повна документація API.
