Aviasales api: Страница не найдена — Aviasales

Содержание

API простым языком: что это и зачем нужен

Немногие могут объяснить, что такое API, но все ими пользуются. РБК Тренды выяснили, что такое программные интерфейсы и где их применяют

API (Application Programming Interface или интерфейс программирования приложений) — это совокупность инструментов и функций в виде интерфейса для создания новых приложений, благодаря которому одна программа будет взаимодействовать с другой. Это позволяет разработчикам расширять функциональность своего продукта и связывать его с другими.

Большинство крупных компаний разрабатывают API для клиентов или для внутреннего использования. Обычные пользователи тоже применяют разные API. РБК Тренды объясняют, как это работает.

Когда пользователь посещает любую страницу в интернете, он взаимодействует с API удаленного сервера. Это составляющая сервера, которая получает запросы и отправляет ответы.

Кроме того, благодаря API человек может совершать различные действия, не покидая сайт. Именно для этого большинство современных сайтов используют по крайней мере несколько сторонних API, которые предлагают сторонние разработчики. Также компании разрабатывают собственные API и продают их как готовый продукт. К примеру, Weather Underground, которая принадлежит IBM, продает доступ к своему API для получения метеорологических данных. Эту информацию используют погодные приложения и сервисы.

Приложение Weather Underground (Фото: Google Play)

ProgrammableWeb, веб-сайт, посвященный экономике API, в настоящее время отслеживает более 24 тыс. различных программных интерфейсов. Существуют сотни API для финансовых систем, обмена сообщениями в социальных сетях, платежей, электронной коммерции, криптовалют и прочих сфер. Наиболее быстрорастущий сегмент API относится к обмену и анализу данных в различных приложениях.

Как работает API

Интерфейс представляет собой промежуточный слой между двумя приложениями. Он позволяет двум программам обмениваться информацией и выполнять функции, не раскрывая своего внутреннего API. Скрытие части функций называется инкапсуляцией.

Есть три метода взаимодействия с API:

  1. Процесс, который может выполнять программа при помощи этого интерфейса.
  2. Данные, которые нужно передать интерфейсу для выполнения им функции.
  3. Данные, которые программа получит на выходе после работы с API.

Разработчик имеет полную свободу в выстраивании функций API. Например, отдельный набор функций может определять возможность регистрироваться и авторизоваться в программе.

API бывают публичные и частные. Первые предназначены для совместного использования с внешним миром, например, API YouTube. Сторонние разработчики могут создавать приложения, чтобы воспользоваться возможностями этих интерфейсов. Вторые — это внутренние приложения, разработанные для определенной аудитории или пользовательской базы. Они часто используются на предприятиях и внутри компаний. Для работы с таким API нужно получить доступ.

Для чего используют API

Разработчикам программный интерфейс позволяет:

  • упростить и ускорить выпуск новых продуктов, так как можно использовать уже готовые API для стандартных функций;
  • сделать разработку более безопасной, выведя ряд функций в отдельное приложение, где они будут скрыты;
  • упростить настройку связей между разными сервисами и программами и не сотрудничать для разработки своего продукта с создателями различных приложений;
  • сэкономить деньги, так как не нужно разрабатывать все программные решения с нуля.

До появления Windows и других графических операционных систем программистам для создания окон на экране компьютера приходилось писать тысячи строк кода. Когда же Microsoft предоставила разработчикам API Windows, на создание окон стало уходить всего несколько минут работы.

Бизнесу API нужны, чтобы:

  • проводить транзакции;
  • интегрировать потоки данных с клиентами и партнерскими системами;
  • повысить безопасность автоматизированных процессов;
  • развивать собственные приложения;
  • внедрять инновации, например, при работе с клиентами.

В 1990-е годы организация, которая хотела запустить систему управления взаимоотношениями с клиентами (CRM), была вынуждена вкладывать огромные средства в программное обеспечение, оборудование и специалистов. Теперь компании используют облачные службы вроде Salesforce. Доступ на уровне API к функциям Salesforce позволяет бизнесу включить ключевые элементы функциональности CRM-системы — например, возможность просматривать историю клиента.

Правительствам API позволяют:

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

Уже в 40 городах США используется бесплатный API Open311, который позволяет отслеживать проблемы на основе местоположения пользователя. Человеку достаточно лишь отправить в городскую систему фото с выбоиной на дороге и указанием геолокации.

Примеры API в нашей жизни

Google Календарь. Приложение-календарь на Android разработает на API, позволяющем подключить свой календарь напрямую к сторонним приложениям. Пользователи могут использовать несколько разных программ с встроенными и обновляемыми календарями, где будут все важные события, встречи и т.д. Компании могут встраивать API календаря на свои сайты, чтобы, к примеру, записывать своих клиентов на прием. Встраивание в форму записи Google Календаря позволяет клиентам автоматически создавать событие и вносить детали о предстоящей встрече. Благодаря API сервер сайта напрямую обращается к серверу Google с запросом на создание события, получает ответ Google, обрабатывает его и передает соответствующую информацию в браузер, которая поступает клиенту в виде сообщения с подтверждением.

Заказ авиабилетов. Многие пользуются агрегаторами билетов, такими как Aviasales и SkyScanner. Такие сервисы собирают информацию о стоимости авиабилетов в разных авиакомпаниях и отображают ее в едином окне. Это позволяет реализовать API, встроенный в сайты авиакомпаний, который помогает в реальном времени обновлять информацию о направлениях и стоимости.

Поиск авиабилета на Aviasales

Навигация на сайтах и в приложениях. Крупные компании, в том числе Apple, Google, «Яндекс» и другие, разработали API, позволяющие подключить собственный картографический сервис к другим площадкам. Так, в «Яндекс.Карты» встроены сервисы «Транспорт» и «Пробки». Многие приложения на Android, например, по доставке еды или для спорта, используют встроенный в ОС API, чтобы подключить карты Google к своему сервису. На iOS аналогичная ситуация с Apple Maps.

Кнопки авторизации. На многих сайтах есть кнопки, позволяющие зарегистрироваться через уже существующие аккаунты на популярных площадках и в соцсетях. Это возможно благодаря API, которые есть у Google, Facebook, Apple, Twitter, «ВКонтакте» и других компаний.

API RU · KosyanMedia/aviasales-self-service-api Wiki · GitHub

Запрос вариантов перелета с ценами

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

curl 'http://example.ru/api/search?from=MOW&to=LED&date1=2017-09-25&date2=2017-10-01&adults=2&children=1&infants=1&cabin=Y&partner=avsl&password=pass&locale=ru&currency=rub'

Параметры запроса

  • from — IATA код пункта отправления.
  • to — IATA пункта назначения.
  • date1 — YYYY-MM-DD дата вылета.
  • date2 — YYYY-MM-DD дата возвращения. Для перелётов в одну сторону не передаётся.
  • adults — Количество взрослых пассажиров.
  • children — Количество пассажиров детей от 2 до 12 лет.
  • infants — Количество пассажиров детей до 2х лет.
  • cabin — Класс перелёта. «Y» — эконом , «C» — бизнес, «F» — первый.
  • partner — Идентификатор клиента делающего запрос.
  • password — Пароль клиента делающего запрос.
  • locale — Локаль (по умолчанию ru).
  • currency — Валюта (по умолчанию rub).

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

<?xml version='1.0' encoding='utf-8' ?>
<variants>
    <variant>
        <price>2664</price>
        <currency>rub</currency>
        <url>BOOKING_PAGE_DEEPLINK</url>
        <seats>3</seats>
        <isCharter>false</isCharter>
        <commission>0.0493</commission>
        <segment>
            <flight>
                <operatingCarrier>UN</operatingCarrier>
                <marketingCarrier>SU</marketingCarrier>
                <number>3</number>
                <departure>DME</departure>
                <departureDate>2017-09-25</departureDate>
                <departureTime>09:55</departureTime>
                <arrival>LED</arrival>
                <arrivalDate>2017-09-25</arrivalDate>
                <arrivalTime>11:10</arrivalTime>
                <equipment>735</equipment>
                <cabin>Y</cabin>
                <baggage>1PC23</baggage>
                <handbags>1PC5</handbags>
                <baggageRecheck>false</baggageRecheck>
                <virtualInterline>false</virtualInterline>
                <fareCode>WOW1</fareCode>
                <isBus>false</isBus>
                <isTrain>false</isTrain>
            </flight>
        </segment>
        <segment>
            <flight>
                <operatingCarrier>UN</operatingCarrier>
                <marketingCarrier>SU</marketingCarrier>
                <number>3</number>
                <departure>LED</departure>
                <departureDate>2017-10-01</departureDate>
                <departureTime>09:55</departureTime>
                <arrival>DME</arrival>
                <arrivalDate>2017-10-01</arrivalDate>
                <arrivalTime>11:10</arrivalTime>
                <equipment>736</equipment>
                <cabin>Y</cabin>
                <baggage>1PC23</baggage>
                <handbags>1PC5</handbags>
                <baggageRecheck>false</baggageRecheck>
                <virtualInterline>false</virtualInterline>
                <fareCode>WOW1</fareCode>
                <isBus>false</isBus>
                <isTrain>false</isTrain>
                <technicalStop>
                    <airportCode>AER</airportCode>
                </technicalStop>
                <technicalStop>
                    <airportCode>AAQ</airportCode>
                </technicalStop>
            </flight>
        </segment>
    </variant>
    <variant>
    ...more variants...
    </variant>
</variants>

Пример пустого ответа

<?xml version='1.0' encoding='utf-8' ?>
<variants></variants>
  • Сервер должен вернуть результаты поиска менее чем за 30 секунд.
  • Ответы с любым статусом кроме HTTP 200 считаются ошибками. Тело ответа должно содержать описание ошибки.
  • Все ответы со статусом HTTP 200 считаются успешными ответами.
  • Строка BOOKING_PAGE_DEEPLINK – URL, ведущий на страницу бронирования с языком и валютой, в которых был сделан запрос.
Содержание ответа
  • /variants — корневой элемент, содержащий варианты перелётов.
  • //variant — полный вариант перелёта.
  • price (mandatory) — полная цена за всех пассажиров для данного перелёта.
  • currency (mandatory) — валюта используемая в цене билетов.
  • url (mandatory) — URL приземляющий пользователя на страницу бронирования билетов.
  • seats (optional) – количество билетов, доступных для бронирования по текущему тарифу. Цифра в диапазоне 0..9. 0 — нет доступных билетов и 9 — доступно 9 и более билетов.
  • isCharter (optional) — признак чартерного варианта перелёта true|false.
  • commission (optional) — процентная ставка комиссии для конкретного предложения.
  • segment — сегменты перелёта. Первый сегмент перелёт туда, второй обратно.
  • segment/flight — 1..n, все перелёты в одну сторону.
  • //flight — информация об одном перелёте.
  • operatingCarrier (mandatory) — IATA код авиакомпании осуществляющей рейс.
  • marketingCarrier (optional) — IATA код авиакомпании продающей рейс, указывается если отличается от авиакомпании осуществляющей рейс (code share).
  • number (mandatory) — номер рейса.
  • departure (mandatory) — IATA код аэропорта отправления.
  • departureDate (mandatory) — дата отправления, ‘YYYY-MM-DD’, местное время.
  • departureTime (mandatory) — время отправления, ‘HH:MM’, местное время.
  • arrival (mandatory) — IATA код аэропорта назначения.
  • arrivalDate (mandatory) — дата прибытия, ‘YYYY-MM-DD’, местное время.
  • arrivalTime (mandatory) — время прибытия, ‘HH:MM’, местное время.
  • equipment (optional) — IATA транспортного средства осуществляющего перевозку.
  • cabin (optional) — класс перелёта. «Y» — эконом , «C» — бизнес, «F» — первый.
  • baggage (optional) — строка в формате {N}PC{WW} где N — количество мест багажа по текущему тарифу, и WW — максимальный вес каждого места. При отсутствии информации о багаже необходимо отправить пустое значение. Для тарифов, не предусматривающих багаж, используется строка 0PC.
  • handbags (optional) — строка в формате {N}PC{WW} где N — количество мест ручной клади по текущему тарифу, и WW — её максимальный вес. При отсутствии информации о ручной клади необходимо отправить пустое значение. Для тарифов, не предусматривающих ручную кладь, используется строка 0PC.
  • baggageRecheck (optional) — признак того, что пассажиру нужно сделать речек багажа между перелётом с признаком и предыдущим перелётом true|false.
  • virtualInterline (optional) — признак того, что пассажиру нужно заново пройти регистрацию между перелётом с признаком и предыдущим перелётом true|false.
  • fareCode (optional) — код тарифа для текущего варианта перелёта.
  • isBus (optional)/isTrain (optional) — признак того, что сегмент является частью мультимодальной перевозки и выполняется автобусом/поездом true|false.
  • //technicalStop — список технических остановок
  • airportCode — IATA-код аэропорта технической остановки

