Навіщо автоматизувати доставку через API

Ручне оформлення відправок через сайт Нової Пошти — це 3–5 хвилин на замовлення. При 20 замовленнях на день — це годинна рутина щодня. API Нової Пошти дозволяє скоротити це до секунд: замовлення прийшло → ТТН сформована → трекінг-номер відправлений клієнту → статуси оновлюються автоматично.

Додатково: мінімізація помилок ручного введення адрес, автоматичний вибір найближчого відділення, реальний розрахунок вартості у кошику.

Огляд Nova Poshta API v2

API Нової Пошти — безкоштовний REST API з JSON. Потрібен API-ключ, який генерується в особистому кабінеті:

Особистий кабінет → Налаштування → Безпека → Згенерувати API-ключ

Базовий URL: https://api.novaposhta.ua/v2.0/json/

Всі запити — POST з JSON-тілом:

{
  "apiKey": "ваш_api_ключ",
  "modelName": "Назва_моделі",
  "calledMethod": "НазваМетоду",
  "methodProperties": { ... }
}

Відповідь завжди містить поля success (true/false), data (масив результатів) та errors.

Пошук відділень та адрес

Отримання списку міст

{
  "modelName": "Address",
  "calledMethod": "getCities",
  "methodProperties": {
    "FindByString": "Одеса",
    "Limit": 20
  }
}

Повертає масив міст з полями Ref (унікальний ідентифікатор), Description (назва), AreaDescription (область).

Пошук відділень у місті

{
  "modelName": "AddressGeneral",
  "calledMethod": "getWarehouses",
  "methodProperties": {
    "CityRef": "ідентифікатор_міста",
    "Limit": 50,
    "Page": 1
  }
}

Повертає відділення з Ref, Description (назва відділення), Number, MaxWeightAllowed.

Пошук вулиць для адресної доставки

{
  "modelName": "Address",
  "calledMethod": "getStreet",
  "methodProperties": {
    "CityRef": "ідентифікатор_міста",
    "FindByString": "Дерибасівська"
  }
}

Розрахунок вартості доставки

Реальний розрахунок у кошику замість фіксованої ціни — суттєве покращення UX:

{
  "modelName": "InternetDocument",
  "calledMethod": "getDocumentPrice",
  "methodProperties": {
    "CitySender": "ref_міста_відправника",
    "CityRecipient": "ref_міста_отримувача",
    "Weight": "1.5",
    "ServiceType": "WarehouseWarehouse",
    "Cost": "500",
    "CargoType": "Parcel",
    "SeatsAmount": "1"
  }
}

Параметри:

  • ServiceType: WarehouseWarehouse (відділення→відділення), WarehouseDoors (відділення→адреса), DoorsDoors (адреса→адреса)

  • Cost: оголошена вартість посилки (для страховки НП)

  • Weight: вага у кілограмах

Відповідь містить Cost (вартість доставки у гривнях) та CostRedelivery (вартість зворотної доставки при НП).

Створення ТТН (товарно-транспортна накладна)

Це найважливіший метод — він формує відправку і повертає трекінг-номер:

{
  "modelName": "InternetDocument",
  "calledMethod": "save",
  "methodProperties": {
    "PayerType": "Sender",
    "PaymentMethod": "Cash",
    "DateTime": "20.04.2026",
    "CargoType": "Parcel",
    "Weight": "1.5",
    "ServiceType": "WarehouseWarehouse",
    "SeatsAmount": "1",
    "Description": "Одяг",
    "Cost": "500",
    "CitySender": "ref_вашого_міста",
    "Sender": "ref_вашого_контрагента",
    "SenderAddress": "ref_вашого_відділення",
    "ContactSender": "ref_вашого_контакту",
    "SendersPhone": "0671234567",
    "CityRecipient": "ref_міста_отримувача",
    "Recipient": "ref_контрагента_отримувача",
    "RecipientAddress": "ref_відділення_отримувача",
    "ContactRecipient": "ref_контакту_отримувача",
    "RecipientsPhone": "0507654321"
  }
}

Відповідь: IntDocNumber — трекінг-номер (14 цифр), Ref — унікальний ідентифікатор документа.

Важливо: Ref vs створення контрагента

Для отримувача зазвичай потрібно спочатку створити контрагента (метод CounterpartyGeneral.save), а потім використовувати його Ref. Або використовуйте спрощений варіант з параметрами RecipientName, RecipientPhone напряму — це залежить від версії API.

Трекінг статусів відправки

