Перейти до вмісту

Інтеграція з Новою поштою в Python

Матеріал з K2 ERP Wiki

},

import httpx


14.1. Створення інтеграції

26.1. інтеграційні функції ERP

"external_order_id": command.external_order_id,
"phone": "+380671112233",

GET /api/v1/nova-poshta/cities?query=Київ

entity_type="np_delivery_order",
def get_print_form(self, document_refs: list [str], format: str = "pdf") -> bytes:

! # Чи потрібно показувати строк зберігання у відділенні? Тип задачі ! properties: dict | None = None,

|- | style="background:#c8e6c9;" | Зелений | #c8e6c9 | Успішно: ЕН створено, маркування надруковано, доставлено. |}

[[Категорія:Доставка]]

* timeout;
* HTTP 429;
* HTTP 500;
* HTTP 502;
* HTTP 503;
* HTTP 504;
* тимчасової недоступності API;
* тимчасової помилки друку маркування;
* тимчасової помилки синхронізації статусів. Колір
! | style="background:#c8e6c9;" | Зелений
|-
| Передано у реєстр
| IN_SCAN_SHEET
| Відправлення додано в реєстр. |-
| InternetDocument
| Робота з експрес-накладними. |-
| base_url
| varchar
| URL API. Пріоритет
== 4. Передумови ==
}
=== Етап 3. Nova Poshta Client ===
щоб передати партію посилок у Нову пошту. |}

== 2. Область сценарії використання ==

 order.sent_at = utc_now()
class NovaPoshtaClient:
 def get_tracking_statuses(self, document_numbers: list [str]) -> "TrackingStatusResponse":
 order.np_status = item.get("Status")
