Partners API

Данное API предназначено для партнёров, которые работают как дистрибьюторы и сторонние продавцы билетов в отрыве от продаж пользователя Qtickets.

API принимает GET/POST запросы на функции указанные в этой документации. Методы не различаются: как GET, так и POST вернут идентичный ответ.

Все запросы отправляются на сервер: https://qtickets.ru

Авторизация

Каждый запрос к API должен содержать заголовок
Authorization: Bearer YOUR_API_KEY. API ключ выдается техподдержкой.

В случае, если ключ неверный или отсутствует заголовок, сервер вернет JSON с кодом ошибки:

{
   "status": "error",
   "code": "WRONG_AUTHORIZATION",
   "message": "Wrong authorization"
}

Events/Lists — листинг мероприятий

Метод api/partners/v1/events/lists возвращает список предстоящих мероприятий, в которых включена возможность продажи билетов через партнеров. Пример ответа:

{
    "status": "success",
    "result":[
        {
            "event_id": 12,
            "show_id": 20,
            "event_name": "Название мероприятия 1",
            "start_date": "2018-05-04T06:22:00+10:00",
            "scheme":{
                "id": 48,
                "venue_id": 120,
                "place_name": "Кремлевский дворец",
                "place_address": "ул. Воздвиженка, 1",
                "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая"
            },
            "city":{
                "id": 2,
                "name": "Москва",
                "timezone": "Europe/Moscow",
                "coords":[
                    55.7558,
                    37.6176
                ]
            },
            "last_update_hash": "63e9effbdeca7a633d73d118a65dc78478110a39"
        },
        {
            "event_id": 12,
            "show_id": 21,
            "event_name": "Название мероприятия 1",
            "start_date": "2019-01-03T17:00:00+10:00",
            "scheme":{
                "id": 48,
                "venue_id": 120,
                "place_name": "Кремлевский дворец",
                "place_address": "ул. Воздвиженка, 1",
                "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая"
            },
            "city":{
                "id": 2,
                "name": "Москва",
                "timezone": "Europe/Moscow",
                "coords":[
                    55.7558,
                    37.6176
                ]
            },
            "last_update_hash": "becffa60e0c682208f537fe71818aab62ba2b5a4"
        },
        {
            "event_id": 33,
            "show_id": 41,
            "event_name": "Название мероприятия 2",
            "start_date": "2018-12-31T18:00:00+07:00",
            "scheme":{
                "id": 48,
                "venue_id": 120,
                "place_name": "Кремлевский дворец",
                "place_address": "ул. Воздвиженка, 1",
                "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая"
            },
            "city":{
                "id": 2,
                "name": "Москва",
                "timezone": "Europe/Moscow",
                "coords":[
                    55.7558,
                    37.6176
                ]
            },
            "last_update_hash": "9e02e444620a3621f08c85732f1634f48fe35571"
        }
    ]
}

Где:

  • event_id — Идентификатор мероприятия
  • show_id— Идентификатор даты мероприятия
  • event_name — Название мероприятия
  • scheme — Массив информации о месте проведения и доступных билетах (scheme.zones), где venue_id – идентификатор площадки, place_name – название места проведения, place_address – адрес места проведения, place_description – уточнения для более точного ориентирования.
  • city — Город
  • start_date — Дата начала мероприятия
  • last_update_hash — Содержит хэш, который меняется при некоторых изменениях в мероприятии. Например, поменялись квоты или места для продажи. Этот параметр будет возвращаться во всех последующих методах, и если он изменится, то это сигнал для пересинхронизации.

Все последующие запросы к API должны содержать event_id. В случае, если мероприятие содержит более 1-й даты, то также нужно указывать и show_id.

Events/Seatmap — карта мест зала

Метод api/partners/v1/events/seatmap/{event_id}/{show_id?}

ответ:

{
  ....
  "seatmap": {
    "width": 1361,
    "height": 1342,
    "zones": {
      "RIGHT_PARTERRE": {
        "name": "Правый боковой партер",
        "description": null,
        "width": 950.10009765625,
        "height": 155.70689392089844,
        "offset": [
          163.10000610351562,
          233.19309997558594
        ],
        "seats": {
          "RIGHT_PARTERRE-1;1": {"coords": [225, 347], "row": 1, "place": 1},
          "RIGHT_PARTERRE-1;2": {"coords": [245, 347], "row": 1, "place": 2}
        }
      },
      "CENTER_PARTERRE": {
        "name": "Партер",
        "description": null,
        "width": 950.5,
        "height": 585.7999877929688,
        "offset": [
          163.10000610351562,
          392.20001220703125
        ],
        "seats": {
          "CENTER_PARTERRE-1;1": {"coords": [299, 444], "row": 1, "place": 1},
          "CENTER_PARTERRE-1;2": {"coords": [299, 464], "row": 1, "place": 2}
        }
      }
    }
  }
}