Для покупки билетов пользователь будет отправлен на URL из тега variant/url. Для отслеживания продаж и привязывания к посетителям передаётся дополнительный GET параметр marker.

Полный URL бронирования строится следующим образом:

  1. Парсим изначальный URL диплинка
  2. В секцию параметров добавляем параметр marker=<marker_value (убедитесь что параметры запроса изначального URL диплинка соответствуют стандарту RFC3986)
  3. Кодируем секцию параметров методом urlencode

marker_value — строка содержащая не более 256 символов. Маркер переданный при переходе на бронирование должен быть частью информации о бронировании в статистике, если пользователь после перехода сделал бронирование.

Используйте онлайн-инструмент https://aviasales-gate-tester.herokuapp.com/ для проверки соответствия гейта API

Пример запроса сложного маршрута

curl 'http://example.ru/api/search?from=MOW&to=LED&date1=2017-09-25&from2=LED&to2=IKT&date2=2017-10-01&from3=IKT&to3=VVO&date3=2017-10-03&adults=2&children=1&infants=1&cabin=Y&partner=avsl&password=pass&locale=ru&currency=rub'

Пример ответа сложного маршрута

<?xml version='1.0' encoding='utf-8' ?>
<variants>
    <variant>**Используйте онлайн-инструмент https://aviasales-gate-tester.herokuapp.com/ для проверки соответствия гейта API**

        <price>2664</price>
        <currency>rub</currency>
        <url>BOOKING_PAGE_DEEPLINK</url>
        <seats>3</seats>
        <isCharter>false</isCharter>
        <isVirtualInterline>false</isVirtualInterline>
        <commission>0.0493</commission>
        <segment>
            <flight>
                <operatingCarrier>UN</operatingCarrier>
                <marketingCarrier>SU</marketingCarrier>
                <number>3</number>
                <departure>DME</departure>
                <departureDate>2017-09-25</departureDate>
                <departureTime>09:55</departureTime>
                <arrival>LED</arrival>
                <arrivalDate>2017-09-25</arrivalDate>
                <arrivalTime>11:10</arrivalTime>
                <equipment>735</equipment>
                <cabin>Y</cabin>
                <baggage>1PC23</baggage>
                <handbags>1PC5</handbags>
                <baggageRecheck>false</baggageRecheck>
                <fareCode>WOW1</fareCode>
                <isBus>false</isBus>
                <isTrain>false</isTrain>
            </flight>
        </segment>
        <segment>
            <flight>
                <operatingCarrier>UN</operatingCarrier>
                <marketingCarrier>SU</marketingCarrier>
                <number>3</number>
                <departure>LED</departure>
                <departureDate>2017-10-01</departureDate>
                <departureTime>09:55</departureTime>
                <arrival>IKT</arrival>
                <arrivalDate>2017-10-01</arrivalDate>
                <arrivalTime>11:10</arrivalTime>
                <equipment>736</equipment>
                <cabin>Y</cabin>
                <baggage>1PC23</baggage>
                <handbags>1PC5</handbags>
                <baggageRecheck>false</baggageRecheck>
                <fareCode>WOW1</fareCode>
                <isBus>false</isBus>
                <isTrain>false</isTrain>
                <technicalStop>
                    <airportCode>AER</airportCode>
                </technicalStop>
                <technicalStop>
                    <airportCode>AAQ</airportCode>
                </technicalStop>
            </flight>
        </segment>
        <segment>
            <flight>
                <operatingCarrier>SU</operatingCarrier>
                <marketingCarrier>SU</marketingCarrier>
                <number>3</number>
                <departure>IKT</departure>
                <departureDate>2017-10-03</departureDate>
                <departureTime>10:55</departureTime>
                <arrival>VVO</arrival>
                <arrivalDate>2017-10-03</arrivalDate>
                <arrivalTime>15:00</arrivalTime>
                <equipment>736</equipment>
                <cabin>Y</cabin>
                <baggage>1PC23</baggage>
                <handbags>1PC5</handbags>
                <baggageRecheck>false</baggageRecheck>
                <fareCode>WOW1</fareCode>
                <isBus>false</isBus>
                <isTrain>false</isTrain>
            </flight>
        </segment>
    </variant>
    <variant>
    ...more variants...
    </variant>
</variants>

Статистика продаж

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

curl 'http://example.ru/api/statistics?date1=2012-05-01&date2=2012-06-01&partner=aviasales&password=secret&locale=ru'

Параметры запроса
  • date1 — YYYY-MM-DD дата.
  • date2 — YYYY-MM-DD дата.
  • partner — идентификатор партнёра.
  • password — пароль партнёра.
  • locale — Локаль (по умолчанию ru)

Ответ должен содержать все брони осуществлённые в период с date1 по date2

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

<bookings>
  <booking>
    <id>JHKHVR</id>
    <PNR>VQEGQY</PNR>
    <created_at>2012-05-02 00:02:01</created_at>
    <marker>1232:1222.t</marker>
    <price>1199</price>
    <profit>200</profit>
    <currency>RUB</currency>
    <state>PAID</state>
    <segment>
      <flight>
        <operatingCarrier>UN</operatingCarrier>
        <number>3</number>
        <departure>DME</departure>
        <departureDate>2012-09-25</departureDate>
        <departureTime>09:55</departureTime>
        <arrival>LED</arrival>
        <arrivalDate>2012-09-25</arrivalDate>
        <arrivalTime>11:10</arrivalTime>
        <equipment>735</equipment>
        <cabin>Y</cabin>
      </flight>
    </segment>
    <adults>1</adults>
    <children>0</children>
    <infants>0</infants>
  </booking>
  ...more bookings...
</bookings>
Содержание ответа
  • /bookings — корневой элемент содержащий информацию о бронированиях.
  • //booking — информации об одном бронировании.
  • id — уникальный идентификатор бронирования.
  • PNR — PNR бронирования
  • created_at — YYYY-MM-DD HH:MM:SS время и дата бронирования в таймзоне UTC.
  • marker — маркер переданные в GET параметре marker при переходе на бронирование.
  • from — IATA код аэропорта отправления.
  • to — IATA код аэропорта назначения.
  • price — цена билетов.
  • profit — прибыль партнёра от данного бронирования.
  • currency — валюта в которой указаны прибыль и цена билета.
  • state — состояние брони. Подробности про допустимые состояния бронирования вы найдёте ниже.
  • segment — информация о перелётах (аналогично поисковому запросу).
  • //flight — информация об одном перелёте.
  • operatingCarrier — код авиакомпании осуществляющей рейс.
  • number — номер рейса.
  • departure — IATA код аэропорта отправления.
  • departureDate — дата отправления, ‘YYYY-MM-DD’, местное время.
  • departureTime — время отправления, ‘HH:MM’, местное время.
  • arrival — IATA код аэропорта назначения.
  • arrivalDate — дата прибытия, ‘YYYY-MM-DD’, местное время.
  • arrivalTime — время прибытия, ‘HH:MM’, местное время.
  • equipment — IATA транспортного средства осуществляющего перевозку.
  • cabin — класс перелёта. «Y» — эконом , «C» — бизнес, «F» — первый.
  • adults — кол-во взрослых пассажиров.
  • children — кол-во детей.
  • infants — кол-во детей до 2 лет.

Валидные значениния тега

state
  • PROCESSING — временный статус. Оплата/подтверждение еще не поступили, ожидаем. Должен перейти в paid или в cancelled в ближайшие сутки. Теги и должны содержать реальную стоимость заказа и профит, быть отличными от нуля. Заказы в статусе PROCESSING в счет не включаются, но, поскольку мы ожидаем финализацию статуса в течение суток, ситуации, где по итогам месяца в сверке фигурируют нефинализированные брони, возникать не должно.

  • PAID — заказ оплачен. Если в заказ не вносятся никакие изменения, статус paid сохраняется до конца срока жизни статистики. В случае внесения изменений заказ в статусе Paid может перейти в любой статус, кроме processing. Теги и должны содержать реальную стоимость заказа и профит, быть отличными от нуля. За заказы в статусе PAID мы ожидаем получить комиссию соответственно значениям в теге

  • CANCELLED — заказ отменен. В этот статус бронирование может быть переведено из статусов processing и paid. Теги и должны быть больше нуля, в мы ожидаем получить значение цены заказа, который пытался забронировать пользователь, в — рассчитанный % комиссии от этой цены. Заказы в статусе CANCELLED не включаются в счет по итогам месяца, комиссию за них мы не ожидаем.

  • REFUND — возвраты, за которые Aviasales возвращает комиссию, согласно договору. В этот статус бронирование может быть переведено только из статуса paid. Теги и должны быть больше нуля. Значения в тегах и после перехода заказа из PAID в REFUND сохраняются. Если покупка и возврат произошли в текущем месяце, то такие заказы, переведенные в статус REFUND, не включаются в итоговый счет, комиссию за них мы не ожидаем. Если покупка произошла раньше, и комиссию за заказ мы уже получили, то заказ в API также нужно перевести в статус REFUND, а комиссия за него будет возвращена. Для пересчета общей суммы комиссии нужно подать список вынужденных возвратов в ежемесячном финансовом отчете.

  • PAID_REFUND — заказы, за которые, согласно договору, комиссия агентству не возвращается. В этот статус бронирование может быть переведено только из статуса paid. Значения в тегах и после перехода заказа из PAID в PAID_REFUND сохраняются. За заказы в статусе PAID_REFUND мы ожидаем получить комиссию соответственно значениям в теге .

  • PART_REFUND — частичный возврат. В этот статус бронирование может быть переведено только из статуса paid, если имел место возврат части билетов/сегментов, но в самом заказе остался как минимум один оплаченный билет/сегмент. В этом случае заказ должен быть переведен в статус PART_REFUND. Если возвращенный билет/сегмент попадает под правила для REFUND (т.е. за эту часть Aviasales должны вернуть комиссию, согласно договору), то у PART_REFUND букинга price уменьшается на сумму возврата. Значение в = стоимость оставшегося заказа, значение уменьшается соответственно. Если возвращенный билет/сегмент попадает под правила для PAID_REFUND, мы ожидаем получить полную комиссию за весь заказ, включая возвращенную часть. Изменений в и не происходит.

Схема валидных переходов статусов

Жизненный цикл бронирования

Список направлений

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

curl 'http://example.ru/api/supported_directions?partner=aviasales&password=secret'

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

MOW,LED

LED,MOW

...

MOW,KUF

KUF,MOW

Содержание ответа

Мы ожидаем получить в ответе пары IATA-кодов городов вылета и прилёта.

Всеволод Биллевич (Aviasales) о фирменном SDK

На прошлой неделе у Артемия Лебедева вышло мобильное приложение «Тревел — Артемий Лебедев и его путевые заметки». В нем собраны все материалы из путешествий Темы (ну какой еще гид начнет рассказ о городе фразой «В Рязани видно, что все деньги украдены»), а построено оно на базе SDK Aviasales и это, пожалуй, самый яркий пример того, как продукт может быть адаптирован под партнерский контент.