|-
| AC-14
| Tracking API повертає новий статус. SEO-опис
{| class="wikitable"
! | Відправники, отримувачі. Де застосовується для
! | style="background:#c8e6c9;" | Зелений
|-
| Маркування надруковано
| MARKING_PRINTED
| Маркування або PDF отримано / надруковано. Поле
 pass
'''Критично критично:''' якщо ЕН уже розроблена, повторний запит не повинен створювати нову ЕН. Тип
== 1. Мета ==
== 11. технічна архітектура рішення для бізнесу ==
 "calledMethod": called_method,
|-
| Замовлень до відправки
| Замовлення без ЕН. # Чи потрібна інтеграційні функції ERP з NovaPay? Статус K2 ERP
|-
| AC-7
| K2 ERP передає валідне замовлення. |-
| Common
| Загальні довідники. |-
| Повернення не контролюються
| Менеджер здатна пропустити повернення. | Телефон, ПІБ, прив'язка до контрагента. "warehouse_ref": "recipient-warehouse-ref"

 if old_status != new_status:

* суму післяплати;
* платника комісії;
* тип зворотної доставки;
* контроль статусу оплати;
* зв'язок із фінансовими документами в K2 ERP. ! Валідація, мапінг, дедублікація, черга
 entity_type="np_delivery_order",
! | Довідник міст оновлюється. Критерій

 "city_ref": "sender-city-ref",
 order.status = "CREATED"
 "middle_name": "Іванович",

=== 5.4. Адресна доставка ===

=== 12.2. Загальний формат API-запиту ===
- Internet Document - Дублювання ЕН Повторний запит здатна створити другу накладну. Статус

Типовий запит має містити:

style="background:#ffcc80;" | Важлива
Відділення → Поштомат WarehousePostomat - default_warehouse_ref varchar Відділення відправника.=== Етап 7. Dashboard та аудит ===
if new_status == "DELIVERED":

Retry дозволений для: це Python-клас або пакет, який інкапсулює роботу з API Нової пошти виступає ключовою рисою Nova Poshta Client. |-

Фіолетовий #f3e5f5 Спеціальний або ручний сценарій. Стан
order.status = new_status

Управлінський результат: менеджер і керівник повинні бачити, скільки замовлень передано в Нову пошту, скільки ЕН створено, які посилки доставлені, які очікують отримання, які повертаються, де виступає як помилки адреси, оплати, ваги або статусу. Дія системи критично: конкретний modelName, calledMethod і methodProperties потрібно брати з актуальної документації API Нової пошти. |-

Застарілі довідники користувач системи здатна обрати неактивне відділення. db.commit() - ref varchar Ref відділення. data={
  • реалізувати створення ЕН;
  • реалізувати мапінг K2 ERP → API Нової пошти;
  • реалізувати валідацію;
  • реалізувати hash документа;
  • реалізувати дедублікацію. Поле
  • створення інтеграції Нової пошти;
  • перевірка API Key;
  • синхронізація міст;
  • синхронізація відділень;
  • пошук міст і відділень;
  • розрахунок вартості доставки;
  • створення ЕН;
  • збереження номера ЕН;
  • друк маркування;
  • синхронізація статусів;
  • дедублікація;
  • retry-механізм;
  • журнал подій;
  • dashboard API;
  • базові unit-тести;
  • mock API для інтеграційних тестів. ЕН

5.5. Зворотна доставка / післяплата

SEO title: Технічне завдання: Інтеграція з Новою поштою для Python

SEO keywords: Python, Нова пошта, Nova Post API, API Нова пошта, експрес-накладна, ТТН, ЕН, доставка, K2 ERP, CRM, інтернет-магазин, FastAPI, логістика, відділення, поштомати, реєстр відправлень

</noinclude>
 {{SEO
Шаблон для службового SEO-опису сторінки. 

}}

Retry заборонений для:

== 31. Джерела ==
! |-
| backward_delivery_amount
| numeric
| Сума післяплати. | Окрема шахматка повернень і статусів. | Черга, API-статуси, транспортування. model_name: str,

! ! |-
| recipient_name
| varchar
| ПІБ отримувача. |-
| error_message
| text
| Помилка. |-
| AC-3
| API Key неправильний. |-
| ContactPerson
| Контактні особи. Python-сервіс виконує валідацію. |-
| Неправильний телефон
| API здатна відхилити ЕН. Тип

=== 7.4. Формування реєстру ===
! |-
| recipient_ref
| varchar
| Отримувач, якщо створений. | Його не можна вибрати для нових ЕН. |-
| name
| varchar
| Назва інтеграції. | style="background:#ffcc80;" | Помаранчевий
|-
| Помилка
| ERROR
| Помилка створення або синхронізації. {| class="wikitable"
== 22. Обробка помилок ==

 "sender": {
<pre>

=== 20.5. np_scan_sheets ===
 v

<pre>
 "seats_amount": 1,

 model_name="TrackingDocument",
{| class="wikitable"
{| class="wikitable"

! | Версіонування клієнта і contract-тести. # Чи потрібно підтримувати декілька відправників? order.status = "NEEDS_RETRY"
|-
| Неправильний API Key
| інтеграційні функції ERP не працюватиме. |-
| longitude
| numeric
| Довгота. Створюється запис delivery_order зі статусом PENDING_CREATE. | style="background:#fff9c4;" | Додаткова
|}

 called_method="save",
 "payment_method": "Cash"
Замовлення доставляється у поштомат. |-
| Warehouse
| Відділення або поштомат. Очікуваний результат
POST /api/v1/nova-poshta/tracking/sync
=== 21.1. Базовий API-клієнт ===
|-
| API Layer
| REST API для прийому замовлень і команд із K2 ERP. Замовлення
=== 26.6. Dashboard ===
 },

23. Dashboard менеджера і керівника

pass

інтеграційні функції ERP призначена для: 1. Тип помилки

class="wikitable"
  • створити FastAPI-проєкт;
  • налаштувати PostgreSQL;
  • створити моделі інтеграції, довідників, ЕН, подій;
  • налаштувати Alembic;
  • реалізувати healthcheck. |-
idempotency_key varchar - warehouse_type varchar ЕН додаються до реєстру. |- np_document_number - Друк маркування Високий Потрібно для складу. )
return order

я хочу натиснути кнопку «Створити ЕН Нової пошти», Критично критично: API Key потрібно зберігати тільки в зашифрованому вигляді або secret storage. order.np_document_number = document_data.get("IntDocNumber")

np_validator.validate(command) sha256(external_order_id + recipient_phone + city_ref + warehouse_ref + cost + weight) ) properties={

5.3. Доставка у поштомат

5.1. Створення експрес-накладної з K2 ERP

- ScanSheet }

5.6. Синхронізація статусів

6. |-

Недоступність API ЕН не створюються. Поле
v
"calledMethod": "save",
entity_id=order.id,
"idempotency_key": "K2-ORDER-2026-000123-np-v1",
self.api_key = api_key
- raw_response jsonb - Audit Logger - Recipient Перевести в NEEDS_CORRECTION. |- AC-4 Міста, населені пункти, відділення, поштомати, вулиці. called_method="getStatusDocuments",

14.8. Створення експрес-накладної

12.1. Призначення

)
order = np_order_repository.get_by_document_number(db, number)
called_method: str,
! Поле

Нова пошта

! |-
| updated_at
| timestamp
| Дата оновлення версій. Офіційна сторінка інтеграції описує генерацію API Key у бізнес-кабінеті, а API-портал Nova Post окремо вказує функції ERP для бізнесу: обробка й відправлення замовлень, доступ до функцій Nova Post та інформації про посилки. |-
| ref
| varchar
| Ref міста в Новій пошті. |-
| Delivery Queue
| Черга створення ЕН. # Чи потрібно підтримувати міжнародну доставку? Worker викликає API Нової пошти. Тип
 payload = np_mapper.to_internet_document_payload(order)
! Колір
Замовлення доставляється кур'єром на адресу. | style="background:#bbdefb;" | Блакитний
|-
| У дорозі
| IN_TRANSIT
| Посилка рухається між терміналами. | Валідація номера до відправки. |-
| WarehouseNotFoundError
| Відділення або поштомат не знайдено. | Друга ЕН не створюється. SEO-опис

 "cargo_type": "Parcel",

<syntaxhighlight lang="python">
[[Категорія:Інтеграції]]
== 13. Конфігурація клієнта ==
я хочу бачити статус доставки прямо в K2 ERP, 
 if order.status in ["CREATED", "DELIVERED"] and order.np_document_number:
! Дата
NOVA_POSHTA_RETRY_BACKOFF_SECONDS=5
! |-
| City
| Місто / населений пункт з довідника Нової пошти. |-
| Directory Sync Worker
| Оновлює довідники міст, відділень, поштоматів, вулиць. # Чи потрібно формувати реєстри? SEO-опис
 payload={
class NovaPoshtaApiError(Exception):

=== 17.2. Довідник відділень і поштоматів ===

! | Dashboard, список відправлень, картка замовлення. |}

=== 20.1. nova_poshta_integrations ===

 language: str = "ua"
 "Documents": [
</pre>
NOVA_POSHTA_TIMEOUT_SECONDS=30
|-
| id
| uuid
| Внутрішній ID. |-
| city_ref
| varchar
| Ref міста. 
 new_status="CREATED",
== 24. Безпека ==
! | style="background:#fff9c4;" | Додаткова
|-
| Адреса  Адреса
| DoorsDoors
| Кур'єрська доставка від дверей до дверей. | Номер зберігається в K2 ERP. |-
| description
| varchar
| Назва / SEO-опис. | style="background:#fff9c4;" | Контроль
|-
| Доставлено
| Успішні доставки. Тип
платформа повинна забезпечити:
PATCH /api/v1/nova-poshta/internet-documents/{document_id}

 "methodProperties": properties or {},

=== 23.1. Основні KPI ===
 for item in response.get("data", []):
</div>

 def create_scan_sheet(self, document_refs: list [str]) -> "ScanSheetResponse":

! Приклади використання
== 9. Статуси відправлень ==

=== 14.14. Dashboard ===
 except Exception as exc:
<syntaxhighlight lang="python">
pass
entity_id=order.id,
"recipient_name": command.recipient.full_name,

POST /api/v1/nova-poshta/delivery/calculate-price

"counterparty_ref": "sender-counterparty-ref",
Довідник
 document_data = response ["data"][0]

POST /api/v1/nova-poshta/delivery/calculate-date

== 19. Черга створення ЕН ==
== 30. Відкриті питання ==
платформа повинна логувати:

Потрібно передати:

=== 14.11. Друк маркування ===
 "phone": "+380501112233"
</div>

 payload={"external_order_id": command.external_order_id},

=== 17.1. Довідник міст ===
 def create_internet_document(self, payload: "InternetDocumentPayload") -> "InternetDocumentResponse":
from pydantic_settings import BaseSettings

! | Відмова, помилка API, неправильна адреса. |-
| AC-8
| API повертає номер ЕН. Показник

 for number in document_numbers
== 25. Логування та аудит ==
 pass
=== 19.2. Пріоритети задач ===
|-
| Address
| Робота з адресними довідниками. |-
| service_type
| varchar
| Тип доставки. | ЕН не створюється, статус NEEDS_CORRECTION. |-
| Tracking Worker
| Оновлює статуси відправлень.== Див. 32. так само ==

class NovaPoshtaClient:

! |-
| is_active
| boolean
| Активність. |-
| area
| varchar
| Область. |-
| Scan Sheet Service
| Формує реєстри відправлень. | Статус стає REFUSED і підсвічується червоним. | Показати менеджеру. ! | style="background:#ef9a9a;" | Червоний
|-
| Повернення
| RETURNING
| Відправлення повертається. :contentReference [oaicite:3]{index=3}
{| class="wikitable"
<pre>

! |-
| style="background:#ef9a9a;" | Червоний
| #ef9a9a
| Помилка або негативний результат. |-
| cargo_type
| varchar
| Тип вантажу. |-
| np_document_number
| varchar
| Номер ЕН / ТТН. |-
| Contact Person
| Контактна особа. | Вони підсвічуються помаранчевим. ! | Оновлювати довідники щодня або частіше. Подія

 event_type="NP_DOCUMENT_QUEUED",
 order.raw_response = response
{| class="wikitable"

[[Категорія:K2 ERP]]

order.status = "CREATING"
)

20.3. np_warehouses

task_name="send_np_document",
payload=item,

платформа повинна не допускати дублювання ЕН. Як зменшити

AC-1 Адміністратор створює інтеграцію Нової пошти. SEO-опис
}
 def __init__(self, base_url: str, api_key: str, timeout_seconds: int = 30):
Для реалізації задачі необхідно отримати:
! |}

 existing = np_order_repository.get_by_idempotency_key(

8. SEO-опис
! API повертає Ref і номер ЕН. ! ! |-
| style="background:#eeeeee;" | Сірий
| #eeeeee
| Чернетка, скасовано або неактивно. # Чи потрібно підтримувати декілька складів? |-
| Description
| Назва українською. | Перевести в NEEDS_RETRY. |-
| AC-5
| платформа запускає синхронізацію відділень. |-
| Sender
| Відправник. користувач системи натискає «Створити ЕН» або спрацьовує автоматичне правило. | Перевести в NEEDS_CORRECTION. K2 ERP отримує номер ЕН. |-
| Синхронізація статусів
| Середній
| Фоновий бізнес-процес. Дія
{| class="wikitable"
 if existing:
! Критерій
 "service_type": "WarehouseWarehouse",
До MVP не входить:
|-
| Створення запиту на ЕН
| Замовлення, отримувач, місто, відділення, сума. Коментар

* наявність external_order_id;
* наявність idempotency_key;
* чи не розроблена вже ЕН для цього замовлення;
* API Key активний;
* місто відправника існує;
* місто отримувача існує;
* відділення або поштомат існує;
* відділення активне;
* телефон отримувача валідний;
* ПІБ отримувача заповнено;
* вага більше 0;
* кількість місць більше 0;
* оголошена вартість більше або дорівнює 0;
* тип сервісу сумісний із адресними даними;
* післяплата не перевищує правила бізнесу;
* платник доставки визначений;
* форма оплати визначена;
* SEO-опис вантажу заповнений. |-
| idempotency_key
| Унікальний ключ конкретної спроби створення ЕН. Колір

 }
=== 17.4. Графік оновлення версій довідників ===

 audit_logger.log(
 base_url: str = "https://api.novaposhta.ua/v2.0/json/"

Ключі дедублікації:
== 18. Дедублікація ==

 return existing
 "modelName": "InternetDocument",

я хочу сформувати реєстр відправлень, 
 properties=payload,

 "np_document_number": order.np_document_number,
'''критично:''' у Нової пошти API-запити зазвичай будуються через поля modelName, calledMethod та methodProperties. |-
| source
| varchar
| K2_ERP, PYTHON_SERVICE, NOVA_POSHTA, USER. |-
| Print Service
| Отримує PDF / маркування / друковані форми. |}

! |-
| recipient_phone
| varchar
| Телефон отримувача. |-
| settlement_type
| varchar
| Тип населеного пункту. | інтеграційні функції ERP зберігається в системі. |-
| Розрахунок доставки
| Параметри, вартість, дата. |-
| Скасування ЕН
| Хто скасував, причина. |}

 return data

! 

K2 ERP / CRM / Website / WMS

 payload = {

* місто;
* вулицю;
* будинок;
* квартиру / офіс, якщо виступає як;
* контактну особу;
* телефон;
* часові або сервісні параметри, якщо доступні;
* тип сервісу DoorsDoors або WarehouseDoors залежно від сценарію. | style="background:#bbdefb;" | Блакитний
|-
| Прийнято Новою поштою
| ACCEPTED_BY_NP
| Відправлення прийнято оператором. | style="background:#fff9c4;" | Жовтий
|-
| Доставлено
| DELIVERED
| Відправлення отримано. |-
| Delivery Order
| Замовлення на доставку в K2 ERP. |-
| Area
| Область. |-
| is_active
| boolean
| Активність. 
'''критично:''' коди сервісів і доступність конкретних сценаріїв потрібно перевірити за довідниками API Нової пошти, оскільки правила можуть змінюватися. pass

* додати rate limiting;
* додати моніторинг;
* додати alerting;
* додати dead letter queue;
* додати резервне копіювання;
* додати безпечне зберігання секретів. K2 ERP створює замовлення. | style="background:#ffcc80;" | Потрібна дія
|-
| Помилки API
| Помилки створення або статусів. Print Service отримує маркування. | Типи вантажу, типи сервісу, форми оплати тощо. '''Критично критично:''' інтеграційні функції ERP не повинна створювати дублікати експрес-накладних. * Документація моделей Address, InternetDocument, TrackingDocument, Counterparty, ContactPerson, ScanSheet.</div>

 "recipient_warehouse_ref": command.recipient.warehouse_ref,
=== 26.5. Статуси ===
щоб контролювати якість логістики, повернення, затримки та помилки. # Який формат друку потрібен: A4, термопринтер, PDF, Zebra? Конкретні моделі та методи потрібно звіряти з актуальною офіційною документацією API перед реалізацією production-версії.<pre>

* реалізувати dashboard API;
* реалізувати список проблемних відправлень;
* реалізувати фільтри;
* реалізувати експорт, якщо потрібно. |-
| Валідація
| Результат, список помилок.=== 22.1. Типи помилок ===

{{DISPLAYTITLE:Технічне завдання: Інтеграція з Новою поштою для Python}}

=== 22.2. Retry-логіка ===

* потрібно обрати поштомат зі списку доступних;
* потрібно перевіряти обмеження по вазі та габаритах;
* потрібно валідувати телефон отримувача;
* потрібно контролювати статус прибуття й термін зберігання. |-
| DeliveryCalculationError
| Не вдалося розрахувати доставку. |-
| seats_amount
| integer
| Кількість місць. |-
| updated_at
| timestamp
| Дата оновлення версій. |-
| style="background:#ffcc80;" | Помаранчевий
| #ffcc80
| Потрібна дія або виступає як ризик.</pre>

 order = np_order_repository.get_by_id(db, delivery_order_id)

<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">

! |-
| document_hash
| Hash основних параметрів відправлення. Колір

 def get_streets(self, city_ref: str, query: str) -> "StreetListResponse":

* перевіряє замовлення;
* перевіряє отримувача;
* перевіряє місто;
* перевіряє відділення / адресу;
* розраховує вартість доставки;
* створює експрес-накладну;
* зберігає номер ЕН;
* передає номер ЕН назад у K2 ERP;
* формує маркування для друку. |}

 pass

# Який бізнес-кабінет і API Key використовуються? | Валідація параметрів вантажу. |-
| Scan Sheet
| Реєстр прийому-передачі. |-
| Dashboard API
| інформаційні дані для менеджера, складу та керівника. Критерій

=== 21.2. Створення ЕН ===
! Причина
! * [[Python]]
* [[FastAPI]]
* [[K2 ERP]]
* [[Нова пошта]]
* [[Nova Post API]]
* [[Експрес-накладна]]
* [[ТТН]]
* [[ЕН]]
* [[Доставка]]
* [[Відділення]]
* [[Поштомати]]
* [[Післяплата]]
* [[Реєстр відправлень]]
* [[API інтеграція]]
* [[Логістика]]

GET /api/v1/nova-poshta/internet-documents/{document_id}/print-form
 response.raise_for_status()
створення експрес-накладних забезпечується через '''Головна ідея:''' розробити Python-сервіс, який інтегрує K2 ERP / CRM / інтернет-магазин / WMS із API Нової пошти; так само реалізовано розрахунку вартості доставки, синхронізації довідників, отримання статусів, друку маркувань та контролю відправлень. Очікуваний результат
|-
| ValidationError
| Некоректні інформаційні дані замовлення. | платформа повертає PDF або інший доступний формат. | style="background:#eeeeee;" | Сірий
|-
| Очікує створення ЕН
| PENDING_CREATE
| Замовлення в черзі на створення ЕН. |-
| entity_type
| varchar
| integration, order, document, scan_sheet, directory. |-
| оновлення версій довідників
| Низький
| Регламентна задача. | style="background:#ef9a9a;" | Критично
|-
| Повернення
| Посилки повертаються. |-
| AC-15
| Відправлення доставлено. Поле
 |
 | 3. |}

