Інтеграція 1С-Бітрікс зі службою доставки Нова Пошта (Україна)

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Інтеграція 1С-Бітрікс зі службою доставки Нова Пошта (Україна)
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Інтеграція 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 день