Мы поговорили с Всеволодом Биллевичем, который курировал разработку с самого начала, и попросили рассказать о том, что такое SDK Aviasales и как с ним лучше работать.

Как вы пришли к идее выпустить SDK? Почему SDK, а не API?

Партнерский API существует у нас уже давно. Но вряд ли кто-то возьмется разрабатывать iOS приложение, имея в распоряжении только API. Все-таки трудозатраты на такое приложение слишком велики. Поэтому мы решили не ждать, когда нас об этом попросят, а сделать такой инструмент, с помощью которого можно было бы легко внедрить поисковую форму в существующие приложения, либо создать приложение по поиску авиабилетов с нуля.

Для каких платформ сейчас он реализован?

Сейчас есть SDK есть только для iOS. Разрабатываем для Android, запуск планируется к лету. Для Windows Phone доступен только партнерский API.

Какие функции у него есть?

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

Шаблонное iPhone-приложение, которое тоже входит в состав SDK, состоит из поисковой формы, экрана ожидания, результатов поиска, фильтров и экрана с подробной информацией о билете. Поисковый модуль может быть встроен в существующее приложение различными способами, например, как модальное окно или как экран в таббаре. Для интерфейса подготовлены локализации на русском и английском. Испанскую локализацию любезно предоставил один из разработчиков, и мы добавили её в проект.

Были ли какие-нибудь сложности при его разработке?

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

Основной проблемой стало то, что SDK стал развиваться независимо от основного приложения, использовать разную кодовую базу. Это усложнило разработку и замедлило внедрение новых фич. С новой версии SDK мы планируем не повторять эту ошибку, а сделать так, чтобы наше флагманское приложение само использовало SDK.

Сколько приложений сейчас использует ваш SDK?

Сейчас опубликовано около 20 iOS—приложений, использующих наш SDK. Однако примерно 15 из них созданы одним нашим партнером, и различаются они, по сути, только локализацией на различные языки.

Насколько просто его интегрировать в свое приложение?

Процесс интеграции я бы не назвал сложным. Сейчас он состоит из 6 пунктов, которые очень подробно описаны в документации к SDK. Хотя, конечно, есть, куда стремиться. В новой версии SDK, над которой мы работаем, действия разработчика по внедрению поискового модуля будут минимизированы до 2-3 шагов. Распространять будущие версии SDK будем, скорее всего, через CocoaPods.

Какие лучшие примеры интеграции?

Лучший пример интеграции сторонними разработчиками — это, несомненно, приложение для Travel.ru. Ребята объединили свой поиск отелей с нашим поиском авиабилетов, и получилось крутое приложение для путешественников. Кроме того, разработчики из CleverPumpkin (они занимаются разработкой мобильных продуктов для Travel.ru) «допилили» наше шаблонное приложение до полноценной поддержки iPhone 6 и iPhone 6+, когда они только стали доступны.

The app was not found in the store. 🙁

Другой хороший пример использования SDK Aviasales — приложение с путеводителями Redigo.

Из более свежих решений — приложение для Артемия Лебедева. В нём, помимо поиска авиабилетов, представлены отчёты Артемия о его поездках.

Разработка велась силами нашей команды, поэтому мы позволили себе использовать «расширенную» версию SDK, которая уже практически не уступает по функциональности и внешнему виду основному нашему приложению. Новую версию SDK мы планируем выпустить в этом году, где обязательно учтём все пожелания от разработчиков.

Спасибо, хороших вам полетов!

Если вы нашли опечатку — выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать [email protected]

Вакансии компании Aviasales.ru — работа в Москве, Санкт-Петербурге, Казани, Самаре

«Я много путешествую и, соответственно, часто летаю. Для удобного централизованного отслеживания скидок и распродаж авиакомпаний в 2007 году я создал этот сайт. Однако сайт оказался полезен не только мне, стал расти, развиваться, прирастать новыми сервисами и на сегодняшний день стал одним из самых больших и полезных ресурсов про авиабилеты в рунете», —  основатель и руководитель проекта Константин Калинов.

 

Сейчас Aviasales.ru – это крупнейший в Рунете Интернет-поисковик авиабилетов с посещаемостью более чем в 10 миллионов пользователей ежемесячно и дополнительными функциями по поиску отелей, страховых полисов и сервисов по аренде автомобилей.

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

У нас удобный интерфейс, отлаженные и быстрые механизмы поиска, множество полезных функций на сайте, мобильные приложения под iPhone, iPad и Android. И, конечно, у нас большое количество очень интересных задач по разработке и поддержке ресурса, для решения которых мы ищем новых сотрудников.

Сегодня в нашей компании работают более 150 человек. На сегодняшний день у нас три офиса:

  • офис на прекрасном острове Пхукет в Таиланде, где находятся продуктовые команды разработки aviasales.ru, нашей партнерской программы TravelPayouts, команды аналитики и стратегического партнерства;
  • офис в Санкт-Петербурге, где ведется вся мобильная разработка;
  • офис в Москве, представленный отделом рекламы, маркетинга, PR, финансов, а также сотрудниками других отделов.
 

У всех наших сотрудников есть, независимо от локации:

  • отличная зарплата и ежеквартальный бонус по результатам работы;
  • отпуск — 28 календарных дней;
  • ДМС;
  • удобный график работы;
  • классный офис со всеми плюшками.

Если вы умеете работать в команде и при этом самостоятельно ставить задачи и находить пути их решения, берете на себя ответственность за свою работу и не можете жить без Интернета, то присоединяйтесь к одному из самых больших и полезных ресурсов про авиабилеты в Рунете! 

Поддержку, достойную оплату и щедрый обмен знаниями и опытом гарантируем 🙂

travelpayouts-js — npm

Node.js библиотека для работы с Travelpayouts API с некоторыми opinionated defaults и использованием промисов. Поддерживается только получение данных об авиабилетах. Библиотека вдохновлена node-travelpayouts, в ней можно найти так же работу с поиском авиабилетов и партнерской статистикой.

Установка

$ npm install travelpayouts-js

Использование

  1. Зарегистрируйтесь в Travelpayouts
  2. Получите API-токен в разделе Разработчикам → API
  3. Подключите библиотеку в коде:
const lib = require('travelpayouts-js');
const api = lib({token: 'полученный_токен'})

Или в одну строку:

const api = require('travelpayouts-js')({token: 'полученный_токен'});

Также можно передать токен как TPAPITOKEN=token через process.env при запуске приложения или указав в .env-файле.

  1. Готово. Теперь можно вызывать методы API.

Дефолтные настройки

Во многих методах есть некоторые предустановленные по умолчанию опции, которые используются при запросе. Чтобы перезаписать их, нужно явно передать нужную опцию и ее значение. В целом в качестве дефолтов я старался использовать дефолтные значения из документации API, но это не везде так.

Возможно, вам понадобится, чтобы запрос прошел без каких-то опций, у которых установлены дефолты (и даже если их не указать, они все равно будут подставлены в строку запроса). Для этого можно передать в опциях параметр removeParams со значением в виде массива названий параметров, которые нужно удалить из запроса, например:

Мы хотим убрать из метода api.weekMatrix() дефолтные параметры depart_date и return_date (там, в случае если не передать их, они устанавливаются как завтрашняя дата и сегодняшняя дата + 2 недели соответственно):

api.weekMatrix({ origin: "MOW", destination: "BKK", removeParams: ['depart_date', 'return_date'] })

Теперь эти два параметра не будут подставлены в запрос, даже если для них были какие-то дефолты. Чтобы точно понять какие данные уходят в запрос, можно использовать параметр debug (подробнее ниже в разделе Отладка).

Всё это я постарался подробно описать в каждом из методов. Также я попытался максимально описать некоторые, не всегда очевидные, моменты использования API.

Обработка ошибок

Поскольку мне нужна была стабильная работа модуля, даже в случае если API вернет ошибку (неважно по какой причине — упало API или неправильно переданы параметры) — на ошибки возвращается пустой массив (кроме методов holidaysByRoutes, minPricesCalendar directions и airline — тут вернется пустой объект). В будущем постараюсь сделать это опциональным или настраиваемым.

Результаты ответа API и переформатирование

Результаты некоторых методов API я переформатирую в другой вид, для своего удобства. Например объект в массив. Об этом подробно написано в каждом из методов, которые это затронуло, с пояснениями что было и что стало.

Генерация ссылок на поиск билетов

У вас есть возможность возвращать данные по билетам, которые уже будут содержать нужную ссылку на поисковую выдачу с подставленными данными (город вылета и прилета, даты вылета/прилета, кол-во взрослых, детей и младенцев и прочее). Подробнее можно почитать в разделе Партнерские ссылки.

Для генерации ссылки нужно передать вместе с опциями запроса параметр generateUrls, например:

api.city({
	origin: "MOW",
	generateUrls: {
		oneway: 0,
		adults: 1,
		children: 0,
		infants: 0,
		trip_class: 0
		marker: 666777888
		with_request: true
		currency: 'rub'
		locale: 'ru'
		url: 'http://whitelabel.yoursite.ru'
	}
})
.then(data => console.log(data))

Можно передавать все параметры из таблицы описания параметров запроса (здесь, пролистать чуть ниже после открытия), кроме: origin_iata, destination_iata, depart_date, return_date (они подставляются из параметров каждого конкретного билета).

Кроме того можно подставить URL запроса: по умолчанию он http://hydra.aviasales.ru. Полезно, если у вас есть White Label или вы хотите спрятать ссылку на aviasales. Для этого нужно добавить в опции параметр url со значением в виде домена (показано выше в примере).

В каждом методе где можно сгенерировать ссылку — она будет параметром searchlink в каждом из билетов. Например:

{
	origin: 'MOW',
	destination: 'TBS',
	price: 7280,
	transfers: 1,
	airline: 'A3',
	flight_number: 973,
	departure_at: '2018-01-24T05:20:00Z',
	return_at: '2018-02-04T11:50:00Z',
	expires_at: '2017-07-22T13:27:20Z',
	searchlink: 'http://hydra.aviasales.ru/searches/new?origin_iata=MOW&destination_iata=TBS&depart_date=2018-01-24&return_date=2018-02-04&adults=1&children=0&infants=0&trip_class=0&marker=2178729379&with_request=true&currency=rub&locale=ru'
}

Отладка

В любой из методов можно передать параметр debug: true. В таком случае в консоль будет выводиться следующая информация:

  • опции которые были переданы в запросе к API;
  • конечный URL запроса (из консоли можно кликнуть этот URL и открыть в браузере (обычно нужно зажать для этого клавишу Cmd (MacOS) или Ctrl (Windows))).

Выглядит это так:

Методы

Цены

api.latest(options)

Цены на авиабилеты за 48 часов

Замечания
  1. Если не указывать period_type = month явно, то он будет использован по умолчанию и будет автоматически подставлен beginning_of_period = дата текущего месяца с первого числа.
  2. Если не указывать period_type = month явно и указать beginning_of_period, то будет использован period_type = month и переданный beginning_of_period.
  3. Если указать period_type = year, то beginning_of_period (даже если передать его) не будет использован (потому что в случае запроса с сочетанием этих двух параметров API отдает пустой ответ).
  4. Если не передаются оба значения origin и destination — из запроса удаляются period_type и beginning_of_period (в случае если сделать запрос с ними — запрос зависнет и ничего не вернет). В случае, если запрос идет без origin и destinationAPI вернет 30 самых дешевых билетов, которые были найдены за последние 48 часов (это из документации к API. Если передать параметр limit — то вернет не 30, а кол-во указанное в нем).
  5. Можно делать запросы указывая отдельно origin или destination. В этом случае будут выводиться билеты все из origin в разных направлениях или соответственно наоборот все в destination из разных origin.
  6. Этот метод поддерживает использование двухзначных кодов страны.
Параметры
currency

Type: string

Default: rub

origin

Type: string

Default: none

destination

Type: string

Default: none

beginning_of_period