== 20. Модель даних ==

POST /api/v1/nova-poshta/internet-documents
! |-
| AC-20
| виступає як повернення. SEO-опис

</pre>

я хочу надрукувати маркування по створеній ЕН, 

<pre>
=== 14.3. Синхронізація довідників ===
</div>
! |-
| ApiError
| API повернув помилку. |-
| number
| varchar
| Номер відділення. |-
| API Event
| Подія інтеграції. Компонент

=== 14.12. Синхронізація статусів ===
</div>
 "cost": command.delivery.cost,
 },
NOVA_POSHTA_BASE_URL=https://api.novaposhta.ua/v2.0/json/
</div>
</pre>

 new_status="PENDING_CREATE",
 response = await nova_poshta_client.call_api(
{| class="wikitable"

 retry_count: int = 3

 "backward_delivery": {
! | Черга, retry, dashboard помилок. |-
| raw_request
| jsonb
| Запит. 
</pre>

</div>
! | платформа показує AuthError і не створює ЕН. KPI
 payload={"delivery_order_id": str(order.id)},

До MVP входить:

POST /api/v1/nova-poshta/integrations
<syntaxhighlight lang="json">
 {"DocumentNumber": number}

 "warehouse_ref": "sender-warehouse-ref",

{| class="wikitable"
 entity_id=order.id,
async def sync_np_statuses(document_numbers: list [str], db: "Session") -> None:
 "status": "PENDING_CREATE",
 "recipient_phone": command.recipient.phone,
|-
| Відділення  Відділення
| WarehouseWarehouse
| Класична доставка між відділеннями.<pre>

 v
NOVA_POSHTA_RETRY_COUNT=3
 "payer": "Recipient"
|-
| Integration Account
| конфігурація API Нової пошти. |-
| cost
| numeric
| Оголошена вартість. |-
| DuplicateDocumentError
| ЕН уже створено. ! |-
| documents_count
| integer
| Кількість ЕН. |-
| CityNotFoundError
| Місто не знайдено. |-
| raw_response
| jsonb
| Відповідь API. |-
| Друк маркування
| Хто надрукував, коли, формат. finally:
 response = await client.post(self.base_url, json=payload)
{

POST /api/v1/nova-poshta/scan-sheets

NOVA_POSHTA_LANGUAGE=ua

<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">

 self,
=== Етап 2. Базовий Python-сервіс ===
== 16. Валідація перед створенням ЕН ==
|-
| Ref
| Унікальний ідентифікатор міста в Новій пошті. ! | K2 ERP оновлює статус відправлення. SEO-опис
{| class="wikitable"
 event_type="NP_DOCUMENT_CREATED",
Для адресної доставки потрібно підтримати пошук вулиць за містом. |-
| Tracking Status
| Статус доставки. 
=== 26.3. Створення ЕН ===
 raise NovaPoshtaApiError(str(data.get("errors") or data))
|-
| Створення ЕН
| Високий
| базовий бізнес-процес відвантаження. | Отримання статусів за номерами ЕН. |-
| AC-19
| виступає як помилки створення ЕН. SEO-опис
== 5. Основні бізнес-сценарії ==

{| class="wikitable"
 number = item.get("Number")
! # Як часто синхронізувати статуси? def update_internet_document(self, ref: str, payload: "InternetDocumentPayload") -> "InternetDocumentResponse":
== 14. API Python-сервісу ==
У старій відкритій документації API описані моделі `InternetDocument`, `Common`, `Counterparty`, `ContactPerson`, `Address`, `ScanSheet`, а так само структура запиту через `modelName`, `calledMethod` і `methodProperties`; це корисно як орієнтир, але production-реалізацію потрібно звіряти з актуальним API-порталом. | Idempotency key і перевірка external_order_id. |-
| weight
| numeric
| Вага. |-
| default_contact_ref
| varchar
| Контакт за замовчуванням. |-
| AC-2
| Адміністратор перевіряє підключення. | style="background:#bbdefb;" | Блакитний
|-
| ЕН створено
| CREATED
| Експрес-накладну створено. |-
| TrackingError
| Не вдалося отримати статус. |-
| event_type
| varchar
| Тип події. |-
| default_city_ref
| varchar
| Місто відправника. * Довідники API: міста, відділення, типи сервісів, типи вантажів. SEO-опис

Замовлення доставляється у відділення Нової пошти. |-
| sender_ref
| varchar
| Відправник. | Очікує створення, прибуло у відділення. |}

=== 26.4. Друк і реєстри ===

 ) -> dict:
=== 19.1. Логіка черги ===
! Критерій
- payer_type varchar Довідник відділень оновлюється. | style="background:#c8e6c9;" | Норма
Відмова Отримувач відмовився.

Перед створенням експрес-накладної платформа повинна перевірити:

"cargo_type": command.delivery.cargo_type,
new_status = np_status_mapper.from_np(item)
response = await nova_poshta_client.call_api(
"apiKey": "********",
db=db,
! | style="background:#eeeeee;" | Сірий
|}

GET /api/v1/nova-poshta/dashboard?date_from=2026-05-01&date_to=2026-05-31

10. Тип
 order.np_document_ref = document_data.get("Ref")
 }
|-
| id
| uuid
| ID інтеграції. |-
| np_document_ref
| varchar
| Ref ЕН. | style="background:#ef9a9a;" | Критично
|}

 "delivery": {

== 26. Acceptance Criteria ==
=== 11.2. Основні компоненти Python-сервісу ===
 "payer_type": "Recipient",
щоб наклеїти його на посилку. | style="background:#c8e6c9;" | Норма
|-
| У дорозі
| Відправлення в транспортуванні. |}

 "last_name": "Петренко",

== 3. Основні функції ERP API Нової пошти ==
! |-
| Створення реєстру
| Номер реєстру, список ЕН. | Зупинити інтеграцію, повідомити адміністратора. |-
| latitude
| numeric
| Широта. | style="background:#ffcc80;" | Помаранчевий
|-
| Скасовано
| CANCELLED
| ЕН або замовлення скасовано. ЕН, статуси, маркування, реєстри
 "weight": command.delivery.weight,
Потрібно передати:
 |
 | 5. |-
| delivery_price
| numeric
| Розрахована вартість доставки. |-
| payload
| jsonb
| Технічні інформаційні дані. |-
| Counterparty
| Контрагенти. |-
| Повторна операційна дія
| Хто запустив, причина, результат. Що зберігати
|-
| AC-11
| користувач системи натискає «Друк маркування». Очікуваний результат
 pass
Приклад `.env`:
=== 12.3. Основні методи Python-клієнта ===
=== 11.1. Загальна схема ===
! |-
| external_order_id
| varchar
| ID замовлення K2 ERP.=== 26.2. Довідники ===
=== Етап 6. Статуси та друк ===
Приклад hash:
{| class="wikitable"

 "apiKey": self.api_key,

 old_status = order.status
! оновлення версій статусів
<div style="border-left: 6px solid #6a1b9a; background: #f3e5f5; padding: 12px 16px; margin: 16px 0;">
=== 23.3. Проблемні відправлення ===
Сервіс повинен забезпечити:

 async with httpx.AsyncClient(timeout=self.timeout_seconds) as client:

! |-
| Отримання статусу
| Старий статус, новий статус, джерело. pass
 db.commit()

2. | style="background:#bbdefb;" | В роботі
|-
| Прибуло
| Очікує отримувача. |-
| Поштомати
| 1 раз на добу або частіше
| Потрібно враховувати активність і обмеження. ! |-
| Створення ЕН
| Номер ЕН, Ref, дата, відповідь API. |-
| api_key_encrypted
| text
| Зашифрований API Key. Коментар

 "modelName": model_name,
! # Чи потрібно створювати контрагентів через API? # Чи потрібна адресна доставка? |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування або прибуття. ! HTML
</syntaxhighlight>
|-
| Чернетка
| DRAFT
| Замовлення виступає як в K2 ERP, але ЕН ще не створено. | Повернення, retry, проблемні статуси. # Чи потрібна післяплата? Поле
== 15. Приклад запиту на створення ЕН ==
</syntaxhighlight>
|-
| external_order_id
| ID замовлення в K2 ERP. Значення
7. async def call_api(

* Офіційна сторінка інтеграції Нової пошти для бізнесу. SEO-опис
 if not order:
Python Status Sync Worker

<pre>
 "contact_ref": "sender-contact-ref",

 order = np_order_repository.create(
=== 7.1. Створення ЕН ===
=== Етап 1. Аналіз API Нової пошти ===
</div>
 "amount": 1500.00,
У відкритій документації API метод `getCities` у моделі `Address` описується як метод отримання довідника населених пунктів; там же зазначено рекомендацію зберігати копію довідників на стороні клієнта й оновлювати її раз на добу. |-
| AC-12
| користувач системи формує реєстр. | Повернути існуючу ЕН. Значення
<div style="border-left: 6px solid #2e7d32; background: #e8f5e9; padding: 12px 16px; margin: 16px 0;">
 "enabled": true,
 ]

 order.error_message = str(exc)
=== 20.6. np_events ===

! Python-сервіс зберігає номер ЕН. {| class="wikitable"
 retry_backoff_seconds: int = 5
 "raw_request": command.model_dump(),
 def delete_internet_document(self, ref: str) -> "DeleteDocumentResponse":
|-
| id
| uuid
| ID події. | Зберегти raw-відповідь. |}

<pre>

Python Nova Poshta Integration Service
 "cost": 1500.00,
 "idempotency_key": command.idempotency_key,
<pre>
|-
| id
| uuid
| Внутрішній ID. Модель
 continue
<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">
 "recipient": {
Потрібно зберігати:
[[Категорія:Технічні завдання]]
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
K2 ERP / Dashboard / складський облік / Менеджер
Python-сервіс:
 new_status=new_status,
Типові моделі API:
 def get_document_delivery_date(self, payload: "DeliveryDatePayload") -> "DeliveryDateResponse":
! |-
| number
| varchar
| Номер реєстру. API Нової пошти
! |-
| recipient_address
| text
| Адреса для кур'єрської доставки. |-
| description
| varchar
| Назва міста. |}

 order.delivered_at = utc_now()

 old_status=old_status,

[[Категорія:Логістика]]

! |-
| PhoneValidationError
| Некоректний телефон отримувача. |-
| np_document_ref
| Ref експрес-накладної в API. SEO-опис
=== 17.3. Довідник вулиць ===

=== 14.13. Створення реєстру ===

=== 14.9. оновлення версій експрес-накладної ===

! "weight": 2.5,
 old_status="CREATING",
'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker. |-
| entity_id
| uuid
| ID сутності. | style="background:#c8e6c9;" | Зелений
|-
| Відмова
| REFUSED
| Отримувач відмовився. |}

9. |-
| status
| varchar
| Статус K2 ERP. |-
| AC-10
| Відділення не знайдено. * Офіційна документація API Нової пошти в кабінеті / API-порталі. | style="background:#ef9a9a;" | Червоний
|-
| Потребує повтору
| NEEDS_RETRY
| Технічна помилка, можна повторити. |-
| np_status
| varchar
| Оригінальний статус Нової пошти. | style="background:#c8e6c9;" | Норма
|-
| Маркування надруковано
| Готові до пакування відправлення. | Ручна перевірка, нестандартна доставка. Сутність

== 7. User Story ==
<syntaxhighlight lang="python">
== 10. Єдина логіка кольорів ==

! |-
| status
| varchar
| Статус. |-
| Зміна API
| Можуть змінитись методи або поля. |-
| IsBranch
| Ознака наявності відділень, якщо доступна.<pre>

* реалізувати call_api;
* реалізувати get_cities;
* реалізувати get_warehouses;
* реалізувати get_document_price;
* реалізувати get_document_delivery_date;
* реалізувати create_internet_document;
* реалізувати get_tracking_statuses;
* реалізувати get_print_form;
* реалізувати create_scan_sheet;
* реалізувати обробку помилок. ! | Статус стає DELIVERED і підсвічується зеленим. |-
| Address
| Адреса для кур'єрської доставки. Ризик

{| class="wikitable"
Nova Poshta API Client
 )
=== 7.3. Контроль статусів ===
POST /api/v1/nova-poshta/directories/sync
 db.commit()
 },
Метою задачі виступає як створення Python-сервісу для інтеграції з Новою поштою з метою автоматизації процесів доставки. Очікуваний результат

 "description": "Одяг",

* інтернет-магазинів;
* CRM;
* ERP;
* WMS;
* складів;
* служб доставки;
* торгових компаній;
* дистриб'юторів;
* компаній, які створюють багато експрес-накладних;
* компаній, які хочуть контролювати доставку прямо з K2 ERP. |-
| AC-6
| Відділення стало неактивним. |-
| is_active
| boolean
| Активність. * API Portal Nova Post. |-
| AC-9
| Повторний запит має той самий idempotency_key. | style="background:#fff9c4;" | Жовтий
|-
| Створюється
| CREATING
| Виконується API-запит до Нової пошти. | style="background:#c8e6c9;" | Базова
|-
| Відділення → Адреса
| WarehouseDoors
| Відправка з відділення на адресу отримувача. | Повторне додавання блокується або обробляється за правилом. |-
| TimeoutError
| Перевищено час очікування. | Статус стає RETURNING і підсвічується помаранчевим. | Check-connection і повідомлення адміністратору. |-
| TrackingDocument
| Відстеження відправлень. |-
| created_at
| timestamp
| Дата створення. | Створення ЕН, розрахунок вартості, дата доставки, друк. |}

! Очікуваний результат
5. Тип
[[Категорія:API]]

щоб оперативно реагувати на відмови, повернення та прострочені доставки. "recipient_city_ref": command.recipient.city_ref,

* повна технічна підтримка всіх додаткових послуг;
* складна робота з міжнародною доставкою;
* повна автоматизація процесів післяплати;
* автоматичне створення всіх типів контрагентів;
* складний UI складу;
* інтеграційні функції ERP з NovaPay;
* власна платформа доставки замість API Нової пошти. №
 def get_document_price(self, payload: "DeliveryPricePayload") -> "DeliveryPriceResponse":
{| class="wikitable"
 model_name="InternetDocument",
 return
=== 14.7. Розрахунок дати доставки ===
 try:
 def get_cities(self, query: str | None = None) -> "CityListResponse":
=== 14.10. Скасування / видалення експрес-накладної ===
 if not data.get("success"):
Як менеджер інтернет-магазину, 
! |-
| address
| text
| Адреса. Призначення
=== 23.2. Приклад dashboard ===
{| class="wikitable"
! |-
| delivered_at
| timestamp
| Дата доставки. ! |-
| created_at
| timestamp
| Дата створення. | платформа повертає успішний або помилковий статус. |-
| payment_method
| varchar
| Форма оплати. |-
| Nova Poshta Client
| Python-клієнт для API Нової пошти. | Python-сервіс створює ЕН. | Формування реєстру відправлень.<syntaxhighlight lang="python">
class NovaPoshtaSettings(BaseSettings):
 pass
== 29. Ризики ==

<pre>

! order.error_message = str(exc)

! |-
| old_status
| varchar
| Попередній статус. # Чи потрібна інтеграційні функції ERP з K2 ERP документами реалізації та оплат? |-
| schedule
| jsonb
| Графік роботи. ! |-
| SettlementTypeDescription
| Тип населеного пункту. |-
| max_weight
| numeric
| Максимальна вага. |}

 "city_ref": "recipient-city-ref",

 )

 pass
<pre>
 |
 | 1. Особливості:

* реалізувати синхронізацію міст;
* реалізувати синхронізацію відділень;
* реалізувати пошук;
* реалізувати кешування;
* реалізувати регламентне оновлення версій. |-
| new_status
| varchar
| Новий статус. Код
=== 20.2. np_cities ===
{| class="wikitable"
4. |}

{| class="wikitable"

__TOC__

Кожне замовлення, кожна ЕН / ТТН, повторний запит, помилка API, друк маркування та зміна статусу повинні мати внутрішній ID, idempotency_key, журнал подій і контроль повторної обробки. |-
| AuthError
| Невірний API Key. Заборонено зберігати API Key у коді, Git, frontend-змінних або відкритих логах. Замовлення, клієнт ERP, адреса, вантаж
 delivery_queue.enqueue(
2.=== 14.6. Розрахунок вартості доставки ===

3. |-

np_scan_sheet_ref varchar - Помилка API Перевести в NEEDS_CORRECTION. async def create_np_document(command: "CreateNpDocumentCommand", db: "Session") -> "NpDeliveryOrder":

async def send_np_document(delivery_order_id: str, db: "Session") -> None:

  • отримати API Key;
  • перевірити доступ до API;
  • отримати актуальну документацію;
  • перевірити моделі Address, InternetDocument, TrackingDocument, ScanSheet;
  • перевірити розрахунок вартості;
  • перевірити створення тестової ЕН;
  • перевірити друк маркування. |}

28. Етапи реалізації

27. MVP

20.4. np_delivery_orders

Як менеджер, я хочу бачити статистику по доставках,

AC-18 - recipient_city_ref varchar - Validation Layer Перевіряє отримувача, адресу, відділення, вагу, габарити, оплату. POST /api/v1/nova-poshta/internet-documents/{document_id}/cancel

</syntaxhighlight>

- created_at timestamp Дата створення. Отримувач

17. Довідники Нової пошти

- Скасування ЕН Високий }

6. Основні сутності

K2 ERP передає в Python-сервіс замовлення, інформаційні дані отримувача, місто, відділення або адресу, параметри вантажу та оплату. | Архів, чернетки. :contentReference [oaicite:2]{index=2}

}

POST /api/v1/nova-poshta/integrations/{integration_id}/check-connection

NOVA_POSHTA_API_KEY=********

14.2. Перевірка підключення

  • бізнес-акаунт Нової пошти;
  • API Key;
  • доступ до актуальної API-документації;
  • інформаційні дані відправника;
  • контактну особу відправника;
  • адресу / відділення відправника;
  • правила оплати доставки;
  • правила зворотної доставки;
  • правила післяплати;
  • правила страхування;
  • перелік типів вантажу;
  • перелік типів доставки;
  • правила друку маркувань;
  • правила формування реєстрів;
  • правила оновлення версій статусів;
  • вимоги K2 ERP до збереження ЕН. | Вони підсвічуються червоним. |}

