Интеграция 1С-Битрикс со службой доставки Новая Почта (Украина)
Новая Почта — доминирующий логистический оператор в Украине. Практически весь e-commerce в Украине работает через НП: отделения есть в большинстве населённых пунктов, трекинг работает в реальном времени, API задокументирован и стабилен. Интеграция с Битрикс строится на публичном API v2.
API Новой Почты
НП предоставляет единый JSON-API: https://api.novaposhta.ua/v2.0/json/. Авторизация через apiKey в теле запроса. Формат запроса единый для всех операций:
private function apiCall(string $model, string $method, array $props): array
{
$payload = [
'apiKey' => $this->apiKey,
'modelName' => $model,
'calledMethod' => $method,
'methodProperties' => $props,
];
$ch = curl_init('https://api.novaposhta.ua/v2.0/json/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$response['success']) {
throw new \RuntimeException('НП API: ' . implode(', ', $response['errors']));
}
return $response;
}
Поиск города и отделения
НП использует Ref-идентификаторы для всех объектов. Маппинг локации Битрикс → Ref города НП:
public function getCityRef(string $cityName): ?string
{
$cache = \Bitrix\Main\Data\Cache::createInstance();
$key = 'np_city_' . md5($cityName);
if ($cache->initCache(86400, $key, '/np/')) {
return $cache->getVars();
}
$response = $this->apiCall('Address', 'getCities', [
'FindByString' => $cityName,
'Limit' => 5,
]);
$ref = $response['data'][0]['Ref'] ?? null;
if ($ref) {
$cache->startDataCache();
$cache->endDataCache($ref);
}
return $ref;
}
Клиент вводит номер отделения НП (например, «5»), ищем Ref этого отделения:
public function getWarehouseRef(string $cityRef, string $warehouseNumber): ?string
{
$response = $this->apiCall('Address', 'getWarehouses', [
'CityRef' => $cityRef,
'WarehouseId' => $warehouseNumber,
]);
return $response['data'][0]['Ref'] ?? null;
}
Создание накладной
public function createDocument(
\Bitrix\Sale\Shipment $shipment,
string $recipientCityRef,
string $recipientWarehouseRef
): string {
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$response = $this->apiCall('InternetDocument', 'save', [
'NewAddress' => '1',
'PayerType' => 'Recipient', // получатель платит за доставку
'PaymentMethod' => 'Cash',
'CargoType' => 'Cargo',
'Weight' => max($shipment->getWeight() / 1000, 0.1),
'ServiceType' => 'WarehouseWarehouse',
'SeatsAmount' => '1',
'Description' => 'Товар магазина',
'Cost' => (string)round($order->getPrice()),
'CitySender' => $this->getOption('SENDER_CITY_REF'),
'Sender' => $this->getOption('SENDER_COUNTERPARTY_REF'),
'SenderAddress' => $this->getOption('SENDER_WAREHOUSE_REF'),
'ContactSender' => $this->getOption('SENDER_CONTACT_REF'),
'SendersPhone' => $this->getOption('SENDER_PHONE'),
'CityRecipient' => $recipientCityRef,
'RecipientAddress' => $recipientWarehouseRef,
'RecipientsPhone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'RecipientName' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
]);
return $response['data'][0]['IntDocNumber'] ?? '';
}
PayerType: Recipient — стандарт украинского e-commerce: получатель оплачивает доставку при получении. PayerType: Sender — магазин берёт стоимость на себя.
Трекинг
public function trackDocument(string $docNumber): array
{
$response = $this->apiCall('TrackingDocument', 'getStatusDocuments', [
'Documents' => [['DocumentNumber' => $docNumber]],
]);
return $response['data'][0] ?? [];
}
Возвращает StatusCode, Status, ScheduledDeliveryDate, информацию об отделении. Агент Битрикс опрашивает раз в 2 часа для активных отправлений.
Кейс
Магазин одежды, ~150 заказов в сутки, 99% через Новую Почту. Проблема: клиенты вводили номер отделения произвольно («відд 5», «5», «відділення №5»). Реализовали нормализацию ввода и fuzzy-поиск по справочнику отделений при оформлении. Число неверно оформленных накладных сократилось с ~15 в неделю практически до нуля.
Сроки
| Состав | Срок |
|---|---|
| Расчёт + создание накладной | 4–5 дней |
| + Выбор отделения с подсказками | +2 дня |
| + Трекинг + уведомления | +2 дня |
| + Наложенный платёж | +1 день |







