Skip to content

Интеграция с Webhook

Webhook-ите позволяват на вашите системи да получават известия в реално време, когато се случват събития във вашия Wink акаунт — нови резервации, анулации, актуализации на плащания и други. Това ръководство ви превежда през настройката и добрите практики.

Това ръководство е за разработчици, които интегрират Wink с външни системи като системи за управление на имоти (PMS), мениджъри на канали, CRM системи или персонализирани табла за управление.

  1. Регистрирате URL за webhook в Wink.
  2. Когато настъпи събитие (например нова резервация), Wink изпраща HTTP POST към вашия URL.
  3. Вашият сървър обработва съдържанието и отговаря с 200 OK.
  1. Влезте в акаунта си (Extranet, Studio или TripPay — всички поддържат webhook-и).
  2. Отидете на Applications, след това Webhooks. Вижте Webhooks.
  3. Кликнете Create webhook.
  4. Въведете име (например “PMS Booking Sync”).
  5. Въведете вашия webhook URL — HTTPS крайна точка на вашия сървър.
  6. Изберете събития — Изберете конкретни събития, на които да се абонирате, или оставете празно, за да получавате всички събития.
  7. Включете Enabled.
  8. Кликнете Save — отговорът показва вашия signing secret само веднъж; запазете го сега.

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.

Вижте всички видове събития

Всяка доставка е HTTP POST към вашия webhook 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-SignatureHMAC подпис — виж по-долу.

Всеки webhook има signing secret (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-стил; уверете се, че имате 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')));
}
// 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)));
}

Ротирайте тайната от портала или с 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 дни — след което доставката се маркира като dead.
  • Всеки друг 4xx се третира като “отказахте тази доставка” и не се повтаря.
  • Всяко събитие, доставка и опит (статус, откъс от отговора) е видимо под Applications > Webhooks и чрез API (…/webhook/event/grid, …/webhook/delivery/grid). Можете да повторите доставката на всяка доставка (POST …/webhook/delivery/{deliveryId}/redeliver, което стартира нова серия опити), да повторите всички мъртви доставки на webhook наведнъж (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 (виж Проверка на подписите) преди обработка; отхвърляйте всичко, което не минава.
  • Логване — Логвайте всяко получено webhook съдържание. Това улеснява отстраняването на проблеми при интеграцията.

Можете да деактивирате webhook без да го изтривате. Това спира доставките, за да можете да отстраните проблеми без да губите конфигурацията. Когато сте готови, включете го отново.

Изтриването на webhook го премахва завинаги. Всяка интеграция, която разчита на този webhook, ще спре да получава известия.

  • Каталог на Webhook събитията — Всеки тип събитие, генериран от каталога на платформата.
  • Референция на Webhooks API — Схеми на съдържанието за всяко събитие, заглавки и крайни точки за управление на абонаменти и доставки.
  • Webhooks — Пълна референция за управление на webhook-и.
  • Applications — Управление на вашите API идентификационни данни.
  • Developers > APIs — Пълна API документация.