Інтеграція 1С-Бітрікс зі службою доставки Нова Пошта (Україна)
Нова Пошта — домінуюча служба доставки на українському ринку e-commerce. Покриття — практично кожен населений пункт України, власна мережа відділень, кур'єрська доставка. API Нової Пошти (версія 2.0) — JSON-over-HTTP з авторизацією через API-ключ. Документація українською та російською мовами, добре структурована.
Принципи API Нової Пошти
Всі запити — POST на https://api.novaposhta.ua/v2.0/json/. Авторизація через поле apiKey в тілі кожного запиту. Структура запиту однакова:
{
"apiKey": "your_api_key",
"modelName": "TrackingDocument",
"calledMethod": "getStatusDocuments",
"methodProperties": {}
}
Це нетипова для REST архітектура — один ендпоінт для всіх методів, метод передається як поле calledMethod. Зате просто обгортається в один PHP-метод:
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_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$response['success']) {
throw new \RuntimeException(implode(', ', $response['errors'] ?? ['Unknown error']));
}
return $response['data'];
}
Розрахунок вартості доставки
public function calcCost(string $citySender, string $cityRecipient, float $weight): float
{
$data = $this->apiCall('InternetDocument', 'getDocumentPrice', [
'CitySender' => $citySender, // ref міста-відправника
'CityRecipient' => $cityRecipient, // ref міста-отримувача
'ServiceType' => 'WarehouseDoors', // відділення-двері
'Weight' => $weight,
'Cost' => 0, // оголошена вартість
'CargoType' => 'Cargo',
'SeatsAmount' => 1,
]);
return (float)($data[0]['Cost'] ?? 0);
}
Типи доставки (ServiceType): WarehouseWarehouse (відділення-відділення), WarehouseDoors (відділення-двері), DoorsDoors (двері-двері), DoorsWarehouse (двері-відділення). Ціноутворення відрізняється.
Пошук міста та відділення за ключовим словом
public function findCity(string $query): array
{
return $this->apiCall('Address', 'searchSettlements', [
'CityName' => $query,
'Limit' => 5,
'Page' => 1,
]);
}
public function findWarehouse(string $cityRef, ?string $query = null): array
{
return $this->apiCall('AddressGeneral', 'getWarehouses', [
'CityRef' => $cityRef,
'FindByString' => $query,
'Limit' => 50,
]);
}
На сайті реалізується динамічний пошук: покупець вводить назву міста — викликається searchSettlements, обирає місто — завантажуються відділення через getWarehouses. Результати кешуються на 1–4 години.
Створення ТТН (експрес-накладної)
public function createDocument(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$data = $this->apiCall('InternetDocument', 'save', [
'PayerType' => 'Recipient', // отримувач сплачує
'PaymentMethod' => 'Cash',
'DateTime' => date('d.m.Y'),
'CargoType' => 'Cargo',
'VolumeGeneral' => 0.001,
'Weight' => max($this->getWeight($shipment), 0.1),
'ServiceType' => 'WarehouseWarehouse',
'SeatsAmount' => 1,
'Description' => 'Товар',
'Cost' => $order->getPrice(),
'CitySender' => $this->getOption('SENDER_CITY_REF'),
'Sender' => $this->getOption('SENDER_REF'),
'SenderAddress' => $this->getOption('SENDER_WAREHOUSE_REF'),
'ContactSender' => $this->getOption('CONTACT_REF'),
'SendersPhone' => $this->getOption('SENDER_PHONE'),
'CityRecipient' => $props->getItemByOrderPropertyCode('NP_CITY_REF')?->getValue(),
'RecipientAddress' => $props->getItemByOrderPropertyCode('NP_WAREHOUSE_REF')?->getValue(),
'RecipientsPhone'=> $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'RecipientName' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'Recipient' => $this->createOrGetRecipient($props),
]);
$intDocNumber = $data[0]['IntDocNumber'] ?? ''; // ТТН
$props->getItemByOrderPropertyCode('NP_TTN')?->setValue($intDocNumber);
$order->save();
return $intDocNumber;
}
Параметри Sender, SenderAddress, ContactSender — це ref-и об'єктів у системі Нової Пошти. Отримуються один раз при налаштуванні інтеграції через метод Counterparty/getCounterparties.
Трекінг ТТН
public function trackDocument(string $ttn): array
{
$data = $this->apiCall('TrackingDocument', 'getStatusDocuments', [
'Documents' => [['DocumentNumber' => $ttn]],
]);
$doc = $data[0] ?? [];
return [
'status' => $doc['Status'] ?? '',
'warehouseTo' => $doc['WarehouseRecipient'] ?? '',
'scheduledDate' => $doc['ScheduledDeliveryDate'] ?? '',
];
}
Нова Пошта не надає push-вебхуки для зміни статусів. Polling агентом раз на 2–3 години для активних ТТН.
Терміни
| Склад | Термін |
|---|---|
| Розрахунок + пошук міста/відділення + віджет | 4–5 днів |
| + Створення ТТН + трекінг | +2 дні |
| + Автостворення ТТН при зміні статусу | +1 день |