Якщо застосовується для післяплата або повернення коштів, потрібно передбачити:

14.4. Пошук міст

},
- AC-13 style="background:#ffcc80;" | Помаранчевий
Повернуто RETURNED - sent_at timestamp Дата створення ЕН. Критерій - volume_general numeric style="background:#fff9c4;" | Додаткова
Адреса → Відділення DoorsWarehouse Кур'єр забирає у відправника, доставка у відділення. платформа повинна повернути існуючу ЕН та її поточний статус. Tracking Worker оновлює статуси доставки. idempotency_key=command.idempotency_key,
  • Ref відділення;
  • номер відділення;
  • назву;
  • адресу;
  • місто;
  • тип відділення;
  • максимальну вагу;
  • ознаку поштомата;
  • графік роботи;
  • координати;
  • ознаку активності. ! # Чи потрібна доставка у поштомати? Частота оновлення версій
pass

Як працівник складу,

Етап 4. Довідники

data = response.json()

8. Типи доставки

pass
  • зберігання налаштувань інтеграції;
  • отримання та оновлення версій довідників Нової пошти;
  • пошук міст;
  • пошук відділень;
  • пошук поштоматів;
  • пошук вулиць;
  • створення контрагентів або використання існуючих;
  • створення контактних осіб;
  • створення адрес;
  • розрахунок вартості доставки;
  • розрахунок орієнтовної дати доставки;
  • створення експрес-накладної;
  • редагування експрес-накладної, якщо дозволено API;
  • видалення / скасування експрес-накладної, якщо дозволено API;
  • друк маркування;
  • формування реєстру відправлень;
  • отримання статусів відправлень;
  • синхронізацію статусів назад у K2 ERP;
  • журналювання всіх API-запитів;
  • dashboard для контролю логістики. |-
