Интеграция Webhook
Вебхуки позволяют вашим системам получать уведомления в реальном времени при событиях в вашем аккаунте Wink — новые бронирования, отмены, обновления платежей и многое другое. Это руководство проведет вас через процесс настройки и лучшие практики.
Аудитория
Заголовок раздела «Аудитория»Это руководство предназначено для разработчиков, интегрирующих Wink с внешними системами, такими как системы управления недвижимостью (PMS), менеджеры каналов, CRM или пользовательские панели управления.
Как работают вебхуки
Заголовок раздела «Как работают вебхуки»- Вы регистрируете URL вебхука в Wink.
- Когда происходит событие (например, новое бронирование), Wink отправляет HTTP POST на ваш URL.
- Ваш сервер обрабатывает полезную нагрузку и отвечает
200 OK.
Настройка вебхука
Заголовок раздела «Настройка вебхука»- Войдите в свой аккаунт (Extranet, Studio или TripPay — все поддерживают вебхуки).
- Перейдите в
Applications, затемWebhooks. См. Webhooks. - Нажмите
Create webhook. - Введите название (например, “PMS Booking Sync”).
- Введите ваш URL вебхука — HTTPS-эндпоинт на вашем сервере.
- Выберите события — выберите конкретные события для подписки или оставьте пустым, чтобы получать все события.
- Включите переключатель Enabled.
- Нажмите
Save— ответ покажет ваш секрет подписи один раз; сохраните его сейчас.
Типы событий
Заголовок раздела «Типы событий»Wink публикует сегодня 70 типов событий вебхуков по бронированиям, объектам, аккаунтам (управляющим сущностям) и инвентарю (типы номеров, тарифные планы, основные тарифы, доп. услуги, удобства, каналы продаж, акции). Наиболее распространённые:
| Категория | Примеры |
|---|---|
| Бронирование | 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 |
Полный сгенерированный список — с описанием, кто его получает, и ссылкой на страницу справки по каждому событию — это Каталог событий вебхуков. Страница справки для каждого события (JSON тело, заголовки, политика повторных попыток) находится в Webhooks API.
Просмотреть все типы событий
Что вы получаете
Заголовок раздела «Что вы получаете»Каждая доставка — это HTTP POST на ваш URL вебхука с 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.
Заголовки
Заголовок раздела «Заголовки»| Заголовок | Значение |
|---|---|
Wink-Version | Версия контракта, 2.0. |
Wink-Event-Id | То же, что id в теле — ваш ключ идемпотентности. |
Wink-Delivery-Id | Уникальный для эндпоинта и события; меняется только при повторной доставке. |
Wink-Event-Type | То же, что type в теле. |
Wink-Delivery-Attempt | Номер попытки доставки, начиная с 1. |
Wink-Signature | HMAC-подпись — см. ниже. |
Проверка подписей
Заголовок раздела «Проверка подписей»Каждый вебхук имеет секрет подписи (whsec_…), который Wink показывает один раз при создании вебхука или смене секрета. Храните его как пароль. Каждая доставка содержит
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-стиль; убедитесь, что у вас есть RAW тело, а не распарсенный объект)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 часа, пока вы не завершите обновление.
Повторные попытки и повторная доставка
Заголовок раздела «Повторные попытки и повторная доставка»- Отвечайте любым
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, что запускает новую серию попыток), повторно доставить все мертвые доставки вебхука сразу (POST …/webhook/{webhookId}/redeliver-dead), или отменить одну. - Доставки хранятся 30 дней.
Тестовые события
Заголовок раздела «Тестовые события»Отправьте себе синтетическое событие webhook.test из портала или с помощью
POST /api/managing-entity/{id}/webhook/{webhookId}/test. Оно подписано и доставляется точно так же, как реальное
событие, чтобы вы могли проверить свой эндпоинт, проверку подписи и обработку идемпотентности перед подпиской
на живые события.
Лучшие практики
Заголовок раздела «Лучшие практики»- Используйте HTTPS — Wink отправляет полезные нагрузки только на HTTPS-эндпоинты.
- Отвечайте быстро — Возвращайте
200 OKсразу после получения полезной нагрузки. Тяжелую обработку выполняйте асинхронно. - Идемпотентность — Ваш обработчик должен быть идемпотентным; устраняйте дубликаты по
Wink-Event-Id. Wink повторяет попытки, если не получает ответ2xx. - Проверяйте источник — Проверяйте заголовок
Wink-Signature(см. Проверка подписей) перед обработкой; отклоняйте всё, что не проходит проверку. - Логирование — Логируйте каждую полученную полезную нагрузку вебхука. Это значительно облегчает отладку интеграций.
Приостановка и удаление
Заголовок раздела «Приостановка и удаление»Вы можете отключить вебхук без удаления. Это приостанавливает доставку, чтобы вы могли устранить неполадки, не теряя настройки. Когда будете готовы, включите его снова.
Удаление вебхука навсегда удаляет его. Любая интеграция, зависящая от этого вебхука, перестанет получать уведомления.
Дополнительные материалы
Заголовок раздела «Дополнительные материалы»- Каталог событий вебхуков — Все типы событий, сгенерированные из каталога платформы.
- Справочник Webhooks API — Схемы полезных нагрузок по событиям, заголовки и эндпоинты управления подписками и доставкой.
- Webhooks — Полная справка по управлению вебхуками.
- Applications — Управление вашими API-учетными данными.
- Developers > APIs — Полная документация API.
