Бронь и оплата

Ваша база

API показывает вашему отделу только ваше: ваши брони, ваших детей и семьи этих детей. Брони, дети и семьи других отделов не видны и не меняются. Корпоративные брони (группы от организаций) не видны никому через API.

Запрос к чужой записи отвечает 404 not_found — так же, как к несуществующей. По ответу нельзя понять, есть ли такая запись у другого отдела.

Чей ребёнок

Ребёнка «ведёт» отдел, который оформил ему бронь на самую позднюю по датам смену. В расчёт идут:

  • действующие брони;
  • брони, снятые из-за неоплаты (место снято, но ребёнок остаётся у вас — чтобы перезвонить).

Отменённая вручную бронь ребёнка не удерживает. Борьбы за детей нет: переход между отделами свободный, лагерь его не запрещает.

Пример. Тимура в прошлом году возил ваш отдел — он ваш. В этом году другой отдел оформил ему бронь на июльскую смену, а у вас брони на этот год нет — Тимур переходит к другому отделу:

  • у вас приходит событие child.removed, Тимур пропадает из GET /children и из семьи;
  • ваши прошлые брони Тимура остаются в ваших списках и отчётах — это ваши продажи, — но без контактов семьи: в брони contacts_hidden: true, телефоны родителя и плательщика — null, менять их нельзя;
  • у другого отдела приходит child.added.

Если потом вы оформите Тимуру бронь на смену позже июльской — он вернётся к вам.

Чья семья

Семью вы видите, если у вас есть хотя бы один её ребёнок — или ваша бронь на эту семью без карточки ребёнка. В карточке семьи (GET /families/{id}) — только ваши дети и ваши брони: брат или сестра, которых ведёт другой отдел, не показываются.

Один телефон — одна семья во всей системе лагеря. Основной телефон семьи (phone, в виде +7XXXXXXXXXX) — ключ, по которому её узнают: через API он не меняется. Второй номер добавляйте в extra_phones.

Общая семья (shared: true)

Если в семье есть дети и вашего, и другого отдела, семья общая. Её общие данные вам не показываются и не меняются — чтобы отделы не переписывали данные друг друга:

  • full_name — как вы записали родителя в своей брони;
  • вторых номеров (extra_phones) и города нет;
  • PATCH /families/{id} с ФИО, городом, согласием на рассылки или вторыми номерами — отказ 403 family_shared.

Свои external_id и metadata ставить можно всегда.

Найти семью или ребёнка

НужноЗапрос
Семья по телефонуGET /families?phone=87010000001 — любая запись телефона, ищется по основному и вторым номерам
Семья по ФИОGET /families?name=Тестов — часть ФИО родителя или вашего ребёнка, от 2 символов
Семьи, изменившиеся с моментаGET /families?updated_since=2027-05-14T00:00:00Z
Семья по номеру вашей CRMGET /families/by-external-id/{external_id}
Все ваши детиGET /children
Кто был в сезонеGET /children?season_id_visited=2
Кого не было в этом сезоне (для обзвона)GET /children?season_id_not_visited=3
Дети по году рожденияGET /children?birth_year_from=2014&birth_year_to=2016
Один ребёнокGET /children/{id}
Брони ребёнка или семьиGET /bookings?child_id=40871, GET /bookings?parent_id=22014
Бронь по номеру вашей CRMGET /bookings/by-external-id/{external_id}

Пример ответа GET /families/22014:

JSONCode
{ "id": "22014", "version": "2027-05-14T09:31:07.482913Z", "full_name": "Тестова Айгерим Болатовна", "phone": "+77010000001", "extra_phones": ["+77020000002"], "city": { "id": "1", "name": "Астана" }, "marketing_opt_in": true, "shared": false, "merged_from": [], "children": [ { "id": "40871", "family_id": "22014", "full_name": "Тестов Тимур Аскарович", "birth_date": "2016-04-12", "external_id": "child-551", "metadata": {} } ], "bookings": [], "external_id": "client-2207", "metadata": { "segment": "vip" } }

В bookings — краткие сведения о ваших бронях детей семьи, свежие первыми (в примере пусто для краткости).

Изменить семью и ребёнка

Нужно право bookings.

Семья — PATCH /families/{id}, можно с If-Match: <version>:

TerminalCode
curl -X PATCH https://partners.zvezdnyy-burabai.edu.kz/ext/v1/families/22014 \ -H "Authorization: Bearer $ZB_KEY" \ -H "Content-Type: application/json" \ -d '{ "extra_phones": ["8 702 000 00 02", "8 705 000 00 03"], "external_id": "client-2207" }'
ПолеКак
full_nameФИО родителя
city_idГород; null — стереть
marketing_opt_inСогласие на рассылки
extra_phonesВторые номера — заменяют список целиком. Номер другой семьи не принимается (409 phone_taken)
external_idНе передано — не менять; строка — заменить; null — стереть
metadataЗаменяет метки целиком

Отказы: 403 family_shared — общая семья (см. выше); 400 bad_city — города нет в справочнике; 412 version_mismatch — семью изменили после вашего чтения.

Ребёнок — PATCH /children/{id}: только ваши external_id и metadata. ФИО и дата рождения ребёнка меняются правкой брони (PATCH /bookings/{id}).

Свои номера и метки

У брони, семьи и ребёнка можно хранить:

  • external_id — номер записи в вашей CRM (до 255 знаков). Уникален внутри вашего отдела: две брони с одним external_id не бывает (409 external_id_taken);
  • metadata — до 20 пар «ключ — значение». Ключ — от 1 до 40 знаков; значение — строка до 500 знаков, число, true/false или null. Вложенные объекты нельзя (400 bad_metadata).

Лагерь их не разбирает — только хранит и возвращает. Другие отделы ваших номеров и меток не видят.

Используйте external_id как защиту от дублей

Передавайте номер сделки вашей CRM в external_id при оформлении. Если ваша CRM по ошибке попробует оформить ту же сделку второй раз (даже с другим Idempotency-Key), API ответит 409 external_id_taken и назовёт номер уже оформленной брони.

Слияние дублей

Лагерь объединяет дубли карточек — например, если одну семью завели под двумя телефонами:

  • child.merged — две карточки одного ребёнка объединены. data.into_id — номер оставшейся. Старый номер больше не отвечает; ваши external_id и метки перенесены на оставшуюся (если на ней уже был ваш номер — остаётся он). Замените у себя старый номер на into_id.
  • client.merged — то же для семьи. data.into_id — номер оставшейся семьи. Запрос по старому номеру отвечает оставшейся семьёй (её номер — в id, старые — в merged_from).

Сверка раз в сутки

GET /reconcile/bookings — все брони вашего отдела (и отменённые): номер, статус и версия, большими порциями (до 5000 за раз). Раз в сутки сравните со своей базой: чего у вас нет или где version другая — перечитайте эти брони. Так находится всё, что разошлось, даже если какие-то события потерялись у вас.

JSONCode
{ "items": [ { "id": "15230", "status": "active", "version": "2027-05-14T10:02:45.918201Z" }, { "id": "15231", "status": "cancelled", "version": "2027-05-15T09:40:11.003118Z" } ], "next_cursor": "c15231" }

Платёж версию брони не меняет — чтобы сверить деньги, сравнивайте и платежи: GET /payments?updated_since=….

Last modified on