Type: string

Default: первый день текущего месяца (в формате YYYY-MM-DD)

period_type

Type: string

Default: month

Supported: year, month

one_way

Type: Boolean

Default: false

page

Type: Number

Default: 1

limit

Type: Number

Default: 30

Maximum: 1000

show_to_affiliates

Type: Boolean

Default: true

sorting

Type: string

Default: price

Supported: price, route, distance_unit_price

trip_class

Type: Number

Default: 0

Supported: 0, 1, 2

trip_duration

Type: Number

Default: none

api.monthMatrix(options)

Календарь цен на месяц

Замечания
  1. Если не передать явно month, будет использована дата указанная выше в Default. Так сделано потому, что если не передать этот параметр — API почему-то отдает билеты, как будто использована дата следующего месяца.
  2. По дефолту, если не передавать origin или destination — API Travelpayouts использует коды LED (Санкт-Петербург) и HKT (Пхукет) соответственно. Потому передавать их нужно здесь явно, если конечно вам не нужен именно этот маршрут.
  3. Несмотря на заявление в документации к API, что можно передавать двузначный код страны в origin и destination — это не работает и API возвращает ошибку, в которой пишет, что код короче чем 3 знака.
Параметры
currency

Type: string

Default: rub

origin

Type: string

Default: LED (API defaults)

destination

Type: string

Default: HKT (API defaults)

show_to_affiliates

Type: Boolean

Default: true

month

Type: string

Default: первый день текущего месяца (в формате YYYY-MM-DD)

api.weekMatrix(options)

Календарь цен на неделю

Параметры
currency

Type: string

Default: rub

origin

Type: string

Default: LED (API defaults)

destination

Type: string

Default: HKT (API defaults)

show_to_affiliates

Type: Boolean

Default: true

depart_date

Type: string

Default: дата завтрашнего дня (в формате YYYY-MM-DD)

return_date

Type: string

Default: дата: сегодня + 2 недели (в формате YYYY-MM-DD)

api.nearestPlacesMatrix(options)

Цены по альтернативным направлениям

Параметры
currency

Type: string

Default: rub

origin

Type: string

Default: LED (API defaults)

destination

Type: string

Default: HKT (API defaults)

show_to_affiliates

Type: Boolean

Default: true

depart_date

Type: string

Default: дата: сегодня + 2 дня (в формате YYYY-MM-DD)

return_date

Type: string

Default: дата: сегодня + 2 недели (в формате YYYY-MM-DD)

distance

Type: Number

Default: 1000

Описание: расстояние (в километрах) от пунктов назначения и отправления, на котором ищутся соседние города

limit

Type: Number

Default: 1

Описание: количество выводимых вариантов от 1 до 20. Где 1 — это только вариант с указанынми пунктами назначения и отправления

flexibility

Type: Number

Default: 0

Описание: расширение диапазона дат в большую и меньшую сторону. Значение может быть от 0 до 7, где 0 — в результате будут только варианты на указанные даты, 7 — все найденные варианты за неделю до указанных дат и неделю после

api.cheap(options)

Самые дешевые авиабилеты

Замечания

Данный метод переформатирует ответ от API из объекта в массив. В оригинале ответ представляет собой объект с ключами в виде кода города назначения, внутри которого также лежат объекты с ключами в виде чисел, означающих количество пересадок (0-3). В переформатированном виде в каждый из объектов билетов добавляются параметры origin, destination и number_of_changes (количество пересадок). В массиве значения располагаются по возрастанию кол-ва пересадок. В случае если в качестве destination использовать прочерк (-, что означает в любом направлении, объекты для каждого из destination так же располагаются в порядке возрастания кол-ва пересадок).

Параметры
origin

Type: string

Default: MOW (Москва, моя дефолтная настройка)

destination

Type: string

Default: - (тире, при этом значении выводятся любые направления из origin)

depart_date

Type: string

Default: none (указывать в формате YYYY-MM)

return_date

Type: string

Default: none (указывать в формате YYYY-MM)

page

Type: Number

Default: 1

Описание: необязательный параметр, используется для отображения найденных данных (по умолчанию на странице отображается 100 найденных вариантов. Если не выбран destination, то данных может быть больше. В этом случае используйте page, для отображения следующего набора данных, например, page=2).

currency

Type: string

Default: rub

api.monthly(options)

Самые дешевые авиабилеты по месяцам

Возвращает самые дешевые билеты для выбранного направления на год вперёд. По одной цене на каждый месяц.

Замечания

Данный метод переформатирует ответ от API из объекта в массив. В оригинале ответ представляет собой объект с ключами в виде даты в формате YYYY-MM. В переформатированном ответе эта дата добавляется в объект каждого из билетов как параметр month.

Nota bene: Можно передать в origin и destination одновременно двухзначный код страны и трехзначный код города соответственно, и наоборот.

Параметры
currency

Type: string

Default: rub

origin

Type: string

Default: MOW (Москва, API default)

Замечания: можно передавать двузначный код страны (несмотря на то, что в API написано Длина не более 3. Длина не менее 3.)

destination

Type: string

Default: LED (Санкт-Петербург, моя дефолтная настройка) Замечания: можно передавать двузначный код страны

api.direct(options)

Билеты без пересадок

Возвращает самый дешевый билет без пересадок для выбранного направления с фильтрами по датам вылета и возвращения.

Замечания

Данный метод переформатирует ответ от API из объекта в массив.

Параметры
origin

Type: string

Default: MOW (Москва, моя дефолтная настройка)

destination

Type: string

Default: - (любые направления, моя дефолтная настройка)

depart_date

Type: string

Required: false

Default: none (указывать в формате YYYY-MM)

return_date

Type: string

Required: false

Default: none (указывать в формате YYYY-MM)

currency

Type: string

Default: rub

api.calendar(options)

Билеты из города на любое число месяца

Замечания

Данный метод переформатирует ответ от API из объекта в массив. В оригинале ответ представляет собой объект с ключами в виде даты в формате YYYY-MM-DD, для каждого из дней месяца из depart_date. В переформатированном виде эта дата добавляется в объект каждого из билетов как параметр day_of_month.

Параметры
origin

Type: string

Default: MOW (Москва, моя дефолтная настройка)

destination

Type: string

Default: LED (Санкт-Петербург, моя дефолтная настройка)

depart_date

Type: string

Default: текущий месяц (в формате YYYY-MM) Замечания: если не передать сюда ничего, то будет использован текущий месяц в формате YYYY-MM. Если же передать пустую строку, то будут выведены результаты аж на год вперёд. Какие-то особенности API. Также, если ничего не передать и до конца месяца меньше недели — будет использована дата следующего месяца в формате YYYY-MM.

return_date

Type: string

Default: none

Замечания: если не передать сюда ничего, но передать depart_date, то выведутся просто билеты на указанный там месяц. Если передать пустую строку в depart_date и передать return_date, то он выступит своеобразные ограничителем даты и выведет билеты до конца месяца return_date с текущей даты (но почему-то иногда не по 30-31 число, а до 25-29). Если передавать оба параметра, то соответственно выведутся билеты подходящие под оба параметра.

calendar_type

Type: string

Default: departure_date

Supported: departure_date, return_date

trip_duration

Type: Number

Default: none

currency

Type: string

Default: rub

api.holidaysByRoutes(options)

Самые дешевые билеты на выходные

Параметры
currency

Type: string

Default: rub

api.minPricesCalendar(options)

Календарь цен

Параметры
origin

Type: string

Default: none

destination

Type: string

Default: none

depart_date

Type: string

Default: сегодняшняя дата + 2 дня (в формате YYYY-MM-DD)

one_way

Type: Boolean

Default: false

Карта цен

api.directions(options)

Поддерживаемые направления

Параметры
origin_iata

Type: string

Default: MOW (Москва, моя дефолтная настройка)

one_way

Type: Boolean

Default: false

locale

Type: string

Default: ru

api.prices(options)

Цены

Параметры
origin_iata

Type: string

Default: MOW

period

Type: string

Default: текущий месяц с первого числа:month (пример: 2017-07-01:month)

Supported: month (указывать как 2017-08-01:month), season (указывать как 2017-08-01:season), year (указывать как year без месяца)

direct

Type: Boolean

Default: true

one_way

Type: Boolean

Default: false

no_visa

Type: Boolean

Default: true

schengen

Type: Boolean

Default: true

need_visa

Type: Boolean

Default: true

locale

Type: string

Default: ru

min_trip_duration_in_days

Type: Number

Default: 13

max_trip_duration_in_days

Type: Number

Default: 31

Направления

api.airline(options)

Популярные направления авиакомпании

Замечания

Стоит отметить, что это достаточно медленный метод API.

Параметры
airline_iata

Type: string

Default: SU (Аэрофлот, моя дефолтная настройка)

limit

Type: Number

Default: 10 (моя дефолтная настройка) Max: 1000

api.city(options)

Популярные направления из города

Замечания

Данный метод переформатирует ответ от API из объекта в массив. В оригинале ответ представляет собой объект с ключами в виде кода города назначения. В переформатированном виде просто возвращается массив с объектами.

Параметры
origin

Type: string

Default: MOW (Москва, моя дефолтная настройка)

currency

Type: string

Default: rub

Использование с async/await

Минимально необходимая версия NodeJS >= 7.6.

Пример:

const api = require('travelpayouts-js')({token: "your_token_here"});

async function getAll() {

	const week   = api.weekMatrix({origin: "MOW", destination: "BKK"});
	const month  = api.monthMatrix({origin: "MOW", destination: "BKK"});
	const cheap  = api.cheap({origin: "MOW", destination: "BKK", generateUrls: { adults: 1, infants: 0 }});
	const direct = api.direct({origin: "MOW", destination: "BKK"});
	const latest = api.latest({origin: "MOW", limit: 10});

	return await Promise.all([week, month, cheap, direct, latest])
}

// Получить данные:
getAll().then(data => console.log(data))

// Получить именованные данные (ES6 destructuring):
getAll.then(([week, month, cheap, direct, latest]) => {

	console.log(week);
	console.log(month);
	console.log(cheap);
	console.log(direct);
	console.log(latest);

})

Хелперы

Пока что в модуле есть один хелпер — daysBeforeNextMonth. Возвращает количество дней до следующего месяца. Может быть полезно для некоторых методов API, которые возвращают пустые значения, когда до конца месяц остается меньше чем несколько дней.

Использование:

api.helpers.daysBeforeNextMonth

Тесты

To-do.

Todos

[ ] Тесты [ ] Написать лучше оформленную и более понятную документацию [ ] Почистить дублирующийся код

Не откажусь от любой помощи, присылайте пулл-реквесты!

Лицензия

The MIT License (MIT)

Copyright (c) 2017 Alexander Sharabarov [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the «Software»), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

AviasalesSDK on CocoaPods.org

Example

As an example, you are welcome to use our Template Project from Aviasales-iOS-SDK repo.

⚙ Installation

The easiest way is to use CocoaPods. It takes care of all required frameworks and third party dependencies:

pod 'AviasalesSDK', '~> 4.0.0'

We recommend to import AviasalesSDK.h in each file where you use objects or protocols from SDK.

#import <AviasalesSDK/AviasalesSDK.h>

Configure AviasalesSDK object before interaction with SDK like this:

AviasalesSDKInitialConfiguration *configuration = [AviasalesSDKInitialConfiguration configurationWithAPIToken:@"Your api token here"
                                                                                                    APILocale:[NSLocale currentLocale].localeIdentifier
                                                                                                partnerMarker:@"Your partner marker here"];
[AviasalesSDK setupWithConfiguration:configuration];

Don’t forget to replace two placeholders in this example with the actual values.

Features

✈️ Flight Tickets Search

Specify search parameters using a JRSDKSearchInfoBuilder object. Take a look at the example below.

Create search info

Create simple object that describes new search:

JRSDKConfigurableSearchInfo *searchInfoBuilder = [[JRSDKSearchInfoBuilder alloc] init];

