Инструкция по разработке интерфейса
Первое, что вам нужно знать - то, что существует только три основные команды для работы с Накопителем - добавление объявления с заданными параметрами, поиск объявлений по заданным параметрам и запрос подробной информации о конкретном объявлении. Все остальные команды вспомогательные, помогающие вам подготовить набор информации для выполнения основных команд.
Подробное API по всем командам можно прочитать в разделе "API".
Вы можете скачать наш PHP-класс для работы с API - скачать.
Основные команды
Запрос подробной информации о конкретном объявлении
Это самая простая команда. Вы передаете Накопителю идентификатор объявления и получаете массив с информацией об этом объявлении.
Формат возвращаемого массива описан в разделе "API".
Добавление объявления
Для того, чтобы добавить объявление, нужно подготовить для Накопителя следующую информацию:
- Регион.
- Категория (у нас это называется тип объекта, поэтому будьте готовы и к такому названию).
- Набор данных.
- Контактная информация.
- Терминал и код доступа.
Это основные данные, обязательные к заполнению. От терминалов, работающих по предоплате или в кредит, также может приходить флаг оплаченного объявления is_paid.
Самым сложным здесь является набор данных объявления - это динамический набор информации, зависящий от конкретной выбранной категории. Для каждой категории существует свой набор полей формы как для операции добавления, так и для операции поиска. Поэтому при выборе пользователем нужной категории необходимо загружать с сервера информацию о полях, которые нужно сгенерировать в форме.
Все поля формы должны иметь имя "data-NN", где NN - идентификатор атрибута, который пришел в массиве информации о форме от Накопителя. У выпадающих списков имя должно быть в формате "data-NN[]". Квадратные скобки означают, что данные могут передаваться массивом (для списков, позволяющих выбрать несколько вариантов значений).
Подробнее о процедуре подготовки формы будет написано ниже.
После заполнения пользователем данных ваша программа должна отправить их на сервер Накопителя в формате, указанном в API. Если полученные данные корректны, то объявление добавляется и возвращается идентификатор объявления и код доступа к нему. Код доступа потребуется для функций редактирования или удаления объявления.
Поиск объявлений
Для поиска объявлений также нужно указать набор информации:
- Регион.
- Категория.
- Набор данных для поиска.
- Терминал и код доступа.
При поиске следует учитывать следующие особенности:
- Объявление ищется строго по указанной категории.
- Объявление ищется по указанному региону и его дочерним регионам. Если кто-то при добавлении объявления выбрал регион "Россия", то при поиске по региону "Россия > Приморский край" в результат поиска не будут входить объявления из региона "Россия", но будут входить объявления из дочерних регионов - "Владивосток", "Уссурийск" и остальные.
С набором данных (параметрами для поиска) ситуация та же, что и при добавлении. За исключением того, что обычно для тех атрибутов, которые в форме добавления указаны в единичном варианте (продаю квартиру за 3 миллиона рублей), в форме поиска скорее всего это будет интервал значений (куплю квартиру от 2.5 до 3.5 миллионов рублей). Аналогично и с выпадающими списками - если в форме добавления выпадающий список позволял выбирать только одно значение (продаю автомобиль марки Audi), то в форме поиска скорее всего будет возможность выбрать несколько значений (куплю автомобиль марки Audi, Mercedes или Lexus). Может быть и наоборот - в форме добавления объявления можно указать интервал значений, а в форме поиска только одно значение (когда объявление подается в категорию "Куплю" - "куплю квартиру на этаже со второго по восьмой").
Серийный номер объявления и идентификатор объявления
Не путайте два понятия - серийный номер и идентификатор объявления. Первый служит для идентификации объявления целиком в системе. Каждый серийный номер уникален. Второй служит для временной идентификации объявления. Со временем объявления удаляются и старый идентификатор может быть занят другим объявлением.
Клиент, как и ваш интерфейс, в любом случае взаимодействует только с идентификатором объявлений. Серийный номер необходим в редких случаях (способ партнерства "Бланки").
Как обращаться к API
К каждой команде API нужно обращаться, передавая помимо основных команд, номер терминала и код доступа к нему. В целях безопасности, авторизации и ведения учета.
Передаются два параметра:
@param integer $terminal Идентфикатор терминала @param string $code Код доступа к терминалу
Готовим интерфейс
В общем случае схема работы, независимо от типа интерфейса партнера, выглядит вот так:

Процесс, как и везде:
- Клиент запрашивает инфомацию у сервера.
- Сервер формирует запрос к API.
- API получает запрос, обращается к базе данных.
- База данных возвращает данные или выполняет какую-либо операцию, сообщает о результате API.
- API обрабатывает данные и возвращает их серверу партнера.
- Сервер партнера обрабатывает полученную информацию, приводит ее в читабельный вид и возвращает клиенту.
- Повторить с пункта 1 необходимое число раз.
Как было описано выше, основных операций всего 3. Начнем с последних двух - добавление и поиск. Ясно, что для сбора данных от пользователя необходимо пользователю предоставить форму. В форме должна быть возможность выбрать регион, категорию, указать данные и контактную информацию. Начнем по порядку.
Все примеры описаны на языке PHP.
Готовим объект SoapClient
$soap_client = new SoapClient('http://api3.nako-reactor.ru/soap/?wsdl');
Выбор региона
Мы отказались от такого бессмысленного атрибута, как "Станция метро" или "Район", как отдельных атрибутов. И то и другое у нас входят в параметр "Регион". Ведь это удобно: Россия > Санкт-Петербург > м. Гражданский проспект > ул. Учительская > дом 36 > квартира NNN. Если потребуется найти все объявления, относящиеся к метро Гражданский проспект, нужно при поиске просто указать нужное метро. Все объявления с более точно указанным местоположением войдут в результаты поиска. И не нужно вводить специальные выпадающие списки станций метро для разных городов.
Итак. Мы имеем самый главный регион с идентификатором 1 - Земля. Если мы обратимся к API в такой форме:
$result = $soap_client->region(MYTERMINAL, MYCODE, 1);
то получим массив со списком стран. Соответственно, если передать в параметре id значение 18, то получим список регионов России, а также Москву и Петербург.
Постепенно реагируя на выбор пользователем региона, заставляем его уточнить место, к которому относится объявление. Например:
- Пользователь выбрал Россию. Выдали ему список регионов и два города федерального значения.
- Пользователь выбрал Москву. Поискали через API дочерние места, выдали пользователю список станций метро Москвы.
- Пользователь выбрал станцию метро. Поискали, есть ли возможность дальше уточнить местоположение. Если нет (API вернул пустой массив), значит точнее уже некуда. Переходим к выбору категории.