Разова перевірка

{
  "modelName": "TrackingDocument",
  "calledMethod": "getStatusDocuments",
  "methodProperties": {
    "Documents": [
      { "DocumentNumber": "59000000000000", "Phone": "0671234567" }
    ]
  }
}

Повертає Status, StatusCode, WarehouseRecipient, ScheduledDeliveryDate.

Ключові статус-коди

  • 1 — Відправлення створено (ТТН сформована)

  • 2 — Видалено

  • 3 — Відправлення в дорозі

  • 4 — Прибуло у відділення

  • 5 — Видано отримувачу

  • 6 — Повернення

  • 7 — Відправлення отримано

  • 9 — Відмова від отримання

Webhooks для автоматичних оновлень

Замість polling (перевіряти статус кожні N хвилин) — підпишіться на webhook-сповіщення:

{
  "modelName": "InternetDocument",
  "calledMethod": "subscribeToStatusUpdate",
  "methodProperties": {
    "Documents": ["59000000000000"],
    "WebhookUrl": "https://вашсайт.ua/webhooks/novaposhta"
  }
}

НП надішле POST-запит на вашу URL при кожній зміні статусу. Ваш обробник оновлює статус замовлення в БД і відправляє SMS/email клієнту.

Безпека webhook: перевіряйте що запит справді від НП — порівнюйте IP (Нова Пошта публікує список дозволених IP) або використовуйте секретний токен у URL.

Друк накладних

{
  "modelName": "InternetDocument",
  "calledMethod": "printDocument",
  "methodProperties": {
    "DocumentRefs": ["ref_документа"],
    "Type": "pdf",
    "Size": "A5"
  }
}

Повертає Base64-encoded PDF або пряме посилання на файл залежно від параметрів. Підтримувані формати: pdf, html; розміри: A4, A5, 85x85 (стікер).

Типові помилки та як їх уникнути

  • "Не заповнені обов'язкові поля" — перевірте що всі Ref-поля заповнені. Часта причина: Ref міста відправника не збігається з Ref відділення.

  • "Неправильний API ключ" — ключ треба підтвердити в кабінеті (є опція підтвердження через SMS).

  • Rate limiting — API НП має ліміт ~100 запитів/хвилину на ключ. Для масових операцій: черга + затримка між запитами.

  • Застарілі Ref адрес — НП час від часу оновлює Ref відділень. Кешуйте адреси максимум на 24 години, не назавжди.

  • Формат дати — тільки dd.mm.YYYY, не ISO 8601.

  • Вага 0 — якщо вага 0, API поверне помилку. Встановіть мінімум 0.1 кг.

Приклад інтеграції: Laravel

Рекомендований пакет: daaner/nova-poshta-api2 або написати власний HTTP-клієнт через Laravel HTTP Facade:

use Illuminate\Support\Facades\Http;

class NovaPoshtaService
{
    private string $apiKey;
    private string $baseUrl = 'https://api.novaposhta.ua/v2.0/json/';

    public function __construct()
    {
        $this->apiKey = config('services.novaposhta.key');
    }

    public function request(string $model, string $method, array $props = []): array
    {
        $response = Http::post($this->baseUrl, [
            'apiKey'           => $this->apiKey,
            'modelName'        => $model,
            'calledMethod'     => $method,
            'methodProperties' => $props,
        ]);

        $data = $response->json();

        if (!$data['success']) {
            throw new \RuntimeException(implode('; ', $data['errors']));
        }

        return $data['data'];
    }

    public function calculateCost(string $cityFrom, string $cityTo, float $weight, int $cost): float
    {
        $result = $this->request('InternetDocument', 'getDocumentPrice', [
            'CitySender'      => $cityFrom,
            'CityRecipient'   => $cityTo,
            'Weight'          => (string) $weight,
            'ServiceType'     => 'WarehouseWarehouse',
            'Cost'            => (string) $cost,
            'CargoType'       => 'Parcel',
            'SeatsAmount'     => '1',
        ]);

        return (float) $result[0]['Cost'];
    }
}

Висновок

Nova Poshta API добре задокументована і достатньо стабільна для production-використання. Найскладніша частина — перший раз розібратись з Ref-системою ідентифікаторів. Після цього автоматизація доставки стає straightforward завданням.

Ми інтегруємо Nova Poshta API в будь-які платформи — WooCommerce, Laravel, кастомні рішення. Напишіть нам і ми оцінимо обсяг робіт для вашого проекту.