Set necessary parameters for the search (adults = 2 and travelClass = Business means that two adults would like to travel in business class):

searchInfoBuilder.adults = 2;
searchInfoBuilder.travelClass = JRSDKTravelClassBusiness;

Set travel dates and airports (using airports storage from the SDK):

JRSDKTravelSegmentBuilder *travelSegmentBuilder = [JRSDKTravelSegmentBuilder new]
travelSegmentBuilder.departureDate = [NSDate date];
travelSegmentBuilder.originAirport = [[AviasalesSDK sharedInstance].airportsStorage findAnythingByIATA:@"LED"];
travelSegmentBuilder.destinationAirport = [[AviasalesSDK sharedInstance].airportsStorage findAnythingByIATA:@"MOW"];

Save that travel segment to the search info:

searchInfoBuilder.travelSegments = [NSOrderedSet orderedSetWithObject:[travelSegmentBuilder build]];

And finally we can build a JRSDKSearchInfo object for further usage:

JRSDKSearchInfo *searchInfo = [searchInfoBuilder build];

That’s it. Search info is ready for search.

Perform search request

To perform search request use SearchPerformer received from the SDK and send search info to it. Don’t forget to store this performer somewhere during the search process.

JRSDKSearchPerformer *searchPerformer = [[AviasalesSDK sharedInstance] createSearchPerformer];

To retrieve live and final search results set delegate (JRSDKSearchPerformerDelegate) to this search performer:

searchPerformer.delegate = self;

This delegate requires to implement two methods:

First one is called when the search is finished and results are ready to be displayed. After its call, you can release SearchPerformer because it is not reusable.:

- (void)searchPerformer:(JRSDKSearchPerformer *)searchPerformer didFinishSearch:(JRSDKSearchInfo *)searchInfo withResult:(JRSDKSearchResult *)result andMetropolitanResult:(JRSDKSearchResult *)metropolitanResult;

Second needed to receive error if it occures during the search

- (void)searchPerformer:(JRSDKSearchPerformer *)searchPerformer didFailSearchWithError:(NSError *)error;

Optional method is called when a new chunk of tickets is received from server:

- (void)searchPerformer:(JRSDKSearchPerformer *)searchPerformer didFindSomeTickets:(JRSDKSearchResultsChunk *)newTickets inSearchInfo:(JRSDKSearchInfo *)searchInfo temporaryResult:(JRSDKSearchResult *)temporaryResult temporaryMetropolitanResult:(JRSDKSearchResult *)temporaryMetropolitanResult;

Start search performing:

[searchPerformer performSearchWithSearchInfo:searchInfo];
Parsing search result

Search results are received as JRSDKSearchResult objects. If a search is started with a specific airport as a parameter, result и metropolitanResult will be different — tha last one will contain tickets to any airport of the given city.

💸 Tickets purchase

AviasalesSDKPurchasePerformer is object used to perform ticket purchase. Each ticket contains different proposals from different agencies, you should use one of them as an input parameter. Create performer using price and searchId (JRSDKSearchResult > JRSDKSearchResultInfo) that was returned with the search result.

- (instancetype)initWithPrice:(id <JRSDKPrice>)price
                     searchId:(NSString *)searchId;

Generate a link for the purchase:

- (void)performWithDelegate:(id <AviasalesSDKPurchasePerformerDelegate>)delegate;

Open link received by delegate in browser to provide user purchase form.

⚒ Other Utils by SDK

Name How to retrieve object Description
Airports storage [AviasalesSDK sharedInstance].airportsStorage Finds airport by IATA, provides a list of airports
AviasalesAirportsSearchPerformer [[AviasalesAirportsSearchPerformer alloc] init] Finds airports by string
AviasalesNearestAirportsManager [AviasalesSDK sharedInstance].nearestAirportsManager Finds nearest airports to the current user.
JRSDKModelUtils [JRSDKModelUtils <method name here>] Util methods that help you to work with SDK objects

Плагин Travelpayouts для WordPress — удобный доступ к API и виджетам

Обновлено Автор Олег Лажечников Просмотров 220

Возможно многие уже видели анонс, но тем не менее надо рассказать для тех, кто еще не в курсе. Партнерка Travelpayouts выпустила свой плагин для WordPress, который может стать хорошим подспорьем для блогеров. Теперь стало гораздо проще вставить код поисковой формы или виджета в пост, не говоря уже о том, что появилась возможность использовать API от Aviasales.

Раньше плагин назывался KPD Tourismus и стоил 100$. Меня как-то жаба душила его покупать, хотя я давно знал о нем. Так вот ребята из Travelpayouts выкупили его и сделали бесплатным.

Полезные ссылки

Регистрация в партнерке Travelpayouts
Скачать плагин из репозитория
Документация плагина

Настройка плагина

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

Подробно рассказывать не буду, все есть в документации, только объясню, как все устроено. На странице создания записи (поста) в панели доступны 3 типа блоков: Поисковые формы, Виджеты и Таблицы. Именно они нам и нужны. Есть еще настройки каждого из них, но как я уже сказал в начале можно ничего не трогать. Каждый блок состоит из нескольких инструментов.

Поисковые формы

Те, что создали в админке партнерки

Виджеты

  • Виджет карты
  • Отельная карта
  • Виджет календаря
  • Виджет подписок
  • Виджет отеля
  • Виджет популярных направлений

Таблицы

  • 1. Цены на месяц по направлению, в одну сторону
  • 2. Билеты по направлению на ближайшие дни
  • 3. Самые дешевые билеты по направлению
  • 4. Самые дешевые билеты по направлению в этом месяце
  • 5. Цены на билеты по месяцам
  • 6. Билеты без пересадок по направлению
  • 7. Билеты без пересадок ИЗ
  • 8. Популярные направления из города
  • 9. Популярные направления авиакомпании
  • 10. На нашем сайте искали
  • 11. Дешевые перелеты из города
  • 12. Дешевые перелеты в город
  • Возможно еще скоро появятся «Дешевые авиабилеты на праздничные дни»

Как вы уже поняли, ранее в админке партнерки вам были доступны только поисковые формы и виджеты, а сейчас еще добавился обширный список таблиц (данные API Aviasales). Лично мне именно эта функция больше всего понравилась. Да, API и ранее можно было использовать, но теперь это делается в пару кликов.

Таким образом, во время создания поста, вы можете быстренько вставить нужный виджет или таблицу в виде шорткода, они готовы к использованию сразу после инсталляции плагина. Однако, прежде чем вставлять в статью поисковые формы, нужно добавить их в настройках плагина, скопировав код из личного кабинета Travelpayouts.

Зачем нужен плагин

Конечно же, если вы используете лишь одну стандартную поисковую форму в сайдбаре, то плагин вам ни к чему. Но от такой формы очень мало толку. Самый лучший вариант использовать нужные инструменты непосредственно в статьях, в тексте. А посты должны быть так или иначе связаны с авиатематикой. Понятно, что по запросам типа «дешевый билет в Москву» пробиться нереально, поэтому надо что-то придумывать на около-тематику. Здесь как раз очень хорошо подойдут Таблицы, где есть цены на конкретные билеты по конкретным направлениям и условиям, даже нажимать на поиск не надо, уже цена указана, что по идее должно улучшать конверт.

Таблицы можно использовать при написании маршрутов, подборок аля «куда слетать на выходные», размещать в своих путеводителях о том или ином городе,  в постах про аэропорты, и тд. Знаю, что обычно рекомендуют работать с продающими запросами, но на мой взгляд это не для блогов, скорее для сайтов полностью заточенных под авиатиматику и арбитражников. Наверное, все знают, что у меня есть еще один сайт, связанный с билетами, так вот при в 20 раз меньшей посещаемости он дает чуть бОльший заработок в Travelpayouts, нежели этот блог, при том, что я им вообще не занимаюсь. В смысле, что однажды потратил время написал несколько десяток постов и забросил это дело.

Чтобы полноценно работать с партнеркой сугубо в блоговом форме (тексты), придется работать с НЧ и брать количеством статей. Написать пару постов недостаточно.Собственно, это всех популярных тем касается, сейчас я в основном занят отелями и тоже приходится понемногу собирать, чуть там, чуть там. Ну и как я уже выше сказал, помимо этого, надо выискивать посты на блоге, которые потенциально связаны с покупкой билетов, желательно таких постов, которые читают до покупки, а не после.

P.S. Если кто-то поставил уже плагин, может поделитесь, как используете? 🙂

 

Выбрать страховку сейчас очень сложно, поэтому в помощь всем путешественникам я составляю рейтинг. Для этого постоянно мониторю форумы, изучаю страховые договора и сам пользуюсь страховками.

Рейтинг страховых →

Один клик между вами и вашим идеальным отпуском

Сквозь облака

Если вам когда-либо приходилось искать авиабилеты в Интернете, то вы сталкивались с Aviasales или JetRadar, поскольку это одна из крупнейших поисковых систем путешествий, собирающая авиабилеты от 728 авиакомпаний, более 100 агентств и 5 систем бронирования. Придерживаясь последних тенденций, они признали растущее использование мобильных приложений для поиска и бронирования билетов на самолет и приняли соответствующие меры: согласно рейтингу App Store, их приложения входят в десятку лучших.

Масштабы деятельности Aviasales впечатляют: ее веб-сайтом и приложениями пользуются 5 миллионов человек в месяц, при этом пользователи выполняют 400 000 поисков в день и тратят в среднем 30 секунд на поиск билетов. Хотя процесс поиска очень быстрый и простой, бронирование и покупка билетов с мобильного устройства раньше было проблемой. Одна проблема, которая беспокоила большинство людей, заключалась в том, что их личные данные вводились в базу данных вручную. Было крайне важно максимально облегчить этот шаг.Идея, пришедшая в голову команде Aviasales, гениальна в своей простоте, но у нее нет альтернативы для работы: вы делаете снимок своего паспорта, и приложение извлекает вашу личную информацию. Затем вы просто ждете несколько секунд и видите, что все поля заполняются автоматически.

Но так ли просто на практике? В чем уникальность решения? Паспорта отличаются друг от друга точно так же, как и страны, в которых они сделаны: разнообразие происхождения, расположение полей, языки и т. Д.Поэтому компания начала искать решение, которое было бы достаточно гибким, чтобы учесть все различия и при этом гарантировать превосходное качество. Только ABBYY справилась с этой задачей и уже имела под рукой идеальное решение — ABBYY Cloud OCR SDK. Сервис не зависит от платформы (что имеет решающее значение для кроссплатформенных приложений), известен своей отмеченной наградами точностью и очень прост в реализации, что выгодно отличает их продукт от других. ABBYY Cloud OCR SDK, безусловно, входит в число функций, которые повышают качество обслуживания клиентов и гарантируют, что у большинства пользователей смартфонов в карманах есть бренды Aviasales или JetRadar.

Как это работает?

Всего 3 простых шага:

Шаг 1. Информационная страница пассажира. Нажмите кнопку «Новый пассажир». Выберите, чтобы добавить информацию, сделав фотографию. Сосредоточьтесь на машиночитаемой зоне (MRZ).

Шаг 2. Сделайте фото МСЗ. Подождите пару секунд. Паспорт обрабатывается ABBYY Cloud OCR SDK.

Шаг 3. Поздравляем! Вся информация о пассажирах заполнена автоматически!

«Решение ABBYY отлично проявило себя в реальной рабочей ситуации и немного облегчило жизнь пользователям Aviasales.Им больше не нужно вводить свои личные данные вручную. Это значительно ускоряет и упрощает покупку авиабилетов! »

Иван Козлов, VC Mobile Products

Однако пока обрабатывались новые российские паспорта, оказалось, что результатов распознавания с 100% точностью недостаточно!

Дело в том, что из-за новой системы кодирования МСЗ российского паспорта фамилия ШЕВЧУК (ШЕВЧУК на кириллице), например, теперь в Машиносчитываемой зоне (МСЗ) кодируется как S4EV3UK.Известная своей точностью 99,9%, технология ABBYY OCR послушно опознала и извлекла ее как S4EV3UK, что, конечно же, не применимо для регистрации электронных билетов.

