Хочу поделиться PHP библиотекой (SDK) для интеграции с API 2 Новой Почты (НП). Но сначала несколько слов о Новой Почте.
Новая Почта является лидером экспресс-доставки и перевозки грузов по всей Украине. В Новой Почте много услуг, что делает ее лидером на украинском рынке перевозок. Склады есть во всех городах Украины, очень быстрая курьерская служба. Основные услуги, которые компания надает: доставка и возврат грузов в розничных сетях; доставка паллетированного груза; обратная доставка,; наложенный платёж за товар; вызов машины; хранение груза; упаковка груза, доставка груза по городу и прочее. Для упрощения создание ТТН можно использовать API компании, что даст возможность оптимизировать создания ТТН.
Возможности которые дает SDK:
- Работа с адресами
- Работа со справочниками
- Работа с контрагентами
- Методы для получения печатных форм документов
- Работа с реестрами экспресс-накладных
- Работа с экспресс-накладными:
- создавать экспресс-накладные
- редактировать данные в созданных экспресс-накладные (до передачи отправления)
- удалять/отменять созданные экспресс-накладные (до передачи отправления)
- загружать списки документов используя фильтры
- отслеживать статусы отправления
Создайте файл composer.json в корне Вашeго проекта:
{
"require": {
"serj1chen/nova-poshta-sdk-php": "2.0.*"
}
}
Установить composer:
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install
Подключить автолоадер composer:
include_once "vendor/autoload.php";
Способ 2 (git)
Клонировать репозиторий:
git clone git://github.com/serj1chen/nova-poshta-sdk-php
Подключить автолоадер SDK:
include_once "nova-poshta-sdk-php/lib/NovaPoshta/bootstrap.php";
Перед тем как начать работать с SDK, нужно получить API ключ. Переходим за ссылкой https://my.novaposhta.ua, заходим под своим логином в личный кабинет. Далее п.м. Налаштування-> API 2.0. Нажимаем кнопку Створити новий ключ, копируем созданный ключ.
Настройка SDK
use NovaPoshta\Config;
Config::setApiKey('<Ваш ключ>');
Config::setFormat(Config::FORMAT_JSONRPC2);
Config::setLanguage(Config::LANGUAGE_UA);
Возможные форматы передачи данных (формат указывать в метод setFormat):
- FORMAT_JSON
- FORMAT_JSONRPC2 (рекомендую)
- FORMAT_XML
По дефолту будет установлен формат JSONRPC2.
Работа с моделями SDK
В документации НП работа разбита на модели:
- Address: модель для работы с адресами. Примеры работы с моделью
- Common: модель для работы со справочниками. Примеры работы с моделью
- ContactPerson: модель для создания контактного лица. Примеры работы с моделью
- Counterparty: модель для работы с данными контрагента. Примеры работы с моделью
- InternetDocument: модель для оформления отправлений. Примеры работы с моделью
- ScanSheet: модель для работы с реестрами приема-передачи отправлений. Примеры работы с моделью
Работа с методами моделей
Работа с методами модели: save, update, delete. Заполнить модель нужными значениями и вызвать нужный метод. Пример:
use NovaPoshta\ApiModels\Counterparty;
$counterparty = new Counterparty();
$counterparty->setCounterpartyProperty('Recipient');
$counterparty->setCityRef('db5c88d0-391c-11dd-90d9-001a92567626');
$counterparty->setCounterpartyType('PrivatePerson');
$counterparty->setFirstName('Пилипко');
$counterparty->setLastName('Вася');
$counterparty->setMiddleName('Сергеевич');
$counterparty->setPhone('+380661122333');
$counterparty->setEmail('test@i.ua');
$result = $counterparty->save();
Работа с статическими методами. В методы передавать объект MethodParameters:
use NovaPoshta\ApiModels\Counterparty;
use NovaPoshta\MethodParameters\MethodParameters;
$data = new MethodParameters();
$data->CounterpartyProperty = 'Recipient';
$data->Page = 1;
$data->CityRef = '8d5a980d-391c-11dd-90d9-001a92567626';
$data->FindByString = 'Петр';
$result = Counterparty::getCounterparties($data);
Или можно использовать классы MethodParameters, которые наследуются от класса MethodParameters. Классы имеют сеттеры параметров, которые можно передать статическому методу модели. Названия классов с параметрами складываются с двух частей, с названия модели (ApiModels) и названия статического метода модели. Пример использования:
use NovaPoshta\ApiModels\Counterparty;
use NovaPoshta\MethodParameters\MethodParameters;
use NovaPoshta\MethodParameters\Counterparty_getCounterparties;
$data = new Counterparty_getCounterparties();
$data->setCounterpartyProperty('Recipient');
$data->setPage(1);
$data->setCityRef('8d5a980d-391c-11dd-90d9-001a92567626');
$data->setFindByString('Петр');
$result = Counterparty::getCounterparties($data);
use NovaPoshta\Logger;
use NovaPoshta\Config;
class Logger_example extends Logger
{
public static function setOriginalData($toData, $fromData)
{
// ...
}
public static function setData($toData, $fromData)
{
// ...
}
}
Config::setClassLogger($ new Logger_example());
Метод setOriginalData: запрос/ответ API Новой Почты. Параметры: toData — запрос (тип: string); fromData — ответ (тип: string).
Метод setData: запрос/ответ API Новой Почты у формате SDK. Параметры: toData — запрос (объект: DataContainer); fromData — ответ (объект: DataContainerResponse).
$data = new \NovaPoshta\MethodParameters\Address_getCities();
$data->setFindByString('Полтава');
$result = \NovaPoshta\ApiModels\Address::getCities($data);
$citySender = $result->data[0]->Ref;
Выбираем город получателя:
$result = \NovaPoshta\ApiModels\Address::getCities(); // список городов
$cityRecipient = $result->data[60]->Ref;
Выбираем тип контрагента:
$result = \NovaPoshta\ApiModels\Common::getTypesOfCounterparties();
$counterpartyType = $result->data[1]->Ref; // со списка выбираем тип PrivatePerson
Создаем контрагента получателя:
$counterparty = new \NovaPoshta\ApiModels\Counterparty();
$counterparty->setCounterpartyProperty(\NovaPoshta\ApiModels\Counterparty::RECIPIENT);
$counterparty->setCityRef($cityRecipient);
$counterparty->setCounterpartyType($counterpartyType);
$counterparty->setFirstName('Пилипко');
$counterparty->setLastName('Вася');
$counterparty->setMiddleName('Сергеевич');
$counterparty->setPhone('+380661122333');
$counterparty->setEmail('test@i.ua');
$result = $counterparty->save();
$counterpartyRecipient = $result->data[0]->Ref;
Если нет контрагента отправителя в городе Полтава, создаем там контрагента отправителя. Контрагент создастся через несколько минут:
$data = new \NovaPoshta\MethodParameters\Counterparty_cloneLoyaltyCounterpartySender();
$data->setCityRef($citySender);
$result = \NovaPoshta\ApiModels\Counterparty::cloneLoyaltyCounterpartySender($data);
Если у Вас есть контрагент отправитель, то получаем его так же как контрагента получателя, только сюда: setCounterpartyProperty передаем \NovaPoshta\ApiModels\Counterparty::SENDER. Методом cloneLoyaltyCounterpartySender можно использовать только если Вы клиент лояльности, если Вы корпоративный клиент, то у Вас уже должен быть контрагент отправитель в нужном городе.
Теперь получим контрагента отправителя:
$data = new \NovaPoshta\MethodParameters\Counterparty_getCounterparties();
$data->setCityRef($citySender);
$data->setCounterpartyProperty(\NovaPoshta\ApiModels\Counterparty::SENDER);
$result = \NovaPoshta\ApiModels\Counterparty::getCounterparties($data);
$counterpartySender = $result->data[0]->Ref;
Получим контактных персон для контрагентов:
$data = new \NovaPoshta\MethodParameters\Counterparty_getCounterpartyContactPersons();
$data->setRef($counterpartySender);
$result = \NovaPoshta\ApiModels\Counterparty::getCounterpartyContactPersons($data);
$contactPersonSender = $result->data[0]->Ref;
$data = new \NovaPoshta\MethodParameters\Counterparty_getCounterpartyContactPersons();
$data->setRef($counterpartyRecipient);
$result = \NovaPoshta\ApiModels\Counterparty::getCounterpartyContactPersons($data);
$contactPersonRecipient = $result->data[0]->Ref;
Для контрагента отправителя получим склад отправки:
$data = new \NovaPoshta\MethodParameters\Address_getWarehouses();
$data->setCityRef($citySender);
$result = \NovaPoshta\ApiModels\Address::getWarehouses($data);
$addressSender = $result->data[5]->Ref;
Создадим адрес для получателя:
$address = new \NovaPoshta\ApiModels\Address();
$address->setCounterpartyRef($counterpartyRecipient);
$address->setBuildingNumber('2/2');
$address->setFlat('22');
$address->setNote('Первый подъезд');
$address->setStreetRef('c55c9056-4148-11dd-9198-001d60451983');
$result = $address->save();
$addressRecipient = $result->data[0]->Ref;
Теперь получим тип услуги:
$result = \NovaPoshta\ApiModels\Common::getServiceTypes();
$serviceType = $result->data[3]->Ref; // Выбрали: WarehouseDoors
Выбираем плательщика:
$result = \NovaPoshta\ApiModels\Common::getTypesOfPayers();
$payerType = $result->data[1]->Ref; // Выбрали: Recipient
Форму оплаты:
$result = \NovaPoshta\ApiModels\Common::getPaymentForms();
$paymentMethod = $result->data[1]->Ref; // Выбрали: Cash
Тип груза:
$result = \NovaPoshta\ApiModels\Common::getCargoTypes();
$cargoType = $result->data[0]->Ref; // Выбрали: Cargo
Мы выбрали все данные которые нам нужны для создания ЭН. Создаем ЭН:
// Контрагент отправитель
$sender = new \NovaPoshta\Models\CounterpartyContact();
$sender->setCity($citySender)
->setRef($counterpartySender)
->setAddress($addressSender)
->setContact($contactPersonSender)
->setPhone('+380660000000');
// Контрагент получатель
$recipient = new \NovaPoshta\Models\CounterpartyContact();
$recipient->setCity($cityRecipient)
->setRef($counterpartyRecipient)
->setAddress($addressRecipient)
->setContact($contactPersonRecipient)
->setPhone('+380660000000');
// Выбираем тип
$result = \NovaPoshta\ApiModels\Common::getTypesOfPayersForRedelivery();
$redeliveryPayer = $result->data[1]->Ref;
// Выбираем тип обратной доставки
$result = \NovaPoshta\ApiModels\Common::getBackwardDeliveryCargoTypes();
$redeliveryCargoType = $result->data[1]->Ref;
// Обратная доставка ценные бумаги
$backwardDeliveryData = new \NovaPoshta\Models\BackwardDeliveryData();
$backwardDeliveryData->setPayerType($redeliveryPayer);
$backwardDeliveryData->setCargoType($redeliveryCargoType);
$backwardDeliveryData->setRedeliveryString(452);
$internetDocument = new \NovaPoshta\ApiModels\InternetDocument();
$internetDocument->setSender($sender)
->setRecipient($recipient)
->setServiceType($serviceType)
->setPayerType($payerType)
->setPaymentMethod($paymentMethod)
->setCargoType($cargoType)
->setWeight(1)
->setSeatsAmount(1)
->setCost(452)
->setDescription('ТЦ')
->setDateTime('10.09.2015')
->addBackwardDeliveryData($backwardDeliveryData);
$result = $internetDocument->save();
$refInternetDocument = $result->data[0]->Ref;
Получить ссылку на печать ЭН:
$data = new \NovaPoshta\MethodParameters\InternetDocument_printDocument();
$data->addDocumentRef($refInternetDocument);
$data->setCopies(\NovaPoshta\ApiModels\InternetDocument::PRINT_COPIES_FOURFOLD);
$link = \NovaPoshta\ApiModels\InternetDocument::printDocument($data);
После печати ЭН, клеем ЭН на коробку и отправляем груз))
Надеюсь SDK Вам поможет интегрироваться с API Новой Почты. Сейчас я доделываю аналогичное SDK для Python, когда доделаю SDK выложу статью на хабр.
Удачи!
Комментарии (17)
softm
05.08.2015 20:13* Если можно, ответьте — вообще работа с «новой поштой» через апи — хоть на копейку уменьшает цену отправления?
* Потому, что это конечно супер вещь, но если у тебя три посылки в неделю есть ли смысл привинчивать АПИ?cbeta7910
06.08.2015 00:33За каждую оформленную накладную через кабинет Новой почты, ну и через API тоже, начисляют 2 грн на карту. Это кажется не так уж важно, но вот, к примеру, у меня набегает 700-800 грн в месяц бонусов на оформлении посылок через API, а это уже существенная экономия, можно коммунальные оплатить ))
rustem_ck
05.08.2015 23:52Я Вам скажу, как владелец IT-интернет магазина по продаже бубнов (http://habrahabr.ru/post/226361/), что использую такую библиотеку.
К примеру, когда клиент оформляет заказ на сайте и указывает адрес доставки склада Новой Почты, данная библиотека вытягивает актуальный список населённых пунктов, и уже по ним список отделений в этих населённых пунктах. Ввиду нестабильной географической (политической) ситуации в Украине, есть место поддерживать актуальный список населённых пунктов в которые осуществляется доставка.
Одна серйозная проблема — это время отклика работы самого сервера API. Порою бывают такие задержки, когда много клиентов хотят получить запрос отделений разных городов, что мне кажется что сам API включает какую-то защиту от DDOS, либо имеет ограничение на к-во запросов в период времени. Так что пока боремся путём кеширования (ввиде локального хранения списка отделений/городов и обновления через API).cbeta7910
06.08.2015 00:37+1Хорошее решение, имхо. Постоянно дергать их список отделений, учитывая тормознутость и частую недоступность их серверов, а потом еще json обрабатывать, на это все уходит время, ресурсы. Мы затягиваем списки отделений раз в неделю в базу данных и уже с ним работаем из магазина.
achekalin
Ничего не хочу сказать, но лично мне слова «Новая почта» ничего ничего не сказали. Было бы, наверное, разумно хотя бы первое предложение поста написать в смысле «на Украине существует такой провайдер, он хорош тем и тем, и я им пользуюсь. Недавно они запустили вторую версию API для работы с их сервисами. Возникла такая вот техническая задача, для решения которой я написал SDK для работы с ее API.»
Мне кажется, многие читатели Хабра присоединятся к моей просьбе.
P.S. Тем более что по приведенной Вами в начале статьи ссылке вижу словеса вида «между информационной системой компании «Новая Почта» и программным комплексом Партнера/Клиента», что, как бы, намекает, что почта не простая, так что пояснить было бы вполне разумно.
jhekasoft
Это да. А какие есть аналоги «Новой Почты» на России? Интересно просто.
FractalizeR
Я так понимаю, это просто служба доставки. Пусть и с продвинутыми инструментами.
achekalin
В России тоже хватает грузоперевозчиков. По поводу API и прочего не скажу, а вот чем «Новая почта» (второе слово-то зачем с заглавной писать?) выделяется, кроме того, что более ИТ-дружественна — это, кстати, хорошая тема как для вступления к этой статье (о чем я и написал выше), так и для целой заметки обзорного характера «как я пересылаю грузы» (на Украине, в России, в Крыму, в Армении… да где угодно, от автора и его знаний зависит!)
cbeta7910
Новая Почта — это не просто очередной грузоперевозчик, это реальная замена почты, у нее отделения в каждом городе и уже даже селе Украины. Вот этим, собственно, они и выделяются. Благодаря Новой Почте в Украине стало возможно нормально покупать/продавать через интернет в любую точку страны, а не как раньше только в крупных городах через региональных перевозчиков, или укрпочтой, ожидая товар неделями без страховки и гарантии дойдет ли он вообще.
PS. Второе слово именно с большой буквы, такое официальное название, а, как известно, названия не изменяются, даже если они написаны синтаксически не верно.
cbeta7910
При этом стоимость доставки за сутки из любой точки страны в любую точку всего 1$. Учитывая быструю скорость доставки, пересортировку посылок в промежуточных точках, стоимость бензина это недорого. Иностранцы, посещающие Украину, поражаются такой низкой цене за подобный сервис. Наши знакомые итальянцы и немцы восторгались, у них аналогичные службы за подобные услуги берут 10-15 евро и при этом скорость доставки медленнее.
achekalin
По моему, первый абзац вашего ответа — отличное введение для статьи )
tangro
Ну, в защиту автора надо сказать, что «Новая почта» это не «существует такой провайдер, я им пользуюсь», а система, реально заменившая обычную почту для всех людей, кому нужно чтобы посылка вот правда пришла и вот прямо завтра. Количество отделений Новой Почты, их доступность и сервис сделали их не просто какой-то там ещё одной службой доставки, а дефолтным способом отправки документов, наложенных платежей, лотов с аукционов и т.д. Обычной почтой пользуются теперь разве-что гос.учереждения и те, кому в общем то плевать, дойдёт их письмо или нет.
achekalin
Ничего против не имею. Просто считаю, что без вступления рассказывать про сервис, пусть и хороший, но а) работающий в одной стране и б) не всем даже в этой стране известный, и вовсе не являющийся дефолтным синонимом слова «почта» — это неверно по отношению к другим читателям сайта.
С тем же успехом я могу написать статью про работу с API компании «Н??р Мал аж ахуйн компани», а что это компания из Монголии, что она к ИТ не имеет особого отношения — этого не написать, имея в виду, что все читатели Хабра до таких простых вещей легко догадаются.
То, о чем я написал, требует элементарной вежливости к читателю в виде одного-двух предложений. Уверен, что человек не написал их без умысла — просто для него тема привычная и локально-дефолтно-понятная. С другой стороны, будь введение, многие, даже не знакомые с сервисом «Нвоой почты», могли бы хотя бы прочесть и, возможно, попробовать использовать сервис, а так они просто пропустили статью, поскольку до ката не увидели слов «удобный сервис доставки грузов» и «Украина».
neverice
В Украине про Новую Почту знают все. Нет смысла уточнять. А если вы не знаете про Новую Почту, то Вам ее API тем более не нужно и можете смело пропускать статью. Одним словом, критика немного надуманная. Я понимаю, что Хабр находится в ru зоне, но это все таки международный ресурс. Читатели из Украины не возмущаются же, что какой-то сервис доступен только в РФ, а в заголовке этого не уточнили.
achekalin
Так, давайте географию отложим в сторону. Алгоритм «не понял — пропускай» не подходит к Хабру, здесь аудитория другая. Немного уважения к читателю — совсем небольшое требование.
А что на Украине все или не все знают про ту или иную компанию, так, извините, если мы все с упорством будем писать без указания и без вводной о предметах, нам самим понятным (повторюсь, я не о географии), то кому мы сделаем лучше?
Давайте вместе подумаем: что лучше, статья в стиле «Есть такой сервис, нравится тем-то и тем-то, я написал либу для работы с его API» или «Те, кто в теме, поняли, о чем я написал». Если разговор бы шел в записи в личном блоге где-то в ЖЖ (где по дефолту никто не видит записей того, кем не интересуется) — вопроса бы не было. Здесь же пост попадает на глаза с куда большей вероятностью, а варианта настроек «показывать мне ТОЛЬКО то, на что я подписался» особо нет. Из этого я и получаю вывод, что часть читателей, будучи не в теме про НП, должны замереть в процессе прокрутки страницы над незнакомым названием, покопаться в памяти, получить пустой результат, и только тогда скролить дальше.
Vyazovoi
Я вот открыл статью из рассылки с мыслью «что это за почта такая и чем она лучше gmail» и потратил много времени чтобы понять, что, во-первых, это мне не нужно, во-вторых, не доступно мне регионально. По моему тут даже обсуждать нечего — введения этой статье категорически не хватает, отсутствие вводного абзаца это ошибка.
chen14
Вы правы, Добавил несколько слов о Новой Почте. В Украине про Новою Почту знаю все, но не учел что большинство читателей хабра не знают украинские компании)