[ВАШ САБДОМЕН] — субдомен вашої компанії в Marchroute. Точну адресу з уже підставленим субдоменом видно у вашій CRM: Налаштування → Модулі → API → Документація.
Авторизація
Запити авторизуються API-токеном у заголовку. Токен створюється у вкладці «API ключі» і показується лише один раз.
Заголовок
Authorization: Bearer YOUR_API_TOKEN
Кожен токен має набір scopes (доступів). Ендпоінт перевіряє, що токен містить потрібний scope — інакше повертається 403 Insufficient scope.
Scope
Опис
products:sync
Синхронізація товарів і категорій із зовнішньої системи
orders:create
Створення замовлень і операції з клієнтом
payments:manage
Обробка оплат із магазину
person:auth
Авторизація клієнтів магазину та видача їм токенів авторизації
data:read
Доступ тільки на читання (Export API)
Маршрути кабінету контрагента (/person*) використовують токен контрагента, а не API-токен інтеграції.
Термін дії та помилки авторизації
Ключ може бути безстроковим або мати дату завершення (за замовчуванням — 90 днів). Після цієї дати всі запити з ним отримують 401. Причину відмови завжди видно з поля error — його і слід перевіряти в інтеграції, а не текст message. Той самий код дублюється в заголовку WWW-Authenticate.
HTTP
error
Коли виникає
401
missing_token
Заголовок Authorization: Bearer відсутній або порожній
401
invalid_token
Токен не знайдено: неправильний або відкликаний (видалений) ключ
401
token_expired
Термін дії ключа сплив. У відповіді додається expired_at — точний час завершення
403
insufficient_scope
Ключ дійсний, але не має потрібного доступу. У відповіді: required_scopes, token_scopes, missing_scopes
401 — токен прострочений
{
"message": "Token has expired.",
"error": "token_expired",
"error_message": "Термін дії токена сплив, створіть новий ключ у налаштуваннях API.",
"expired_at": "2026-07-01T10:15:00+03:00"
}
Прострочений ключ не можна продовжити — створіть новий у вкладці «API ключі» та замініть його в інтеграції
Товари та категорії
Спершу — хто є хто. У CRM три сутності навколо товару, читайте зверху вниз:
• Виробник — «чий товар». Кожен товар має vendor_id.
• Постачальник — «хто відвантажує замовлення». Повʼязаний з виробниками (багато-до-багатьох, у звʼязки є position — пріоритет). Саме по постачальниках CRM розподіляє замовлення.
• Склад — фізичний склад CRM. Склад має власного службового постачальника: якщо замовлення розподілилось на нього — відвантаження йде зі складу. Такого постачальника видно за полем warehouse_id.
Розподіл замовлення (спрощено): товари кошика → їх виробники → постачальник, повʼязаний з цими виробниками. Повна механіка з прикладами — у POST /order, блок «Розподіл по постачальниках».
Модель даних
Товар (vendor_id)
└─ Виробник — чий товар ..................... GET /vendors
└─ Постачальник — хто відвантажує ...... GET /suppliers
├─ без складу = віртуальний склад (відправляє контрагент)
└─ складський (має warehouse_id)
└─ Склад CRM ................. GET /warehouses
GET/api/v1/warehouses
Довідник складів
Список активних складів CRM. Для кожного складу: його службовий постачальник (supplier_id), виробники цього постачальника (vendors) і уточнюючі параметри (clarifications). Навіщо clarifications: коли виробник повʼязаний з КІЛЬКОМА складськими постачальниками, серед них треба обрати один — перемагає склад, чиї clarifications збігаються із замовленням (його організацією, товаром або категорією товару). Немає збігу — перший складський: фізичний склад завжди пріоритетніший за віртуальний, віртуальний обирається лише коли складських постачальників у виробника немає.
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
id
integer
—
query
Один конкретний склад за ID
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/warehouses" \
-H "Authorization: Bearer YOUR_API_TOKEN"
supplier_id — службовий постачальник складу (null, якщо складу ще не призначали виробників/відправку). Це той самий id, що й у GET /vendors → suppliers[].id.
vendors[] — виробники, чиї замовлення можуть відвантажуватись з цього складу.
clarifications[] — уточнюючі параметри: type = organization | product | category, value = id відповідної сутності. Порожній масив — склад без уточнень (обирається за position).
GET/api/v1/vendors
Довідник виробників
Список виробників (id + назва) із масивом постачальників, з якими пов’язаний виробник. id виробника передається у товар як vendor_id під час синхронізації (POST /products). Постачальник із warehouse_id — «складський»: замовлення, розподілене на нього, відвантажується зі складу.
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
name
string
—
query
Частковий збіг за назвою
id
integer
—
query
Один конкретний виробник за ID
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/vendors" \
-H "Authorization: Bearer YOUR_API_TOKEN"
suppliers[] — постачальники, пов’язані з цим виробником (порожній масив, якщо звʼязків немає).
warehouse_id — id складу, якщо постачальник складський. null — постачальник без складу, тобто ВІРТУАЛЬНИЙ СКЛАД: замовлення відвантажує сам постачальник зі свого боку, фізичний склад CRM у русі товару не бере участі.
is_clarification — склад постачальника має уточнюючі параметри розподілу (див. GET /warehouses): при кількох рівнозначних постачальниках виробника замовлення піде на склад, що збігся за параметрами.
GET/api/v1/categories
Довідник категорій
Плоский список категорій (id, назва, inner_id) із зазначенням батьківської категорії, з пагінацією. Без вкладеності — ієрархія відновлюється за parent_id / parent.inner_id на боці клієнта.
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
name
string
—
query
Частковий збіг за назвою
inner_id
string
—
query
Частковий збіг за inner_id
page
integer
—
query
Номер сторінки (за замовч. 1)
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/categories" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Пагінація: до 30 категорій на сторінку, параметр page.
parent_id — id батьківської категорії у CRM (null для кореневих).
parent — коротка інформація про батька ({ id, name, inner_id }) або null.
GET/api/v1/product
Отримати інформацію про товар
Повертає товар з усіма зв’язками: категорії, виробник, додатки, характеристики, варіації та набір знижок. Потрібно передати або id (внутрішній id CRM), або inner_id (зовнішній). id має пріоритет, якщо передані обидва. Опис полів товару — див. нижче в POST /products.
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
id
integer
—
query
Внутрішній id товару в CRM
inner_id
string
—
query
Зовнішній inner_id товару
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/product" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Потрібен щонайменше один із параметрів (id або inner_id), інакше — 422.
404, якщо товар не знайдено.
custom_fields — обʼєкт кастомних полів {code: value}; довідник полів ведеться у картці товару CRM (Розширені налаштування). Варіанти (variations_parameters[]) мають власні custom_fields з тим самим довідником.
collection — присутнє лише якщо товар входить у колекцію кольорів (категорія type="collection"): id/назва колекції, parent_id (категорія-батько) і colors[] — усі товари-кольори колекції.
POST/api/v1/products
Синхронізувати товари (upsert за inner_id)
Приймає один товар або масив товарів. Ключ upsert — inner_id (string; число приймається і тихо приводиться до рядка). Назва декодується з HTML-entity. vendor_id привʼязує товар до виробника напряму (id з GET /vendors). category_id прив’язує до категорії за внутрішнім id CRM; category_inner_id — за зовнішнім inner_id категорії (пріоритет у category_id, якщо передані обидва).
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
inner_id
string
так
тіло
Зовнішній унікальний ID, ключ upsert (число приймається і приводиться до рядка)
name
string
так
тіло
Назва товару
price
numeric
так
тіло
Ціна
cost
numeric
—
тіло
Собівартість
description
string
—
тіло
Опис
sku
string
—
тіло
Артикул
vendor_sku
string
—
тіло
Артикул постачальника
uktzed
string
—
тіло
Код УКТЗЕД
vendor_id
integer
—
тіло
ID виробника (з GET /vendors). Привʼязує товар до виробника напряму
category_id
integer
—
тіло
Внутрішній id категорії в CRM (з GET /categories)
category_inner_id
string
—
тіло
Зовнішній inner_id категорії (як раніше працював category_id)
availability_days
integer
—
тіло
Середня кількість днів до появи товару в доступі
max_installment_months
integer
—
тіло
Максимум місяців розстрочки для товару; у замовленні береться мінімум серед товарів
url
string
—
тіло
URL товару
url_image
string
—
тіло
URL зображення для синхронізації
document_name
string
—
тіло
Назва для документів
custom_fields
object
—
тіло
Кастомні поля товару {code: value}. Точковий merge: передані ключі перекривають, решта зберігається
name_print
string
—
тіло
Назва кольору/принту — реальне поле товару, підпис кольору в колекції
prepayment
numeric
—
тіло
Передоплата: сума або відсоток (див. prepayment_is_percent)
Логіка звʼязків між SKU: зміна ціни / показ-приховування (див. details)
additionals
array
—
тіло
Додаткові товари
discount_set
array
—
тіло
Опис набору/знижки
Додаткова інформація
dimensions — габарити (валідуються)
Масив габаритів. Це єдиний масив місць: кожен елемент означає конкретне місце weight (кг), length (см), width (см), height (см) (усі numeric > 0) та hand (boolean. Показує, чи товар потребує ручної обробки на пошті). Зазвичай передають одне місце.
Масив варіацій. Елемент без sku або name пропускається. options[] — значення варіації; кожне без sku/name теж пропускається. Примітка: опція з name "Немає" вважається порожнім значенням — у назві товару в документах вона не виводиться.
value_type — як трактувати price/cost опції: "default" (за замовч.) — надбавка до базової, "procent" — відсоток від базової, "absolute" — фіксоване значення замість базової.
sku_mode — як артикул опції формує артикул варіанта: "append" (за замовч.) — приклеюється до артикула варіації (ST-1 + RED), "replace" — артикул варіанта буде саме таким, як задано в опції (без базового).
Уточнення для конкретної комбінації варіацій. Ідентифікується через original_sku АБО variation_by_text (інакше елемент пропускається). Поля price/cost/active застосовуються лише якщо передані; dimensions нормалізуються.
original_sku — згенерований артикул комбінації (базовий артикул товару + артикули опцій), він же ключ зіставлення.
sku — переозначення артикула варіанта: підсумковий артикул саме такий, як задано (повна заміна original_sku). Порожній sku = переозначення немає, діє original_sku. Правило «додавати до базового чи задавати повністю» налаштовується на рівні опції варіації (sku_mode в options[]).
Увага: при зміні базового артикула товару комбінації перегенеруються з новими original_sku, тож переозначення, надіслані зі старим original_sku, не зіставляться і зникнуть — надсилайте variations_params уже з новими original_sku.
url_image — картинка конкретного варіанта (як в опцій): порожнє значення знімає її. Пріоритет показу: власна картинка варіанта → картинка опції комбінації → картинка товару.
custom_fields — кастомні змінні варіанта {code: value}, довідник полів спільний з товаром. Якщо поля з таким code ще немає в довіднику — значення однаково збережеться, але колонкою в редакторі воно зʼявиться лише після створення поля (розділ «Кастомні поля» товару).
display_logic — логіка звʼязків між SKU (ціна / показ)
Масив правил звʼязку двох SKU (опцій або додаткових товарів товару) — sku_a (тригер) і sku_b (ціль). Кожне правило має тип type:
• type="price" — якщо клієнт обрав sku_a, ціна цілі sku_b перераховується за полем price (форматом «формула ціни»). Не змінює базову ціну sku_b, поки тригер не активний.
• type="show" — якщо обрано sku_a, ціль sku_b показується; якщо тригер не обрано — sku_b приховується (керує видимістю опції в калькуляторі товару).
Правила застосовуються по черзі. price-формула: «200» → +200 до ціни sku_b; «-200» → -200; «20%» → +20% до ціни sku_b (мінус-відсоток теж працює через знак у числі перед %). Тобто це дельта до поточної ціни цілі, а не нова ціна. sku_a/sku_b — це sku конкретних опцій/додаткових товарів цього ж товару.
Один об’єкт (не масив). Створює бандл: товар отримує type="bundle". products[] — масив inner_id товарів набору (резолвляться у локальні id, відсутні ігноруються). value/is_percent/name визначають знижку (name за замовч. = назва товару).
{
"processed_count": 2,
"processed": [
1001,
1002
],
"is_failed": true,
"failed": [
{
"data": 1003,
"error": {
"price": [
"The price field is required."
]
}
}
]
}
Тіло може бути як одним об’єктом товару, так і масивом об’єктів.
inner_id — рядок; число приймається і тихо приводиться до string.
custom_fields — обʼєкт {code: value}; значення читаються назад у GET /product як custom_fields. Merge точковий: передані ключі перекривають, непередані значення зберігаються. Плоскі url_print/code_print застарілі й мапляться в custom_fields автоматично; name_print — знову реальне поле товару (іде напряму).
Категорія: category_id — за внутрішнім id CRM (з GET /categories); category_inner_id — за зовнішнім inner_id. Якщо передані обидва — використовується category_id. Невідома категорія → товар потрапляє у failed.
У failed[].error для помилок валідації — об’єкт {поле: [помилки]}, а для винятку — рядок повідомлення; failed[].data містить inner_id, name або "N/A".
POST/api/v1/products/refresh
Позначити застарілі товари
Позначає товари з джерела API, які не оновлювалися понад тиждень, як застарілі та відв’язує їхні категорії. Тіло не читається.
Scope: products:sync
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/products/refresh" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Масив категорій. Батьки прив’язуються через inner_parent_id (0 = корінь). Обов’язкові лише inner_id і name — решта полів мають значення за замовчуванням.
Scope: products:sync
Поле
Тип
Обов.
Де
Опис
inner_id
string
так
тіло
Зовнішній унікальний ID, ключ upsert (число приймається і приводиться до рядка)
name
string
так
тіло
Назва
type
string
—
тіло
Тип (category/collection). Не передали — category (в існуючої категорії тип не змінюється)
inner_parent_id
string
—
тіло
Зовнішній ID батька (0 або відсутній = корінь; число приймається і приводиться до рядка)
img
string
—
тіло
URL зображення
icon
string
—
тіло
Код іконки з довідника (кнопка «Іконки категорій» нижче). CRM показує іконку лише в категорій верхнього рівня
order_index
string
—
тіло
Порядок сортування
Додаткова інформація
type — колекції кольорів (type="collection")
Колекція — особлива категорія, що обʼєднує пов’язані товари (кольори/принти одного виробу) зі спільними характеристиками.
• Кожен колір — окремий повноцінний товар зі своїми name, sku, inner_id, ціною та фото; у колекцію він потрапляє звичайною прив’язкою до цієї категорії (category_id / category_inner_id при синку товару).
• name_print товару — підпис кольору (показується на картці кольору в CRM).
• У списку товарів CRM колекція показується одним рядком (товар-представник із бейджем «Колекція»); пошук знаходить будь-який колір, але відкриває колекцію цілком. У редакторі всі кольори редагуються разом: спільні поля — фолбек, перевизначення — на конкретному кольорі.
• Ціна в списку показується лише коли вона однакова у всіх кольорів.
• Колекції не зʼявляються в дереві каталогу як категорії — це технічне групування.
• Файловий імпорт/експорт: колонка collection_key — рядки з однаковим значенням збираються в колекцію (значення стає її назвою); товар живе лише в одній колекції — інша прив’язка знімається.
Частковий upsert: поля, не передані в елементі, в існуючої категорії не змінюються (зокрема type і батько).
Порожнє тіло → 400 { "error": "No categories provided" }.
Обробка поелементна, відповідь завжди 200 (крім порожнього тіла). category у відповіді — повний об’єкт категорії.
Невалідний елемент: { message: "Validation failed", category: <inner_id>, error: {...} }. Якщо inner_parent_id≠0, а батька не знайдено: { message: "Parent category not found", category: {...} } (елемент пропускається).
Замовлення
Порядок роботи: спочатку довідники (способи доставки, події, знижки) — їх id передаються при створенні замовлення. Головний ендпоінт розділу — POST /order: у відповідь приходить створене замовлення (201) або, у двокроковому сценарії підтвердження, 202 з order_hash — тоді оформлення завершується через POST /order/confirm.
Після створення замовлення живе у воронці CRM: PUT /order/{id} оновлює поля, PUT /order/{id}/events/{code} рухає його подіями, GET /order/{id} і /history читають стан.
Життєвий цикл замовлення
Довідники: /events · /delivery/types · /pickup/points · /discount/types
│
POST /order ────────────────────────────► 201 створено (+ auth-токен клієнта)
│ is_need_confirm=true, клієнт існує, запит без auth
▼
202 order_hash ──► POST /order/confirm ──► 201 створено
Далі: GET /order/{id} · GET /order/{id}/history — читання
PUT /order/{id} — оновлення (організація, знижка, склад/постачальник)
PUT /order/{id}/events/{code} — рух по воронці
DELETE /person/{person_id}/order/{id} — скасування клієнтом
GET/api/v1/organizations
Довідник організацій
Усі організації з рахунками та способами оплати. Відповідь — масив організацій. Опціональний пошук за назвою через query-параметр name.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
name
string
—
query
Пошук за назвою організації (часткове співпадіння)
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/organizations" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Блок клієнта. Можна не передавати — замовлення створиться без клієнта (person_id: null) з warning.
person.id
integer
—
тіло
ID наявного клієнта CRM. Перекриває пошук за phone/email — замовлення привʼязується саме до цього клієнта. Немає такого id → ідентифікатор ігнорується, warning. Не збігається з клієнтом auth-токена → auth ігнорується, warning.
person.phone
string
—
тіло
Телефон клієнта. Невалідний формат не валить запит: телефон відкидається з warning.
person.email
string
—
тіло
Email клієнта. Невалідний формат не валить запит: email відкидається з warning.
person.f_name
string
—
тіло
Ім’я
person.l_name
string
—
тіло
Прізвище
person.m_name
string
—
тіло
По батькові
person.password
string(4-128)
—
тіло
Пароль акаунта (опц.)
address
object
—
тіло
Блок адреси доставки. Можна не передавати — тоді береться спосіб доставки за замовчуванням без адреси
address.id
integer
—
тіло
ID наявної адреси CRM. Перекриває побудову адреси з решти полів блоку (delivery_id/location/params ігноруються). Немає такого id → 422.
address.delivery_id
integer
—
тіло
ID способу доставки (з GET /delivery/types)
address.pickup_point_id
integer
—
тіло
ID точки самовивозу (з GET /pickup/points), якщо спосіб самовивозу
address.params
object
—
тіло
Ідентифікатори для поштових інтеграцій (REF-и довідників, індекс тощо). Набір полів залежить від інтегратора — див. блок «Поля доставки за інтегратором» нижче.
address.location
object
—
тіло
Гео-адреса. Якщо передано — type і city обовʼязкові
address.location.type
string
—
тіло
Warehouse | Doors (обовʼязкове, якщо передано address.location)
address.location.city
string
—
тіло
Місто
address.location.ware
string
—
тіло
Обов’язкове, якщо address.location.type=Warehouse
address.location.street
string
—
тіло
Обов’язкове, якщо address.location.type=Doors
address.location.country
string
—
тіло
Країна
address.location.region
string
—
тіло
Область
address.location.district
string
—
тіло
Район
address.location.build
string
—
тіло
Будинок
address.location.flat
string
—
тіло
Квартира
address.location.place
string
—
тіло
Місце
products
array
так
тіло
Позиції кошика
products.*.inner_id
string
—
тіло
Зовнішній inner_id товару (обовʼязковий, якщо не передано products.*.id)
products.*.id
integer
—
тіло
Внутрішній ID товару в CRM. Перекриває пошук за inner_id. Немає такого id → 422.
products.*.quantity
integer
так
тіло
Кількість
products.*.options
array
—
тіло
Опції (кожна з sku)
products.*.additionals
array
—
тіло
Додаткові товари (кожен з sku)
products.*.discount
numeric
—
тіло
Пряма знижка на позицію (сума або відсоток) ЗА ОДНУ ОДИНИЦЮ товару — CRM сама множить на quantity. Пріоритетніша за discount_id; якщо не задано — підтягується знижка товару.
products.*.discount_is_percent
boolean
—
тіло
Чи знижка products.*.discount у відсотках. По замовч. false (сума). Якщо discount не задано — ігнорується.
products.*.discount_id
integer
—
тіло
ID наявного типу знижки
is_need_confirm
boolean
—
тіло
За замовч. false. true → не створювати без підтвердження (див. нижче)
is_have_orders
boolean
—
тіло
За замовч. true. Чи враховувати наявність попередніх замовлень клієнта при кроці підтвердження. false → не вимагати підтвердження навіть для наявного клієнта
discount_id
integer
—
тіло
ID знижки рівня замовлення (не бандл). Автоматично накидається на всі товари.
organization_id
integer
—
тіло
Задати організацію замовлення вручну (ID наявної організації). Якщо передано — автовизначення організації працювати для замовлення НЕ буде. Відповідальність за коректність організації (наявність необхідного рахунку тощо) на стороні клієнта.
За замовч. true. Чи розбивати кошик на окремі замовлення по постачальниках (див. блок «Розподіл по постачальниках»). false → завжди одне замовлення; постачальник призначається, лише якщо один спільний покриває всіх виробників кошика.
analytics
object
—
тіло
UTM/аналітика (структура не валідується)
comment
string
—
тіло
Коментар до замовлення
custom_fields
object
—
тіло
Кастомні поля замовлення {code: value}. Довідник полів ведеться у картці замовлення CRM (блок «Кастомні поля»); значення читаються назад у GET /order/{id} та приходять у вебхуку order. При розбитті кошика по постачальниках — однакові для всіх створених замовлень
Додаткова інформація
discount — матриця знижок — пріоритети застосування
На позицію замовлення зберігаються ДВА поля знижки: пряме число (discount) і тип-знижка (discount_id). При розрахунку ціни спрацьовує лише ОДНА за таким пріоритетом:
① ПРЯМА знижка позиції → products[i].discount (з products[i].discount_is_percent)
Якщо задано і > 0 — застосовується ЗАВЖДИ, перебиває будь-який тип-знижку (і позиції, і замовлення).
Якщо в запиті не задано — підставляється власна знижка товару (product.discount).
② ТИП-знижка ПОЗИЦІЇ → products[i].discount_id
Перебиває тип-знижку рівня замовлення на цій позиції.
③ ТИП-знижка рівня ЗАМОВЛЕННЯ → discount_id (корінь тіла)
Fallback для позицій, де тип-знижку позиції не задано. Бандли (is_bundle=true) ігноруються.
④ Немає знижки — ціна без знижки.
ПРІОРІТЕТ:
products[i].discount ⟶ перебиває ⟶ products[i].discount_id ⟶ перебиває ⟶ discount_id замовлення ⟶ fallback ⟶ product.discount (БД)
Тобто: пряме число позиції > тип-знижка позиції > тип-знижка замовлення. Пряме число товару з БД працює лише коли в запиті знижку позиції не передали.
ЗНИЖКА × QUANTITY: знижка застосовується до ціни ОДНІЄЇ одиниці, а вже уцінена ціна множиться на quantity. Тобто передавайте знижку за одну штуку — сумарну за всю кількість передавати НЕ потрібно (discount=100 при quantity=2 → −200 з підсумку).
Ключ
Опис
products[i].discount
Пряме число (сума або %). НАЙВИЩИЙ пріоритет у розрахунку ціни. З discount_is_percent.
products[i].discount_is_percent
true → discount у відсотках; false/нема → абсолютна сума.
products[i].discount_id
Тип-знижка позиції. Перебиває discount_id замовлення на цій позиції. Діє, якщо немає прямого discount.
discount_id (корінь)
Тип-знижка рівня замовлення. Fallback для позицій без власної тип-знижки. Бандли не приймаються.
product.discount (БД)
Власна знижка товару. Підставляється, лише якщо в запиті не передано products[i].discount.
Приклади розрахунку
[
{
"_приклад": "Пряме число перебиває будь-який тип",
"вхід": {
"products[0].discount": 100,
"products[0].discount_is_percent": false,
"discount_id": 5,
"price": 500
},
"застосовано": "−100 грн (пряме число позиції), discount_id=5 проігноровано у розрахунку",
"ціна": "500 − 100 = 400 грн"
},
{
"_приклад": "Тип позиції перебиває тип замовлення",
"вхід": {
"products[0].discount_id": 10,
"discount_id": 5,
"price": 1000,
"DiscountType(10)": "30%"
},
"застосовано": "discount_id=10 позиції (30%), тип замовлення 5 проігноровано на цій позиції",
"ціна": "1000 − 30% = 700 грн"
},
{
"_приклад": "Відсоткова знижка позиції",
"вхід": {
"products[0].discount": 50,
"products[0].discount_is_percent": true,
"price": 1000
},
"застосовано": "−50% (пряме число позиції)",
"ціна": "1000 − 500 = 500 грн"
},
{
"_приклад": "Знижка за одиницю × quantity",
"вхід": {
"products[0].discount": 100,
"products[0].quantity": 2,
"price": 500
},
"застосовано": "−100 грн з ціни КОЖНОЇ одиниці, потім × quantity",
"ціна": "(500 − 100) × 2 = 800 грн"
}
]
За замовчуванням false. Замовлення НЕ створюється одразу і повертається 202 з order_hash ЛИШЕ якщо одночасно: потрібне підтвердження (is_need_confirm=true) І клієнт уже існує (за phone/email) І запит не ідентифікований (немає auth-токена). CRM зберігає дані у кеш на 24 год. Магазин показує клієнту підтвердження (напр. SMS-код), а потім завершує оформлення викликом POST /order/confirm з цим хешем. За замовчуванням замовлення створюєтся одразу (201).
Відповідь 202 (очікує підтвердження)
{
"message": "Order data saved.",
"order_hash": "a1b2c3...",
"person_id": 12
}
auth — токен клієнта у відповіді
У відповіді 201 поле auth містить auth-токен клієнта: акаунт створюється/забезпечується автоматично. Якщо в person передано password і клієнт новий — встановлюється саме цей пароль. Токен можна одразу використати для запитів кабінету клієнта (/person*). Виняток: замовлення без клієнта (person_id: null) — auth буде null.
warnings — мʼякі помилки клієнта (warnings)
Проблеми з ідентифікацією клієнта НЕ валять створення замовлення. Замовлення створюється (201), а деталі повертаються масивом warnings у відповіді (обʼєкти {warning: код, message: текст}) та дописуються в коментар замовлення (існуючий коментар не затирається).
422 за клієнтом не буває взагалі — будь-яка проблема лише деградує до warning.
Ключ
Опис
phone_not_valid
Невалідний телефон — відкидається.
email_not_valid
Невалідний email — відкидається.
person_id_not_found
person.id не знайдено — ідентифікатор ігнорується.
auth_mismatch
person.id не збігається з клієнтом auth-токена — auth ігнорується, замовлення йде на person.id.
contacts_conflict
Телефон і email належать різним клієнтам — пріоритет за телефоном, email лишається його власнику.
phone_taken
Телефон зайнятий іншим клієнтом (при person.id/auth) — контакт не додається.
email_taken
Email зайнятий іншим клієнтом (при person.id/auth) — контакт не додається.
person_missing
Жодного валідного ідентифікатора (id/телефон/email) — замовлення створюється БЕЗ клієнта: person_id null, auth null.
Відповідь 201 з warnings
{
"message": "Order created successfully",
"order_id": 12345,
"person_id": null,
"warnings": [
{
"warning": "email_not_valid",
"message": "Попередження: імейл невалідний - g.cc@l"
},
{
"warning": "person_missing",
"message": "Попередження: замовлення створено без клієнта — не передано жодного валідного ідентифікатора (id, телефон або email)"
}
]
}
is_split_by_supplier — розподіл по постачальниках
Кожен товар належить виробнику, а виробник повʼязаний з одним чи кількома постачальниками. При створенні замовлення кошик ділиться так:
① Збираються виробники всіх товарів кошика.
② Обирається постачальник, що покриває НАЙБІЛЬШЕ виробників кошика — його товари стають одним замовленням. Крок повторюється для решти, тож кошик розбивається на мінімальну кількість замовлень (номери base_number-1, base_number-2...).
③ Якщо кілька постачальників покривають однаково — ФІЗИЧНИЙ СКЛАД ПРІОРИТЕТНІШИЙ ЗА ВІРТУАЛЬНИЙ: спершу складський, чий склад збігається з замовленням за уточнюючими параметрами (organization/product/category — див. GET /warehouses, clarifications), далі просто перший складський з активним складом, і лише якщо складських немає — перший без складу за position звʼязки vendor-supplier.
④ Товари, виробники яких не мають постачальника, потрапляють в замовлення без постачальника.
Постачальник із warehouse_id — «складський» (GET /vendors → suppliers[].warehouse_id): замовлення, розподілене на нього, автоматично відвантажується з його складу. is_split_by_supplier=false вимикає РОЗБИТТЯ: завжди створюється одне замовлення (так працюють інтеграції eCommerce — зовнішнє замовлення не можна дробити). Постачальник при цьому все одно резолвиться: якщо один спільний покриває ВСІХ виробників кошика — призначається він (при кількох — те саме уточнення складами, крок ③); спільного немає — замовлення лишається без постачальника.
analytics — аналітика замовлення (UTM, gclid, джерело)
Об’єкт зберігається в аналітиці замовлення «як є»: кожен ненульовий ключ записується, тож зберігається будь-який переданий ключ. Якщо gclid не передано, але клієнт уже мав замовлення за останню добу — gclid (і timestamp/ga_timestamp) підтягуються з попереднього замовлення. Поля comment, e_commerce_id, external_order_id, source_id, передані на верхньому рівні тіла, також потрапляють у аналітику. Розпізнавані ключі:
organization_id — ручний вибір організації та автовизначення
За замовчуванням організація замовлення визначається автоматично за правилами розподілу (постачальник/категорії товарів, оплати тощо). Щоб зафіксувати організацію вручну, передайте organization_id — тоді автовизначення для цього замовлення взагалі не запускається, і замовлення прикріплюється саме до переданої організації. Окремий прапорець для режиму при створенні не передається: режим визначається лише наявністю organization_id (є → ручний/фіксований, немає → автовизначення). Якщо замовлення розбивається на кілька (різні постачальники), задана організація застосовується до всіх частин. CRM не перевіряє коректність переданої організації (наявність активного рахунку тощо) — відповідальність повністю на стороні клієнта. Змінити організацію вже створеного замовлення (зокрема повернути автовизначення) можна через PUT /order/{id}.
Приклад: зафіксувати організацію
{
"organization_id": 1
}
address — доставка — загальна логіка
Перевізник визначається способом доставки address.delivery_id (GET /delivery/types): за ним CRM знаходить інтегратора (Нова Пошта / Укрпошта / Meest / самовивіз).
Тип доставки задається в address.location.type:
• Warehouse — на відділення;
• Doors — адресна (кур’єром до дверей).
Ідентифікатори з довідників перевізника передаються в address.params (city / ware / street — це REF-и, а не назви). Текстова адреса (місто, вулиця, будинок) — в address.location. Назву населеного пункту в address.location.city БАЖАНО передавати ЗАВЖДИ — незалежно від режиму та типу доставки.
ПІДЙОМ НА ПОВЕРХ: поверх передається в address.params.floor (ціле число 1–57), для Укрпошти додатково address.params.lift (true/false — чи є ліфт). Значення підтягуються у форму ТТН і їдуть у накладну автоматично. Працює лише для адресної доставки (location.type = "Doors") і лише з указаною квартирою (location.flat) — без квартири підйом недоступний (помилка). Потрібен увімкнений перемикач «Підтримувати підйом на поверх» у налаштуваннях модуля доставки.
Нижче — точний набір полів для кожного інтегратора (тисніть кнопку).
Доставка: перевізник — за address.delivery_id; тип (Warehouse/Doors) — за address.location.type; REF-и довідників — в address.params. Деталі за інтегратором — у кнопках вище.
POST/api/v1/order/confirm
Підтвердити відкладене замовлення
Створює раніше відкладене замовлення за його order_hash (отриманим у відповіді 202 від POST /order). Відповідь ідентична POST /order (201): з ключами order та auth.
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
order_hash
string
так
тіло
Хеш відкладеного замовлення (з відповіді 202)
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/confirm" \
-H "Authorization: Bearer YOUR_API_TOKEN"
404: { "error": "Order data not found" } — якщо кеш порожній або прострочений (24 год).
GET/api/v1/order/{id}
Отримати замовлення
Одне замовлення зі зв’язками: клієнт (person), товари (products), доставка (delivery), накладна, статус, аналітика, організація (лише id/назва) та очікувані оплати.
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/{id}" \
-H "Authorization: Bearer YOUR_API_TOKEN"
404: { "status": "error", "message": "Order not found" }.
custom_fields — обʼєкт кастомних полів замовлення {code: value}; якщо жодне не заповнене — {}. Довідник ведеться у картці замовлення CRM (блок «Кастомні поля»), значення задаються там же або через POST /order і PUT /order/{id}.
GET/api/v1/order/{id}/history
Історія станів замовлення
Масив записів історії (status, checkpoint), по одному на кожен унікальний статус, найновіші зверху.
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/{id}/history" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Оновлює організацію/прапорець ручної організації/знижку/аналітику, а також склад або постачальника замовлення. Поля organization_id та is_manual_organization записуються незалежно одне від одного.
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
organization_id
integer
—
тіло
Змінює організацію замовлення (ID наявної організації або null). При передачі ненульового значення, is_manual_organization автоматично стає true (автовизначення вимикається).
is_manual_organization
boolean
—
тіло
Чи застосовувати правила автовизначення організації. true → автовизначення вимкнено (фіксована організація); false → правила застосовуються (повертає автовизначення). УВАГА: якщо передати false, організація може бути ПЕРЕВИЗНАЧЕНА правилами розподілу — навіть та, що ви передали в цьому ж запиті. Записується незалежно від organization_id.
discount_id
integer
—
тіло
ID знижки рівня замовлення (не бандл; або null). Автоматично накидається на всі товари замовлення з перерахунком сум.
warehouse_id
integer
—
тіло
Перенести замовлення на склад (ID з GET /warehouses). Постачальник складу привʼязується АВТОМАТИЧНО. Не можна передавати разом із supplier_id → 422.
supplier_id
integer
—
тіло
Змінити постачальника замовлення (ID з GET /suppliers). Постачальник має бути повʼязаний з виробниками ВСІХ товарів замовлення, інакше 422 «непідходяще значення». Якщо постачальник складський (має warehouse_id) — замовлення автоматично переноситься на його склад.
analytics
object
—
тіло
Повна логіка як при створенні: touchpoints[], агрегація UTM, fallback gclid; оновлює наявну аналітику замовлення.
custom_fields
object
—
тіло
Кастомні поля замовлення {code: value}. Точковий merge: передані ключі перекривають, порожнє значення (null / "") видаляє ключ, непередані значення зберігаються
Блок analytics обробляється тією ж логікою, що й при POST /order (туди ж дивіться структуру touchpoints).
is_manual_organization:false вмикає автовизначення — задана організація (навіть передана поруч) може бути замінена правилами розподілу. Щоб зафіксувати організацію, передавайте лише organization_id (is_manual_organization виставиться у true автоматично).
warehouse_id і supplier_id — взаємовиключні: передавайте ЛИШЕ ОДНЕ з них. Склад завжди тягне за собою свого постачальника; складський постачальник тягне за собою свій склад.
При зміні складу резерви замовлення знімаються зі старого складу і переоформлюються на новому автоматично.
422 { "details": { "supplier_id": ["Непідходяще значення: постачальник не повʼязаний з виробниками товарів замовлення"] } } — постачальник не покриває виробників товарів.
PUT/api/v1/order/{id}/events/{code}
Ініціювати подію замовлення
Запускає подію обробки замовлення {code} (коди — з GET /events).
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
code
string
так
шлях
Код події
custom
array
—
тіло
Дані події (за замовч. [])
cURL
curl -X PUT "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/{id}/events/{code}" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Приклад відповіді
{
"error": "Event initialized successfully."
}
Успіх повертається під ключем "error" (історична назва поля).
429: { "error": "Зачекайте і повторіть спробу" } — якщо заблоковано.
DELETE/api/v1/person/{person_id}/order/{id}
Скасувати замовлення клієнтом
Скасовує замовлення клієнта. Замовлення має належати вказаному клієнту — інакше 404. Без reason_id — причина «Скасовано клієнтом» (статус «Скасовано»). З reason_id назва та поведінка беруться зі довідника: якщо причина is_total — замовлення видаляється повністю, інакше переводиться у статус «Скасовано».
404: { "error": "Order not found" } — замовлення не існує або не належить клієнту.
GET/api/v1/checks/redirect/{from}
Чеки за коротким посиланням
За коротким посиланням на чек знаходить замовлення і повертає всі URL фіскальних чеків. З параметром strong=true повертається лише той чек, на який вказує саме це посилання.
Scope: orders:create
Поле
Тип
Обов.
Де
Опис
from
string
так
шлях
Токен короткого посилання на чек (redirect_code)
strong
boolean
—
query
true — лише чек цього redirect_code, без решти чеків замовлення
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/checks/redirect/{from}" \
-H "Authorization: Bearer YOUR_API_TOKEN"
В API два різні токени — не плутайте. API-токен ІНТЕГРАЦІЇ створюється в CRM і авторизує запити вашого магазину (саме він у заголовку всіх ендпоінтів цієї документації). Auth-токен КЛІЄНТА — особистий токен покупця для його кабінета (розділ «Кабінет клієнта»).
Цей розділ — про отримання auth-токена клієнта. Два шляхи: безпарольний (GET /auth/person/{id}/link → код → POST /auth/login/code → токен) і класичний логін/пароль (POST /auth/login; реєстрація — POST /auth/register). Токен клієнта також повертається одразу у відповіді POST /order (поле auth).
POST/api/v1/auth/login/code
Обміняти код на токен (ліміт 60/хв)
Обмінює тимчасовий код авторизації (дійсний 2 тижні) на токен клієнта. Код приходить із персонального посилання авторизації — його можна отримати за ID клієнта через GET /auth/person/{id}/link або з розсилок (напр. поле url у подіях eSputnik).
Scope: person:auth
Поле
Тип
Обов.
Де
Опис
code
string
так
тіло
Тимчасовий код авторизації
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/auth/login/code" \
-H "Authorization: Bearer YOUR_API_TOKEN"
404: { "status": "error", "message": "Code not found" }.
GET/api/v1/auth/person/{id}/link
Код авторизації клієнта за ID (ліміт 60/хв)
Обмінює ID клієнта на його персональний код авторизації. Повертається код (7 символів), який клієнт обмінює на токен через POST /auth/login/code — наприклад, для безпарольного входу за посиланням. Код дійсний 2 тижні; протухлий перевипускається автоматично при зверненні.
Scope: person:auth
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID клієнта (person_id)
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/auth/person/{id}/link" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Приклад відповіді
{
"person_id": 12,
"auth_link": "a1b2c3d"
}
404, якщо клієнта або його користувача не знайдено.
POST/api/v1/auth/login
Вхід (логін+пароль) → auth-токен
Логін за email або телефоном + пароль.
Scope: person:auth
Поле
Тип
Обов.
Де
Опис
login
string
так
тіло
Email або телефон
password
string
так
тіло
Пароль
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/auth/login" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Кабінет покупця. Ендпоінти БЕЗ {id} (/person, /person/orders, /person/password) працюють з auth-токеном КЛІЄНТА у заголовку Authorization — його дає розділ «Авторизація клієнта» або поле auth у відповіді POST /order. Ендпоінти З {id} (/person/{id}, /person/{id}/orders) — серверні: викликаються з API-токеном інтеграції (scope orders:create), коли токена клієнта на руках немає.
GET/api/v1/person
Профіль поточного клієнта
Потрібен токен клієнта (Authorization: Bearer <token> з /auth/login), а не API-токен інтеграції.
Scope: auth:customer
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/person" \
-H "Authorization: Bearer CUSTOMER_API_TOKEN"
Повертає замовлення, лише якщо воно належить авторизованому клієнту (за токеном клієнта). Якщо замовлення не існує або належить іншому клієнту — 404. Таким запитом можна переконатися, що замовлення належить користувачу.
Scope: auth:customer
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/person/order/{id}" \
-H "Authorization: Bearer CUSTOMER_API_TOKEN"
Порядок роботи: довідники (методи, банки, типи оплат) → створення оплати → за потреби фіскалізація чеків. Способів створити оплату кілька, кожен під свій сценарій — щоб не гадати, одразу відкрийте гід «Який метод оплати обрати?» нижче. Оплата завжди привʼязується до замовлень масивом orders[] = [{ order_id, amount? }].
GET/api/v1/payment/methods
Доступні методи оплати
Методи, що видимі та придатні для використання. Можна звузити вибірку за банком та/або типом оплати. Поле payment_mode визначає, як саме створюється та повертається платіж: «module» — через платіжний модуль (шлюз), який налаштовано в CRM; «callback» — CRM надсилає запит у ваш магазин (вебхук create_payment), і ви обробляєте платіж самі; «instant» — платіж створюється одразу, без шлюзу й вебхуку (готівка, термінал тощо); «manual» — ручне додавання IBAN-платежу: у extra передаються account_id, payer та purpose, платіж створюється одразу. Поле is_auto = true означає, що метод видимий і автоматично повертається (режим module з активним модулем або callback).
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
bank_id
numeric
—
query
Фільтр за ID банку (точний збіг)
payment_type_id
numeric
—
query
Фільтр за ID типу оплати (точний збіг)
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/payment/methods" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Список усіх типів оплат (code/name), відсортований за назвою.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
code
string
—
query
Фільтр за кодом типу (точний збіг)
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/payment/types" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Приклад відповіді
[
{
"id": 1,
"name": "Картка",
"code": "card"
}
]
Який метод оплати обрати?
У CRM є кілька ендпоінтів створення оплати — кожен під свій сценарій. Коротко: якщо платіж має провести МОДУЛЬ, налаштований у CRM, — беріть POST /payment (отримаєте посилання). Якщо гроші вже отримані і треба просто ЗАФІКСУВАТИ факт оплати в CRM — POST /payment/manual. Якщо це оплата за реквізитами на конкретний рахунок — POST /payment/iban. Якщо оплату створюєте ВИ на своєму боці (напр. інтеграція, якої немає в CRM) і хочете спершу завести її як очікувану, а підтвердити після фактичної оплати клієнтом — POST /payment/pending, а потім POST /payment/pending/confirm. Оберіть сценарій нижче.
Схема вибору
Платіж проводить шлюз, налаштований у CRM (Plata by Mono, monopay тощо)?
→ ТАК → POST /payment → отримуєте посилання (або текст-інструкцію) → клієнт платить. Готово.
Гроші вже отримані, треба лише внести факт у CRM і прив’язати до замовлень?
→ POST /payment/manual
Оплата за реквізитами на конкретний рахунок (IBAN)?
→ POST /payment/iban
Оплату створюєте ВИ у себе (стороння інтеграція, якої немає в CRM)?
→ POST /payment/pending (заводимо очікувану) → коли клієнт оплатив → POST /payment/pending/confirm (підтверджуємо).
POST/api/v1/payment
Створити оплату
Створює оплату обраним способом (payment_method_id) для одного або кількох замовлень. Замовлення завжди передаються масивом orders[] = [{ order_id, amount? }] — від одного до будь-якої кількості. Поле amount у кожному рядку необовʼязкове: якщо його не передано (або значення ≤ 0), сума береться як поточний залишок замовлення (total_remaining). Так само можна передати amount лише для частини замовлень — решта порахується за залишком. Підсумкова сума платежу = сума всіх amount (явних і порахованих за залишком). Якщо всі замовлення вже сплачені (загальна сума 0) — повертається помилка. Подальша поведінка залежить від режиму способу оплати (payment_mode): module — створюється сесія шлюзу, яка повертає АБО посилання на оплату (status=link), АБО лише текст-інструкцію без посилання (status=awaiting, напр. «клієнт повинен підтвердити в застосунку») — залежно від провайдера; callback — запит у ваш магазин (вебхук create_payment), магазин сам обирає режим відповіді (посилання або текст); instant — платіж створюється одразу (status=paid); manual — ручний IBAN-платіж: створюється одразу (status=paid), обовʼязкові extra.account_id та extra.payer.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
orders
array
так
тіло
Масив замовлень для оплати (мін. 1)
orders.*.order_id
integer
так
тіло
ID замовлення
orders.*.amount
numeric
—
тіло
Сума на це замовлення (>0). Якщо не передано — береться залишок замовлення
payment_method_id
integer
так
тіло
ID наявного способу оплати
extra
array
—
тіло
Додаткова інформація, специфічна для модуля — набір полів залежить від провайдера
extra.phone
string
—
тіло
Телефон клієнта для цього платежу, якщо відрізняється від указаного в замовленні
extra.card
string
—
тіло
Номер/останні цифри картки — для модулів, що цього потребують (напр. УкрСиб)
extra.months
integer
—
тіло
Кількість місяців розстрочки для installments-модулів (за замовч. 3)
extra.account_id
integer
—
тіло
Для manual: ID IBAN-рахунку організації, на який зараховано платіж
paid → { payment_id }; link → { link, pending_id, text? }; awaiting → { pending_id, text }.
failed → HTTP 400 з полем { error }.
POST/api/v1/payment/manual
Додати оплату і прив’язати до замовлень
Замовлення передаються масивом orders[] = [{ order_id, amount? }] — будь-яка кількість. amount у рядку необовʼязковий: якщо не передано (або ≤ 0) — береться залишок замовлення. Загальна сума платежу рахується автоматично як сума всіх amount.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
payment_method_id
integer
так
тіло
ID способу оплати (GET /payment/methods) — тип платежу визначається ним
transaction_number
string
так
тіло
Унікальний ID транзакції (ключ блокування)
organization_id
numeric
так
тіло
ID організації
orders
array
так
тіло
Масив замовлень (мін. 1)
orders.*.order_id
integer
так
тіло
ID замовлення
orders.*.amount
numeric
—
тіло
Сума на це замовлення (>0). Якщо не передано — береться залишок
{
"message": "Payment created successfully",
"payment_id": 123
}
POST/api/v1/payment/iban
Створити IBAN-оплату
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
amount
numeric
так
тіло
Сума
account_id
numeric
так
тіло
ID IBAN-рахунку
payer
string
так
тіло
Платник
transaction_number
string
—
тіло
ID транзакції (за замовч. "-")
purpose
string
—
тіло
Призначення платежу (за замовч. "-")
date
date
—
тіло
Дата (за замовч. now)
Тіло запиту
{
"amount": 1499,
"account_id": 7,
"payer": "Іван Петренко",
"purpose": "Оплата за замовлення 250001"
}
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/payment/iban" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount":1499,"account_id":7,"payer":"Іван Петренко","purpose":"Оплата за замовлення 250001"}'
Приклад відповіді
{
"message": "Payment created successfully",
"payment_id": 123
}
POST/api/v1/payment/pending
Створити очікувану оплату
Замовлення передаються масивом orders[] = [{ order_id, amount? }] — будь-яка кількість. amount у рядку необовʼязковий: якщо не передано (або ≤ 0) — береться залишок замовлення. Загальна сума очікуваної оплати рахується автоматично як сума всіх amount.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
payment_method_id
integer
так
тіло
ID способу оплати (GET /payment/methods) — тип платежу визначається ним
transaction_number
string
так
тіло
ID транзакції
organization_id
numeric
так
тіло
ID організації
orders
array
так
тіло
Масив замовлень (мін. 1)
orders.*.order_id
integer
так
тіло
ID замовлення
orders.*.amount
numeric
—
тіло
Сума на це замовлення (>0). Якщо не передано — береться залишок
Підтверджує pending за transaction_number, перетворюючи на реальну оплату.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
transaction_number
string
так
тіло
ID транзакції pending
commission
numeric
—
тіло
Перекриває комісію pending
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/payment/pending/confirm" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Приклад відповіді
{
"message": "Payment confirmed successfully"
}
POST/api/v1/order/{id}/checks/fiskalize
Фіскалізувати замовлення
Пробиває фіскальний чек по замовленню за поточними політиками модуля фіскалізації (передоплата, післяплата, залишок нефіскалізованої суми). Дія аналогічна кнопці «Фіскалізувати» в CRM: чек створюється одразу, відкладений перевипуск (якщо був) скасовується.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/{id}/checks/fiskalize" \
-H "Authorization: Bearer YOUR_API_TOKEN"
checks — актуальні (несторновані) чеки замовлення після фіскалізації.
200 { "success": "skipped" } — фіскалізація пропущена політикою (напр., часткова оплата при вимкненому чеку передоплати).
200 { "error": "Order is fiskalized" } — замовлення вже повністю фіскалізоване.
422 — модуль фіскалізації не активний; 503 — касова зміна не відкрита; 429 — повторіть пізніше.
POST/api/v1/order/{id}/checks/return
Повернути (сторнувати) чеки замовлення
Сторнує всі актуальні чеки замовлення (чек повернення в ПРРО). Чеки, додані вручну або без модуля фіскалізації, пропускаються і повертаються у полі skipped.
Scope: payments:manage
Поле
Тип
Обов.
Де
Опис
id
integer
так
шлях
ID замовлення
cURL
curl -X POST "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/order/{id}/checks/return" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Правила спільні для ВСІХ розділів Export API: доступ лише на читання (scope data:read); списки посторінкові (page, limit); майже до кожного списку є парний ендпоінт «…/filter» — він повертає доступні випадні фільтри та варіанти сортування, а обрані значення передаються у списковий ендпоінт query-параметром filter (масив {value, data:[{value}]}).
GET/api/v1/export/products
Список товарів (пагінація)
Виключає застарілі товари.
Scope: data:read
Поле
Тип
Обов.
Де
Опис
search
string
—
query
Частковий збіг за назвою або артикулом
sort
string
—
query
created_at|name|price|cost|sku _asc/_desc (за замовч. created_at_desc)
page
integer
—
query
Номер сторінки (за замовч. 1)
limit
integer
—
query
Записів на сторінку (за замовч. 15)
dateRange
array[2]
—
query
[from, to] — фільтр за датою
filter
array
—
query
Масив фільтрів {value, data:[{value}]}
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/export/products" \
-H "Authorization: Bearer YOUR_API_TOKEN"
all_ids заповнюється лише за наявності права на аналітику, інакше []. oldestFilterDate у цій відповіді відсутній (на відміну від /checks, /payments, /realizations).
GET/api/v1/export/orders/search
Швидкий пошук (до 10)
Scope: data:read
Поле
Тип
Обов.
Де
Опис
request
string
—
query
Запит (потрібно ≥3 символів); порожній → []
cURL
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/export/orders/search" \
-H "Authorization: Bearer YOUR_API_TOKEN"
curl -X GET "https://[ВАШ САБДОМЕН]-api.marchroute.com/api/v1/export/analytics/{tab}/{type}/filter" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Приклад відповіді
[]
Webhook та підпис HMAC
CRM надсилає вихідні запити (POST) на URL магазину (вкладка «Webhook»). Тип події передається у заголовку MR-Endpoint, а тіло — JSON. Кожен запит підписується секретом HMAC-SHA256, щоб ваш сервер міг переконатися, що запит надійшов саме від CRM і не був змінений.
Секрет генерується кнопкою у вкладці «Webhook» і показується лише один раз — зберігайте його як пароль.
Заголовки запиту
Заголовок
Опис
MR-Endpoint
Тип події (напр. payment_confirmed). За ним маршрутизуйте обробку
Signature
HMAC-SHA256 від канонічного payload (hex)
Timestamp
Unix-час (с) формування запиту. Вікно валідності — 300 с
Client-Id
Ідентифікатор клієнта CRM
Content-Hash
SHA-256 від тіла запиту (hex)
Як формується підпис
Підписується не саме тіло, а канонічний payload — рядок із 5 частин, розділених \n:
payload
METHOD ← напр. POST (у верхньому регістрі)
RESOURCE_PATH ← шлях URL магазину без хосту
CLIENT_ID ← ваш Client-Id
TIMESTAMP ← те саме значення, що в заголовку Timestamp
BODY_HASH ← sha256(тіло запиту), hex
Далі signature = hash_hmac('sha256', payload, secret).
Важливо про тіло. Тіло серіалізується канонічно: асоціативні ключі рекурсивно сортуються (ksort), порядок елементів списків зберігається, JSON кодується з прапорами JSON_UNESCAPED_UNICODE, JSON_UNESCAPED_SLASHES, JSON_PRESERVE_ZERO_FRACTION. На прийомі підписуйте сирий байтовий рядок тіла — не перепарсюйте JSON, інакше підпис «попливе».
Події (MR-Endpoint)
Значення заголовка MR-Endpoint та приклади тіл, які CRM надсилає магазину:
POSTMR-Endpoint: order
Замовлення (основні поля)
Коли надсилається: Коли замовлення переходить на чекпоінт, в якому вказана відповідна функція при вході. Надсилає актуальний стан замовлення.
custom_fields — кастомні поля замовлення {code: value} з довідника CRM (блок «Кастомні поля» в картці замовлення; задаються там або через POST /order / PUT /order/{id}); якщо жодне не заповнене — {}.
Коли надсилається: Коли в замовленні зʼявляється підтверджений платіж (клієнт оплатив, або менеджер підтвердив оплату вручну). Надсилається разом зі списком замовлень, яких стосується платіж.
Коли надсилається: Після кожного створеного фіскального чека по замовленню (фіскалізація або ручний чек). Надсилає реф та урл чека.
У кожного чека є короткий redirect_code — використовуйте його як скорочувач посилань: зробіть на своєму сайті сторінку, відправляйте клієнта на неї з цим кодом і обмінюйте його на реальні посилання запитом GET /checks/redirect/{redirect_code} — він поверне всі повʼязані чеки замовлення, а з параметром strong=true — лише цей конкретний чек.
Коли надсилається: Коли підтверджується очікувана оплата за способом, який обробляє ваш магазин (магазин сам проводить транзакцію — callback-режим). CRM просить магазин завершити підтвердження на своєму боці.
Коли надсилається: Коли по замовленню оформлюється повернення коштів за способом оплати, який обробляє ваш магазин (callback-режим). Магазин має провести повернення на своєму боці.
Коли надсилається: Коли спосіб оплати працює в режимі «Колбек»: CRM надсилає запит у ваш магазин, а магазин обробляє платіж і повертає режим відповіді. Режим «link» — повертається посилання на оплату; режим «default» — повертається лише текст, який показується оператору (напр. «Клієнт повинен підтвердити в застосунку»).