Zum Hauptinhalt springen

Canali OTA

Diese Seite ist in Ihrer Sprache noch nicht verfügbar. Es wird die Standardversion angezeigt.

Zuletzt aktualisiert: 27. Oktober 2026

Canali OTA

Superficie di prenotazione in ingresso per le OTA (partner tipo Viator). Il contratto è indipendente dal provider e stabile — gli stessi percorsi servono ogni provider, {provider} seleziona la mappatura del payload. Viator è uno skeleton documentato, generic parla questo contratto così com'è per integrazioni su misura, GetYourGuide risponde 501 fino alla certificazione. Solo in ingresso: l'app non spinge mai disponibilità al partner.

Endpoint

GET  /api/ota/{provider}/availability?product_id={id}&date=YYYY-MM-DD[&to_date=YYYY-MM-DD]
POST /api/ota/{provider}/bookings
POST /api/ota/{provider}/bookings/{external_reference}/cancel

{provider} è uno tra viator, getyourguide, generic. Provider sconosciuti o disabilitati rispondono 404.

Rate limit: 60 richieste al minuto per collegamento.

Autenticazione

Ogni richiesta porta due header:

  • X-Ota-Connection: {public_id} — l'id pubblico del collegamento, visibile nella pagina admin dei canali OTA. Mai l'id interno.
  • X-Ota-Signature: {hex} — HMAC-SHA256 esadecimale con chiave il segreto di firma del collegamento (mostrato una sola volta alla creazione o rotazione) calcolato su:
{METHOD}\n{REQUEST-URI}\n{RAW-BODY}

REQUEST-URI è l'esatto request target inclusa la query string — /api/ota/viator/availability?product_id=P-1&date=2027-01-15. RAW-BODY è il corpo non parsato (stringa vuota per le GET).

$signature = hash_hmac(
    'sha256',
    "POST\n/api/ota/viator/bookings\n".$rawJsonBody,
    $webhookSecret,
);

Errori: collegamento sconosciuto 404 {"error":"unknown_connection"}; firma mancante o errata 401 {"error":"bad_signature"}. L'azienda si risolve sempre dal collegamento — il payload non può scegliere il tenant.

Mappatura prodotti

I partner vendono valori external_product_id. Ogni id si mappa nell'interfaccia admin a un solo prenotabile — un evento o un'area — più una price_key opzionale (null usa la risoluzione prezzo predefinita del prenotabile). Gli id non mappati rispondono 404 {"error":"unknown_product"}.

Disponibilità

GET /api/ota/generic/availability?product_id=P-1&date=2027-01-15

{
  "product_id": "P-1",
  "days": [
    {"date": "2027-01-15", "available": true, "remaining": 7}
  ]
}
  • available false significa chiuso, esaurito o fuori dalla finestra vendita.
  • remaining è la capacità residua; null significa senza limite.
  • I prodotti-area restituiscono in più windows: [{from, to, remaining}] — i segmenti vendibili del giorno. Ogni segmento ha la propria disponibilità (capienza del segmento meno il picco simultaneo, limitata da ogni pool giornaliero che il segmento occupa); il remaining del giorno è il gruppo più grande che entra in UN solo segmento, non il totale del giorno.
  • Il remaining di un evento è limitato da OGNI data del suo periodo — una prenotazione consuma il pool di ogni giorno che l'evento occupa.
  • Un evento senza fine vale solo nel suo giorno di inizio.
  • to_date estende l'intervallo fino a 31 giorni.

Creare una prenotazione

POST /api/ota/generic/bookings

{
  "product_id": "P-1",
  "external_reference": "partner-ref-1001",
  "customer": {"name": "Mario Bianchi", "email": "[email protected]", "phone": "+39002"},
  "number": 2,
  "from": "2027-01-15T10:00:00+00:00",
  "to": "2027-01-15T11:00:00+00:00",
  "date": "2027-01-15"
}

from/to valgono per i prodotti-area (finestre vendibili); date è il giorno di calendario per i prodotti-evento e deve cadere dentro il periodo dell'evento.

I prodotti-evento prenotano la foglia che il canale può indirizzare: un evento semplice si prenota direttamente, un evento con fasce orarie prenota la fascia che inizia a from (from diventa obbligatorio — mancante o non corrispondente risponde 422), e un evento con posti risponde available: false invece di pubblicizzare uno slot che il partner non potrebbe mai prenotare (la scelta del posto resta sul widget).

Risposta:

{"booking": {"reference": "partner-ref-1001", "status": "confirmed",
             "booking_code": "BK-AB12", "number": 2,
             "created_at": "2027-01-10T09:30:00+00:00"}}

Le prenotazioni arrivano gratuite — se il prenotabile mappato richiederebbe un pagamento la prenotazione è rifiutata con 422 {"error":"payment_required"} e la capacità impegnata viene rilasciata. Il denaro incassato dal partner si riconcilia fuori dall'app.

Gli errori di validazione rispondono 422 con error (booking_failed) e una mappa fields. I replay di un riferimento fallito restituiscono lo stesso esito registrato.

Idempotenza

external_reference è la chiave di idempotenza, unica per collegamento. Un retry che ri-invia lo stesso riferimento riceve l'esito registrato — 200 con lo stesso payload di prenotazione — senza toccare di nuovo la capacità. Non riusare mai un riferimento per ordini diversi.

Annullamento

POST /api/ota/{provider}/bookings/{external_reference}/cancel

Annulla la prenotazione sottostante attraverso il normale flusso di cancellazione e porta la riga del registro a cancelled. Riferimento sconosciuto → 404 {"error":"unknown_reference"}. Annullare un riferimento già annullato è un no-op 200. Il rimborso del denaro incassato dal partner è affare del partner — l'endpoint non innesca mai un rimborso.

Checklist onboarding partner

  1. Owner/admin crea un collegamento nella pagina dei canali OTA (/ota, feature di piano ota) e copia il public_id.
  2. Ruota/copia il segreto di firma una volta — dopo è solo in scrittura.
  3. Mappa ogni external_product_id del partner su un evento o un'area (+ price_key opzionale).
  4. Il partner firma METHOD\nREQUEST-URI\nRAW-BODY a ogni chiamata e invia entrambi gli header.
  5. Smoke-test availability → bookings → cancel con un riferimento usa-e-getta, poi go-live.

Cookies und Datenschutz

Wir verwenden notwendige Cookies, um die Sicherheit und den ordnungsgemäßen Betrieb der Anwendung zu gewährleisten. Optionale Cookies werden nur mit Ihrer Einwilligung verwendet.

Lesen Sie die Datenschutzerklärung Lesen Sie die Cookie-Richtlinie

Unverzichtbar

Unverzichtbare Cookies sind für das Funktionieren der Website erforderlich und können nicht deaktiviert werden.

Immer eingeschaltet

Funktional

Funktionale Cookies ermöglichen erweiterte Funktionen und eine individuelle Anpassung, beispielsweise indem sie Ihre Sprache und Ihre Einstellungen speichern.

Analytik

Analytics-Cookies helfen uns zu verstehen, wie Besucher mit der Anwendung interagieren, damit wir sie verbessern können.

Marketing

Marketing-Cookies werden verwendet, um Besucher über verschiedene Websites hinweg zu verfolgen und ihnen relevante und ansprechende Werbung anzuzeigen.