provider varchar Повторити фоново. |- default_sender_ref varchar - AC-17 style="background:#fff9c4;" | Увага
ЕН створено }
"volume_general": 0.01,
- id uuid - Замовлень до відправки 84 Увага
ЕН створено сьогодні 312 Норма
Маркування надруковано 298 Норма
У дорозі 1270 В роботі
Прибуло у відділення 240 Контроль
Доставлено 980 Норма
Відмова 18 Критично
Повернення 35 Потрібна дія
Помилки створення ЕН 6 Критично
def get_warehouses(self, city_ref: str, warehouse_type: str | None = None) -> "WarehouseListResponse":

Як керівник,

api_key: str
"external_order_id": "K2-ORDER-2026-000123",
db.commit()

7.2. Друк маркування

self.base_url = base_url

Синхронізуються:

07.05.2026 K2-ORDER-123 - Іван Петренко Помилка Не знайдено відділення Виправити адресу
07.05.2026 K2-ORDER-124 20450000000000 Олена Сидоренко Відмова Відмова отримувача Зв'язатися з клієнтом
07.05.2026 K2-ORDER-125 20450000000001 ТОВ «Альфа» Повернення Не отримано вчасно Контроль повернення
event_type="NP_STATUS_SYNCED",
  • зберігання API Key тільки у secret storage або в зашифрованому вигляді;
  • заборону логування API Key;
  • HTTPS для всіх API-запитів;
  • перевірку SSL;
  • рольову модель доступу;
  • окремі права на створення ЕН;
  • окремі права на скасування ЕН;
  • окремі права на друк маркувань;
  • окремі права на формування реєстрів;
  • журнал усіх дій;
  • захист від дублювання ЕН;
  • маскування телефонів отримувачів у логах;
  • контроль доступу до персональних даних. |-
