Клубы, корты, слоты и брони
Партнёрский сайт, агрегатор или бот может показывать клубы AISOLUS, свободное время и цены без авторизации, а бронировать — от имени игрока, вошедшего по SMS.
Публичные методы: клубы и слоты
curl "https://адрес-вашего-сервера/api/v1/clubs"
# → {"items": [{"id": "c1", "name": "Флэйм Падел", "address": "Сколково, корты №4 и №5",
# "courts": 6, "priceFrom": 3500, "hasAI": true, "lat": null, "lon": null}, …]}
curl "https://адрес-вашего-сервера/api/v1/clubs/c1/courts"
# → {"items": [{"id": "7d1e3b5a-…", "name": "Корт 4", "indoor": true, "hasAI": true}, …]}
curl "https://адрес-вашего-сервера/api/v1/clubs/c1/slots?day=2026-10-03"
# → {"day": "2026-10-03", "items": [
# {"time": "08:00", "free": true, "freeCourts": 2, "price": 2800, "priceLabel": "Счастливые часы"},
# {"time": "09:30", "free": false, "freeCourts": 0, "price": 3500, "priceLabel": ""}, …]}GET /v1/clubs— все клубы: число кортов, цена от, есть ли AI на кортах (hasAI), координаты, если заданы.GET /v1/clubs/{club_id}/courts— корты:idпригодится, чтобы бронировать конкретный корт.GET /v1/clubs/{club_id}/slots— слоты по 90 минут от открытия до закрытия клуба. Слот свободен, если свободен хотя бы один корт. Цена — по сетке клуба для обычного игрока;priceLabelзаполнен для «счастливых часов». Персональная цена (категория клиента, промокод) применяется при брони.
Неизвестный клуб — 404 club_not_found, неверная дата — 400 bad_day.
Брони от имени игрока
Бронирование всегда идёт от имени игрока и оплачивается из его кошелька. Партнёр получает токен игрока через вход по SMS (см. «Токен игрока») и передаёт его в Authorization: Bearer. Отдельного «партнёрского» способа бронировать без игрока в API нет.
# правила клуба для этого игрока
curl "https://адрес-вашего-сервера/api/v1/bookings/rules?club_id=c1" -H "Authorization: Bearer <токен игрока>"
# → {"depthDays": 14, "cancelFreeHours": 24, "maxPerDay": 0, "maxActive": 0, "category": null, …}
# что даст промокод (ничего не бронирует)
curl "https://адрес-вашего-сервера/api/v1/promo/check?club_id=c1&code=AUTUMN10&day=2026-10-03&at=18:00" \
-H "Authorization: Bearer <токен игрока>"
# → {"code": "AUTUMN10", "price": 3500, "discount": 350, "total": 3150, "note": ""}
# бронь
curl -X POST "https://адрес-вашего-сервера/api/v1/bookings" \
-H "Authorization: Bearer <токен игрока>" -H "Content-Type: application/json" \
-d '{"club_id": "c1", "day": "2026-10-03", "time": "18:00", "promo_code": "AUTUMN10"}'
# → {"id": "b71c2e94-…", "clubId": "c1", "club": "Флэйм Падел", "court": "Корт 4",
# "day": "2026-10-03", "time": "18:00", "durationMin": 90, "price": 3150, "status": "confirmed"}Порядок проверок при брони и ответы:
| Проверка | Ответ при отказе |
|---|---|
| Клуб существует | 404 club_not_found |
| Дата и время в формате, время — начало слота клуба, слот не в прошлом | 400 bad_day_or_time, bad_slot_time, slot_in_past |
| Правила клуба для игрока: глубина брони, лимит в день, лимит активных | 409 с error: too_far_ahead, day_limit, active_limit |
Есть свободный корт (указанный в court_id или любой) | 409 slot_taken |
| Промокод подходит | 4xx с причиной |
| На кошельке хватает денег | 402 с {"error": "insufficient_funds", "balance": …, "price": …} |
Двое бронируют один корт одновременно — второй получит 409 slot_taken: облако не допустит двух подтверждённых броней на один корт и слот.
Управление бронью
GET /v1/bookings/my— последние 50 броней игрока с долями разделённой оплаты.POST /v1/bookings/{booking_id}/reschedule— перенос на другой слот того же клуба; разница цены списывается или возвращается.POST /v1/bookings/{booking_id}/cancel— отмена. Если до начала осталось не меньше окна бесплатной отмены (cancelFreeHoursиз правил), стоимость возвращается на кошелёк; иначеrefund: 0.POST /v1/bookings/{booking_id}/split— разделить стоимость с 1–3 игроками; каждый оплачивает долю черезPOST /v1/bookings/splits/{split_id}/accept, деньги уходят автору брони. Кого позвать —GET /v1/players/recent.POST /v1/bookings/waitlist— встать в очередь на слот, где заняты все корты. Когда бронь отменят, уведомление получит первый в очереди.- Прокат:
GET /v1/bookings/rental— что есть в клубе,POST /v1/bookings/{booking_id}/rental— добавить к брони,GET /v1/bookings/{booking_id}/rental-pass— QR для стойки проката.
Бронь и видео матча
Если корт оснащён AISOLUS, матч, сыгранный по брони, связывается с ней автоматически: сервер корта видит текущую бронь и её состав (GET /v1/cv/court-bookings), а результат матча привязывается к брони по корту и времени. Участники матча получают хайлайты и разбор в карточке матча — см. «Трансляции и повторы».