News Malta Budget 2027 announced an eco tax of €10 per adult per night for short lets (capped at €80 per person) from 1 January 2027 — not yet law. Czytaj więcej
Guestbud

Dla programistów · dla Programiści

Webhooki

Odbieraj podpisane zdarzenia na żywo — rezerwacje, zameldowania, płatności, odblokowane pobyty, dodatki, wiadomości — i weryfikuj podpis HMAC-SHA256.

Webhooki wysyłają zdarzenia do Twojego systemu w chwili, gdy następują, więc nie musisz odpytywać API.

Zdarzenia #

ZdarzenieKiedy
booking.createdUtworzono rezerwację (panel, import z kanału lub API)
booking.updatedZmieniły się daty, goście, godziny zameldowania/wymeldowania lub dane kontaktowe
booking.cancelledRezerwacja została anulowana
checkin.completedGość ukończył (lub zaktualizował) zameldowanie online
payment.completedOpłata turystyczna zapłacona lub kaucja zablokowana/zapłacona (także gdy personel oznaczy ją jako zapłaconą)
booking.unlockedWszystkie kroki wykonane — przewodnik pobytu jest odblokowany
extras.orderedGość zapłacił za dodatki — także za wcześniejsze zameldowanie lub późne wymeldowanie
message.sentWysłano wiadomość do gościa przez kanał rezerwacji (Airbnb, Booking.com … przez Hostaway lub Channex)
feedback.receivedGość ocenił pobyt (1–5) na stronie opinii po prośbie o recenzję
pingZdarzenie testowe z przycisku Test

Co zawiera data #

ZdarzeniePola data
booking.created, booking.updated, booking.cancelledbookingId, ref, source (importy z kanałów); reason: "stay-times", gdy kupione wcześniejsze zameldowanie / późne wymeldowanie zmieniło godziny
checkin.completedbookingId, ref
payment.completedbookingId, leg (eco lub deposit), status (paid lub held), manual: true, gdy personel oznaczył płatność jako zapłaconą
booking.unlockedbookingId
extras.orderedbookingId, leg: "extras", status: "paid"
message.sentbookingId, ref, via (np. Hostaway)
feedback.receivedbookingId, ref, rating (1–5)

Wersja każdego zdarzenia do odczytu maszynowego — nagłówki, treść i data — znajduje się w sekcji webhooks dokumentu OpenAPI oraz w dokumentacji API.

Dodaj webhook #

Settings → Webhooks (Ustawienia → Webhooki): wpisz adres URL https://, zaznacz wybrane zdarzenia (brak zaznaczenia = wszystkie) i kliknij Add webhook. Sekret podpisu (signing secret) jest pokazywany tylko raz — zapisz go w swoim odbiorniku.

Settings → Webhooks
Settings → Webhooks

Żądanie #

POST z treścią JSON:

{
  "id": "evt_…",
  "event": "payment.completed",
  "createdAt": "2026-11-18T14:03:11.000Z",
  "tenant": "t_…",
  "data": { "bookingId": "b_…", "leg": "eco", "status": "paid" }
}

Nagłówki:

NagłówekZawartość
X-GP-Eventnazwa zdarzenia
X-GP-Deliveryunikalny identyfikator dostarczenia
X-GP-Timestampczas Unix w sekundach
X-GP-Signaturev1= + szesnastkowy HMAC-SHA256 z <timestamp>.<raw body> z użyciem Twojego sekretu podpisu

Weryfikacja podpisu (Node.js) #

const crypto = require('crypto');
function verify(rawBody, headers, secret) {
  const ts = headers['x-gp-timestamp'];
  const expected = 'v1=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
  const given = String(headers['x-gp-signature'] || '');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

Zawsze weryfikuj względem surowej treści żądania i odrzucaj stare znaczniki czasu, aby zablokować ataki powtórzeniowe.

Weryfikacja podpisu (C# / .NET) #

using System.Security.Cryptography; using System.Text;
static bool Verify(string rawBody, string ts, string signature, string secret) {
  if (!long.TryParse(ts, out var t) || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t) > 300) return false;
  using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
  var hex = Convert.ToHexString(h.ComputeHash(Encoding.UTF8.GetBytes(ts + "." + rawBody))).ToLowerInvariant();
  return CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes("v1=" + hex), Encoding.ASCII.GetBytes(signature ?? ""));
}

W .NET Framework zamiast Convert.ToHexString użyj BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(), a porównanie w stałym czasie wykonaj prostą pętlą.

Weryfikacja podpisu (PHP) #

$expected = 'v1=' . hash_hmac('sha256', $_SERVER['HTTP_X_GP_TIMESTAMP'] . '.' . file_get_contents('php://input'), $secret);
$ok = abs(time() - (int)$_SERVER['HTTP_X_GP_TIMESTAMP']) < 300 && hash_equals($expected, $_SERVER['HTTP_X_GP_SIGNATURE'] ?? '');

Dostarczanie i ponowienia #

Odpowiedz dowolnym statusem 2xx w ciągu 10 sekund. Nieudane dostarczenia są ponawiane po 30 sekundach i po 5 minutach (łącznie trzy próby). Recent deliveries pokazuje ostatnie 200 prób wraz z wynikiem.

  • id w treści i nagłówek X-GP-Delivery pozostają takie same przy każdym ponowieniu — zapisuj je i ignoruj duplikaty.
  • Zdarzenia mogą przychodzić w innej kolejności; korzystaj z createdAt i pobieraj rezerwację, aby poznać jej aktualny stan.
  • Przekierowania nie są obsługiwane, a wywoływane są wyłącznie publiczne adresy https:// (bez sieci prywatnych i lokalnych).
  • Żądania mają nagłówki Content-Type: application/json i User-Agent: GuestPortal-Webhooks/1.

Najczęściej zadawane pytania #

Czy w zdarzeniu otrzymuję pełną rezerwację? #

Zdarzenie zawiera identyfikatory i informację o zmianie. Pełną rezerwację pobierzesz przez GET /api/v1/bookings/{id} z użyciem klucza API — dzięki temu w treści webhooków nie są przesyłane żadne dane osobowe.

Czy kanały mogą wysyłać webhooki do Guestbud? #

Tak — to kierunek odwrotny. Hostaway i Channex mogą natychmiast informować Guestbud o nowych i zmienionych rezerwacjach; zobacz Hostaway i Channex. Te adresy przychodzące są tajne dla każdej firmy i wyzwalają jedynie ponowny import danej rezerwacji.

Czy webhooki są wysyłane z konta demo? #

Nie.