где:

  • ключи в seatmap.zones.[*] — это идентификаторы категорий zone_id
  • ключи в seatmap.zones.*.seats.[*] — это идентификаторы мест seat_id
  • seatmap.width — Ширина схемы зала (float)
  • seatmap.height — Высота схемы зала (float)
  • seatmap.zones[*].width — Ширина сектора для категории билета (float)
  • seatmap.zones[*].height — Высота сектора для категории билета (float)
  • seatmap.zones[*].offset — Смещение сектора категории билета (array)

В zones содержится список категорий, каждая категория имеет свой уникальный идентификатор zone_id (ключ массива), название name и места seats.

Место имеет свой уникальный идентификатор seat_id (ключ массива), boolean флаг доступности для продажи available, а также ряд row и номер места place. Координаты места указаны в свойстве coords

Для мест, где указано admission: true продаются входные билеты, в параметре free_quantity оставшееся кол-во для продажи.

Events/Offers — статус мест в мероприятии, доступных партнёру

Метод api/partners/v1/events/offers/{event_id}/{show_id?}

ответ:

{
  ...
  "offers": {
    "full": {
      "name": "Полный",
      "seats": {
        "RIGHT_PARTERRE-1;1": {"available": true, "price": 600},
        "RIGHT_PARTERRE-1;2": {"available": false, "price": 600},
        "RIGHT_PARTERRE-1;3": {"available": false, "price": 600}
      }
    },
    "preferential": {
      "name": "Льготный",
      "seats": {
        "RIGHT_PARTERRE-1;1": {"available": true, "price": 300}
      }
    }
  }
}

где:

  • ключи в offers.[*] — идентификатор тарифа offer_id, может быть пустым «»
  • ключи в offers.*.seats.[*] — это идентификаторы мест seat_id

В методе бронирования билета, следует передавать seat_id и offer_id из этого метода.

Tickets/Add — бронирование билета для места

Метод api/partners/v1/tickets/add/{event_id}/{show_id?}

В GET или POST параметрах нужно передать:

  • seat_id идентификатор места
  • offer_id идентификатор тарифа, значение может быть пустым или NULL
  • paid признак оплаты билета 0 или 1. Можно также вместо этого использовать paid_at с датой оплаты
  • reserved_to если билет еще не оплачен, нужно передавать дату, до которой билет бронируется, например 2018-05-24T17:00:00+10:00
  • external_id необязательный параметр, может содержать произвольное уникальное значение, по которому в дальнейшем будет вестись работа по этому конкретному билету, например ticket12345
  • external_order_id идентификатор заказа из вашей системы. Если параметр неизвестен на этапе бронирования билетов, укажите его позднее в методе update
  • user_session любая строка, до 40 символов, идентифицирующая пользователя. Примеры: id пользователя из вашей системы или md5(session_id())
  • price необязательный параметр, стоимость билета
  • client_email необязательный параметр, email покупателя
  • client_phone необязательный параметр, телефон покупателя
  • client_name необязательный параметр, имя покупателя
  • client_surname необязательный параметр, фамилия покупателя
  • client_middlename необязательный параметр, отчество покупателя

Пример ответа:

{
     "event_id": 12,
     "show_id": 21,
     "event_name": "Название мероприятия 1",
     "start_date": "2019-01-03T17:00:00+10:00",
     "scheme":{
         "id": 48,
         "venue_id": 120,
         "place_name": "Кремлевский дворец",
         "place_address": "ул. Воздвиженка, 1",
         "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая",
         "width": 1000,
         "height": 800
     },
     "city":{
         "id": 2,
         "name": "Москва",
         "timezone": "Europe/Moscow",
         "coords":[
             55.7558,
             37.6176
         ]
     },
     "last_update_hash": "2f030832e2eb309b811dc9675df611273aefe618",
     "status": "success",
     "result": {
         "id": "27061",
         "paid": 0,
         "reserved_to": "2018-05-24T17:00:00+10:00",
         "external_id": "ticket12345",
         "barcode": null,
         "price": null,
         "client_email": null,
         "client_phone": null,
         "client_name": null,
         "client_surname": null,
         "client_middlename": null
     }
}