Благодаря открытому API команда разработчиков Aviasales / JetRadar легко добавила небольшой скрипт во всю систему, который позволил преобразовать кодировку имени пассажира MRZ в традиционное официальное написание имени, подходящее для регистрации на рейс (то есть S4EV3UK преобразуется в SHEVCHUK).

Всего за 2 недели интегрировали автоматическое заполнение личных данных в заявку.

Как понять, чего хочет пользователь

Aviasales / JetRadar уже является одной из крупнейших поисковых систем для путешествий, и они продолжают расти на 200% в год и расширять свою клиентскую базу. Ключ к их огромному успеху — это правильно расставить приоритеты: они всегда ставят своих клиентов на первое место. Помимо прочего, это означает предвидение желаний пользователей и постоянный поиск.

Таким образом, в последней версии мобильных приложений Aviasales / JetRadar пользователям нужно только сфотографировать паспорт, а мы сделаем все остальное: захватим из него личные данные пассажира и заполним поля.Благодаря автоматизации за последние 4 месяца более 10 000 счастливчиков смогли получить билеты в последнюю минуту и ​​максимально использовать свой отпуск. Сегодня эта функция доступна в Aviasales и JetRadar для iOS, а скоро будет запущена для Android. Распознавание паспортов на ходу на основе ABBYY Cloud OCR SDK, безусловно, входит в число функций, которые повышают качество обслуживания клиентов и гарантируют, что у большинства пользователей смартфонов в карманах есть бренды Aviasales или JetRadar.

API EN · KosyanMedia / aviasales-self-service-api Wiki · GitHub

Запрос цены / наличия

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

curl 'http://example.com/api/search?from=BKK&to=BOM&date1=2017-09-25&date2=2017-10-01&adults=2&children=1&infants=1&cabin=Y&partner=jtrdr&password=pass&locale=en¤cy=usd'

Параметры запроса

  • из — IATA код города / аэропорта вылета.
  • С по — код города / аэропорта прилета по IATA.
  • date1 — ГГГГ-ММ-ДД дата отправления.
  • date2 — ГГГГ-ММ-ДД дата отправления в оба конца. Может быть опущено при поиске в один конец.
  • взрослые — «1», если опущено!
  • детей — по умолчанию «0».
  • младенцы — по умолчанию «0».
  • каюта — предпочтительный класс бронирования. «Y» — эконом, «C» — бизнес, «F» — первый / премиум.По умолчанию пусто (без предпочтений).
  • партнер — идентификатор компании партнера. Мы вышлем стоимость «aviasales».
  • пароль — пароль текущего партнера.
  • locale — язык пользователя (по умолчанию en ).
  • currency — Валюта пользователя (по умолчанию usd ).

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

  
 <варианты>
  <вариант>
    2664 
    долл. США 
    BOOKING_PAGE_DEEPLINK 
    6 
    false 
   <комиссия> 0.045 
   <сегмент>
    <рейс>
      UN 
      SU 
      3 
      BKK 
      25 сентября 2012 г. 
      09:55 
      Спецификация 
      25 сентября 2012 г. 
      11:10 
      735 
      Y 
      1PC23 
      1PC5 
      WOW1 
      ложь 
      false 
     
          AER 
     
     
          AAQ 
     
    
   
  
<вариант>
...больше вариантов ...

  
  • Сервер должен ответить через 30 секунд или меньше.
  • Все ответы, отличные от HTTP 200, являются ошибками. Ответ должен содержать текстовое описание ошибки.
  • Все ответы HTTP 200 являются успешными.
  • BOOKING_PAGE_DEEPLINK строка — это URL-адрес страницы бронирования. Язык и валюта страницы бронирования должны соответствовать языку и валюте, указанным в запросе.

Пример пустого ответа (предложений нет)

  
 
  

Содержание ответа

  • / варианты — корневой элемент, содержащий варианты тикета.
  • // вариант — полноценный вариант
  • Цена (обязательно) — полная стоимость для всех пассажиров.
  • валюта (обязательно) — код валюты, используемой в цене. Например руб.
  • url (обязательно) — ссылка на страницу с вариантами бронирования.
  • места (опционально) — места, доступные для бронирования по текущему тарифу. 0..9 номер. 0 при отсутствии билетов и 9 при наличии более 9 билетов.
  • isCharter (необязательно) — квалифицирует маршрут как чартер true | false
  • комиссия (опционально) — ставка комиссии по конкретному предложению
  • сегмент — 1 элемент в одну сторону, 2 в оба конца
  • сегмент / рейс — 1..n, более одного, если в запрошенном участке
  • есть точки соединения
  • // рейс — информация о рейсе одним прыжком
    • operatingCarrier (обязательно) — код авиакомпании IATA (2 латинские буквы) самолет принадлежит этой авиакомпании
    • marketingCarrier (необязательно) — IATA-код авиакомпании (2 латинские буквы) код-шеринговой авиакомпании. Необходимо указать, если отличается от OperatingCarrier
    • Номер (обязательно) — 2..4 цифры, полный номер рейса (действующий перевозчик + номер)
    • вылет (обязательно) — IATA код аэропорта вылета (3 латинские буквы)
    • Дата отправления (обязательно) — дата отправления, «ГГГГ-ММ-ДД», местный
    • Время отправления (обязательно) — время отправления, «ЧЧ: ММ», местное
    • прилет (обязательно) — код IATA аэропорта прилета (3 латинские буквы)
    • прибытие (обязательно) — дата прибытия, «ГГГГ-ММ-ДД», местное
    • arrivalTime (обязательно) — время прибытия, ‘ЧЧ: ММ’, местное
    • оборудование (опционально) — код типа оборудования самолета / автобуса / поезда ИАТА (или отечественного).несколько букв / цифр
    • Кабина (опция) — класс кабины. может быть «F» для «первый», «C» для «бизнес», «Y» для «эконом / диван»
    • багаж (необязательно) — код строки багажа в формате {N} PC {WW}, где N — количество мест, разрешенное текущим тарифом, а WW — максимальный вес каждого багажа. Если информация о багаже ​​недоступна, укажите пустую строку и значение 0PC для тарифов только с ручной кладью.
    • сумки (необязательно) — код строки сумок в формате {N} PC {WW}, где N — количество мест, разрешенное текущим тарифом, а WW — максимальный вес каждой сумки.Если информация о сумках недоступна, укажите пустую строку.
    • fareCode (необязательно) — код тарифа или основа тарифа для текущего варианта.
    • isBus (необязательно) / isTrain (необязательно) — квалифицирует сегмент как часть мультимодального маршрута, осуществляемого автобусом / поездом true | false .
    • // TechnicalStop — Список технических остановок
      • airportCode — IATA-код аэропорта

Клиент перенаправляет браузер пользователя на URL из тега вариант / URL .Клиент также может добавить строку маркера отслеживания (также называемую подидентификатором) к URL-адресу варианта / URL-адреса для отслеживания клиентов. Полный URL-адрес бронирования deeplink построен следующим образом:

  1. Разобрать URL-адрес Deeplink
  2. Добавьте marker = в раздел параметров запроса (убедитесь, что параметры запроса исходного URL-адреса ссылки на контент соответствуют стандарту RFC 3986)
  3. Кодировать раздел параметров запроса

marker_value — строка, содержащая не более 256 символов.Маркеры следует возвращать как часть информации о бронировании в статистике.

Пример запроса нескольких городов

curl 'http://example.ru/api/search?from=MOW&to=LED&date1=2017-09-25&from2=LED&to2=IKT&date2=2017-10-01&from3=IKT&to3=VVO&date3=2017-10-03&adults=2&children= 1 & infants = 1 & cabin = Y & partner = avsl & password = pass & locale = ru & currency = rub '

Пример ответа с несколькими городами

  
<варианты>
    <вариант>
         2664 
         руб. 
         BOOKING_PAGE_DEEPLINK 
         3 
         false 
         0,0493 
        <сегмент>
            <рейс>
                 UN 
                 SU 
                 3 
                 DME 
                 25 сентября 2017 г. 
                 09:55 
                 LED 
                 25.09.2017 
                 11:10 
                 735 
                 Y 
                 1PC23 
                 1PC5 
                 WOW1 
                 ложь 
                 false 
            
        
        <сегмент>
            <рейс>
                 UN 
                 SU 
                 3 
                 светодиод 
                 01.10.2017 
                 09:55 
                 IKT 
                 01.10.2017 
                 11:10 
                 736 
                 Y 
                 1PC23 
                 1PC5 
                 WOW1 
                 ложь 
                 false 
                
                     AER 
                
                
                     AAQ 
                
            
        
        <сегмент>
            <рейс>
                 SU 
                 SU 
                 3 
                 IKT 
                 03.10.2017 
                 10:55 
                 VVO 
                 03.10.2017 
                 15:00 
                 736 
                 Y 
                 1PC23 
                 1PC5 
                 WOW1 
                 ложь 
                 false 
            
        
    
    <вариант>
    ...больше вариантов ...
    

  

Отчетность о продажах

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

curl 'http://example.com/api/statistics?date1=2016-05-01&date2=2016-06-01&partner=aviasales&password=secret'

Параметры запроса

  • date1 — дата ГГГГ-ММ-ДД.
  • date2 — дата ГГГГ-ММ-ДД.
  • партнер — идентификатор партнера.
  • пароль — пароль текущего партнера.

Ответ должен содержать все бронирования, созданные между date1 и date2.

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

  <бронирования>
  
     JHKHVR 
     AEFE3S 
     02.05.2012 00:02:01 
     1232: 1222.t 
     1199 
     200 
     руб. 
     ПЛАТНЫЙ 
    <сегмент>
      <рейс>
         UN 
         3 
         DME 
         25 сентября 2012 г. 
         09:55 
         LED 
         25 сентября 2012 г. 
         11:10 
         735 
         Y 
      
    
     1 
     0 
     0 
  
  ...больше бронирований ...

  
Содержание ответа
  • / bookings — корневой элемент для всех бронирований.
  • // бронирование — информация об одном бронировании.
  • id — уникальный идентификатор бронирования.
  • PNR — PNR бронирования.
  • created_at — ГГГГ-ММ-ДД ЧЧ: ММ дата и время бронирования по всемирному координированному времени.
  • marker — маркер отправлен в диплинк бронирования в параметре GET marker.
  • из — происхождение IATA.
  • С по — пункт назначения IATA.
  • цена — цены билетов.
  • profit — прибыль метапоискового агентства по данному бронированию.
  • валюта — валюта для полей цена и прибыль.
  • состояние — состояние бронирования. Возможные значения ОБРАБОТКА / ОПЛАТА / ОТМЕНА.
  • сегмент — то же, что и в поисковой выдаче.
  • // рейс — информация о рейсе одним прыжком
    • operatingCarrier — код авиакомпании IATA (2 латинские буквы) самолет принадлежит этой авиакомпании
    • номер — 2..4 цифры, полный номер рейса (действующий перевозчик + номер)
    • вылет — IATA код аэропорта вылета (3 латинские буквы)
    • Дата отправления — дата отправления, ГГГГ-ММ-ДД, местное
    • Время отправления — время отправления, «ЧЧ: ММ», местное
    • прилет — код аэропорта прилета IATA (3 латинские буквы)
    • прибытиеДата — дата прибытия, «ГГГГ-ММ-ДД», местный
    • arrivalTime — время прибытия, ‘ЧЧ: ММ’, местное
    • оборудование — код типа оборудования самолета / автобуса / поезда ИАТА (или отечественного).несколько букв / цифр
    • кабина — класс кабины. может быть «F» для «первый», «C» для «бизнес», «Y» для «эконом / диван»
  • взрослых — взрослых.
  • детей — Дети.
  • младенцы — младенцы.

