Foglalási flow
A foglalási folyamat end-to-end integrálása — service discovery, availability, foglalás létrehozása, lifecycle figyelése, lemondás.
Áttekintés#
A Bokko foglalási folyamat 5 fázisból áll:
- Discover — elérhető szolgáltatások és munkatársak lekérdezése
- Plan — szabad időpontok keresése adott dátumtartományra
- Reserve — foglalás létrehozása
- Lifecycle — foglalás státuszának figyelése (webhook vagy polling)
- Cancel — foglalás lemondása, ha szükséges
Discover — Szolgáltatások és munkatársak#
Szolgáltatások listázása (GET /services)#
curl -X GET "https://api.bokko.io/v1/services?salonSlug=pelda-szalon" \
-H "Authorization: Bearer bk_live_..."Visszaadja az összes aktív, online foglalható szolgáltatást. A serviceId értékre az availability search-ben és a foglalás létrehozásakor lesz szükséged.
Munkatársak listázása (GET /staff)#
curl -X GET "https://api.bokko.io/v1/staff?salonSlug=pelda-szalon" \
-H "Authorization: Bearer bk_live_..."Az availability search response-ban a slots[].staffId megjelöli, melyik munkatárs végzi a szolgáltatást — ezt a GET /staff válasz alapján tudod megjeleníteni.
Plan — Szabad időpontok keresése (POST /availability/search)#
Request body mezők#
| Mező | Típus | Leírás |
|---|---|---|
salonSlug | string (kötelező) | A foglalt szalon azonosítója |
serviceId | string (kötelező) | A keresett szolgáltatás azonosítója |
staffId | string (opcionális) | Ha megadod, csak az adott munkatárs slotjai jelennek meg |
dateRange.from | YYYY-MM-DD (kötelező) | Keresési időszak kezdete (szalon helyi időzóna) |
dateRange.to | YYYY-MM-DD (kötelező) | Keresési időszak vége — inclusive, max 31 nappal a from után |
<!-- doc-example: request POST /availability/search -->
curl -X POST "https://api.bokko.io/v1/availability/search" \
-H "Authorization: Bearer bk_live_..." \
-H "Content-Type: application/json" \
-d '{
"salonSlug": "pelda-szalon",
"serviceId": "svc_haircut_01",
"staffId": "staff_anna_01",
"dateRange": {
"from": "2026-05-12",
"to": "2026-05-18"
}
}'Response mezők és időzóna semantika#
Request/propose fázis — szalon helyi időzóna:
slots[].date—YYYY-MM-DDa szalon helyi időzónájában (nem UTC)slots[].startTime—HH:MMszalon-local wall-clock időslots[].endTime—HH:MMszalon-local wall-clock időslots[].serviceId,slots[].staffId— azonosítók
UTC timestamp:
snapshotAt— UTC ISO 8601 timestamp (a snapshot kibocsátásának pillanata)
Confirmed lifecycle — UTC ISO 8601: Miután a foglalás megerősítve lett, az időbélyegek (confirmedAt, cancelledAt, completedAt) UTC ISO 8601 formátumban érkeznek — ezeket soha ne értelmezd szalon helyi időként.
Megjegyzés a confirmedSlot-ról: cancelled vagy declined státuszú foglalásoknál a confirmedSlot mező mindig null az API-ban, még akkor is, ha a foglalás korábban meg volt erősítve. Ez jelzi, hogy az időpont már nem foglalt.
Truncation és suppression#
Ha a keresés 500-nál több slotot adna vissza, a válasz csonkul:
meta.truncated: truejelzi a csonkítástmeta.returnedSlots— ténylegesen visszaadott slotok számameta.slotLimit— a csonkítási határ (500)
Ha az online foglalás ki van kapcsolva a szalonban:
meta.availabilitySuppressed: truedata.slotsüres tömb
Hibák#
availability.date_range_too_wide(400) — adateRangeszélesebb 31 napnál
Reserve — Foglalás létrehozása (POST /bookings)#
Idempotency-Key#
Minden foglalás-létrehozási kéréshez RFC 4122 UUID v1–v5 formátumú Idempotency-Key header szükséges. Az idempotency ablak 24 óra.
Az UUID-t egyszer generáld shell változóba. Retry esetén pontosan ugyanezt a kulcsot küldd:
<!-- doc-example: request POST /bookings -->
IDEMPOTENCY_KEY="$(uuidgen)"
curl -X POST "https://api.bokko.io/v1/bookings" \
-H "Authorization: Bearer bk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-d '{
"salonSlug": "pelda-szalon",
"serviceId": "svc_haircut_01",
"expectedPricingVersion": "a1b2c3d4e5f6",
"staffId": "staff_anna_01",
"slot": {
"date": "2026-05-12",
"startTime": "10:00"
},
"guest": {
"name": "Teszt Vendég",
"phone": "+36301234567"
}
}'Foglalás státuszok (state machine)#
| Státusz | Leírás |
|---|---|
requested | Létrehozva, vár a megerősítésre |
confirmed | Megerősítve a szalon által |
declined | Elutasítva |
rescheduleProposed | Átütemezési javaslat érkezett |
cancelled | Lemondva |
completed | Teljesítve |
noShow | Vendég nem jelent meg |
Lifecycle figyelése#
Webhook-első megközelítés (ajánlott)#
Állíts be webhookot a PUT /webhooks/config endpointon — értesítést kapsz minden foglalásváltozásnál.
A 8 webhook event:
booking.requestedbooking.confirmedbooking.declinedbooking.cancelledbooking.reschedule_proposedbooking.reschedule_confirmedbooking.completedbooking.no_show
Minden event X-Bokko-Signature: sha256=<hex> fejléccel érkezik HMAC-SHA256 aláírással — ellenőrizd a hitelesség megállapításához. Részletes leírás: Webhooks →
Polling fallback#
Ha webhook nem áll rendelkezésre, lekérdezheted a foglalás állapotát:
curl -X GET "https://api.bokko.io/v1/bookings/{bookingId}?salonSlug=pelda-szalon" \
-H "Authorization: Bearer bk_live_..."Cancel — Foglalás lemondása (POST /bookings/{bookingId}/cancel)#
IDEMPOTENCY_KEY="$(uuidgen)"
curl -X POST "https://api.bokko.io/v1/bookings/{bookingId}/cancel?salonSlug=pelda-szalon" \
-H "Authorization: Bearer bk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}"A lemondás idempotens: ha a foglalás már cancelled státuszban van, a kérés 409 booking.invalid_transition hibával tér vissza — ez nem valódi hiba, a cancel sikeresen megtörtént.
Hibák a flow során#
| Kód | HTTP | Mikor fordul elő |
|---|---|---|
booking.slot_unavailable | 409 | A kért időpont már nem elérhető |
booking.service_pricing_changed | 409 | Az ár változott az availability search és a foglalás között |
idempotency.payload_mismatch | 409 | Azonos Idempotency-Key, eltérő payload |
idempotency.request_in_progress | 503 | A kérés feldolgozása még folyamatban van (retryable) |
auth.plan_insufficient | 403 | A kulcs tenantjának nincs Pro előfizetése |
Retry stratégia#
idempotency.request_in_progress(503) — retryable: igen, ugyanolyan Idempotency-Key-jelbooking.slot_unavailable(409) — retryable: nem; keress új időpontotbooking.service_pricing_changed(409) — retryable: nem; kérd le újra a szolgáltatáslistát
Best practices#
- Idempotency-Key shell változóba generáld, ne inline — retry alatt ne változzon
- Webhook-elsőbbség: polling csak fallbackként; valós idejű értesítésekhez webhookot használj
- Időzóna: az availability slot
date/startTime/endTimeszalon-local; aconfirmedAtés hasonló lifecycle mezők UTC — ne keverd össze - Slot freshness: az availability snapshot gyorsan elavulhat; a foglalás előtt ne tárold cache-ben 30 másodpercnél tovább