где в result содержится:

  • id — идентификатор билета, в дальнейшем потребуется для работы в других методах
  • external_id — ваш внешний идентификатор, если был передан в запросе
  • barcode — будет содержать значение для ШК кода, в случае, если билет оплачен paid: 1

В случае, если закончились билеты, в ответе вернется ошибка:

{
"status": "error",
"code": "SEAT_NOT_AVAILABLE",
"message": "Seat "6-1;52" is not available"
}

Tickets/Update — обновление билета

Метод api/partners/v1/tickets/update/{event_id}/{show_id?} служит для обновления билета, например продлить бронь reserved_to или сделать билет оплаченным paid: 1
В запросе нужно передать:

  • id идентификатор билета или external_id
  • paid 0 или 1
  • reserved_to в случае, если paid: 0
  • external_order_id идентификатор заказа из вашей системы
  • price необязательный параметр, стоимость билета
  • client_email необязательный параметр, email покупателя
  • client_phone необязательный параметр, телефон покупателя
  • client_name необязательный параметр, имя покупателя
  • client_surname необязательный параметр, фамилия покупателя
  • client_middlename необязательный параметр, отчество покупателя

Tickets/Remove — удаление билета

Метод api/partners/v1/tickets/remove/{event_id}/{show_id?} служит для отмены брони. Например, пользователь сначала добавил билет в корзину, а потому удалил его сразу или закрыл вкладку в браузере.
В запросе нужно передать:

  • id идентификатор билета или external_id
    Ответ:

    {
    "event_id": 12,
    "show_id": 21,
    "event_name": "Название мероприятия 1",
    "scheme":{
    "id": 48,
    "venue_id": 120,
    "place_name": "Кремлевский дворец",
    "place_address": "ул. Воздвиженка, 1",
    "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая",
    "width": 1000,
    "height": 800
    },
    "city":{
    "id": 2,
    "name": "Москва",
    "timezone": "Europe/Moscow",
    "coords":[
      55.7558,
      37.6176
    ]
    },
    "start_date": "2019-01-03T17:00:00+10:00",
    "last_update_hash": "2f030832e2eb309b811dc9675df611273aefe618",
    "status": "success",
    "result": true
    }

Tickets/Check — статус места

Метод api/partners/v1/tickets/check/{event_id}/{show_id?}

В GET или POST параметрах нужно передать:

  • seat_id идентификатор места
  • offer_id идентификатор тарифа, значение может быть пустым или NULL

Пример ответа:

{
  ...
  "result": {
    "seat_id": "CENTER_PARTERRE-20;5",
    "offer_id": "full",
    "available": true,
    "coords": [
      967,
      525
    ],
    "row": 20,
    "place": 5,
    "price": 300,
    "currency_id": "RUB"
  }
}

BATCH режим

Позволяет одним запросом забронировать/обновить/удалить несколько билетов.

Пример бронирования нескольких билетов:
POST https://qtickets.ru/api/partners/v1/tickets/add/12/4076
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN

{
  "batch": [
    {
      "user_session": "ASeUqnvcgkJy",
      "seat_id": "2-2;37",
      "offer_id": null,
      "paid_at": null,
      "reserved_to": "2021-09-12T17:00:00+10:00",
      "price": 800,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество"
    },
    {
      "user_session": "ASeUqnvcgkJy",
      "seat_id": "2-2;38",
      "offer_id": null,
      "paid_at": null,
      "reserved_to": "2021-09-12T17:00:00+10:00",
      "price": 1000,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество"
    },
  ]
}

ответ:

....
"result": [
    {
      "id": 120299,
      "paid": 0,
      "paid_at": null,
      "reserved_to": "2021-09-12T10:00:00+03:00",
      "external_id": null,
      "external_order_id": null,
      "barcode": null,
      "price": 800,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество"
    },
    {
      "id": 120300,
      "paid": 0,
      "paid_at": null,
      "reserved_to": "2021-09-12T10:00:00+03:00",
      "external_id": null,
      "external_order_id": null,
      "barcode": null,
      "price": 1000,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество"
    }
]
....
Оплата нескольких билетов, а также привязка их к заказу:
POST https://qtickets.ru/api/partners/v1/tickets/update/12/4076
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN

{
  "batch": [
    {
      "id": 120260,
      "external_order_id": "6a5cc185-bc59-451f-b7cb-94376476ae01",
      "paid_at": "2021-09-12T17:00:00+10:00"
    },
    {
      "id": 120261,
      "external_order_id": "6a5cc185-bc59-451f-b7cb-94376476ae01",
      "paid_at": "2021-09-12T17:00:00+10:00"
    }
  ]
}
Удаление нескольких билетов:
POST https://qtickets.ru/api/partners/v1/tickets/remove/12/4076
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN

{
  "batch": [
    {
      "id": 120260
    },
    {
      "id": 120261
    }
  ]
}
Проверка статусов нескольких мест:
POST https://qtickets.ru/api/partners/v1/tickets/check/12/4076
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN

{
  "batch": [
    {
      "seat_id": "CENTER_PARTERRE-20;5",
      "offer_id": "preferential"
    },
    {
      "seat_id": "CENTER_PARTERRE-20;5",
      "offer_id": "full"
    },
    {
      "seat_id": "CENTER_PARTERRE-20;6",
      "offer_id": "full"
    }
  ]
}

Tickets/Find — поиск билетов

Метод api/partners/v1/tickets/find/{event_id?}/{show_id?} служит для поиска ранее добавленных билетов. URL параметры {event_id} и {show_id} в данном запросе необязательные.

В GET или POST параметре нужно передать массив filter с такими возможными полями для фильтрации:

  • external_order_id идентификатор заказа из вашей системы (строка или массив)
  • external_id идентификатор билета из вашей системы (строка или массив)
  • barcode значение ШК кода (строка или массив)
  • id идентификатор билета из системы Qtickets (строка или массив)

Пример запроса:

POST https://qtickets.ru/api/partners/v1/tickets/find/{event_id?}/{show_id?}`
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json

{
  "filter": {
    "external_order_id": "6a5cc185-bc59-451f-b7cb-94376476ae01",
    "external_id": ["ticket12345"],
    "barcode": ["872964136579", "879979255977"],
    "id": [134857, 134858]
  }
}

ответ:

{
  "status": "success",
  "result": [
    {
      "id": 134856,
      "paid": 1,
      "paid_at": "2022-04-06T20:56:00+03:00",
      "reserved_to": "2022-04-07T10:00:00+03:00",
      "external_id": null,
      "external_order_id": "EXT-007",
      "barcode": "872964136579",
      "price": 1222.03,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество",
      "deleted": 0
    },
    {
      "id": 134857,
      "paid": 1,
      "paid_at": "2022-04-06T20:56:00+03:00",
      "reserved_to": "2022-04-07T10:00:00+03:00",
      "external_id": null,
      "external_order_id": "EXT-007",
      "barcode": "879979255977",
      "price": 100.55,
      "client_email": "mail@email.com",
      "client_phone": "+79101234567",
      "client_name": "Имя",
      "client_surname": "Фамилия",
      "client_middlename": "Отчество",
      "deleted": 0
    }
  ]
}

В ответе возвращаются найденные билеты, в том же виде, как возвращает данные методы add и update, единственное отличие, здесь также добавляется поле deleted, в котором будет значение 1 для отменённого билета (например, если закончилось время бронирования)

Events/Seats — статус мест в мероприятии (устаревший метод)

Метод api/partners/v1/events/seats/{event_id}/{show_id?}

Этот метод устарел. Не используйте его в новом коде. Используйте метод Events/Offers

Пример ответа:

{
   "event_id": 12,
   "show_id": 21,
   "event_name":"Название мероприятия 1",
   "start_date":"2019-01-03T17:00:00+10:00",
   "scheme":{
        "id": 48,
        "venue_id": 120,
        "place_name": "Кремлевский дворец",
        "place_address": "ул. Воздвиженка, 1",
        "place_description": "м. Библиотека им. Ленина, Александровский сад, Боровицкая",
        "width": 1000,
        "height": 800,
        "zones":[
            {"zone_id": 8, "name": "VIP left", "description": "", "seats":[{"seat_id": "8-1;42"/*....*/}]},
            {"zone_id": 7, "name": "Supervip right", "description": "", "seats":[{"seat_id": "7-1;8"/*....*/}]},
            {"zone_id": 6, "name": "VIP right 2", "description": "", "seats":[{"seat_id": "6-1;52"/*....*/}]},
            {"zone_id": 5, "name": "Supervip left", "description": "", "seats":[{"seat_id": "5-1;8"/*....*/}]},
            {"zone_id": 4, "name": "VIP left 1", "description": "", "seats":[{"seat_id": "4-1;49"/*....*/}]},
            {"zone_id": 3, "name": "Танцевальный партер", "description": "", "seats":[{"seat_id": "3-1;1"/*....*/}]},
            {"zone_id": 2, "name": "VIP right 1", "description": "", "seats":[{"seat_id": "2-2;49"/*....*/}]},
            {"zone_id": 1, "name": "VIP 3", "description": "", "seats":[{"seat_id": "1-1;49"/*....*/}]}
        ]
    },
   "city":{
        "id": 2,
        "name": "Москва",
        "timezone": "Europe/Moscow",
        "coords":[
            55.7558,
            37.6176
        ]
   },
   "last_update_hash":"2f030832e2eb309b811dc9675df611273aefe618",
   "zones": [
     {
       "zone_id":7,
       "name":"Supervip right",
       "seats":[
         {"seat_id":"7-1;8","available":true,"coords":[283,977],"row":1,"place":8,"price":0,"currency_id":"RUB"},
         {"seat_id":"7-1;7","available":true,"coords":[299,963],"row":1,"place":7,"price":0,"currency_id":"RUB"},
         {"seat_id":"7-1;6","available":true,"coords":[316,949],"row":1,"place":6,"price":0,"currency_id":"RUB"},
         {"seat_id":"7-1;5","available":true,"coords":[333,935],"row":1,"place":5,"price":0,"currency_id":"RUB"},
         {"seat_id":"7-1;4","available":true,"coords":[349,921],"row":1,"place":4,"price":0,"currency_id":"RUB"},
         {"seat_id":"7-1;3","available":true,"coords":[366,907],"row":1,"place":3,"price":0,"currency_id":"RUB"}
       ]
     },
     {
       "zone_id":6,
       "name":"VIP right 2",
       "seats":[
         {"seat_id":"6-1;52","available":true,"coords":[58,600],"row":1,"place":52,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;53","available":true,"coords":[74,614],"row":1,"place":53,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;51","available":true,"coords":[58,579],"row":1,"place":51,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;50","available":true,"coords":[74,565],"row":1,"place":50,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;49","available":true,"coords":[91,551],"row":1,"place":49,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;48","available":true,"coords":[108,537],"row":1,"place":48,"price":0,"currency_id":"RUB"},
         {"seat_id":"6-1;47","available":true,"coords":[125,523],"row":1,"place":47,"price":0,"currency_id":"RUB"}
       ]
     },
     {
       "zone_id":3,
       "name":"Танцевальный партер",
       "seats":[
         {"seat_id":"3-1;1","available":true,"coords":[730,806],"free_quantity":14,"admission":true,"price":300,"currency_id":"RUB"}
       ]
     },
     {
       "zone_id":1,
       "name":"VIP 3",
       "seats":[
         {"seat_id":"1-1;3","available":true,"coords":[1032,137],"row":1,"place":3,"price":1234,"currency_id":"RUB"},
         {"seat_id":"1-1;2","available":true,"coords":[1052,137],"row":1,"place":2,"price":100,"currency_id":"RUB"}
       ]
     }
   ]
}

где:

  • scheme.width — Ширина схемы зала (float)
  • scheme.height — Высота схемы зала (float)
  • scheme.zones[*].width — Ширина сектора для категории билета (float)
  • scheme.zones[*].height — Высота сектора для категории билета (float)
  • scheme.zones[*].offset — Смещение сектора категории билета (array)

В zones содержится список категорий, каждая категория имеет свой уникальный идентификатор zone_id, название name и места seats.

Место имеет свой уникальный идентификатор seat_id, boolean флаг доступности для продажи available, а также ряд row и номер места place. Координаты места указаны в свойстве coords

Для мест, где указано admission: true продаются входные билеты, в параметре free_quantity оставшееся кол-во для продажи.

Список возможных ошибок в ответе

В случае, если status: error

  • UNKNOWN_ERROR — неизвестная ошибка, вероятно стоит обратиться в техподдержку
  • WRONG_AUTHORIZATION — авторизация не удалась, вероятно неверный API KEY
  • EVENT_NOT_FOUND — мероприятие не найдено
  • SEAT_NOT_FOUND — место не найдено
  • SEAT_NOT_AVAILABLE — место недоступно для продажи
  • TICKET_NOT_FOUND — билет не найден
  • VALIDATION_ERROR — ошибка валидации параметров в запросе
Следующая статья
»

Статьи по теме