Используйте этот онлайн-инструмент для проверки вашей реализации API шлюза: https://aviasales-gate-tester.herokuapp.com/

Поддерживаемые направления

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

curl 'http: // example.ru / api / supported_directions? partner = aviasales & password = secret '

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

LON, PAR

PAR, LON

...

NYC, MOW

MOW, NYC

Содержание ответа

Ожидаем в ответ пару кодов IATA городов отправления и прибытия.

Итоги конкурса проектов с Aviasales API

Наш конкурс проектов с использованием Aviasales API и других открытых данных завершен, и мы, как и обещали, подводим итоги сегодня.Еще раз хотим поблагодарить всех участников за интерес и рвение — мы получили больше регистраций и заявок, чем ожидали, и это очень приятно! Для финала мы отобрали 20 самых интересных.



Оценивая работу, мы обратили внимание на следующие критерии:

  • оригинальность идеи
  • техническая реализация (степень готовности прототипа и его работоспособность)
  • коммерческая составляющая проекта
  • внешний вид и удобство использования.

И мы рады объявить победителя — бирючину .Travel стал проектом под руководством Вадима Мерзликина — он получает 150 000 рублей на разработку и продвижение.
‘)

Решающую роль сыграли два фактора: техническая реализация проекта и его коммерческая составляющая. Мы пока не видим здесь прорывных инноваций и супер-идей, но это наиболее продуманный и законченный проект, который уже получил первые результаты и начал набирать аудиторию, а значит, при правильной стратегии он заработает.Отдельно хотим отметить серьезность подхода к продвижению проекта — верный путь, товарищи!

Изначально мы собирались не делать разницы между интернетом и мобильным и оценивать все проекты вместе, но в ходе голосования решили установить еще один дополнительный приз за лучший мобильный проект — это приложение Ивана Рыговского Traveler Today , которое получит 50 000 руб. Мы считаем, что у проекта хороший потенциал.

Было несколько интересных идей в описаниях работ других финалистов, но, к сожалению, не все проекты были доработаны до той стадии, когда мы можем увидеть и протестировать особенности, заявленные в презентации.Мы надеемся, что все вы (в том числе победитель) продолжите развиваться и через пару месяцев вы покажете намного больше готовых проектов, а мы, как и обещали, всегда поможем советом и направим проект в нужное русло.
А чтобы работать было веселее, мы даем всем участникам конкурса более высокую ставку — 70%, на первые 3 месяца. Как только вы решите, что проект готов, напишите в поддержку, и мы его включим.

Что ж, более подробные комментарии мы дадим каждому человеку лично — в ближайшее время вам будут приходить письма с критикой и рекомендациями.

Не бросайте и еще раз спасибо за участие!

Наши предыдущие посты:

» Aviasales со вкусом Airbnb
» Как переключился дизайн материалов Aviasales
« А у нас есть SDK, и вы?

Тест безопасности веб-сайта | Проверка безопасности на соответствие GDPR и PCI DSS

0 тестов, запущенных

тестов за 24 часа

— тестов
запущенных

— тестов за
24 часа

Free API

ImmuniWeb Community Edition предоставляет бесплатный API для безопасности веб-сайтов Тестовое задание.Он разделяет количество тестов, выполненных через веб-интерфейс:

9055 Бесплатная учетная запись 9055
Тип учетной записи Тестов в день Ежемесячная подписка
Нет учетной записи 10 Бесплатная
Fre e

Premium API

ImmuniWeb Community Edition также предоставляет премиальный API для большего количества тестов через API или веб-интерфейс:

Государственные школы, местные органы власти и некоммерческие организации могут запросить бесплатный доступ к премиум API.

Документация API

Спецификации API

9055 www.immuniweb.com/websec/api/v1/chsec/[ustamp].html — где «устамп» — произвольная временная метка UNIX (должна быть целым числом). Такая конструкция сделана для предотвращения кеширования на стороне клиента.
Имя поля Значение
Протокол HTTP / HTTPS
Тип запроса POST

Спецификация данных POST

проверенного URL-адреса домен для тестирования.
Имя поля Значение
api_key секретный токен, который вы отправляете вместе с запросом
dnsr «вкл.» Означает, что результаты теста будут скрыты, «выкл.» Означает, что результаты теста будут отображаться в статистике.
choosen_ip IP-адрес тестируемого сервера (если тестируемый домен разрешается на несколько адресов).
recheck «false» будет использовать результаты из кеша, если сервер был протестирован в течение последних 24 часов, «true» выполнит новый тест без просмотра кеша.
token значение токена, отправляемого сервером, если тестируемый домен разделен на несколько IP-адресов.

Пример транзакции с использованием CURL

