Система гарантирования прав граждан Республики Казахстан в сфере выездного туризма |
Администратор системы ТУРИСТІК ҚАМҚОР |
Система реестра туров имеет программный шлюз для автоматического добавления туров из приложений онлайн-бронирования туроператоров. Шлюз использует HTTPS-протокол и JSON-формат передачи данных с аутентификацией через переменные внутри JSON-структуры. Ниже описаны общие условия для успешной передачи данных в систему реестра туров и необходимые методы.
Подключение производится по стандартному для HTTPS-протокола порту 443/tcp (production) и HTTP-протокол 80/tcp для тестирования (для удобства отладки). В HTTP-заголовках должны присутствовать заголовки Content-Type со значением application/json и User-Agent со произвольным значением, позволяющим однозначно определить программу онлайн-бронирования и версию ПО. Используется HTTP-метод POST. Запрос производится на корень сервера. В теле запроса должна быть валидная JSON-структура запроса.
Чтобы подключиться к шлюзу, нужно сначала отладить передачу данных на тестовой платформе. Параметры подключения к тестовой платформе: адрес: http://test.fondkamkor.kz, логин test, пароль test. Затем, когда вы будете готовы отсылать реальные данные, свяжитесь с технической поддержкой для получения доступа к рабочей платформе реестра туров. В качестве примера ниже в документации используется кроссплатформенная утилита wget.
Нижеописанные методы используются для создания и отмены туров.
Создание туркода с одним местом пребывания
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=create.json \ --header 'Content-Type: application/json'При этом файл create.json содержит следующее:
{
"input":{
"q_touragent":"ADIYA TRAVEL",
"q_touragent_bin":"123456789012",
"q_country":"Россия",
"q_countryen":"Russia",
"q_airport_start":"ALA",
"q_airlines":"DV",
"q_airport":"AAQ",
"q_date_from":"17.11.2018",
"q_date_to":"24.11.2018",
"q_days":8,
"q_remark":"tour notes here",
"clientcounter":0,
"c_name_0":"Client_$CID",
"c_borned_0":"01.01.1970",
"c_doc_date_0":"02.11.2016",
"c_doc_number_0":"N08462365",
"c_doc_production_0":"MIA OF RK",
},
"module":"voucher",
"section":"partner",
"object":"queries",
"param1":"163",
"param2":"save",
"formid":163,
"agentlogin":"test",
"agentpass":"test",
"return":"q_number"
}
Ответ сервиса будет примерно таким:
HTTP/1.1 200 OK
Server: nginx/1.1.4
Content-Type: application/json;charset=UTF-8
Connection: close
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Date: Sat, 19 Nov 2016 22:57:01 GMT
FastCGI-PID: 17961
{"status":200,"string":"4Ru61117-33"}
Здесь черным цветом указаны стандартные HTTP-заголовки ответа, красным - тело ответа (формат JSON).Запрос | ||||
---|---|---|---|---|
Переменная | Назначение поля | Обяза- тельно | Формат данных | Описание |
module | Название модуля системы | Да | строка | для работы с турами и справочниками значение должно быть "voucher" |
section | Режим аутентификации | Да | строка | для подключения систем туроператоров значение должно быть "partner" |
object | Название метода | Да | строка | Меняется в зависимости от типа запроса. Может быть "queries" или "dictionaries" |
param1, formid | ID шаблона данных | Да | число | для подключения систем туроператоров значение должно быть равно 163 |
param2 | Действие над туром | Да | строка | save - при сохранение тура, bad - при порче тура |
return | Возвращаемое поле тура | Да | строка | Название возвращаемой переменной (при ответе). Переменная q_number содержит ТурКод. Вместо q_number можно указать любое другое поле из вычисляемых или передаваемых, но полезным для туроператора будет именно q_number. |
agentlogin | Логин туроператора | Да | строка | На тестовой платформе - test |
agentpass | Пароль туроператора | Да | строка | На тестовой платформе - test |
Хэш (объект) input: | ||||
q_touragent | Название турфирмы-агента | Да | строка | Название, позволяющее найти турагента при отсутствии туроператора |
q_touragent_bin | БИН турфирмы-агента | Да | строка | БИН компании-турагента (12 цифр), позволяющий найти турагента при отсутствии (недееспособности) туроператора. |
q_country | Русскоязычное название страны пребывания | Да | строка | Должно присутствовать в справочнике стран (см. справочные методы). |
q_countryen | Англоязычное название страны пребывания | Да | строка | Должно присутствовать в справочнике стран (см. справочные методы). |
q_airlines | IATA-код авиалиний | Да | строка, [A-Z0-9]{2} | Должно присутствовать в справочнике авиалиний (см. справочные методы). Если авиаперелет на место курорта осуществлялся одной авиакомпанией, а возврат другой, указывайте код последней. |
q_airport_start | IATA-код аэропорта вылета | Да | строка, [A-Z]{3} | Должно присутствовать в справочнике аэропортов и совпадать со страной Казахстан (см. справочные методы). |
q_airport | IATA-код аэропорта прилета | Да | строка, [A-Z]{3} | Должно присутствовать в справочнике аэропортов и совпадать со страной (см. справочные методы) |
q_date_from | Дата начала тура (вылет) | Да | строка, ДД.ММ.ГГГГ или ГГГГ-ММ-ДД | Дата должна быть в будущем |
q_date_to | Дата конца тура (прилет) | Да | строка, ДД.ММ.ГГГГ или ГГГГ-ММ-ДД | Дата должна быть больше даты начала |
q_days | Число дней тура | Нет | число | Не должно быть меньше единицы |
q_remark | Заметки по туру | Нет | строка | |
q_hotel | Название отеля | Нет | строка | Название отеля проживания |
q_flight | Номер авиарейса туда | Нет | строка | Код авиарейса (заглавные латинские буквы, пробел, тире или цифры). Заполняется номер рейса из аэропорта вылета (Казахстан) в аэропорт прилета (страна отдыха). |
q_flight_from | Номер авиарейса обратно | Нет | строка | Код авиарейса (заглавные латинские буквы, пробел, тире или цифры). Заполняется номер обратного рейса из аэропорта прилета (страна отдыха) в аэропорт вылета (Казахстан) (последний по времени перелет в турпакете). |
clientcounter | Счетчик туристов | Да | число | Число меньше на единицу, чем число туристов в туре (для 1 туриста = 0) |
c_name_0 | Имя туриста 1 | Да | строка | ФИО туриста. Если компания туроператора решит не передавать ФИО, должно быть значение Client_$CID |
c_borned_0 | Дата рождения туриста 1 | Да | строка, ДД.ММ.ГГГГ или ГГГГ-ММ-ДД | Должна быть в прошлом, и больше 2х лет от даты прилета обратно (не infant). Если компания туроператора решит не сообщать дату рождения, должно быть значение 01.01.1970 |
c_doc_date_0 | Дата выдачи паспорта туриста 1 | Нет | строка, ДД.ММ.ГГГГ или ГГГГ-ММ-ДД | Дата должна быть в прошлом. Необязательна. |
c_doc_number_0 | Номер паспорта туриста 1 | Да | строка | Допустимы цифры и буквы, до 15 символов. |
c_doc_production_0 | Госорган, выдавший паспорт туристу 1 | Нет | строка | Аббревиатура органа государства, необязательна. |
Ответ | ||||
Название поля | Назначение поля | Формат данных | Описание | |
status | Код ответа | число | 200 - успешно, другое значение - ошибка. | |
string | Текст ответа | строка | Если ошибка - ее текст, если успешно - ТурКод |
Только один турист допустим в присланном туре, иначе сервис вернет ошибку. ПО туроператора должно присвоить возвращенный туркод каждому туристу и отобразить в соответствующих печатаемых документах для туриста.
Создание туркода с несколькими местами пребывания
Дополнительные данные для сложных туров с несколькими перелетами.
Запрос | ||||
---|---|---|---|---|
Переменная | Назначение поля | Обяза- тельно | Формат данных | Описание |
offercounter | Счетчик дополнительных перелетов | Да | число | Число, меньшее на единицу, чем количество дополнительных перелетов. С четырьмя перелетами в туре, будет равно 2 (три дополнительных перелета, указанных переменными из этой таблицы, минус единицу). Не указывается вообще, если нет дополнительных перелетов. Не может быть отрицательным |
offertype_0 | Тип дополнительного трансфера | Да | строка | Единственное поддерживаемое значение "flight". |
o_date_from_0 | Период пребывания в следующей стране, дата начала | Да | строка | Дата в формате ДД.ММ.ГГГГ или ГГГГ-ММ-ДД. Это дата прилета (чаще всего и вылета) этого дополнительного перелета. |
o_date_to_0 | Период пребывания в следующей стране, дата конца | Да | строка | Дата в формате ДД.ММ.ГГГГ или ГГГГ-ММ-ДД. Это дата покидания новой локации, если дополнительный перелет всего один, то будет совпадать с концом тура. Не будет совпадать с датой дополнительного перелета. |
o_airlines_0 | Код авиакомпании-перевозчика | Да | строка | То же, что q_airlines, но для дополнительного перелета. |
o_airport_0 | Код аэропорта (доп. страна) | Да | строка | То же, что q_airport, но для дополнительного перелета. |
o_flight_0 | Номер авиарейса | Нет | строка | Код авиарейса (заглавные латинские буквы, пробел, тире или цифры). То же, что и q_flight, но для дополнительного перелета. |
o_country_0 | Страна пребывания (рус) | Да | строка | То же, что и q_country, но для дополнительного перелета. |
o_hotel_0 | Название отеля | Нет | строка | То же, что и q_hotel, но для дополнительного перелета. |
В конце имени переменной, если встречается 0, для каждого последующего перелета увеличивать значение на единицу (в названии переменной). Например, o_date_from_0, o_date_from_1 для двух дополнительных перелетов, каждая содержит соответствующее значение для своего дополнительного перелета.
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=create.json \ --header 'Content-Type: application/json'При этом файл create.json содержит следующее:
{
"input":{
"q_touragent":"ADIYA TRAVEL",
"q_touragent_bin":"123456789012",
"q_country":"Россия",
"q_countryen":"Russia",
"q_airport_start":"ALA",
"q_airlines":"DV",
"q_airport":"AAQ",
"q_date_from":"17.11.2018",
"q_date_to":"24.11.2018",
"q_days":8,
"q_remark":"tour notes here",
"clientcounter":0,
"c_name_0":"Client_$CID",
"c_borned_0":"01.01.1970",
"c_doc_date_0":"02.11.2016",
"c_doc_number_0":"N08462365",
"c_doc_production_0":"MIA OF RK",
"offercounter":1,
"offertype_0":"flight",
"o_date_from_0":"19.11.2018",
"o_date_to_0":"21.11.2018",
"o_airlines_0":"TK",
"o_airport_0":"IST",
"o_country_0":"Турция",
"offertype_1":"flight",
"o_date_from_1":"21.11.2018",
"o_date_to_1":"24.11.2018",
"o_airlines_1":"TG",
"o_airport_1":"BKK",
"o_country_1":"Таиланд",
},
"module":"voucher",
"section":"partner",
"object":"queries",
"param1":"163",
"param2":"save",
"formid":163,
"agentlogin":"test",
"agentpass":"test",
"return":"q_number"
}
Порча туркода
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=bad.json \ --header 'Content-Type: application/json'При этом файл bad.json содержит следующее:
{
"input":{
"msg":"Аннулируйте туркод - в нем неправильно указан город прилета. Верный туркод - 123456-7890",
"replyto":"manager@touroperator.kz"
},
"module":"voucher",
"section":"partner",
"object":"queries",
"param1":"4Ru61117-32",
"param2":"bad",
"agentlogin":"test",
"agentpass":"test"
}
Ответ сервиса будет примерно таким:
HTTP/1.1 200 OK
Server: nginx/1.1.4
Content-Type: application/json;charset=UTF-8
Connection: close
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Date: Sat, 19 Nov 2016 22:57:01 GMT
FastCGI-PID: 17961
{"target":"/Voucher/partner/queries/33/view","status":200,
"string":"<h3>Вы будете перенаправлены на запрошенный адрес</h3>..."}
Подробное объяснение новых структур запроса и ответа:
Запрос | ||||
---|---|---|---|---|
Переменная | Назначение поля | Обяза- тельно | Формат данных | Описание |
param1 | ТурКод | Да | число | ТурКод, по которому будет найден тур в реестре. |
param2 | Действие над туром | Да | строка | save - при сохранение тура, bad - при порче тура |
Хэш (объект) input: | ||||
msg | Текст описания | Да | строка | Объяснение причины отмены тура. Должно быть осмысленным, оператор турфирмы должен заполнять это поле вручную, иначе запрос будет проигнорирован. |
replyto | E-mail оператора | Да | строка | Обратный адрес для связи с туроператором, пославшим запрос на отмену заявки |
Ответ | ||||
Название поля | Назначение поля | Формат данных | Описание | |
target | Ссылка на отмененный тур | строка | URL-адрес для просмотра в браузере. |
Если тур видоизменился (изменились его параметры, перечисленные в запросе создания тура), необходимо отменить старый тур, создать новый и получить новый ТурКод. Если не отменить старый, взнос за тур будет списан с баланса туроператора дважды.
Функция повтора создания туркода
При недоступности сервиса, возврате ошибок или иных причинах неполучения туркода для туриста ПО туроператора должно либо попытаться позже (спустя какое-то время, не мгновенно) еще раз получить туркод, либо оповестить сотрудников туроператора об ошибке. В случае повторяющейся проблемы неполучения туркода ПО должно прекратить попытки создания туркода и оповестить сотрудников туроператора. Если в Фонд обратится сам турист и сообщит об отсутствии ТурКода, это может грозить туроператору лишением лицензии.
Если ПО туроператора многократно (бесконечно) пытается создать тур и получить ТурКод, необходимо ограничить попытки сутками с момента начала попыток, либо лимитировать количество попыток создания тура. Причины, по которым система не выдает туркод могут быть самыми разными: аккаунт туроператора может быть заблокирован в системе Фонда, деньги на счету туроператора могут закончиться, в поле запроса создания тура могут быть найдены ошибки, распознаваемые системой Фонда, но не распознаваемые со стороны ПО туроператора и тому подобное. Бесконечность попыток при условии увеличивающегося количества туров, которые требуется сохранить - может привести к перегрузке одной или обеих систем.
Справочные методы
Для синхронизации названий в параметрах туров нужны справочники названий, используемые всеми поставщиками туров. На условиях синхронизации данных сможет работать статистика и основные функции фонда. В параметрах тура используются названия стран и аэропортов. Туры, в параметрах которых указаны несовпадающие или неизвестные значения стран, аэропортов, не будут обработаны должным образом, система вернет ошибку при попытке их создания.
Получение массива данных по странам:
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=dict_countries.json \ --header 'Content-Type: application/json'При этом файл dict_countries.json содержит следующее:
{
"input":{
"what":["country","countryen","currency"],
"output":"array"
},
"module":"voucher",
"section":"partner",
"object":"dictionaries",
"param1":"get",
"param2":"countries",
"agentlogin":"test",
"agentpass":"test"
}
Запрос | ||||
---|---|---|---|---|
Переменная | Назначение поля | Обяза- тельно | Формат данных | Описание |
object | Название метода | Да | строка | Меняется в зависимости от типа запроса. Может быть "queries" или "dictionaries" |
param1 | Действие над справочником | Да | строка | Единственное допустимое для уровня туроператора действие над справочником - получение информации (get) |
param2 | Название справочника | Да | строка | Доступные справочники: countries, airports, airlines, agents |
Хэш (объект) input: | ||||
what | Массив запрашиваемых полей | Нет | список строк | Если не указать эту переменную, будут выведены все столбцы, что увеличит объем ответа. |
output | Структура ответа | Нет | строка | Если не указать эту переменную, массив variants будет содержать объекты, а не списки. |
Ответ | ||||
Название поля | Назначение поля | Формат данных | Описание | |
target | Ссылка на отмененный тур | строка | URL-адрес для просмотра в браузере. |
HTTP/1.1 200 OK Server: nginx/1.1.4 Content-Type: application/json;charset=UTF-8 Connection: close Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Date: Sat, 19 Nov 2016 22:57:01 GMT FastCGI-PID: 17961 {"variants":[["Австралия","Australia","USD"],["Австрия","Austria","EUR"],["Азербайджан","Azerbaijan","USD"], ... ,["Ямайка","Jamaica","USD"],["Япония","Japan","USD"]],"dictname":"countries"}
Получение массива данных по аэропортам:
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=dict_airports.json \ --header 'Content-Type: application/json'При этом файл dict_airports.json содержит следующее:
{
"input":{
"what":["iata","icao","country","countryen"],
"output":"array"
},
"module":"voucher",
"section":"partner",
"object":"dictionaries",
"param1":"get",
"param2":"airports",
"agentlogin":"test",
"agentpass":"test"
}
Ответ будет аналогичным по структуре.
Получение массива данных по авиалиниям:
wget -q -O - 'http://test.fondkamkor.kz' -S --post-file=dict_airlines.json \ --header 'Content-Type: application/json'При этом файл dict_airlines.json содержит следующее:
{
"input":{
"what":["iata","icao","country","airline","companyname","address","airline_url"],
"output":"array"
},
"module":"voucher",
"section":"partner",
"object":"dictionaries",
"param1":"get",
"param2":"airlines",
"agentlogin":"test",
"agentpass":"test"
}
Ответ будет аналогичным по структуре.
Все приведенные файлы примеров вы можете скачать одним файлом.
Также вы можете скачать в формате XLS для ручной сверки со справочниками в своей программе списки названий стран (27кб, 260 стран) и кодов аэропортов IATA с привязкой к странам (1.6мб, 9432 кода).
Если вы встретили ошибку вида "Invalid Country/IATA combination. Check dictionaries synchronisation, please", но уверены в том, что вы подали правильное название страны и код аэропорта, возможно, он отсутствует в наших справочниках, обратитесь в таком случае в техническую поддержку фонда, чтобы справочники были обновлены.
Может возникнуть ситуация, когда код IATA признается несуществующим, хотя он есть на самом деле (вы получаете ошибку вида "Invalid Country/IATA code..."). В этом случае нужно обратиться в техническую поддержку с просьбой добавить код IATA в базу. Аэропорты строятся, меняют название - все это приводит к устареванию базы данных.
Если вы отладили подключение и вам требуются координаты подключения к рабочей платформе, или же у вас возникли вопросы, свяжитесь с технической поддержкой.
На правах рекомендации
После опробования нескольких реализованных решений передачи данных у разных туроператоров с различным программным обеспечением появились наблюдения, которые могут стать ценными, если вы собираетесь реализовывать передачу данных на своем программном обеспечении:
Обновления документации:
13.12.2016
Удален абзац:
"На сегодня (20.11.2016) остается открытым вопрос о количестве туристов в туре. Если их количество все же будет равным количеству в реальном туре, то переменная clientcounter должна будет равна N-1, где N - количество туристов в туре, а переменные c_name_0 ... c_doc_production_0 должны быть продублированы с соответствующими суффиксами _1, _2 и т.д. - под каждого туриста. Если же их количество будет фиксировано одним туристом в туре, встанет задача хранить туркод для каждого туриста в программе туроператора (и распечатывать в ваучерах или иных документах для туриста массив туркодов)."
Вместо него добавлена фраза:
"Только один турист допустим в присланном туре, иначе сервис вернет ошибку. ПО туроператора должно присвоить возвращенный туркод каждому туристу и отобразить в соответствующих печатаемых документах для туриста."
03.10.2017
Добавлена информация по двум обязательным полям ввода при передачи данных для получения туркода: q_airlines и q_airport_start. Добавлено описание запроса справочника airlines. Обязательность начнет действовать с 1го января 2018 года.
31.05.2022
Добавлена инфорамация по оформлению дополнительных авиаперелетов в ходе путешествия, поля отелей, БИН турагента.