Довідник сутностей обміну
Усі типи сутностей обміну ApexSFA: поля payload, ключі ідемпотентності, порядок первинного завантаження, приклади конвертів.
Цей документ описує що саме облікова система може надіслати в ApexSFA і як портал це застосовує: для кожного entity_type — призначення, ключ ідемпотентності, поля payload, семантика delete, залежності, ліміти й формати.
Транспорт (підпис X-Signature, X-Tenant-Id, ліміти, загальні коди відповіді) описано в розділі 3; тут — лише те, що потрібно для побудови конвертів.
Зміст
- 1. Конверт і ендпоінти
- 2. Загальні правила
- 3. Рекомендований порядок першого завантаження
- 4. Зведена таблиця entity_type
- 5. Оргструктура й постачання
- 6. Каталог і ціни
- 7. Контрагенти, точки, привʼязки
- 8. Люди й транспорт
- 9. Обладнання
- 10. Залишки, WMS, акциз
- 11. Продажі й документи руху товару
- 12. Борги
- 13. Каса
- 14. Стан заявок порталу в обліку
- 15. Рейси (ходки)
- 16. Модуль логістики
- 17. Приклади конвертів
1. Конверт і ендпоінти
| Метод | Шлях | Що приймає |
|---|---|---|
POST | /api/v1/webhooks/1c/inbound | один конверт |
POST | /api/v1/webhooks/1c/inbound/batch | {"items": [конверт, …], "partial": true} — від 1 до 5000 конвертів |
Конверт
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
entity_type | string | так | Один із типів, перелічених у зведеній таблиці. Інше значення → 422 VALIDATION_ERROR. |
operation | string | так | create | update | upsert | delete. create, update і upsert обробляються однаково — як upsert. Окремо поводиться лише delete. |
external_id | string | так | 1–50 символів. Ідентифікатор обʼєкта в обліковій системі (зазвичай GUID). Для багатьох сутностей — ключ ідемпотентності; див. кожну сутність. |
payload | object | ні (за замовчуванням {}) | Поля сутності. |
Примітка. Рекомендуємо GUID обʼєкта (36 символів). Ідентифікатори довші за 50 символів не використовуйте.
Відповідь
- Одиночний конверт, успіх —
200:
{"data": {"accepted": true, "entity_id": "3f2a9c1e-7b4d-4e0a-9f51-2c8d6a1b0e47", "operation_performed": "upsert", "details": {"upserted": 412, "depleted": 3}}}details — лічильники обробника (є не в усіх сутностей; напр. {"skipped": "manual_override"}).
- Одиночний конверт, бізнес-помилка (запис не знайдено, порушене правило) —
422:
{"error": {"accepted": false, "error": "Product with code_1c=… not found — create it first"}}- Батч —
200з результатом по кожному рядку:
{"data": {"accepted_count": 2, "failed_count": 1, "results": [
{"index": 0, "entity_type": "product", "external_id": "…", "accepted": true, "entity_id": "…", "operation_performed": "upsert", "error": null, "details": null},
{"index": 1, "entity_type": "price_list_item", "external_id": "…", "accepted": false, "entity_id": null, "operation_performed": null, "error": "Product with code_1c=… not found — create it first", "details": null}
]}}partial: true(за замовчуванням) — кожен конверт у власній точці збереження; помилка одного не скасовує інших. Будь-яка помилка рядка стаєaccepted: falseз текстом, а не помилкою всього пакета.partial: false— увесь батч атомарно: на першій бізнес-помилці все відкочується, відповідь422{"error": {"code": "BATCH_ATOMIC_FAILURE", "message": "…", "accepted_so_far": N, "failed_at_index": N}}. У цьому режиміdetailsпо рядках не повертаються.- Порожній
items→200з нулями (легальний «порожній хвіст» вигрузки). - Понад 5000 конвертів →
422VALIDATION_ERRORз текстомbatch too large.
Порада. Завжди надсилайте дані через
/inbound/batchзpartial: true— так кожен рядок отримує власний результат і текст помилки.
Постобробка лише батчу. Після батчу, у якому був хоча б один agent, портал підвʼязує документи обліку (goods_document, cash_document, борги), що прийшли раніше за торгового. Після батчу з counterparty — долінковує ієрархію контрагентів (дитина, що прийшла раніше за папку-батька). В одиночному ендпоінті цього не відбувається.
2. Загальні правила
Ідемпотентність. Повтор того самого конверта безпечний: майже всі сутності — upsert за природним ключем (зазвичай external_id). Окремого ключа запиту (request id) немає. Винятки, де повтор має побічний ефект, позначено в описі сутності (напр. debt_reset видаляє всі борги, trip перебудовує склад рейсу).
Частковий payload. Для більшості довідників поле оновлюється, лише якщо ключ присутній у payload. Відсутній ключ = «не чіпати». Явне null / "" = «очистити» (якщо поле не обовʼязкове).
Ручні правки на порталі. Записи, які редагували на порталі, обмін оновлює лише частково — зазвичай тільки is_active. Відповідь тоді містить details: {"skipped": "manual_override"}. Так поводяться product, manufacturer, counterparty, client_assignment; у agent/driver — поля ПІБ і телефону, виправлені в картці.
Філія. Тенант = одна точка синхронізації з одним рядком філії. Усі склади, торгові, водії, точки й рейси з обміну лягають у філію тенанта, від імені якого прийшов запит. Коди філії в payload (branch_code, branch_external_id, branch_code_1c, filial_code) приймаються, але не читаються.
Рядки. Пробіли по краях обрізаються, невидимі символи нульової ширини видаляються (у довідниках оргструктури, контрагентів, людей, транспорту, обладнання). Більшість текстових полів довідників обрізаються до розміру колонки без помилки. У client і product текстові поля пишуться як є — задовге значення дасть помилку рядка (у partial-батчі — accepted: false).
Числа.
| Де | Що приймається |
|---|---|
Документи руху товару, каса, goods_period.totals, обладнання-транспорт (габарити, маса), logistics_product | число або рядок; кома як десятковий роздільник, пробіли й нерозривні пробіли-тисячники допустимі: "1 234,50" |
Дні відстрочки (payment_terms_days, days) | 7, 7.0, "7", "7,0" |
Ціни (price, base_price, discount_percent), суми боргів (amount, remaining_amount), credit_limit, shipped_quantity, shipped_total_amount, кількості залишків (qty) | число або рядок з крапкою: 12.5 або "12.50". Кома в цих полях — помилка. |
product_stock.items[].amount | кома допустима; некоректне значення → null без помилки |
Рекомендація: гроші й кількості передавати рядком з крапкою ("1234.50") — так не губиться точність.
Дати й час.
| Формат | Де | Часовий пояс |
|---|---|---|
YYYY-MM-DD (зайве після 10-го символу ігнорується) | більшість дат (inventory_date, on_date, date_from/date_to, doc_date/due_date боргів, as_of, дати партій) | дата без часу |
ISO 8601 дата-час YYYY-MM-DDTHH:MM:SS[±HH:MM|Z] | goods_document.doc_date, cash_document.doc_date, started_at періодів, order_state_period.date_from, equipment_unit.installed_at | без зони = Europe/Kyiv; з зоною — як вказано |
| ISO 8601 дата-час | sale.shipped_at | передавайте з явним зсувом (+03:00 або Z); порожнє значення — поточний момент |
Закритий місяць. Для goods_document і goods_period документи з датою в закритому періоді не змінюються. Місяць M закривається з дня sales_close_day (за замовчуванням 10, допустимо 1–28) місяця M+1 за київським часом; адміністратор може відкрити період у налаштуваннях. Для каси (cash_*) такого захисту немає.
3. Рекомендований порядок першого завантаження
Порядок випливає з того, як обробники шукають посилання: «жорстке» посилання (немає — помилка) вимагає, щоб залежність прийшла раніше; «мʼяке» (немає — запис приймається без звʼязку) лише відкладає звʼязок до наступного обміну.
1. branch
2. warehouse, logistics_warehouse
3. supplier → supplier_point
4. price_type
5. manufacturer
6. product_category (батьки раніше за дітей) → product
7. agent, driver
8. vehicle → transport_list
9. counterparty (папки раніше за елементи — бажано) → client
10. client_assignment, manufacturer_price_type, manufacturer_payment_term
11. equipment_type → equipment_unit
12. price_list_item, product_external_code
13. Модуль логістики: logistics_manufacturer / logistics_own_manufacturer,
logistics_counterparty → logistics_point,
logistics_product_category → logistics_product → logistics_product_code
14. Залишки: product_stock, wms_stock, product_stock_snapshot, logistics_stock,
stock_document, excise_marks
15. Документи: sale, logistics_order, debt_reset → debt_document,
goods_document → goods_period, trip, cash_document + cash_balance → cash_period,
order_state → order_state_period| Залежність | Тип | Що буде, якщо залежності ще нема |
|---|---|---|
warehouse, stock_document → філія | жорстка | 422 «Точка не має рядка філії…»; спершу branch |
supplier_point → supplier | жорстка | 422 NotFound |
product_category.parent_code_1c → батьківська категорія | жорстка | 422 |
product.category_code_1c → категорія | мʼяка | товар без категорії; звʼязок — при наступному обміні товару |
product.manufacturer_external_id → manufacturer | мʼяка | товар без звʼязку з виробником (текстова назва manufacturer лишається); звʼязок — при наступному обміні товару |
price_list_item → product | жорстка | 422 NotFound |
price_list_item / client.price_list_code → прайс | — | прайс створюється автоматично; назва береться з price_type з тим самим code, якщо він уже є, інакше «Прайс {code}» |
client.counterparty_external_id → counterparty | мʼяка | точка без контрагента |
client_assignment → client і agent | жорстка | 422 NotFound |
manufacturer_price_type → точка | мʼяка | details.skipped = client_not_found (не помилка) |
manufacturer_price_type / manufacturer_payment_term → manufacturer | жорстка | 422 NotFound |
manufacturer_payment_term → counterparty | мʼяка | details.skipped = counterparty_not_found |
equipment_unit → equipment_type | жорстка (лише при створенні) | 422 NotFound |
equipment_unit.client_code_1c → точка | жорстка | 422 NotFound |
vehicle.driver_external_id → водій | мʼяка | авто без водія |
product_stock / wms_stock → склад | жорстка | 422 «Unknown warehouse» |
product_stock / wms_stock / product_stock_snapshot → товар | мʼяка | рядок пропускається, коди — у details |
goods_document → точка, контрагент, торговий, склад, виробник, товар | мʼяка | документ приймається з кодами й назвами; точку й торгового портал допривʼяже, коли вони прийдуть |
debt_document → точка | — | точку (і контрагента) буде створено з полів боргу, якщо передано client_name |
sale → заявка порталу | жорстка | 422 NotFound |
trip (без number) → водій | жорстка | 422 NotFound |
logistics_point → logistics_counterparty | жорстка | 422 NotFound |
4. Зведена таблиця entity_type
| entity_type | Група | Призначення | Ключ пошуку існуючого | delete |
|---|---|---|---|---|
branch | Оргструктура | Рядок філії точки синхронізації | єдиний рядок філії тенанта; external_id привʼязується один раз | ігнорується |
warehouse | Оргструктура | Склад | external_id | is_active=false |
supplier | Постачання | Постачальник | external_id | is_active=false |
supplier_point | Постачання | Точка постачання постачальника | external_id | is_active=false |
price_type | Постачання | Тип ціни | external_id | is_active=false |
manufacturer | Каталог | Виробник | external_id | is_active=false |
product_category | Каталог | Категорія товарів (дерево) | external_id | мʼяке видалення |
product | Каталог | Товар | external_id | мʼяке видалення |
price_list_item | Каталог | Ціна товару в прайсі | (прайс за price_list_code, товар за product_code_1c) | фізичне видалення |
product_external_code | Каталог | Артикул товару в мережі | (товар, sync_kind_external_id) | фізичне видалення |
manufacturer_price_type | Каталог | Тип цін точки по виробнику | (точка, виробник) | мʼяке видалення |
manufacturer_payment_term | Борги | Відстрочка контрагента по виробнику | (контрагент, виробник) | мʼяке видалення |
counterparty | Клієнти | Контрагент (юрособа) | external_id | is_active=false |
client | Клієнти | Торгова точка | external_id | мʼяке видалення |
client_assignment | Клієнти | Привʼязка точки до торгового | (точка, торговий) | видалення привʼязки |
agent | Люди | Торговий | external_id | доступ знято, запис лишається |
driver | Люди | Водій / експедитор | external_id | не підтримується |
vehicle | Транспорт | Автомобіль | external_id | is_active=false |
transport_list | Транспорт | Списки авто й водіїв, що беруть участь в обміні | — (снапшот) | — |
equipment_type | Обладнання | Тип обладнання | external_id | is_active=false |
equipment_unit | Обладнання | Одиниця обладнання | external_id | мʼяке видалення |
product_stock | Залишки | Знімок залишків складу без партій | склад warehouse_code_1c | не підтримується |
product_stock_snapshot | Залишки | Залишок складу на кінець дня (історія) | (склад, дата) | — |
wms_stock | Залишки | Знімок партій WMS-складу | склад warehouse_code_1c | не підтримується |
stock_document | Залишки | Документ інвентаризації для ревізії | external_id | не підтримується |
excise_marks | Залишки | Пакет акцизних марок | УІ марки | не підтримується |
sale | Продажі | Факт відвантаження по заявці порталу | id / номер заявки | — |
goods_document | Продажі | Документ руху товару (продажі, повернення, надходження…) | external_id | is_posted=false |
goods_period | Продажі | Кінець вигрузки вікна + контрольні суми | — (кожен конверт — новий запуск) | — |
debt_reset | Борги | Повне скидання боргів перед новою вигрузкою | — | — |
debt_document | Борги | Документ заборгованості точки | external_id | status=closed |
cash_document | Каса | ПКО / РКО / банківська виписка | external_id | is_posted=false |
cash_balance | Каса | Залишок по касі / рахунку | (account_code, вид коштів) | фізичне видалення |
cash_period | Каса | Кінець вигрузки вікна каси | — | — |
order_state | Заявки | Стан заявки порталу в обліку | external_id або order_number | — |
order_state_period | Заявки | Кінець списку станів → скасування зниклих | — | — |
trip | Рейси | Ходка → рейс порталу / призначення водія | external_id | рейс скасовано |
logistics_order | Логістика | Заявка, створена в обліку | external_id | скасування, якщо не в рейсі |
logistics_manufacturer | Логістика | Виробник із позначкою логістики | як manufacturer | як manufacturer |
logistics_own_manufacturer | Логістика | Виробник модуля логістики | external_id | is_active=false |
logistics_counterparty | Логістика | Контрагент логістики | external_id | is_active=false |
logistics_point | Логістика | Точка доставки логістики | external_id | is_active=false |
logistics_warehouse | Логістика | Склад логістики | external_id | is_active=false |
logistics_product_category | Логістика | Категорія каталогу логістики | external_id | is_active=false |
logistics_product | Логістика | Товар каталогу логістики | external_id | is_active=false |
logistics_product_code | Логістика | Код товару логістики в мережі | (товар, kind_external_id) | фізичне видалення |
logistics_stock | Логістика | Знімок залишків складу логістики | склад warehouse_code_1c | не підтримується |
«Не підтримується» = delete повертає 422.
5. Оргструктура й постачання
branch
Філія — це сама точка синхронізації. Обмін записує в її єдиний рядок GUID і адресу; другого рядка філії не створює.
- Ключ. Береться єдиний рядок філії тенанта. Якщо в нього ще немає GUID —
external_idзаписується в нього (якщо цей GUID не стоїть на іншому рядку). Якщо рядка немає взагалі — створюється (тодіnameобовʼязкове). - Інший GUID (друга філія довідника обліку) →
200,details.skipped = "other branch of the same point", нічого не змінюється. - Повтор — ідемпотентний.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | лише якщо рядка філії ще немає | Назва. Існуючу назву обмін не перезаписує (її веде адміністратор платформи). |
address | string ≤2000 | ні | Адреса. |
delete: 200, details.skipped = "point branch is not deactivated" — філія не вимикається. Якщо рядка філії немає — 422.
При першій привʼязці GUID етапи заявки виставляються так, що етап «перевірка» на порталі вимкнено (цикл заявки веде облікова система).
warehouse
Склад торгового контуру.
- Ключ:
external_id. Склад завжди належить філії тенанта. - Новий склад веде залишки з облікової системи (
product_stock).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | Порожнім затерти не можна (422). |
address | string ≤2000 | ні | |
wms_enabled | bool | ні | Змінюється лише якщо ключ передано. Відсутній ключ не скидає прапорець, увімкнений на порталі. |
excise_enabled | bool | ні | Так само. Потрібен для excise_marks зі складом. |
is_active | bool | ні | |
branch_external_id | — | ні | Приймається, не читається. |
delete: is_active=false; немає складу — 422.
supplier
Постачальник. Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤500 | так при створенні | |
code | string ≤100 | ні | |
tax_id | string ≤50 | ні | |
is_active | bool | ні | |
counterparty_external_id | string | ні | Звʼязок з контрагентом; невідомий — ігнорується. |
delete: is_active=false; немає — 422.
supplier_point
Точка постачання (адреса відвантаження) постачальника. Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
supplier_external_id | string | так | external_id постачальника. Невідомий → 422 «push the supplier first». |
name | string ≤500 | так при створенні | |
code | string ≤100 | ні | |
address | string ≤500 | ні | |
is_active | bool | ні |
delete: is_active=false; немає — 422.
price_type
Тип ціни. Його code збігається з кодом прайсу (price_list_code) у price_list_item і client — з нього береться назва автоматично створеного прайсу.
Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤500 | так при створенні | |
code | string ≤100 | ні (рекомендовано) | Код типу цін = код прайсу. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
6. Каталог і ціни
manufacturer
Виробник (бренд-власник), у розрізі якого працюють торгові команди, продажі, борги.
- Ключ:
external_id. Цей самий код передається в інших сутностях якmanufacturer_external_id. - Запис із ручними правками на порталі: оновлюється лише
is_active,details.skipped = "manual_override".
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | |
code | string ≤100 | ні | |
tax_number | string ≤20 | ні | ЄДРПОУ / ІПН. |
supplier_external_id | string | ні | Постачальник виробника; невідомий → звʼязок скидається в порожній. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
product_category
Категорія товарів, дерево.
- Ключ:
external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string | ні | При створенні без name — порожня назва. |
parent_code_1c | string | ні | external_id батьківської категорії. Невідома → 422 (спершу батьки). Ключ відсутній — батько не змінюється. |
slug, code, description, image_url | string | ні | |
sort_order | int | ні | |
is_active | bool | ні |
delete: мʼяке видалення; немає — 422.
product
Товар основного каталогу (КПК, B2B, звіти).
- Ключ:
external_id. - Повтор: upsert, поля з payload перезаписуються.
- Ручні правки на порталі: оновлюються лише
is_activeтаis_in_stock,details.skipped = "manual_override". - Назва:
nameзавжди пишеться в «назву з обліку»; видима назва змінюється, лише якщо джерелом назви товару обрано облік (на порталі можна обрати інше джерело). - Артикул і штрихкод: порожні →
null; довші за 50 символів або вже зайняті іншим товаром — поле пропускається (товар приймається, у лозі попередження). - Новий штрихкод у товару без фото ставить товар у чергу фонового збагачення (фото, вага, бренд з відкритих каталогів).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | рекомендовано | При створенні без нього — порожня назва. |
base_price | number/string з крапкою | ні | Базова ціна; при створенні за замовчуванням 0. |
unit | string ≤20 | ні | Одиниця; за замовчуванням шт. |
sku | string ≤50 | ні | Артикул. |
barcode | string ≤50 | ні | Штрихкод. |
brand | string ≤100 | ні | |
manufacturer | string ≤200 | ні | Назва виробника текстом (показується, поки не встановлено звʼязок). |
manufacturer_external_id | string | ні | Звʼязок з manufacturer (мʼякий). Порожнє значення — розвʼязати. |
category_code_1c | string | ні | Звʼязок з product_category (мʼякий). Не застосовується, якщо категорію перевизначено на порталі. |
description | string | ні | |
currency | string(3) | ні | За замовчуванням UAH. |
vat_rate | number | ні | Ставка ПДВ, %. За замовчуванням 20. |
is_active | bool | ні | |
is_in_stock | bool | ні | Довідково; наявність визначається залишками (product_stock). |
category_1c | string ≤200 | ні | Категорія з обліку текстом (довідково). |
kind_1c | string ≤100 | ні | Вид номенклатури (довідково). |
is_excisable | bool | ні | Підакцизний товар. |
pack_size | int | ні | Фасовка (штук в упаковці), мінімум 1; 0/порожнє ігнорується. |
weight_kg | decimal | ні | |
volume_liters | decimal | ні | |
units_per_pallet, units_per_euro_pallet, units_per_block, units_per_box, package_type, pallet_type, uktved, uktved_code, shelf_life_days, unit_barcode, consumer_barcode, height_mm, length_mm, width_mm | будь-які | ні | Логістичний паспорт товару; зберігається блоком і показується в картці. Порожні й нульові значення ігноруються, решта доливається до вже збережених. |
delete: мʼяке видалення; немає — 422.
price_list_item
Ціна товару в прайсі (типі цін).
- Ключ: пара (прайс за
price_list_code, товар заproduct_code_1c).external_idрекомендовано у вигляді"<price_list_code>:<product_code_1c>"— якщо полів у payload немає, вони беруться з двох половинexternal_id. - Прайс з таким кодом створюється автоматично, якщо його ще немає.
- Товар має існувати → інакше 422 «create it first».
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
price_list_code | string | так (або в external_id) | Код прайсу = code типу цін. |
product_code_1c | string | так (або в external_id) | external_id товару. |
price | number/string з крапкою | так при створенні | Ціна. |
discount_percent | decimal | ні | За замовчуванням 0. |
min_quantity | int | ні | За замовчуванням 1. |
delete: запис фізично видаляється; немає — 422.
product_external_code
Артикул товару в мережі (код, під яким товар фігурує в замовленнях мережі). Портал використовує його для розпізнавання файлів замовлень.
- Ключ: (товар за
product_code_1c,sync_kind_external_id).external_id— довільний унікальний ідентифікатор рядка (не використовується для пошуку). - Товару немає на порталі →
200,details.skipped = "product not on portal"(не помилка).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
product_code_1c | string | так | external_id товару. |
sync_kind_external_id | string ≤200 | так | Ідентифікатор виду коду (мережі). |
code | string ≤200 | так (крім delete) | Код товару в мережі. |
sync_kind_name | string ≤300 | ні | Назва виду коду. |
delete: рядок видаляється; немає — 200 без помилки.
manufacturer_price_type
Тип цін, за яким точка купує товари конкретного виробника (перекриває загальний прайс точки).
- Ключ: (точка
client_code_1c, виробникmanufacturer_external_id).external_idзберігається; рекомендований формат"<GUID точки>-<код виробника>". - Невідома точка →
200,details = {"skipped": "client_not_found", "client_code_1c": "…"}. - Невідомий виробник → 422.
- Відповідь:
details.price_list_resolved— чи знайдено прайс з таким кодом (код зберігається завжди; прайс може прийти пізніше). - Мʼяко видалений рядок оживає при наступному upsert.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
client_code_1c | string | так | external_id точки. |
manufacturer_external_id | string | так | |
price_list_code | string ≤50 | так при створенні | Код типу цін. |
delete: якщо передано обидва ключі — пошук за парою; інакше — за external_id. Мʼяке видалення; немає — 422.
7. Контрагенти, точки, привʼязки
counterparty
Контрагент — юридична особа (власник точок, постачальник).
- Ключ:
external_id. - Ручні правки на порталі: оновлюється лише
is_active,details.skipped = "manual_override". - Нова відстрочка (
payment_terms_days) перераховує терміни оплати відкритих боргів точок цього контрагента, у яких немає власної відстрочки (лише документи, де облік не дав пізнішого терміну сам).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤500 | так при створенні | |
kind | buyer | supplier | both | ні | За замовчуванням buyer. Інше значення → 422. |
code | string ≤100 | ні | |
tax_number | string ≤50 | ні | ІПН. |
edrpou | string ≤20 | ні | |
contact_person, director, bank_name | string ≤200 | ні | |
bank_iban | string ≤34 | ні | |
legal_address, address | string ≤2000 | ні | |
phone | string ≤20 | ні | |
email | string ≤255 | ні | |
external_codes | array | ні | Коди контрагента в мережах: [{"kind": "…", "code": "…"}] (або масив рядків). Пробіли в коді прибираються, дублі відкидаються. Коди, додані вручну на порталі, зберігаються. |
payment_terms_days | int | ні | Відстрочка платежу, днів. Некоректне значення — поле пропускається. |
is_group | bool | ні | Папка довідника. |
parent_external_id | string | ні | Батьківська папка. Ще не прийшла → звʼязок допишеться після батчу, у якому вона прийде (лише через /inbound/batch). Порожнє — відвʼязати. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
client
Торгова точка — адреса, куди ходить торговий і везуть товар.
- Ключ:
external_id. Цей же код передається якclient_code_1cв інших сутностях. - При створенні точки портал допривʼязує до неї документи руху товару, що прийшли раніше з цим кодом.
- Точка завжди належить філії тенанта.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | рекомендовано | При створенні без нього — порожня назва. |
address | string | рекомендовано | Зміна адреси або міста ставить точку в чергу геокодування (крім точок з координатами, виставленими вручну). |
legal_name | string ≤300 | ні | |
code | string ≤50 | ні | Внутрішній код точки. |
tax_number | string ≤20 | ні | |
contact_person | string ≤200 | ні | |
contact_position | string ≤100 | ні | |
phone, phone_secondary | string ≤20 | ні | |
email | string ≤255 | ні | |
city, region | string ≤100 | ні | |
direction | string ≤150 | ні | Напрямок доставки (фільтр рейсів). |
postal_code | string ≤10 | ні | |
country | string(2) | ні | За замовчуванням UA. |
category, channel, type | string ≤50 | ні | Категорія, канал збуту, тип точки. |
notes | string | ні | |
external_codes | array | ні | Коди точки в мережах [{"kind","code"}] — для розпізнавання файлів замовлень. Ручні коди порталу зберігаються. |
payment_terms_days | int | ні | Відстрочка, днів. Приймає 7, "7,0". Зміна перераховує терміни відкритих боргів точки. |
credit_limit | decimal з крапкою | ні | null/"" — без ліміту. |
geofence_radius_meters | int | ні | Радіус геозони чек-іну. |
business_hours | object | ні | Графік роботи (довільний JSON-обʼєкт, зберігається як є). |
counterparty_external_id | string | ні | Власник точки. Невідомий або порожній → точка без контрагента. |
price_list_code | string | ні | Прайс точки. Прайс із таким кодом створюється, якщо його немає. Порожнє значення — відвʼязати (точка працює за прайсом за замовчуванням). |
latitude, longitude | number/string (кома допустима) | ні | Записуються лише один раз — у точку без координат, і лише якщо координати в зоні роботи філії. Поза зоною — координати визначаються за адресою. Далі обмін координати не змінює (виправляють на порталі). |
branch_code, branch_external_id, filial_code | — | ні | Приймаються, не читаються. |
delete: мʼяке видалення; немає — 422.
client_assignment
Привʼязка точки до торгового (хто обслуговує точку).
- Ключ: пара (точка, торговий).
external_idдля пошуку не використовується. - Якщо торгового на порталі обʼєднано з іншим (дубль), привʼязка йде на основного.
- На точці може бути лише одна основна (
primary) привʼязка: якщо вже є основний торговий іншого виробника, нова привʼязка стаєsecondary. - Ручна привʼязка порталу не змінюється:
details.skipped = "manual_override".
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
client_code_1c | string | так | external_id точки (не видаленої). Невідома → 422. |
agent_external_id | string | так | external_id торгового. Невідомий → 422. |
role | string ≤20 | ні | primary (за замовчуванням) або secondary. |
delete: привʼязка видаляється (ручна — ні). Точка й торговий мусять існувати навіть для delete, інакше 422.
8. Люди й транспорт
agent
Торговий. Створюється як користувач порталу з роллю «торговий».
- Ключ:
external_id. - Новий торговий створюється неактивним і без пароля. Якщо
agent_kind = "mobile"(або торговий за ознаками «для КПК»), картка одразу активується й отримує запрошення на встановлення пароля (посилання — у картці торгового на порталі).accounting— довідковий запис без доступу. - Email: якщо передана пошта вже зайнята, ставиться службова технічна адреса.
- Відповідь при створенні:
details.created = true. - Користувач, позначений на видалення на порталі, обміном не оживає й дубль не створюється.
- Існуючий торговий: ПІБ і телефон оновлюються, якщо їх не виправляли в картці на порталі; роль змінюється лише між «торговий» і «супервайзер»; email не змінюється.
- Порожній елемент (немає ні імені, ні прізвища) для нового торгового →
200,details.skipped = "no name"; для існуючого → 422.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
last_name, first_name | string ≤100 | так (або name) | |
name | string ≤200 | якщо немає last_name/first_name | Повне ПІБ; перше слово — прізвище. |
phone | string ≤100 | ні | |
email | string ≤255 | ні | Для accounting не використовується як логін. |
agent_kind | mobile | accounting | ні | Торговий для КПК чи довідковий. Перехід mobile → accounting знімає доступ і виводить з команд. |
position | string ≤200 | ні | Посада (довідково). |
manufacturer_external_id, manufacturer_name | string | ні | Виробник, під яким торговий працює (накопичується список). |
manufacturer_access_ids | string | ні | Коди виробників через ;. Ключ присутній → повна синхронізація доступів торгового до виробників (порожній рядок = зняти всі обмеження). Ключ відсутній → доступи не змінюються. |
supervisor_external_id | string | ні | Зберігається довідково; підпорядкування будується на порталі. |
org_path_names, org_path_ids | string ≤1000 | ні | Ланцюжок папок оргструктури через ;; (від найближчої до кореня). Довідково. |
legacy_external_ids | array of string | ні | Старі коди цієї ж людини. Записи порталу зі старими кодами обʼєднуються в одного торгового з новим external_id, документи перепривʼязуються. |
branch_external_id | — | ні | Не читається. |
delete: торговий позначається довідковим (accounting), доступ знімається, торговий виходить з команд; запис і документи лишаються. Невідомий → 200, details.skipped = "unknown". Керівників (роль не «торговий») не вимикає.
driver
Водій або експедитор. Створюється як користувач з роллю «водій», неактивним — доступ до мобільного застосунку видає адміністратор на порталі.
- Ключ:
external_id. На цей код посилаютьсяvehicle.driver_external_idіtrip.driver_external_id. - Email: зайнята пошта → службова технічна адреса.
- Існуючий: оновлюються ПІБ і телефон (якщо не виправлені вручну) та реквізити; роль не змінюється.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
last_name, first_name / name | string | так | Без імені → 422. |
phone | string ≤100 | ні | |
email | string ≤255 | ні | |
license (або driver_license) | string ≤64 | ні | Номер посвідчення. |
license_issued_at | string ≤30 | ні | Дата видачі посвідчення (текстом). |
vehicle | string ≤200 | ні | Авто водія рядком. |
role | string ≤20 | ні | driver | forwarder (довідково). |
code | string ≤50 | ні | Табельний код. |
inn | string ≤20 | ні | |
passport_series | string ≤20 | ні | |
passport_number | string ≤30 | ні |
delete: не використовуйте — щоб вивести водія з обміну, передайте transport_list без нього.
vehicle
Автомобіль.
- Ключ:
external_id. - Кожен upsert вмикає авто (
is_active=true), якщо в payload немає явногоis_active.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | Держномер / назва. |
code | string ≤100 | ні | |
brand, model | string ≤200 | ні | |
capacity | decimal з крапкою | ні | Вантажопідйомність. Некоректне — пропускається. |
is_hired | bool | ні | Найманий транспорт. |
is_accounted | bool | ні | Обліковий/необліковий. |
driver_external_id | string | ні | Основний водій. Невідомий → звʼязок порожній, допишеться наступним обміном. |
length, width, height | number (кома допустима) | ні | Габарити. Одиниця визначається за величиною: >1000 — мм, >100 — см, інакше — м. Зберігаються в метрах. 0 = не заповнено. |
unladen_weight, gross_weight | number (кома допустима) | ні | Маса без вантажу / повна. >1000 — кг, інакше — т. Зберігається в тоннах. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
transport_list
Повний список авто й водіїв, що беруть участь в обміні. Хто поза списком — неактивне авто й водій «поза списком»; у рейсі з ними буде «Не визначено».
- Ключ: немає (снапшот).
external_id— довільний,operationне впливає. - Відповідь:
details = {"vehicles_active", "vehicles_off", "drivers_active", "drivers_off"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
vehicles | array of string | null | ні | external_id авто, які лишаються активними. null — список порожній, активні всі. Ключ відсутній — авто не змінюються. |
drivers | array of string | null | ні | Так само для водіїв і експедиторів. |
9. Обладнання
equipment_type
Тип обладнання (модель холодильника, вітрини тощо). Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤200 | так при створенні | |
code, category | string ≤50 | ні | |
brand, model | string ≤100 | ні | |
manufacturer | string ≤200 | ні | |
is_active | bool | ні |
delete: is_active=false; немає — 422.
equipment_unit
Конкретна одиниця обладнання та її розміщення на точці.
- Ключ:
external_id. - Тип задається лише при створенні; пізніше
type_external_idігнорується. - Якщо серійний та інвентарний номери не передано, портал шукає їх у назві типу за шаблонами
сер. № …таінв. № …/инв. № …. - Зміна точки створює запис в історії переміщень (встановлення / зняття / переміщення) з датою
installed_at.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
type_external_id | string | так при створенні | Невідомий тип → 422. |
qr_code | string ≤64 | ні | За замовчуванням формується з external_id. |
serial_number, inventory_number | string ≤100 | ні | |
client_code_1c | string | ні | Точка, де стоїть обладнання → статус «встановлено». Невідома точка → 422. Порожнє значення — зняти з точки (статус «на складі», якщо був «встановлено»; ремонт/списання не скидаються). Ключ відсутній — розміщення не змінюється. |
installed_at | ISO дата-час | ні | Дата встановлення на точку; без зони — Europe/Kyiv. Некоректне — ігнорується. Якщо не передано, а точка змінилась — поточний момент. |
delete: мʼяке видалення; немає — 422.
10. Залишки, WMS, акциз
product_stock
Знімок поточних залишків складу без партій — для КПК, B2B і звіту «Залишки».
- Ключ: склад
warehouse_code_1c(external_idконверта не використовується для пошуку). - Повна заміна (REPLACE): товари складу, яких немає в знімку, обнуляються (рядок не видаляється).
- Склад має існувати й бути активним, інакше 422. Склад, що веде залишки у WMS (залишки ведуться у WMS), →
200зdetails.skipped(знімок пропущено, не помилка). - Невідомі товари пропускаються, їхні коди (до 50) — у
details.skipped_unknown_products. - Дублікат коду в
items— діє останній. - Відʼємний залишок записується як 0.
- Одночасно оновлюється денний зріз за сьогодні (для історії залишків).
- Відповідь:
details = {"upserted", "depleted", "touched", "skipped_unknown_products"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
warehouse_code_1c | string | так | external_id складу. |
items | array | так | Порожній масив = обнулити весь склад. |
items[].product_code_1c | string | так | external_id товару. |
items[].qty | number/string з крапкою | ні | ""/null = 0. Кома → 422. |
items[].amount | decimal | ні | Собівартість залишку; некоректне → null. |
delete: 422 (не підтримується).
product_stock_snapshot
Залишок складу на кінець конкретного дня — для історії залишків і днів запасу. Поточний залишок не змінює.
- Ключ: (склад,
on_date). Повтор за той самий день перезаписує зріз. - День вважається вигруженим повністю: товари зрізу цього складу за цю дату, яких немає в конверті, обнуляються.
- Склад шукається без перевірки активності; невідомий → 422. Невідомі товари пропускаються (
details.unknown_products— кількість). - Відповідь:
details = {"on_date", "rows", "unknown_products"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
warehouse_code_1c | string | так | |
on_date | YYYY-MM-DD | так | Не в майбутньому, інакше 422. |
items[].product_code_1c | string | так | Рядки без коду або не-обʼєкти пропускаються. |
items[].qty | number/string з крапкою | ні | |
items[].amount | decimal | ні |
wms_stock
Повний знімок партій WMS-складу.
- Ключ: склад
warehouse_code_1c; партія — заbatches[].external_id. - Склад має існувати й бути активним (WMS-модуль на складі вмикати не обовʼязково — партії лягають заздалегідь).
- Вхідна партія спершу «усиновлює» тимчасову партію порталу з тим самим товаром і номером партії (створену при прийманні до обміну) — дубля не буде.
- Партія з GUID, який уже належить іншому товару, пропускається (
batches_skipped_conflict). - Повна заміна: партії складу, яких немає в знімку, обнуляються (не видаляються). Дублікати партії в знімку — кількості сумуються.
- Невідомі товари пропускаються (
details.skipped_unknown_products). - Ліміт: 10 000 партій у конверті, понад — 422.
- Відповідь:
details = {"batches_upserted", "batches_adopted", "batches_created", "batches_skipped_conflict", "stocks_updated", "stocks_depleted", "skipped_unknown_products"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
warehouse_code_1c | string | так | |
products[].product_code | string | так | external_id товару. |
products[].batches[].external_id | string | так | Ідентифікатор партії. |
products[].batches[].batch_number | string | так | Номер партії. |
products[].batches[].manufacture_date | YYYY-MM-DD | ні | Некоректна дата → 422. |
products[].batches[].expiry_date | YYYY-MM-DD | ні | |
products[].batches[].qty | number/string з крапкою | ні | Відʼємне → 0. |
delete: 422.
stock_document
Документ інвентаризації, який облік передає на портал для перерахунку (ревізії) комірником або аудитором.
- Ключ:
external_id. - Повтор: рядки повністю замінюються, але лише поки документ у статусі
new. Якщо його вже взяли в роботу — 422. - Ліміт: 5000 рядків.
- Відповідь:
details = {"doc_status", "lines_count", "lines_replaced"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
inventory_date | YYYY-MM-DD | так | |
kind | detailed | simple | ні | За замовчуванням detailed (до партій), simple — поштучно. |
warehouse_code_1c | string | ні | Невідомий склад → 422. |
doc_number | string ≤100 | ні | |
doc_type | string ≤200 | ні | |
lines[].product_name | string ≤500 | так | |
lines[].product_code | string ≤200 | так | |
lines[].quantity | number/string з крапкою | так (ключ) | |
lines[].line_number | int | ні | За замовчуванням — позиція. Дубль → 422. |
lines[].product_article, lines[].barcode, lines[].batch_id | string ≤200 | ні | |
lines[].batch_document | string ≤300 | ні | |
lines[].batch_date | YYYY-MM-DD | ні | |
lines[].price | number/string з крапкою | ні |
delete: 422.
excise_marks
Пакет акцизних марок (УІ).
- Ключ: УІ марки (GTIN + серійний номер). Повтор — ідемпотентний.
- Зі складом (
warehouse_code_1c; склад має бути активним і зexcise_enabled) — марки приймаються на склад (in_stock); вже продана марка пропускається. Без складу — нова марка створюється як «видана» (issued), існуюча не змінюється. - Некоректні рядки не валять пакет — потрапляють у
skipped_details(до 50) з причиною. - Товар визначається за GTIN; невідомий GTIN — рядок пропускається.
- Ліміт: 5000 марок.
- Відповідь:
details = {"received", "created", "updated", "skipped", "skipped_details"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
marks | array | так | |
marks[].raw | string ≤200 | так (або gtin+serial) | Сирий вміст DataMatrix. |
marks[].gtin | string ≤14 | так, якщо немає raw | |
marks[].serial | string ≤40 | так, якщо немає raw | |
marks[].origin | string | ні | received (за замовчуванням), local_prod, import, manual. |
warehouse_code_1c | string | ні | Невідомий / без акцизу → 422. |
delete: 422.
11. Продажі й документи руху товару
sale
Факт відвантаження по заявці, створеній на порталі: облік провів реалізацію.
- Пошук заявки (по черзі):
external_idяк UUID заявки порталу →order_number(з payload, інакшеexternal_id) →external_idяк ключ заявки, що прийшла з обліку (logistics_order). Не знайдено → 422. - Заявка переходить у статус «відвантажено» (скасовані й відхилені — ні), фіксується фактична кількість по рядках.
- Клієнт B2B отримує сповіщення лише при першому переході у «відвантажено» — повтор не дублює листи.
- Відповідь:
details = {"lines_matched", "shipped_total"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
order_number | string | ні | Номер заявки порталу, якщо external_id — не UUID. |
sale_number_1c | string ≤64 | ні | Номер реалізації в обліку. |
shipped_at | ISO дата-час | ні | Порожнє — поточний момент. |
shipped_total_amount | decimal з крапкою | ні | Якщо не передано — рахується як Σ(факт × ціна рядка). |
lines[].line_number | int | ні | Номер рядка заявки (пріоритетний спосіб зіставлення). |
lines[].product_code_1c | string | ні | Або код товару / артикул / штрихкод. |
lines[].shipped_quantity | decimal з крапкою | так для рядка | Рядок без нього пропускається. Незіставлені рядки ігноруються. |
goods_document
Документ руху товару: реалізація, повернення, надходження, переміщення, оприходування, списання, відповідальне зберігання. На порталі — розділ «Продажі» і «Документи обліку».
- Ключ:
external_id. - Повтор: шапка оновлюється, рядки повністю замінюються.
- Закритий місяць: документ з датою (новою або вже збереженою) у закритому періоді не змінюється —
200,details.skipped = "period closed". - Посилання (склад, контрагент, точка, торговий, виробник, товар) шукаються мʼяко: не знайдено — зберігаються код і назва з payload. Точка: спершу серед торгових точок, потім серед точок логістики. Документ без торгового зовсім (ні коду, ні ПІБ) ставиться на службового «Віртуального торгового».
- Звʼязок із заявкою порталу — за
order_number. - Ліміт: 2000 рядків.
- Відповідь:
details = {"lines", "unmatched_products"}.
Шапка:
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
doc_type | string | так | sale, sale_return, commission_sale, purchase, custody_withdrawal, purchase_return, transfer, surplus, writeoff, custody_receipt, custody_return_supplier, custody_transfer, custody_return. Інше → 422. |
doc_date | ISO дата-час | рекомендовано | Без зони — Europe/Kyiv. Порожнє — поточний момент. Некоректне → 422. |
doc_number | string ≤32 | ні | |
operation_kind | string ≤80 | ні | Вид операції. |
is_posted | bool | ні | За замовчуванням true. |
warehouse_code, warehouse_to_code | string | ні | external_id складу / складу-отримувача. |
warehouse_name, warehouse_to_name | string ≤200 | ні | |
counterparty_code | string ≤64 | ні | external_id контрагента. |
counterparty_name | string ≤300 | ні | |
client_code_1c | string ≤64 | ні | external_id точки. |
client_name | string ≤300 | ні | |
manufacturer_external_id | string ≤64 | ні | Якщо порожній, а всі рядки одного виробника — виробник підіймається в шапку. |
manufacturer_name | string ≤200 | ні | |
agent_external_id | string ≤64 | ні | |
agent_name | string ≤200 | ні | |
trade_kind | string | ні | Вид торгівлі: cash / noncash / cheque або текст («За готівку», «Безготівковий розрахунок», «Чек»…). |
price_type_code | string ≤32 | ні | |
source_system | string ≤64 | ні | |
base_doc_external_id | string ≤64 | ні | Документ-підстава. |
base_doc_number | string ≤32 | ні | |
order_number | string ≤64 | ні | Номер заявки порталу. |
from_pda | bool | ні | Документ із КПК. |
comment | string ≤2000 | ні | |
doc_barcode | string ≤64 | ні | Порожнє не затирає збережений. |
delivery_interval | string ≤64 | ні | |
trip.number | string ≤32 | ні | Ходка, у яку потрапив документ. |
trip.date, trip.shipping_date | YYYY-MM-DD | ні | За номером і датою відвантаження документ привʼязується до рейсу. |
trip.driver, trip.forwarder | string ≤200 | ні | |
trip.vehicle | string ≤100 | ні | |
trip.router_number | string ≤64 | ні | |
total_amount | decimal | ні | Якщо немає — Σ amount рядків. |
total_no_discount, total_vat | decimal | ні | |
total_weight | decimal | ні | Якщо немає — Σ weight рядків. |
Рядки lines[]:
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
product_code_1c | string ≤64 | рекомендовано | external_id товару (основного каталогу або каталогу логістики). Незнайдений — рядок зберігається з кодом, рахується в unmatched_products. |
quantity | decimal | ні | За замовчуванням 0. |
amount | decimal | ні | Сума рядка, за замовчуванням 0. |
line_no | int | ні | За замовчуванням — позиція. |
product_sku, barcode | string ≤50 | ні | Якщо немає — з картки товару. |
product_name | string ≤300 | ні | |
manufacturer_external_id | string ≤64 | ні | Виробник рядка (якщо відрізняється від шапки). |
packs, pack_coef, price, amount_no_discount, discount_pct, vat_amount, weight, cost | decimal | ні | |
price_type_code | string ≤32 | ні | |
batch_doc_external_id | string ≤64 | ні | |
agent_external_id, agent_name | string | ні | Торговий рядка, якщо відрізняється від шапки. |
delete: документ знімається з обліку (is_posted=false). Невідомий → 200, details.skipped = "unknown document". Закритий період → details.skipped = "period closed".
goods_period
Завершення вигрузки вікна документів руху товару: документи вікна, яких у цій вигрузці не було, знімаються з обліку. Плюс звірка контрольних сум «облік / портал».
- Надсилати останнім, після всіх
goods_documentвікна. - Ключ: немає — кожен конверт створює новий запис звірки.
external_id— довільний. - Знімаються (
is_posted=false) документи вікна з видамиdoc_types, які портал востаннє отримував раніше заstarted_at. Закритий місяць не чіпається. - Звірка рахується по всьому вікну (разом із закритою частиною).
- Відповідь:
details = {"unposted", "closed_until", "run_id"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
date_from, date_to | YYYY-MM-DD | так | Вікно (включно), дні за Europe/Kyiv. |
started_at | ISO дата-час | так | Момент початку вигрузки; без зони — Europe/Kyiv. |
doc_types | array of string | ні | Види документів у вигрузці. Порожній — усі види. |
totals[] | array | ні | Контрольні суми облікової системи по видах: {"doc_type", "docs", "quantity", "amount"}. |
Порада. Тримайте годинник облікової системи синхронізованим (NTP) і передавайте
started_atна кілька хвилин раніше реального старту вигрузки.
12. Борги
debt_reset
Скидання всіх боргів тенанта перед повною вигрузкою відкритих документів: усе, що не прийде після скидання, вважається закритим.
- Видаляє всі документи заборгованості тенанта і обнуляє борг усіх точок.
external_idіpayloadне читаються. - Відповідь:
details.cleared— кількість видалених документів.
Увага. Між скиданням і приходом нових документів борги на порталі нульові. Надсилайте
debt_resetпершим конвертом у тому самому пакеті, що й документи боргу, зpartial: false(атомарно).
debt_document
Відкритий (або закритий) документ заборгованості точки.
- Ключ:
external_id. - Точка (
client_code_1c) потрібна лише при створенні. Якщо точки немає, вона створюється з полівclient_*(і контрагент із полівcounterparty_*, якщо єcounterparty_external_idіcounterparty_name) — тими самими правилами, щоclientіcounterparty. Безclient_name→ 422. - Статус:
statusз payload, інакшеopen, якщоremaining_amount > 0, інакшеclosed. - Термін оплати: якщо облік передав
due_dateпізніше заdoc_date— він головний. Інакше портал рахуєdoc_date + відстрочка, де відстрочка — з регістру «контрагент × виробник» (manufacturer_payment_term), інакше точки, інакше контрагента. - Поля
client_payment_terms_days/counterparty_payment_terms_days(> 0) оновлюють відстрочку вже існуючих точки / контрагента. - Борг точки на порталі перераховується один раз наприкінці пакета.
- Відповідь:
details = {"status", "remaining"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
client_code_1c | string | так при створенні | external_id точки. |
doc_number | string ≤64 | ні | За замовчуванням = external_id. |
doc_type | string ≤30 | ні | За замовчуванням realization. |
doc_date, due_date | YYYY-MM-DD (або ISO дата-час) | ні | Некоректне значення мовчки стає null. |
amount | decimal з крапкою | ні | Сума документа. |
remaining_amount | decimal з крапкою | так при створенні | Залишок боргу. |
status | open | closed | ні | |
currency | string(3) | ні | За замовчуванням UAH. |
payment_form | string ≤20 | ні | Нал / безнал. |
notes | string | ні | |
manufacturer_external_id | string | ні | Борг у розрізі виробника. |
agent_external_id | string | ні | Торговий. |
warehouse_external_id | string | ні | Склад. |
accounting_number | string ≤64 | ні | Бухгалтерський номер. |
warehouse_name, agent_name | string ≤200 | ні | Назви для показу, коли довідник не вивантажено. |
doc_branch_name (або branch_name) | string ≤200 | ні | Назва філії документа. |
client_name | string | для створення точки | |
client_address, client_city, client_phone | string | ні | Для створення точки. |
client_payment_terms_days, client_credit_limit, client_price_list_code, client_latitude, client_longitude | — | ні | Для створення точки / оновлення відстрочки. |
counterparty_external_id, counterparty_name, counterparty_legal_name, counterparty_tax_number, counterparty_edrpou, counterparty_phone, counterparty_email, counterparty_legal_address, counterparty_payment_terms_days | — | ні | Для створення контрагента / оновлення відстрочки. |
delete: документ закривається (status=closed, залишок 0), запис лишається. Немає — 422.
manufacturer_payment_term
Відстрочка платежу контрагента по конкретному виробнику (перекриває загальну відстрочку при розрахунку терміну боргу).
- Ключ: (контрагент
counterparty_external_id, виробникmanufacturer_external_id).external_idзберігається; рекомендований формат"<GUID контрагента>-<код виробника>". - Невідомий контрагент →
200,details.skipped = "counterparty_not_found". Невідомий виробник → 422. - Без виробника (
all_manufacturers: trueабо порожнійmanufacturer_external_id) — це одна відстрочка на всіх виробників: записується як відстрочка контрагента;details.counterparty_payment_terms_days. - Мʼяко видалений рядок оживає при наступному upsert.
- Відповідь:
details.days.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
counterparty_external_id | string | так | |
manufacturer_external_id | string | так (або all_manufacturers) | |
all_manufacturers | bool | ні | |
days | int ≥0 | так при створенні | 7, "7,0". Відʼємне або некоректне → 422. |
delete: за парою ключів або (без ключів) за external_id; мʼяке видалення; немає — 422. Для all_manufacturers — details.skipped = "all_manufacturers_delete_ignored".
13. Каса
cash_document
Грошовий документ: прибутковий / видатковий касовий ордер, банківська виписка.
- Ключ:
external_id. Повтор — upsert. - Напрям визначається видом:
cash_in,bank_in— надходження;cash_out,bank_out— витрата. Сума зберігається за модулем. - Посилання (контрагент, точка, торговий, виробник) — мʼякі, як у
goods_document. - Закритого місяця для каси немає.
- Відповідь:
details = {"doc_type", "direction"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
doc_type | string | так | cash_in, cash_out, bank_in, bank_out. Інше → 422. |
doc_date | ISO дата-час | рекомендовано | Без зони — Europe/Kyiv. |
doc_number | string ≤32 | ні | |
amount | decimal (кома допустима) | ні | |
is_posted | bool | ні | За замовчуванням true. |
operation_kind | string ≤80 | ні | |
cash_kind | string | ні | cash/noncash або «Наличные»/«Готівка»/«Безготівкові»; за замовчуванням з виду документа. |
account_code | string ≤64 | ні | Каса / рахунок. |
account_name | string ≤200 | ні | |
account_kind | bank | cashbox | ні | За замовчуванням з виду документа. |
cashflow_item | string ≤200 | ні | Стаття руху коштів. |
branch_name | string ≤200 | ні | |
counterparty_code, counterparty_name | string | ні | |
client_code_1c, client_name | string | ні | |
agent_external_id, agent_name | string | ні | |
manufacturer_external_id, manufacturer_name | string | ні | |
responsible | string ≤200 | ні | |
base_doc_number | string ≤64 | ні | |
comment | string ≤2000 | ні |
delete: is_posted=false; невідомий → 200, details.skipped = "unknown document".
cash_balance
Залишок коштів по касі / рахунку на дату вигрузки.
- Ключ: (
account_code, вид коштів).external_idне використовується. - Відповідь:
details.balance.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
account_code | string ≤64 | так | |
account_name | string ≤200 | ні | |
account_kind | bank | cashbox | ні | |
cash_kind | string | ні | Як у cash_document. |
branch_name | string ≤200 | ні | |
balance | decimal (кома допустима) | ні | За замовчуванням 0. |
as_of | YYYY-MM-DD | ні | За замовчуванням — сьогодні за Europe/Kyiv. |
delete: рядок видаляється; details.deleted.
cash_period
Завершення вигрузки вікна каси: документи вікна, не отримані в цій вигрузці (востаннє отримані раніше за started_at), знімаються з обліку. Надсилати останнім.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
date_from, date_to | YYYY-MM-DD | так | Вікно включно, за Europe/Kyiv. |
started_at | ISO дата-час | так | Без зони — Europe/Kyiv. |
Відповідь: details.unposted. На відміну від goods_period, фільтра за видами документів і захисту закритого місяця немає.
14. Стан заявок порталу в обліку
Заявка порталу потрапляє в облік як непроведений документ. Облік повідомляє про його стан; видалення документа в обліку скасовує заявку на порталі (з повідомленням торговому, керівникам і клієнту B2B). Назад в облік скасування не передається.
order_state
- Пошук заявки:
external_id→ ідентифікатор документа в обліку, отриманий порталом при підтвердженні заявки; абоorder_number. Заявки логістики не розглядаються. Не знайдено →200,details.skipped = "unknown order". deleted: true→ заявку скасовано (якщо вона в статусі, який можна скасувати). Розпроведення без видалення заявку не скасовує — стан лише запамʼятовується.- Відповідь:
details.cancelled.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
order_number | string ≤32 | ні | Номер заявки порталу. |
posted | bool | ні | Документ проведено. |
deleted | bool | ні | Документ видалено / позначено на видалення. |
reason, reason_comment | string | ні | Причина видалення; разом ≤200 символів, потрапляє в причину скасування. |
order_state_period
Кінець списку станів: заявки, передані в облік у вікні, по яких у цій вигрузці не прийшло order_state, вважаються видаленими повністю й скасовуються.
- Розглядаються заявки, підтверджені обліком у проміжку від
date_from+ 1 день доstarted_at− 2 години, які не отримувалиorder_stateпісляstarted_at. count <= 0→ нічого не скасовується (details.skipped = "empty list") — захист від збою запиту в обліку.- У батчі: якщо хоча б один
order_stateу цьому ж батчі не прийнято,order_state_periodвідхиляється (щоб не скасувати заявки, чий стан не записався). - Відповідь:
details.cancelled.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
date_from | ISO дата / дата-час | так | Початок вікна; без зони — Europe/Kyiv. |
started_at | ISO дата-час | так | Початок вигрузки списку. |
count | int | так | Кількість order_state у списку. |
15. Рейси (ходки)
trip
Ходка обліку. Має два режими залежно від наявності payload.number.
Режим «рейс» (є number, а також для будь-якого delete) — ходка стає рейсом на порталі.
- Ключ:
external_id. Якщо рейс не знайдено, але переданоrouter_number— шукається рейс, створений на порталі й переданий в облік (щоб не завести дубль). - Повтор: рейс з обліку перебудовується: водій, авто, статус, склад документів і заявок — за payload. Рейс, зібраний на порталі, облік лише доповнює (порожні поля, статус тільки вперед, точки додаються).
- Номер рейсу на порталі унікальний: при збігу додається суфікс з датою.
- Статус: дата в минулому — «завершено»; сьогодні — «в дорозі» (
shipped) або «завантажено»; майбутня — «збирається» (за Europe/Kyiv). - Водій / експедитор поза списком обміну (
transport_list) або невідомий → «Не визначено»;pickup: trueбез авто → «Самовивіз». - Документи (
document_external_id) і заявки (order_number) привʼязуються до рейсу; ті, що вже в іншому рейсі, не забираються. Документи, що прийдуть пізніше, допривʼяжуться за номером ходки й датою відвантаження (goods_document.trip). - Кілометраж рахується дорогами по точках;
distance_kmз обліку зберігається для звірки й використовується, лише якщо маршрут побудувати не вдалося. - Відповідь:
details = {"created", "distance_km", "trip_number", "documents", "documents_pending", "orders"}(+driver: "not_found").
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
number | string ≤30 | так (ознака режиму) | Номер ходки. |
date | YYYY-MM-DD / ISO | так (або doc_date) | Дата відвантаження. Без дати → 422. |
doc_date | дата | ні | Дата документа. |
driver_external_id, forwarder_external_id | string | ні | |
vehicle_external_id | string | ні | Лише активне авто. |
driver, vehicle, forwarder | string ≤200 | ні | Назви рядком (для показу). |
shipped | bool | ні | Відвантажено. |
pickup | bool | ні | Самовивіз. |
weight | any | ні | Довідково. |
comment | string ≤2000 | ні | |
router_number | string | ні | Номер рейсу порталу, переданого в облік. |
distance_km | number | ні | Кілометраж з обліку. |
points[].document_external_id | string | ні | external_id документа руху товару. |
points[].order_number | string | ні | Номер заявки порталу. |
points[].position | int | ні | Порядок обʼїзду; за замовчуванням — позиція. |
points[].weight | decimal | ні | Вага накладної, якщо документ прийшов без ваги. |
delete: рейс скасовується, документи й заявки відчіплюються. Не знайдено → 200, details.skipped = "trip_not_found".
Режим «призначення водія» (немає number) — лише проставляє водія заявкам порталу, статуси не змінює.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
driver_external_id | string | так | Невідомий водій → 422. |
vehicle | string ≤200 | ні | Авто водія рядком. |
date | дата | ні | Інформативно. |
points[].order_number | string | так для рядка | Ненайдені номери — у details.orders_not_found (до 50), не помилка. |
Відповідь: details = {"assigned", "orders_not_found"}.
16. Модуль логістики
Модуль логістики (3PL-доставка для виробників) має власні довідники й каталог, незалежні від торгового контуру.
logistics_order
Заявка на доставку, створена в обліку: на порталі одразу підтверджена й видима на дошці рейсів. Відвантаження по ній — звичайний sale з тим самим external_id.
- Ключ:
external_idсеред заявок, що прийшли з облікової системи. - Повтор: заявка не перестворюється (
details.skipped = "already imported"); заявка вже в рейсі чи далі —details.skipped = "status=…". - Заявка оформлюється на віртуального B2B-торгового філії, інакше — на першого активного адміністратора; немає жодного → 422.
- Відповідь:
details = {"order_number", "lines", "missed_products"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
client_code_1c (або client_code) | string | так | Невідома точка → 422. |
lines[] | array | так | Порожній → 422. |
lines[].product_code_1c / sku / barcode | string | так | Товар шукається за кодом, артикулом або штрихкодом. Нерозпізнані — у missed_products; жодного не розпізнано → 422. |
lines[].quantity | decimal з крапкою | так | ≤0 — рядок пропускається. |
lines[].unit_price | decimal з крапкою | ні | |
requested_delivery_date | YYYY-MM-DD | ні | |
currency | string | ні | За замовчуванням UAH. |
notes | string | ні |
delete: скасування, якщо заявка ще в статусі «нова» / «підтверджена» і не в рейсі; інакше details.skipped. Немає — 422.
logistics_manufacturer
Виробник торгового довідника з позначкою «логістика». Поля, ключ і delete — як у manufacturer; при upsert додатково ставиться позначка логістики.
logistics_own_manufacturer
Виробник модуля логістики. Ключ: external_id (спільний довідник виробників).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | |
code | string ≤100 | ні | |
tax_number | string ≤20 | ні | |
edrpou | string | ні | Якщо немає tax_number — пишеться в нього (за ним розпізнаються файли замовлень). |
ship_warehouse_external_id | string | ні | Склад відвантаження. |
import_template_key | string ≤40 | ні | Шаблон імпорту файлів замовлень. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
logistics_counterparty
Контрагент логістики. Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤500 | так при створенні | |
code | string ≤100 | ні | |
tax_number | string ≤50 | ні | |
edrpou | string ≤20 | ні | |
phone | string ≤100 | ні | |
email | string ≤200 | ні | |
legal_address | string ≤500 | ні | |
external_codes | array | ні | Як у counterparty. |
price_list_code | string | ні | Прайс; створюється, якщо немає. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
logistics_point
Точка доставки логістики. Ключ: external_id. При створенні допривʼязує документи руху товару, що прийшли раніше з цим кодом точки.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
counterparty_external_id | string | так | logistics_counterparty; невідомий → 422. |
name | string ≤500 | так при створенні | |
code | string ≤100 | ні | |
gln | string ≤64 | ні | GLN — за ним розпізнаються файли замовлень. |
phone | string ≤100 | ні | |
address | string ≤500 | ні | |
city | string ≤200 | ні | |
direction | string ≤150 | ні | Напрямок; також копіюється в торгову точку з тим самим кодом, якщо вона є. |
external_codes | array | ні | Як у client. |
latitude, longitude | number з крапкою | ні | Якщо передано (і точку не виправляли вручну) — перезаписують координати. Лише крапка як десятковий роздільник. |
price_list_code | string | ні | |
is_active | bool | ні |
delete: is_active=false; немає — 422.
logistics_warehouse
Склад модуля логістики (той самий довідник складів, з позначкою «логістика»). Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | |
address | string ≤1000 | ні | |
is_active | bool | ні |
delete: is_active=false; немає — 422. Спершу передайте branch.
logistics_product_category
Категорія каталогу логістики. Ключ: external_id.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤200 | так при створенні | |
code | string ≤50 | ні | |
description | string ≤2000 | ні | |
image_url | string ≤1000 | ні | |
parent_external_id | string | ні | Невідомий батько → звʼязок порожній (без помилки). |
is_active | bool | ні |
delete: is_active=false; немає — 422.
logistics_product
Товар каталогу логістики. Ключ: external_id. Новий штрихкод без фото — у чергу збагачення.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string ≤300 | так при створенні | |
code_1c | string ≤50 | ні | Код товару (запасний ключ для logistics_stock). |
sku, manufacturer_code, barcode, unit_barcode | string ≤50 | ні | |
unit | string ≤20 | ні | |
brand | string ≤100 | ні | |
category_1c | string ≤200 | ні | |
kind_1c | string ≤100 | ні | |
description | string ≤4000 | ні | |
image_url, image_thumbnail_url | string ≤1000 | ні | |
pack_size | int | ні | Мінімум 1. |
weight_kg, volume_liters, base_price | decimal (кома допустима) | ні | |
vat_rate | decimal | ні | Порожнє — 20. |
is_excisable | bool | ні | |
dimensions, attributes | object | ні | Зберігаються як є. |
category_external_id | string | ні | logistics_product_category. |
manufacturer_external_id | string | ні | Виробник. |
is_active | bool | ні |
delete: is_active=false; немає — 422.
logistics_product_code
Код товару логістики в мережі.
- Ключ: (товар
product_external_id— за замовчуваннямexternal_idконверта;kind_external_id). - Товару немає → 422.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
product_external_id | string | ні | За замовчуванням — external_id. |
kind_external_id | string ≤200 | так | |
code | string ≤200 | так | Навіть для delete. |
kind_name | string ≤300 | ні |
delete: рядок видаляється.
logistics_stock
Знімок залишків складу логістики. Аналог product_stock над каталогом логістики.
- Склад має бути активним і саме складом логістики, інакше 422.
- Товар шукається за
external_idтовару логістики, запасний варіант — йогоcode_1c. - Частина невідомих кодів — допустимо (
details.unknown_products); жодного знайденого → 422 (захист від обнулення складу через неправильне поле). - Повна заміна з обнуленням відсутніх + денний зріз за сьогодні.
- Відповідь:
details = {"upserted", "depleted", "unknown_products", "unknown_sample"}.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
warehouse_code_1c | string | так | |
items[].product_code_1c | string | так | |
items[].qty | number/string з крапкою | ні |
delete: 422.
17. Приклади конвертів
Готові батчі: examples/exchange-inbound-batch-catalog.json, examples/exchange-inbound-batch-stock.json, examples/exchange-inbound-batch-sales.json.
client
{
"entity_type": "client",
"operation": "upsert",
"external_id": "5c1e8a20-4b7f-11ee-9d3c-0050569a1b2c",
"payload": {
"name": "Маркет «Колосок»",
"legal_name": "ФОП Петренко О. В.",
"address": "вул. Шевченка, 12",
"city": "Полтава",
"region": "Полтавська",
"phone": "+380671234567",
"channel": "Традиційна торгівля",
"counterparty_external_id": "7a2d4f10-4b7f-11ee-9d3c-0050569a1b2c",
"price_list_code": "000000002",
"payment_terms_days": "14",
"credit_limit": "25000.00",
"external_codes": [{"kind": "GLN", "code": "4820000123456"}],
"latitude": "49.5883",
"longitude": "34.5514"
}
}product
{
"entity_type": "product",
"operation": "upsert",
"external_id": "b3f61c42-4b7f-11ee-9d3c-0050569a1b2c",
"payload": {
"name": "Сік яблучний 1 л",
"sku": "JA-1000",
"barcode": "4820017000123",
"unit": "шт",
"base_price": "18.50",
"vat_rate": 20,
"manufacturer_external_id": "000000017",
"manufacturer": "ТОВ «Сади Приклад»",
"category_code_1c": "c9d02e11-4b7f-11ee-9d3c-0050569a1b2c",
"pack_size": 6,
"weight_kg": "1.1",
"is_active": true
}
}price_list_item
{
"entity_type": "price_list_item",
"operation": "upsert",
"external_id": "000000002:b3f61c42-4b7f-11ee-9d3c-0050569a1b2c",
"payload": {
"price_list_code": "000000002",
"product_code_1c": "b3f61c42-4b7f-11ee-9d3c-0050569a1b2c",
"price": "17.90"
}
}counterparty
{
"entity_type": "counterparty",
"operation": "upsert",
"external_id": "7a2d4f10-4b7f-11ee-9d3c-0050569a1b2c",
"payload": {
"name": "ФОП Петренко Олена Василівна",
"kind": "buyer",
"edrpou": "3012345678",
"tax_number": "3012345678",
"legal_address": "м. Полтава, вул. Шевченка, 12",
"payment_terms_days": 7,
"is_group": false,
"parent_external_id": "1e44a9b0-4b7f-11ee-9d3c-0050569a1b2c",
"is_active": true
}
}goods_document
{
"entity_type": "goods_document",
"operation": "upsert",
"external_id": "e7a1c3d5-6f80-11ef-8a1b-0050569a1b2c",
"payload": {
"doc_type": "sale",
"doc_number": "РН-0004512",
"doc_date": "2026-10-26T14:35:00",
"warehouse_code": "2f6c9e30-4b7f-11ee-9d3c-0050569a1b2c",
"client_code_1c": "5c1e8a20-4b7f-11ee-9d3c-0050569a1b2c",
"client_name": "Маркет «Колосок»",
"counterparty_code": "7a2d4f10-4b7f-11ee-9d3c-0050569a1b2c",
"agent_external_id": "a8b9c0d1-4b7f-11ee-9d3c-0050569a1b2c",
"agent_name": "Іваненко Ігор",
"manufacturer_external_id": "000000017",
"trade_kind": "Безготівковий розрахунок",
"order_number": "ORD-20261026-0042",
"lines": [
{"line_no": 1, "product_code_1c": "b3f61c42-4b7f-11ee-9d3c-0050569a1b2c", "quantity": "24", "price": "17,90", "amount": "429,60"}
]
}
}product_stock
{
"entity_type": "product_stock",
"operation": "upsert",
"external_id": "2f6c9e30-4b7f-11ee-9d3c-0050569a1b2c",
"payload": {
"warehouse_code_1c": "2f6c9e30-4b7f-11ee-9d3c-0050569a1b2c",
"items": [
{"product_code_1c": "b3f61c42-4b7f-11ee-9d3c-0050569a1b2c", "qty": "1320", "amount": "19140.00"},
{"product_code_1c": "b3f61c43-4b7f-11ee-9d3c-0050569a1b2c", "qty": "0"}
]
}
}debt_document
{
"entity_type": "debt_document",
"operation": "upsert",
"external_id": "d2c4e6f8-6f80-11ef-8a1b-0050569a1b2c",
"payload": {
"client_code_1c": "5c1e8a20-4b7f-11ee-9d3c-0050569a1b2c",
"client_name": "Маркет «Колосок»",
"doc_number": "РН-0004512",
"doc_type": "realization",
"doc_date": "2026-10-26",
"due_date": "2026-10-26",
"amount": "429.60",
"remaining_amount": "429.60",
"payment_form": "безнал",
"manufacturer_external_id": "000000017",
"agent_external_id": "a8b9c0d1-4b7f-11ee-9d3c-0050569a1b2c"
}
}order_state
{
"entity_type": "order_state",
"operation": "upsert",
"external_id": "f1e2d3c4-6f80-11ef-8a1b-0050569a1b2c",
"payload": {
"order_number": "ORD-20261026-0042",
"posted": false,
"deleted": true,
"reason": "Клієнт відмовився"
}
}