curl -d «Test_url = twitter.com & choosen_ip = any & dnsr = off & recheck = false» «https://www.immuniweb.com/websec/api/v1/chsec/1451425590.html «

  {
" job_id ":" 2a9e1f1bc92dc0c7a4bde930dff488771eea6d36988208d34163c5496227b8dc ",
" status ":" test_started ",
" status_status 9 ": сообщение запущено: 1 = 2a9e1f1bc92dc0c7a4bde930dff488771eea6d36988208d34163c5496227b8dc "" https: // www.Immuniweb.com/websec/api/v1/get_result/1451425590.html "

  {
" job_id ":" 2a9e1f1bc92dc0c7a4bde930dff488771eea6d36988208d34163c8771eea6d36988208d34163c849c549226d34163c549226d34163c549226 статус «Ваш тест продолжается»
}

curl -d "Test_url = twitter.com & choosen_ip = any & dnsr = off & recheck = false" "https://www.immuniweb.com/websec/api/v1/chsec/1451425590.html "

  {
" test_id ":" c84936eef26eeb8aaef5ffc43f38ddb91adfd90ac27fb416bd0b21fe2edb1004 ",
" status ":" test_cached ",
" status_id3 "сообщение
  • " curl ":
  • id = c84936eef26eeb8aaef5ffc43f38ddb91adfd90ac27fb416bd0b21fe2edb1004 "" https://www.immuniweb.com/websec/api/v1/get_result/1451425590.html "

      ...0.0.0 & choosen_ip = any & dnsr = off & recheck = false "" https://www.immuniweb.com/websec/api/v1/chsec/1451425590.html "

      {
    " error ":" Имя домена 0.0.0.0 решено в неверном IP-адресе ",
    " error_name ":" invalid_ip_resolved "" error_id ": 16
    }

    curl -d" api_key = your_api_key "" https://www.immuniweb.com/websec/gen_pdf/test_id/ "> report.pdf

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

    Набор инструментов командной строки

    Простой интерфейс командной строки для использования бесплатных инструментов ImmuniWeb® Community Edition в конвейерах CI / CD и DevOps.

    Установите

    Загрузите утилиты с GitHub или используйте git:

    git clone "https://github.com/immuniweb/iwtools.git" && cd iwtools / iwtools

    Установите сторонние библиотеки python:

    • termcolor
    • colorama
    • запросов

    Использование

    Проверьте свой веб-сайт на соответствие GDPR и PCI DSS, протестируйте безопасность CMS и CSP, проверьте усиление защиты и конфиденциальность веб-сервера:

    ./iwtools.py websec "https://example.com"

    ./iwtools.py websec --ip 8.8.8.8 "https://example.com"

    ./iwtools.py websec --format raw_json " https://example.com "

    ./iwtools.py websec --api-key ABCDE-12345-FGHIJ-67890 --refresh" https: // example.com "

    Проверьте другие параметры командной строки здесь.

    ImmuniWeb Community Edition - Тест безопасности веб-сайта

    Тест безопасности веб-сайта - это бесплатный онлайн-инструмент для выполнения тестов веб-безопасности и конфиденциальности:

    • Проверка соответствия GDPR связанных с безопасностью веб-приложений
    • Ненавязчивая проверка на соответствие стандарту PCI DSS, связанная с безопасностью веб-приложений.
    • Анализ CMS и ее компонентов на наличие устаревших версий и публично известных уязвимостей.
    • Анализ методов HTTP, которые могут подвергнуть риску веб-сервер, веб-приложение или посетителей веб-сайта.
    • Подробный анализ (синтаксис, достоверность, надежность) заголовков безопасности HTTP:
    • Анализ измененных и, следовательно, потенциально вредоносных библиотек JS.
    • Анализ ViewState на предмет неправильной конфигурации и слабых мест в системе безопасности.
    • Анализ файлов cookie веб-приложений на наличие флагов безопасности.
    • Обнаружение присутствия домена в различных черных списках.
    • Обнаружение криптоджекинга в JS-коде.
    • Обнаружение присутствия WAF.

    Ссылки и инструкции

    Диапазоны IP-адресов

    Диапазоны IP-адресов наших исходящих серверов:

    • 192.175.111.224/27
    • 64.15.129.96/27
    • 70.38.27.240 / 28
    • 72.55.136.144/28
    • 72.55.136.192/28
    • 79.141.85.24/29

    Методология подсчета баллов

    - В начале теста устанавливается оценка 100
    - Баллы добавляются за хорошую и надежную настройку вашего веб-сайта и веб-сервера
    - Баллы вычитаются за небезопасную, неполную или ненадежную конфигурацию вашего веб-сайта или веб-сервера
    - Общее количество баллов за все обнаруженные CMS и компоненты CMS не будут ниже -50 или выше +50
    - Суммарные баллы для всех обнаруженных компонентов JS не будут ниже -20 или выше +20
    - Общие баллы для всех HT Методы TP и CSP не будут ниже -30 или выше +30
    - Общее количество баллов для всех файлов cookie не будет ниже -10 или выше +10
    - Ни один веб-сайт не может получить оценку выше "C", если уязвимый найдено программное обеспечение
    - Ни один веб-сайт не может получить оценку выше "B +", если CMS не обновлена ​​
    - Ни один веб-сайт не может получить оценку ниже "C", если его компоненты CMS и CMS не имеют известных уязвимостей
    - Сервер получает "N", если проверяемый порт закрыт или код состояния HTTP не равен 200, 301, 302, 303, 307 или 308
    Оценка Оценка
    A + Оценка больше 100
    A Оценка от 90 до 99
    A- Оценка от 80 до 89
    Grade 905 9005 9005 Баллы
    B + Баллы от 70 до 79
    B Баллы от 60 до 69
    B- Баллы от 50 до 59
    900 Марка 9059 5 Оценка
    C + Оценка от 35 до 49
    C Оценка от 20 до 34
    F Оценка ниже 20
    Безопасность веб-сайта 90MS 90 555 CMS не обновлена ​​и уязвима
    Описание Оценка
    Присутствует WAF +20
    WAF отсутствует -5
    CMS не обновлена ​​ -15
    -50
    Компонент CMS обновлен +15
    Компонент CMS не обновлен -10
    Компонент CMS не обновлен -30
    JS-компонент обновлен +10
    JS-компонент не обновлен -5
    JS-компонент не обновлен и уязвим Пользовательские методы HTTP -10
    Сервер поддерживает TRACE, TRACK или CONNECT HTTP-метод -10
    A cooki e не имеет установленного флага HttpOnly -5
    Cookie имеет установленный флаг Secure +5
    Cookie имеет флаг SameSite, установленный на Lax +5
    Cookie имеет флаг SameSite, установленный на Strict +5
    У файла cookie не установлен флаг SameSite -1
    Имя файла cookie имеет префикс __Secure- и его предварительные требования +5
    Имя файла cookie имеет префикс «__Host-» и необходимые условия +5
    Список каталогов веб-сервера включен -10
    Веб-сайт использует ресурсы из стороннего домена аины, которые не могут быть разрешены -30
    Обнаружено вредоносное ПО для криптоджекинга -50

    Заголовки безопасности HTTP и оценка политики безопасности содержимого

    0 Заголовок 90 555 +15 Заголовок 5
    Имя заголовка Через HTTP Через HTTPS
    Политика разрешений Заголовок присутствует и действителен +15 +15
    Политика разрешений Заголовок 9055 присутствует и неправильно настроен -10 -10
    Expect-CT Заголовок неправильно настроен -20
    Access-Control-Allow-Origin Заголовок присутствует и действителен +5 +5
    Strict-Transport-Security Заголовок присутствует, действителен и принудительно 0 +25
    Strict-Transport-Security Заголовок отсутствует 0 -20
    Strict-Transport-Security Заголовок имеет продолжительность менее 6 месяцев -10
    Strict-Transport-Security Сертификат сервера не является доверенным 0 -1
    X-Frame-Options Заголовок присутствует и действителен +15 +15
    X-Frame-Options Значение заголовка ALLOWALL -10 -10
    X-XSS-Protection Заголовок присутствует и действителен +20 +20
    X-XSS-Protection Значение заголовка 0 (отключено) -10 -10
    X-XSS-Protection Заголовок отсутствует -10 -10
    X-Content- Параметры типа Заголовок присутствует и действителен +15 +15
    X-Content-Type-Options Заголовок отсутствует -10 -10
    Content-Security- Политика Заголовок присутствует +20 +20
    Content-Security-Policy Заголовок отсутствует -20 -20
    Content-Security-Policy по умолчанию Заголовок -src установить значение «none» или «self» +5 +5
    Content-Security-Policy Заголовок содержит wildc ard в директиве default-src -10 -10
    Content-Security-Policy Заголовок содержит подстановочный знак в любой другой директиве -10 -10
    Content-Security-Policy Заголовок имеет директиву frame-ancestors и ограничивает источники, а заголовок X-Frame-Options не установлен +10 +10
    Content-Security-Policy Заголовок содержит директиву frame-ancestors с подстановочным знаком и Заголовок X-Frame-Options не установлен +5 +5
    Content-Security-Policy Заголовок имеет установленную директиву frame-ancestors и соответствует значению заголовка X-Frame-Options +5 +5
    Content-Security-Policy Заголовок имеет установленную директиву frame-ancestors и несовместим с X-Frame-Options значение заголовка -5 -5
    Content-Security-Policy Заголовок включает блокировку XSS, а заголовок X-XSS-Protection не установлен +15 +15
    Content-Security -Policy включает фильтрацию XSS, а заголовок X-XSS-Protection не установлен +15
    Content-Security-Policy Заголовок имеет набор директив отраженных xss и соответствует значению заголовка X-XSS-Protection +5 +5
    Content-Security-Policy содержит директиву Reflected XSS с другим значением, чем заголовок X-XSS-Protection. -mixed-content набор директив +5 +5
    Сервер Заголовок раскрывает версию программного обеспечения сервера -5 -5
    X-Powered-By Заголовок раскрывает версию программного обеспечения сервера -5 -5
    X-AspNet-Version Заголовок раскрывает версию программного обеспечения сервера - -5

    Бесплатный мониторинг безопасности веб-сайтов

    ImmuniWeb Community Edition обеспечивает бесплатный мониторинг безопасности веб-сайтов и соответствие требованиям с помощью этого теста безопасности веб-сайтов.Вы можете бесплатно добавить до 3 веб-сайтов, которые будут проверяться с помощью теста безопасности веб-сайтов каждые 7 дней. Вы будете уведомлены по электронной почте о новых уязвимостях или неправильных настройках. Вы можете изменить или удалить хосты в любое время.

    Отменить Сохранить

    {%} else {%} {% if (! Limit_exceeded) {%} {%} else {%}

    Вы можете бесплатно отслеживать до {% = max_subscriptions%} веб-сайтов.Удалите один из существующих веб-сайтов, чтобы добавить новый или получать неограниченное количество мгновенных предупреждений с помощью Immuniweb Discovery.

    {%}%} {%}%}

    отечественных туристических интернет-компаний в России готовы к сбросу конкуренции

    Россия до некоторой степени была унизительным рынком для иностранных гигантов онлайн-туризма, таких как Airbnb, Booking Holdings, Expedia Group и Trip.com Group - до сих пор. Последние пару лет вызвали потрясения, которые могут благоприятствовать отечественным туристическим компаниям, обслуживающим русскоязычных путешественников, таким как Aviasales, OneTwoTrip, Ostrovok, Biletix.ru и Туту.ру - по крайней мере, пока.

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

    Booking.com - это редкий иностранный бренд, который стал широко известен в России. По данным туроператора Svoy TS, до пандемии на долю бренда приходилось около 70% онлайн-продаж российских отелей.Но в последнее время бренд столкнулся с турбулентностью.

    Этим летом базирующийся в Нидерландах гигант американского конгломерата оспаривает выводы Федеральной антимонопольной службы России, которая в декабре установила, что этот бренд нарушил антимонопольный закон, наложив на отели так называемое требование паритета цен. В то время как бренд сталкивался с аналогичными жалобами во многих европейских странах в течение многих лет, Россия могла бы занять более жесткую позицию. По закону он может взимать штраф в размере от 1 до 15 процентов от суммы бронирования.com годовой доход, полученный в России.

    Еще один новый закон, касающийся Booking.com среди других зарубежных туристических брендов, - это требование, чтобы у них был местный офис с января 2022 года.

    Кроме того, с 2018 года несколько российских туристических компаний оказали давление на Департамент по туризму и региональной политике Федерального агентства по туризму, чтобы тот ограничил деятельность Booking.com в России. Жесткая тактика Турции и временный запрет на Booking.com, снятый только в октябре, считаются вдохновляющими.

    Между тем, в рамках переоценки глобального портфеля Expedia Group сократила присутствие своего регионального офиса в России, заявили три руководителя местных конкурентов.

    Откат

    Expedia может иметь долгосрочные пагубные последствия, если Россия или другие игроки вмешаются, чтобы выиграть более выгодные контракты на поставку от отельеров и других поставщиков туристических услуг.

    Похожая проблема может затронуть Airbnb. Компания закрыла свой офис в России в 2015 году и закрыла свою дочернюю компанию в 2017 году, переведя операции в другие европейские города.Отсутствие местной наземной игры могло быть на пользу другим игрокам. Несмотря на то, что у компании, вероятно, по-прежнему больше всего объявлений о домах и квартирах в Интернете среди всех игроков в России, компания сталкивается со сложностями из-за местного законодательства, сопротивления условиям Airbnb, согласно которым хозяева не могут отклонять гостей по признаку пола или пола, а также периодическим обвинениям в отмывании денег. против листеров.

    Sutochno.ru - это сервис онлайн-бронирования, который утверждает, что сейчас у него больше предложений по аренде квартир в России, чем на Airbnb.

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

    Россия переходит на метапоиск путешествий Подробнее

    Пандемия ускорила тенденцию ухода среднего класса от традиционных туристических агентств в рамках более широкой тенденции оцифровки, приносящей пользу всем онлайн-игрокам. Например, россияне все чаще используют метапоиск для планирования и бронирования путешествий.

    Эта тенденция является хорошей новостью для местного игрока Aviasales, который заявил, что лидирует на рынке по валовому объему транзакций.Яндекс - номер два. Skyscanner, принадлежащий Trip.com Group, опустился на третье место. Отдельно отстают Momondo и Kayak, два бренда, поддерживаемые Booking Holdings.

    «В 2017 году примерно 5% всех бронирований рейсов в России приходилось на Aviasales», - сказал генеральный директор Макс Крайнов. «Сейчас около 17 процентов. Таким образом, шестая часть авиабилетов, проданных онлайн или офлайн, продается через нас ».

    Aviasales отслеживает прогресс, оценивая, сколько самолетов Boeing 737 на 180 мест ежедневно заполняется заказами.

    «На этой неделе мы заправляли пассажиров с билетами, эквивалентными 430 Boeing 737 в день», - сказал Крайнов. «После пандемии этот показатель должен резко возрасти».

    Как избежать платных рекламных войн

    По мере того как пандемия идет на спад, Booking Holdings и другие мировые гиганты будут активно использовать платный цифровой маркетинг в поиске Google и Яндекс, YouTube и Facebook. Как правило, новые туристические бренды не могут конкурировать с гигантами в привлечении клиентов таким образом. Тем не менее, успех Airbnb в использовании молвы и социальных сетей для роста своей ниши в сфере путешествий вдохновил других более мелких игроков в сфере путешествий в России и во всем мире.

    Около 200 миллионов человек говорят на русском языке, и многие из них предпочитают русскоязычные социальные сети в качестве альтернативы Facebook и Instagram. Разнообразие социальных сетей дает возможность российским брендам превзойти глобальных игроков.

    Контент-маркетинг, например предоставление информации о поездках и местах назначения, также был способом привлечения и удержания клиентов. Хотя Aviasales - это в первую очередь метапоиск, он предлагает оповещения об обновлениях, связанных с Covid, для различных направлений.Этот контент побуждал посетителей создавать вдохновляющие материалы о поездках по городам и курортам. Это может побудить потребителей совершать прямые посещения сайта и приложения Aviasales для планирования будущих поездок.

    Лидеры электронной коммерции в России хотят продавать путешествия

    Необычным фактором для туристического онлайн-сектора России является растущая тенденция компаний, занимающихся электронной коммерцией, увлекающихся продажами туристических услуг.

    Wildberries, крупнейший российский интернет-магазин, занимается продажей путешествий.

    Ozon, еще один гигант электронной коммерции, попытался создать подразделение путешествий.Но за последние пару месяцев операцию по неизвестным причинам свернули.

    OneTwoTrip, московское онлайн-туристическое агентство, диверсифицируется в другие направления бизнеса. Skift недавно сообщил о своем решении «путешествия как услуга», в котором он, по сути, управляет онлайн-продажами путешествий от имени банков, телекоммуникационных компаний и других компаний, у которых есть «встроенная» клиентская база. Этот путь позволяет избежать платной интернет-рекламы и приносит около трети дохода OneTwoTrip.

    Корпоративные поездки для малого и среднего бизнеса - это следующее направление бизнеса OneTwoTrip.Компания считает, что заключенные ею контракты на прямые поставки с отельерами и авиакомпаниями на русскоязычных рынках дадут ей фору в расширении бизнес-агентства, аналогичном тому, что Travelperk и TripActions сделали в других местах.

    Оцифровка продаж путешествий между предприятиями (B2B) - еще одна возможность, которую пытаются использовать местные предприниматели. Emerging Travel Group - материнская компания Ostrovok, туристического онлайн-агентства, основанного десять лет назад в этом месяце. В последние годы группа диверсифицировалась, сказал Феликс Шпильман, генеральный директор группы в Москве.Его бренд RateHawk предлагает услуги по бронированию отелей и гостиниц B2B для туроператоров и корпоративных клиентов.

    «Мы стремимся стать мировым лидером в сфере B2B [бизнес-бизнес] путешествий», - сказал Шпильман. «Это будет включать бизнес агентству, напрямую корпоративным клиентам и покупателей, пользующихся API».

    Aviasales, со своей стороны, имеет отдельное подразделение Travelpayouts, которое ориентировано на потребителей в США и Европе, предлагая туристическим брендам смешанную торговую площадку для распространения и монетизации через партнерскую модель.Он утверждает, что превосходит сопоставимое предложение Expedia Group на многих рынках.

    Развитие пандемии все еще может подорвать краткосрочные продажи путешествий для всех игроков. В последние недели Россия ввела дополнительные ограничения на поездки в некоторые регионы наряду с обязательными вакцинациями.

    Тем не менее, похоже, что со временем выручка от онлайн-путешествий вырастет в процентном выражении, выражающемся двузначными числами. Аналитическая компания SimilarWeb показывает, что количество посещений российских туристических онлайн-брендов в мае выросло до 70 процентов по сравнению с уровнем мая 2019 года, поэтому внутренний туризм в стране несколько улучшился.

    ОБНОВЛЕНИЕ : В статью убрано упоминание Oktogo.ru, который является партнерским сайтом Aviasales, а также уточняется, что на Aviasales приходится 17% всех билетов, проданных в России, а не только через Интернет.

    Ошибка

    при поиске билетов в android api level 21