Полезная хитрость: если вы хотите сделать интерфейс для какого-то конкретного региона, к примеру, город Хабаровск, то установите в вашей программе этот регион начальным и не давайте пользователю подняться выше по дереву регионов. То есть при формировании первого списка регионов обращайтесь к API с нужным вам идентификатором региона. В данном случае с идентификатором Хабаровска.
Еще одна полезная хитрость: гораздо удобнее будет сделать такой выбор динамическим. Например, AJAX. Получаем список дочерних регионов и генерируем следующий выпадающий список.
Ну вот. С регионами разобрались, теперь перейдем к категориям.
Выбор категории
Категория, она же "тип объекта", по структуре похожа на регион - также уточняющий выбор, начиная от корневой, самой главной категории с идентификатором id равным 1.
И здесь у нас тоже новинка. Мало того, что мы убрали станции метро, как параметр объявления, так мы еще убрали совершенно бессмысленный и усложняющий жизнь параметр "Действие". Что было раньше? Пользователь выбирает категорию и видит выпадающий список действий - "куплю/продам/сдаю/сниму" для недвижимости, "куплю/продам/пригоню" для автомобилей, "ищу работу/требуется" для вакансий, "хочу познакомиться" для знакомств и т.д. Каждой категории принадлежит свой собственный набор действий! Теперь у нас нет действий. У нас каждое действие является уточняющей подкатегорией:
- Транспорт.
- Легковые автомобили.
- Продаю.
- Куплю.
- Легковые автомобили.
- ...
- Недвижимость.
- Квартиры.
- Продаю.
- Сдаю.
- Хочу купить.
- Хочу снять.
- Квартиры.
Теперь программистам и пользователям стало жить еще проще:
- Убрали лишний параметр. Нет необходимости держать параметр, который имеет различные варианты значений для каждой категории.
- Пользователь подает объявление именно в ту категорию, в которую ему нужно.
- Если нужно искать объявления о продаже квартиры, то все они точно находятся в категории о продаже квартиры.
$result = $soap_client->category(MYTERMINAL, MYCODE, 1);
Как и с регионами, если ваш сайт определенной тематики, например, автомобильной, то вы можете выдавать список подкатегорий категории "Транспорт".
Форма
Когда пользователь выбрал нужную категорию, вы должны предоставить ему форму для добавления или поиска объявлений, элементы которой соответствуют выбранной категории.
Не у всех категорий есть формы. К примеру, категории "Недвижимость > Жилая недвижимость > Квартиры" форма не нужна, потому что она нужна подкатегориям категории "Квартиры" - "Продаю", "Сдаю" и т.д. Поэтому, что делать, если пользователь выбрал именно ту категорию, у которой нет формы? Как его заставить уточнять категорию дальше? И что ему сообщить? А ничего. Накопитель устроен так, что, если он не находит форму для выбранной категории, то он ищет форму для категории уровнем выше выбранной. Если и там не находит, то еще выше. И так до самой главной категории, у которой есть только одно текстовое поле "Название". Уж тут то пользователь догадается, что такая форма вряд ли та, которая ему нужна для подачи объявления о продаже квартиры. Так что вам здесь нужно заботиться только о том, чтобы дать понять пользователю, что на данный момент, если он дошел до "конечной" категории, а форма все еще пустая, скорее всего это не конечная категория, а список все еще загружается.
Итак.
На данный момент существует 3 вида формы:
- add - для добавления;
- search - для поиска;
- edit - для редактирования.
Необязательный параметр - уровень детализации формы (detail). От него зависит количество элементов в возвращаемой форме. Вообще, форма может содержать очень много атрибутов (для некоторых категорий форма содержит до 40 атрибутов). Уровни детализации служат для того, чтобы упростить пользователям ввод данных. К примеру, для интрефейса в мобильном телефоне 40 атрибутов - это слишком много. Поэтому можно отдавать пользователю упрощенную форму (detail = 1). Если же пользователь пожелает, он может запросить и полную форму (detail = 3). Форма среднего уровня детализации (detail = 2) является компромиссом между краткой и полной формой.
Запрос элементов формы делается так:
$result = $soap_client->form(MYTERMINAL, MYCODE, 34, 'add', 2);
В результате получаем массив элементов формы. Описано в "API".
В этом массиве с каждым элементом формы передается множество полезной информации о том, как привести данные в порядок, в зависимости от конкретного типа данных. Например, атрибут "Цена" возвращается в виде массива данных:
array(
attribute => 7 [Идентификатор атрибута в системе],
is_range => false [Флаг, что атрибут является интервалом],
solid_size => null [Длина целой части],
frac_size => 2 [Длина дробной части],
unit => 'руб.' [Единица измерения],
title => 'Цена' [Название атрибута],
type => 'numeric' [Тип данных]
)
Что означает:
- Номер атрибута в базе данных для хранения этого значения равен attribute.
- Если флаг is_range установлен в true, то нужно отрисовать не одно поле для ввода, а два - минимальное значение и максимальное значение.
- Если указан параметр solid_size и он больше 0, то при проверке введенных данных нужно проверять, чтобы целая часть числа не превышала по длине solid_size. Все равно в Накопителе обрежется.
- Аналогично и с параметром frac_size, который означает максимальную длину для дробной части. В атрибуте "Цена" она равна 2.
- Параметр unit несет в себе единицу измерения. В частности в этом примере он имеет значение руб.
- Само собой, title - это название атрибута. В нашем случае "Цена".
- Ну и type означает тип данных атрибута. Типы данных перечислены в "API". По ним нужно ориентироваться, чтобы знать, какую именно проверку проводить с введенными данными.
Поля для ввода должны получать имена вида data-NN для не_интервалов, data-NN-min и data-NN-max для атрибута-интервала и data-NN[] для выпадающих списков. NN - это reference.
Полезный совет: в поле с типом данных date нужно вводить дату в формате YYYY-MM-DD. Не считайте всех людей специалистами, работающими с форматом даты SQL, как с родным. В России люди привыкли к формату DD/MM/YYYY. Поэтому, либо преобразуйте при отправке в Накопитель пользовательские данные в SQL-формат, либо, что лучше, прицепите к полю ввода данных JS-календарь. К примеру DatePicker от jQuery.
Итак. Вы получили данные с элементами формы. Нужно эту форму нарисовать. Все по порядку.
- Создаем переменную $html (можете назвать ее как угодно), в которой будет храниться сгенерированный html-код формы.
- Организуем цикл по массиву с элементами формы.
- Добавляем в html-код название атрибута, допустим $html .= "<label>" . $elements[$i]['title'] . "</label>";
- Добавляем к нашей строчке, в зависимости от типа данных, текстовое поле либо выпадающий список, либо чекбокс. Если атрибут имеет свойство is_range, то придется добавлять два поля. Имена давайте так, как было написано выше. Например: $html .= 'от' . '<input type="text" name="data-' . $elements[$i]['attribute'] . '-min">' . "до" . '<input type="text" name="data-' . $elements[$i]['attribute'] . '-max">';
- Вешаем функцию проверки введенных данных на поле формы. Это относится только к тем полям, которые представляются в HTML-коде как текстовое поле: [...]'<input type="text" name="data-' . $elements[$i]['attribute'] . '-min" onblur="validateFloat(this)">'[...].
- Для тех полей, которые имеют параметр unit, добавляем этот параметр в виде текста. Пользователь должен знать, что Цена у нас в стране в рублях, а не в тугриках: [...]'<input type="text" name="data-' . $elements[$i]['attribute'] . '-min" onblur="validateFloat(this)"> ' . $elements[$i]['unit'][...].
- Собственно, повторяем то же самое и для всех остальных элементов формы.
Потом сгенерированный HTML-код формы нужно разместить в соответствующий блок на странице.
Это самая сложная часть. Когда ее сделаете, все остальное будет намного легче.
Теперь форма с контактной информацией (для добавления объявления). Она также обязательна.
Контактная информация
Это просто текстовое поле с максимальной длиной 250 символов. Оно обязательно должно быть заполнено. Накопитель отвергает объявления от анонимов. Имя у поля должно быть contact.
Отправка данных
Форму для пользователя сгенерировали, он ее заполнил и нажал на кнопку "Отправить". Ваша задача на вашем сервере: взять все то, что пришло от клиента, оформить так, как описано в описании API и вызвать функцию $soap_client->add(...). При желании можете провести предварительную проверку того, что пришло от клиента. Хотя бы идентификаторы категории, региона и контактную информацию.
Не забывайте передавать также идентификатор вашего терминала и код доступа.
Накопитель добавит информацию в базу данных и вернет вам массив, содержащий идентификатор объявления и его код. Этот код вы обязаны передать пользователю. По этому номеру можно будет проверить, есть ли у базе данных указанное объявление. Особенно актуально для оплаченных объявлений.
Поиск объявлений
Выше была описана процедура добавления объявления. С поиском все почти то же самое, кроме того, что:
- Не требуется заполнять поле "Контактная информация".
- Вместо серийного номера возвращается массив объявлений в виде текстовых строк (сгенерировано из введенных пользователями данных, приведено в строки для удобства распечатки).
- Для получения формы поиска нужно передавать тип формы "search": $soap_client->form(MYTERMINAL, MYCODE, 34, 'search', 2);.
- Поиск выполняется функцией $soap_client->search(...).
Не забывайте отмечать оплаченные объявления и выделять их из всей массы объявлений.
Запрос информации об объявлении
Тут просто. Передаете идентификатор (id) объявления на команду $soap_client->info($id) и получаете массив данных об объявлении, который написан в API. Обрабатываете его и показываете данные пользователю.
Конечно же не нужно забывать, что данные могут быть интервалом, причем может отсутствовать как нижнее значение, так и верхнее. Глупо будет выглядеть информация для пользователя в таком виде:
Цена: руб. Этаж: от 1 до . Всего этажей: от до 10. [...]
Оплата объявления
Оплата объявления - процесс изменения статуса объявления с бесплатного на платное.
Если партнер работает по схеме "Кредит" или "Предоплата", то при добавлении объявления ему достаточно передать параметр is_paid равный 1 и объявление при добавлении будет отмечено как платное, соответственно это коснется внутренного счета партнера. Если на счете недостаточно средств, то команда вернет ошибку.
Для площадок, работающих по схеме "Факт" предусмотрен платежный интерфейс http://payment.nako-reactor.ru/, на который нужно передать идентификатор объявления id (без кода доступа к нему) и адрес страницы referrer, на которую пользователь должен вернуться после оплаты объявления. Все поля обязательны для заполнения. После оплаты объявления внутренний счет партнера будет изменен на сумму, соответствующую его партнерскому проценту.
Улучшение документации
Если вам что-то непонятно по документации, напишите об этом по e-mail, указанному в разделе "Контактная информация" и мы учтем ваши комментарии. Спасибо.