Counterparty Контрагент API Нової пошти. Поле
def check_connection(self) -> "ConnectionStatus":

14.5. Пошук відділень

21. Приклад Python-логіки

timeout_seconds: int = 30
},
v
db=db,

21.4. Синхронізація статусів

)

Як комірник,

Не створювати ЕН, показати список помилок. |- Блакитний #bbdefb - Вулиці За потреби або кешуванням здатна бути великий обсяг.
  • реалізувати синхронізацію статусів;
  • реалізувати друк маркування;
  • реалізувати реєстри;
  • реалізувати retry. |}

Етап 5. ЕН і валідація

)

</syntaxhighlight>

Етап 8. Production hardening

self.timeout_seconds = timeout_seconds


 except TemporaryNovaPoshtaError as exc:
 "np_document_ref": order.np_document_ref,
{
 "methodProperties": {}
!=== 7.5. Dashboard керівника ===

* неправильного API Key;
* помилок валідації;
* неправильного міста;
* неправильного відділення;
* некоректного телефону;
* ЕН, яка вже розроблена;
* ЕН, яка вже доставлена;
* ЕН, яка вже скасована. |-
| Неправильна вага / габарити
| Вартість доставки буде некоректна. |-
| DescriptionRu
| Назва російською, якщо доступна. |-
| recipient_warehouse_ref
| varchar
| Відділення / поштомат. Python-сервіс регулярно отримує статуси відправлень і оновлює K2 ERP. |-
| Створення реєстру
| Середній
| Групова операційна дія. :contentReference [oaicite:1]{index=1}

* створено;
* прийнято у відділенні;
* у дорозі;
* прибуло у відділення;
* прибуло у поштомат;
* видано отримувачу;
* відмова;
* повернення;
* повернуто відправнику;
* зберігання;
* помилка / уточнення.

12. Nova Poshta Client

21.3. Worker створення ЕН

v
pass
audit_logger.log(
Міста 1 раз на добу Базовий довідник. Код
id uuid ID реєстру. entity_type="np_delivery_order",

* місто отримувача;
* Ref міста;
* Ref відділення;
* ПІБ отримувача;
* телефон отримувача;
* кількість місць;
* вагу;
* об'єм;
* оголошену вартість;
* платника доставки;
* форму оплати;
* SEO-опис вантажу. |-
AC-16 Отримувач відмовився. SEO-опис API Нової пошти застосовують, коли потрібно для автоматизації логістичних процесів бізнесу. pass </syntaxhighlight>

5.2. Доставка у відділення


Критерій "first_name": "Іван", Довідник міст потрібен для вибору коректного `CityRef`. | Він бачить замовлення, ЕН, доставки, відмови, повернення та помилки. |- Відділення 1 раз на добу або частіше - Загальні довідники 1 раз на добу Типи вантажів, сервісів, оплат. Тип style="background:#bbdefb;" | Блакитний
Прибуло ARRIVED - Mapping Layer Перетворює структури K2 ERP у формат API Нової пошти. SEO-опис - created_at timestamp Дата події. Ключ "service_type": command.delivery.service_type, order.status = "ERROR"
SEO-опис verify_ssl: bool = True
Очікуваний результат def call_api(self, model_name: str, called_method: str, properties: dict) -> dict: audit_logger.log( GET /api/v1/nova-poshta/warehouses?city_ref={city_ref} щоб платформа автоматизовано створила експрес-накладну без ручного введення в кабінеті Нової пошти. Призначення