Skip to content

Процесс продажи ​

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

text
Покупатель          Партнёр                       Ticket Gateway
    │                  │                                │
    │ выбирает места   │ GET /event-items/{id}/seats    │
    │─────────────────▶│───────────────────────────────▶│
    │                  │◀────── места и остатки ────────│
    │ «Оформить»       │                                │
    │─────────────────▶│ POST /orders                   │
    │                  │───────────────────────────────▶│ бронь
    │                  │◀────── status: held ───────────│ 15 мин
    │ оплачивает       │                                │
    │─────────────────▶│ POST /orders/{id}/confirm      │
    │                  │───────────────────────────────▶│ продажа
    │                  │◀────── status: paid + PIN ─────│
    │◀── билет (QR) ───│                                │

Шаг 1. Выбор мест ​

Запросите схему зала и доступность для сеанса:

bash
curl https://gateway.ticket.kg/api/v1/event-items/2505/seats -H "X-API-Key: $KEY"

Что заказывать, зависит от типа сеанса:

СеансЧто передать в заказе
Со схемой зала: местаseats — массив ID мест с is_available: true
Со схемой зала: зоны без мест (танцпол, фан-зона)zones — ID зоны и количество, не больше available
Без схемы зала (type = 6)prices — ID ценовой категории и количество

seats и zones можно комбинировать в одном заказе. prices используется только отдельно. Подробнее — в разделе Схема зала, места и зоны.

Шаг 2. Бронирование ​

bash
curl -X POST https://gateway.ticket.kg/api/v1/orders \
  -H "X-API-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "partner_order_id": "ORD-1001",
    "event_item_id": 2505,
    "seats": [101, 102],
    "zones": [{"zone_id": 11, "quantity": 2}],
    "customer": {"full_name": "Иван Иванов", "email": "ivan@example.com", "phone": "+996700000000"}
  }'

Ответ 201 Created содержит заказ со статусом held и временем окончания брони expires_at:

json
{
  "data": {
    "id": "3f6c2a1e-8b4d-4c7a-9e2f-1a2b3c4d5e6f",
    "partner_order_id": "ORD-1001",
    "status": "held",
    "expires_at": "2026-11-01T14:15:00+06:00",
    "total": 6000,
    "currency": "KGS",
    "tickets": [ ... ]
  }
}

Сохраните id заказа — он нужен для всех следующих шагов.

Правила бронирования ​

  • Всё или ничего. Если хотя бы одно место занято или в зоне не хватает билетов, не бронируется ничего. Ответ — 409 со списком проблемных мест или зон в details.
  • Срок брони — 15 минут. Точное время — в поле expires_at.
  • Не больше 50 билетов в одном заказе. У сеанса может быть свой, более строгий лимит на заказ. Превышение — 409 limit_exceeded.
  • Продажа целыми рядами. Некоторые ценовые категории продаются только целым рядом. В этом случае нужно передать все места ряда, иначе — 422 validation_error со списком нужных мест в details.required_seats.
  • Сеанс должен продаваться. Если продажи закрыты, сеанс бесплатный или скрыт — 422 event_item_not_available.

Полное описание полей запроса — в справочнике.

Повторы и идемпотентность ​

partner_order_id — ваш собственный номер заказа. Он уникален в рамках партнёра и защищает от двойных броней:

  • Повторный POST /orders с тем же partner_order_id не создаёт новый заказ, а возвращает уже существующий с кодом 200 OK (вместо 201 Created).
  • Поэтому при таймауте или сетевой ошибке запрос можно смело повторить.

Тело повторного запроса не сравнивается

Если вы передадите тот же partner_order_id с другими местами, шлюз вернёт старый заказ, не изменяя его. Для нового набора мест используйте новый partner_order_id.

Это касается и отменённых или истёкших заказов: их partner_order_id занят навсегда. Чтобы покупатель мог попробовать снова, сгенерируйте новый номер.

Шаг 3. Оплата и подтверждение ​

После того как покупатель оплатил заказ у вас, подтвердите продажу:

bash
curl -X POST https://gateway.ticket.kg/api/v1/orders/3f6c2a1e-8b4d-4c7a-9e2f-1a2b3c4d5e6f/confirm \
  -H "X-API-Key: $KEY"
  • Заказ переходит в статус paid.
  • У каждого билета появляются pin и pin_formatted. До подтверждения PIN не выдаётся. Подробнее — в разделе Билеты и PIN.
  • Повторный confirm безопасен: он вернёт тот же оплаченный заказ.

Подтверждайте заранее

Если до окончания брони осталось меньше 10 секунд, подтверждение отклоняется с ошибкой 409 order_expired. Это защищает от гонки с автоматическим удалением истёкших броней.

Если бронь истекла, создайте новый заказ с новым partner_order_id. Места могли уже занять, поэтому покупателю, возможно, придётся выбрать другие.

Рекомендуемый порядок оплаты ​

  1. Создайте заказ и получите expires_at.
  2. Ограничьте время оплаты на своей стороне так, чтобы оно гарантированно заканчивалось раньше expires_at — с запасом хотя бы в 1 минуту.
  3. После успешной оплаты сразу вызовите confirm.
  4. Если confirm не прошёл из-за сети, повторяйте его — это безопасно.
  5. Если confirm вернул order_expired, а деньги уже списаны, верните их покупателю или создайте новый заказ.

Шаг 4. Отмена неоплаченной брони ​

Если покупатель передумал или оплата не прошла, снимите бронь, чтобы места сразу вернулись в продажу:

bash
curl -X DELETE https://gateway.ticket.kg/api/v1/orders/3f6c2a1e-8b4d-4c7a-9e2f-1a2b3c4d5e6f \
  -H "X-API-Key: $KEY"

Заказ переходит в статус cancelled. Если вы не подтвердите и не отмените бронь, она будет удалена автоматически вскоре после expires_at, а заказ получит статус expired.

Оплаченный заказ отменить нельзя — используйте возврат.

Проверка статуса заказа ​

Если вы не уверены, чем закончился запрос (например, оборвалось соединение), запросите заказ:

bash
# по нашему ID
curl https://gateway.ticket.kg/api/v1/orders/3f6c2a1e-8b4d-4c7a-9e2f-1a2b3c4d5e6f -H "X-API-Key: $KEY"

# по вашему номеру заказа
curl "https://gateway.ticket.kg/api/v1/orders?partner_order_id=ORD-1001" -H "X-API-Key: $KEY"

Поиск по partner_order_id особенно полезен, если POST /orders упал по таймауту и вы не получили id заказа.