Замовлення партнера
Як магазин приймає замовлення дропшипера: на кого воно записується, за якими цінами рахується, коли магазин відмовляє і як не створити замовлення двічі.
На цій сторінці
- Що передає партнер
- Замовник, доставка, оплата й отримувач
- Права ключа
- Ціни та знижки
- Замовлення повністю або відмова
- Склади й передзамовлення
- Подарунки за акцією
- Повтор запиту: Idempotency-Key
- Номер замовлення в партнера: external_id
- Очікуваний підсумок: expected_total
- Що магазин пише партнерові й покупцеві
- Які замовлення бачить ключ
- Замовлення в панелі магазину
- Повний цикл на прикладі
- Чого немає
Через API партнер передає магазину замовлення й потім стежить за ними. Так працює дропшипер: покупець оформив замовлення в нього на сайті, програма дропшипера передає магазину, які товари й скільки потрібно, а далі замовленням займається менеджер магазину.
Ви передаєте лише товари й коментар. Доставку, оплату й отримувача через API не передають: їх призначає менеджер магазину в панелі, коли обробляє замовлення.
На цій сторінці описано, на кого магазин записує таке замовлення, за якими цінами його рахує, коли може його не прийняти і як не створити одне замовлення двічі. Кожне поле запитів і відповідей, усі коди помилок і причини відмови зібрано на сторінці «Замовлення: адреси й поля».
| Адреса | Право | Що робить |
|---|---|---|
POST /api/v1/orders/check |
orders:create |
рахує замовлення, нічого не створюючи: ціни, знижки, подарунки, підсумок і причини, через які замовлення не прийняти |
POST /api/v1/orders |
orders:create |
створює замовлення |
GET /api/v1/orders |
orders:read |
замовлення контакту ключа |
GET /api/v1/orders/{id} |
orders:read |
одне замовлення |
Що передає партнер
| Поле | Що це |
|---|---|
items |
товари: номер товару product_id, номер артикула sku_id і кількість qty. Обидва номери обов’язкові |
comment |
коментар до замовлення для менеджера |
external_id |
номер замовлення у вашій системі, за бажанням |
expected_total |
підсумок, який ви очікуєте, за бажанням |
storefront_id, locale |
вітрина й мова замовлення, за бажанням |
Інших полів у замовлення немає. Крім тіла, POST /orders потребує заголовка
Idempotency-Key, про нього нижче. Якщо
передати доставку (shipping), спосіб оплати (payment_method_id),
отримувача (recipient) чи промокод (coupon), магазин відповість 422 з
кодом validation_failed і повідомленням «Такого поля тут немає. Допустимі
поля: storefront_id, external_id, items, comment, expected_total, locale.».
Магазин не пропускає такі поля мовчки, щоб ви не вирішили, що він їх
прийняв.
Товар і артикул вказуйте лише номерами з каталогу API: id товару й id
його артикула в /products або
/skus. Код артикула й
штрихкод у замовленні не приймаються, знайдіть за ними номери через /skus.
Артикул має належати товару, номер якого ви передали.
Замовник, доставка, оплата й отримувач
Власник видає ключ на ваш контакт у магазині, і всі замовлення за цим ключем магазин записує на цей контакт. Замовником у таких замовленнях будете ви.
- Ім’я, телефон і пошта замовника потрапляють у замовлення з картки вашого контакту. Сама картка під час замовлення не змінюється.
- Нових контактів і кабінетів магазин не створює.
- Якщо у вашого контакту є особистий кабінет на сайті магазину, замовлення з’явиться в цьому кабінеті, як і будь-яке інше ваше замовлення.
Замовлення створюється без доставки, без способу оплати й без отримувача. Доставка в підсумок не входить, підсумок дорівнює сумі товарів після знижок. Отримувача, доставку й оплату менеджер магазину призначає в панелі, коли обробляє замовлення. Про те, як передавати магазину адресу й дані отримувача, домовтеся з ним окремо.
Коли менеджер усе призначить, ви побачите це у відповіді
GET /orders/{id},
у полях shipping, payment і recipient замовлення. Через API ці поля
можна лише читати. Поки менеджер нічого не призначив, shipping і
recipient дорівнюють null, а в payment є лише стан оплати. Вартість
доставки, яку призначив менеджер, входить у підсумок замовлення, а номер
накладної з’явиться в shipping.waybill_number.
Права ключа
| Право | Прапорець у формі ключа | Що відкриває |
|---|---|---|
orders:create |
«Створювати нові замовлення» | POST /orders/check і POST /orders |
orders:read |
«Бачити замовлення» | GET /orders і GET /orders/{id} |
Права не залежать одне від одного. Ключ лише з orders:create отримує
створене замовлення повністю у відповіді на POST /orders, але потім
переглянути його вже не зможе: GET /orders/{id} відповість 403 з кодом
missing_scope. Щоб стежити за замовленнями, вашому ключу потрібні обидва
права.
Право на каталог для замовлення не перевіряється, але номери товарів і
артикулів беруться з каталогу, тому ключу
зазвичай позначають і «Бачити товари й категорії». Свої ціни можна звіряти
через /prices.
Ціни та знижки
Покупцем під час розрахунку вважається ваш контакт.
- Ціни ті самі, що віддає вам
/prices: з акціями каталогу, ціною вашої категорії покупців, персональними цінами й цінами від кількості. Якщо у вашого контакту є особистий кабінет, магазин вважає вас зареєстрованим покупцем, і діють ціни для зареєстрованих покупців. Власну ціну позиції передати не можна. - Знижки кошика, які магазин дає без промокоду, діють за вашим контактом: за його категорією покупців і його особистими обмеженнями. Промокод через API не передається.
- Подарунки за акцією магазин кладе сам, докладніше нижче.
- Найменша сума замовлення вітрини до замовлень через API не застосовується.
- Бонуси через API не списуються.
- Доставка в підсумок не входить, поки її не призначить менеджер.
- Валюта замовлення — валюта вітрини, курс записується в замовлення в момент оформлення. Потім замовлення не перераховується, навіть якщо курс зміниться.
Якщо ваші ціни змінилися між перевіркою і створенням замовлення, замовлення
буде створено за новими цінами. Щоб цього не сталося, передавайте очікуваний
підсумок у полі expected_total.
Замовлення повністю або відмова
Кошик на вітрині сам підганяє кількість під залишок, крок продажу й мінімальну кількість. Ваше замовлення магазин так не змінює, бо ви вже пообіцяли своєму покупцеві саме те, що передали. Тому магазин або приймає замовлення точно в тому вигляді, у якому ви його надіслали, або не створює його зовсім і називає всі причини одразу.
Замовлення не буде прийнято, якщо:
- товару немає в каталозі або його не опубліковано;
- артикула немає або він не належить переданому товару;
- артикул знято з продажу;
- кількість менша за мінімальну або не кратна кроку продажу;
- на складах бракує товару, а замовлення понад залишок у магазині заборонено.
Тоді POST /orders відповідає 422 з кодом cannot_place, а причини
перелічено в полі problems. Кожна причина називає поле запиту, якого
стосується, наприклад items.2.qty, і підказує, як її виправити. Наприклад,
за неправильної кількості магазин називає найближчу кількість, яку можна
замовити. Усі причини описано в розділі
«Причини відмови».
Ті самі причини заздалегідь показує POST /orders/check. Надішліть туди те
саме тіло, яке збираєтеся надіслати в POST /orders. Якщо у відповіді
can_place дорівнює true, замовлення приймуть, якщо до створення в магазині
нічого не зміниться.
Кількість у позиції вказуйте в одиницях продажу товару (поле unit),
наприклад у штуках, метрах чи кілограмах. Упаковок і послуг у замовленні через
API немає. Товар, який продають лише упаковками, замовляють кількістю,
кратною упаковці.
Склади й передзамовлення
Наявність магазин перевіряє за тими самими складами, що показує вам
/inventory. Якщо у формі ключа вибрано
склади, магазин дивиться лише на них. Якщо не вибрано, магазин дивиться на
склади, з яких продає вітрина замовлення. З цих самих складів він резервує
товар під замовлення.
Далі все залежить від налаштування «Дозволити замовлення, коли товару немає» в розділі складів магазину.
- Передзамовлення заборонено (так типово). Замовлення на кількість, більшу
за доступну, не приймається, причина
out_of_stockназиває, скільки є. Якщо товар забрало інше замовлення, поки ваше оформлювалося, магазин теж відмовить. Причина будеstock_reserve_failed, і в ній перелічено, чого забракло. - Передзамовлення дозволено. Замовлення приймається на будь-яку кількість.
Скільки товару чекає надходження на склад, видно у відповіді: у
попередженні
backorderі в поліbackorder_qtyпозиції.
Подарунки за акцією
Якщо в магазині діє акція з подарунком до замовлення, магазин покладе
подарунок і у ваше замовлення, так само як у замовлення на вітрині. Подарунок
ви не передаєте й не обираєте: його кладе магазин. У відповідях він стоїть
окремою позицією з is_gift: true.
Подарунок кладеться, лише якщо він є на складах, за якими магазин рахує наявність для ключа: вибраних у ключі, а якщо їх не вибрано — на складах вітрини. Якщо подарунка там немає, замовлення однаково приймається, просто без подарунка. Якщо подарунок — той самий артикул, що ви замовили, залишок спершу йде на ваші позиції, а подарунку дістається те, що лишилося.
Повтор запиту: Idempotency-Key
Буває, що програма надіслала замовлення, але відповіді не дочекалася,
наприклад обірвався зв’язок. Тоді невідомо, чи створено замовлення. Щоб таке
замовлення можна було безпечно надіслати ще раз, POST /orders має
обов’язковий заголовок Idempotency-Key, ключ повтору:
Idempotency-Key: 6f1c2e0a-8d4b-4f5e-9a37-0c2b1d7e5a90
Придумайте для кожного нового замовлення свій рядок і повторюйте запит цього
замовлення з тим самим рядком. Найзручніше UUID або ваш номер замовлення з
префіксом. Ключ повтору — до 255 друкованих знаків ASCII: латиниця, цифри,
розділові знаки й пробіл, без кирилиці й перенесень рядка. Без заголовка
магазин відповідає 428 з кодом idempotency_key_required, а неправильний
ключ повтору отримує 400 з кодом bad_idempotency_key.
Що відбувається, коли надходить запит із ключем, який магазин уже бачив:
| Ситуація | Відповідь |
|---|---|
| замовлення за цим ключем створено, тіло запиту те саме | 201 з тим самим замовленням і заголовком Idempotent-Replayed: true. Друге замовлення не створюється |
| перший запит із цим ключем ще оформлюється | 409 з кодом idempotency_in_progress і заголовком Retry-After: 2, хоч би яке було тіло. Повторіть через дві секунди |
| перший запит завершено, а тіло запиту інше | 422 з кодом idempotency_key_reused. Найімовірніше, ви помилково дали новому замовленню ключ попереднього |
перший запит отримав відмову: помилку перевірки, cannot_place, total_mismatch чи будь-яку іншу |
ключ вільний, замовлення немає. Виправте запит і надішліть його з тим самим ключем |
| замовлення за цим ключем видалили в панелі | ключ вільний, і повтор оформить замовлення заново |
| замовлення створено, але потім власник прив’язав ваш ключ API до іншого контакту | 409 з кодом idempotency_order_hidden. Коли власник змінює контакт ключа, магазин видає новий ключ, а попередній відповідає 401. Замовлення лишилося в попереднього контакту, і новому ключу його не видно. Не надсилайте його з новим ключем повтору, інакше в магазині з’явиться друге таке саме |
Ключі повтору в кожного ключа API свої: той самий рядок у двох ключів API
означає два різні замовлення. Регістр літер у ключі повтору важливий:
order-a1 і Order-A1 — різні ключі.
Що вважається тим самим тілом. Порядок полів в об’єктах значення не має.
Числа в полях storefront_id, expected_total і в полях позицій
product_id, sku_id і qty порівнюються як числа: 2, "2", "2.000" і
2.0 — одне й те саме. Поле зі значенням null, "" чи {} дорівнює полю,
якого немає зовсім. Пробіли по краях рядків не важливі. Решта порівнюється
так, як написано: інший текст коментаря чи інший порядок позицій в items
дають інше тіло. Тому під час повтору надсилайте те саме, що надсилали
першого разу.
Скільки магазин пам’ятає ключ повтору. Ключ повтору діє 24 години від
першого запиту. Після цього запит із тим самим ключем вважається новим і
створить нове замовлення. Якщо відповідь на створення так і не надійшла за
добу, спершу пошукайте замовлення через
GET /orders?external_id=….
Якщо магазин не завершив оформлення. Буває, що перший запит так і не завершився, наприклад магазин перезапустили посеред оформлення. Через 10 хвилин такий запит вважається обірваним, і повтор із тим самим ключем повтору оформить замовлення заново.
Відповідь на повтор — те саме замовлення в його теперішньому вигляді, а
не копія першої відповіді: якщо менеджер устиг змінити статус чи призначити
доставку, ви це побачите. Попередження warnings у відповіді на повтор
завжди порожні.
Номер замовлення в партнера: external_id
У полі external_id передайте номер замовлення у вашій системі, до 64
знаків. Магазин запам’ятає його й поверне у відповідях, а за параметром
?external_id= замовлення можна знайти в списку.
Номер має бути унікальним у межах ключа API, регістр літер у ньому важливий:
A-1 і a-1 — різні номери. Якщо замовлення з таким номером уже прийнято,
POST /orders відповідає 409 з кодом external_id_taken, а номер цього
замовлення в магазині приходить у полі order_id. Якщо замовлення з цим
номером саме зараз оформлює інший запит, відповідь 409 з кодом
external_id_in_progress і заголовком Retry-After: 2. Якщо власник
видалив замовлення в панелі, номер знову вільний.
Зайняті номери й ключі повтору належать ключу API, а не контакту. Якщо власник прив’яже ключ до іншого контакту, номери замовлень попереднього контакту лишаться зайнятими, хоча самі замовлення новому контакту не видно.
Номер захищає від дублів надійніше, ніж Idempotency-Key, бо не спливає
через добу. Якщо ви повторите замовлення з новим ключем повтору й без
external_id, магазин створить друге таке саме замовлення. З тим самим
external_id другого замовлення не буде.
Поле необов’язкове. Порожній рядок означає те саме, що номер не передано.
Очікуваний підсумок: expected_total
У полі expected_total можна передати підсумок, який ви очікуєте, наприклад
"416.64". Якщо підсумок за розрахунком магазину відрізняється хоча б на
копійку, замовлення не створюється: відповідь 409 з кодом total_mismatch, а
підсумок магазину приходить у полі actual_total. Доставки в підсумку під
час створення немає, тому порівнюйте із сумою товарів після знижок.
Поле можна не передавати, але тоді замовлення створюється за цінами, які
діють у момент оформлення. Усередині POST /orders магазин звіряє підсумок
двічі, перед оформленням і в момент оформлення, бо за цей час власник міг
змінити ціну чи знижку. /orders/check повідомляє про розбіжність причиною
total_mismatch.
Що магазин пише партнерові й покупцеві
Про замовлення, що надійшли через API, магазин сам нічого не пише ні вам, ні покупцеві: ні листа про нове замовлення, ні повідомлень про зміну статусу, ні автоматичних повідомлень CRM, ні рахунку на пошту. Це стосується й отримувача, якого призначить менеджер. Співробітники магазину отримують сповіщення про такі замовлення як завжди. Якщо менеджер сам надішле лист із замовлення, він піде.
Виняток один — електронний чек. Якщо в касі магазину ввімкнено «Надсилати чек покупцеві», чек за вашим замовленням піде на пошту чи телефон замовника, які записано в замовленні з картки вашого контакту. Отримувачу чек не надходить ніколи. Власник може вимкнути надсилання чека у формі вашого ключа перемикачем «Надсилати партнерові електронний чек» у блоці «Замовлення партнера». Тоді магазин однаково видасть чек, але нікуди його не надішле.
Якщо власник увімкнув у формі ключа повідомлення партнерові, магазин повідомлятиме ваш сайт, що в замовлення змінився статус або менеджер його змінив. Це не лист, а запит на адресу вашого сайту. Докладніше на сторінці «Повідомлення партнерові (вебхуки)».
Посилань на сторінку оплати API не віддає.
Які замовлення бачить ключ
GET /orders віддає всі замовлення вашого контакту, хоч би звідки вони
надійшли: передані через API, оформлені менеджером телефоном, куплені вами на
вітрині. Звідки надійшло замовлення, показує поле channel. Чужих замовлень
для ключа немає: запит чужого замовлення отримує 404, як запит неіснуючого.
Якщо у вашого контакту кілька ключів, кожен бачить усі замовлення контакту. Якщо власник прив’яже ключ до іншого контакту, попередній ключ одразу перестане працювати й отримуватиме 401. Новий ключ, який магазин видасть замість нього, бачить лише замовлення нового контакту.
Зміни зручно забирати параметром updated_since: він віддає замовлення,
змінені від указаного часу. Час зміни замовлення зсувається під час зміни
статусу, оплати, редагування складу, сум, адреси чи доставки в панелі. Тому
замовлення, якому менеджер призначив доставку, оплату чи отримувача,
потрапить у таку відповідь. Щоб не перепитувати про зміни щоразу, попросіть
власника ввімкнути повідомлення про замовлення. Тоді магазин сам повідомить, що в
замовлення змінився статус або менеджер його змінив. Як це працює, описано на
сторінці «Повідомлення партнерові (вебхуки)».
Замовлення в панелі магазину
У панелі магазину замовлення з API видно в каналі продажів «API: назва ключа», наприклад «API: Сайт партнера». Якщо ключ видалять, підпис каналу збережеться. Замовником у замовленні стоїть контакт ключа. Доставку, оплату й отримувача менеджер заповнює в самому замовленні.
Запити POST /orders і POST /orders/check, які завершилися помилкою,
магазин зберігає в журналі запитів разом із тілом завдовжки до 64 000 знаків.
За кодом із request_id власник знайде ваш запит повністю й побачить, що ви
надіслали. Докладніше на сторінці «Журнал запитів».
Повний цикл на прикладі
Дропшипер отримав замовлення №A-1024 на своєму сайті: дві баночки крему.
Номери товару (1045) і артикула (2108) він заздалегідь узяв із /products.
Знижок на цей товар у магазині немає, тому підсумок дорівнює сумі товарів.
1. Перевірка.
curl https://shop.example.ua/api/v1/orders/check \
-X POST \
-H "Authorization: Bearer <ключ>" \
-H "Content-Type: application/json" \
-d '{
"external_id": "A-1024",
"items": [{ "product_id": 1045, "sku_id": 2108, "qty": "2" }],
"comment": "Запакуйте як подарунок"
}'
У відповіді can_place: true і підсумок "totals": { "total": "416.64", … }.
Повну відповідь наведено в описі адреси
POST /orders/check.
2. Створення. Те саме тіло йде в /orders із ключем повтору й очікуваним
підсумком:
curl https://shop.example.ua/api/v1/orders \
-X POST \
-H "Authorization: Bearer <ключ>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: drop-A-1024" \
-d '{ "external_id": "A-1024", "expected_total": "416.64", "items": [{ "product_id": 1045, "sku_id": 2108, "qty": "2" }], "comment": "Запакуйте як подарунок" }'
Магазин відповідає 201 Created, у заголовку Location адреса замовлення
https://shop.example.ua/api/v1/orders/5120, у тілі замовлення повністю.
3. Повтор. Відповідь не дійшла, і програма надсилає той самий запит ще
раз із тим самим Idempotency-Key: drop-A-1024. Магазин відповідає 201 тим
самим замовленням №5120 і заголовком Idempotent-Replayed: true. Другого
замовлення немає.
Якби програма помилково згенерувала новий ключ повтору, магазин відповів би
409 external_id_taken з "order_id": 5120: номер A-1024 уже зайнятий.
4. Відстеження. Раз на кілька хвилин програма забирає змінені замовлення:
curl "https://shop.example.ua/api/v1/orders?updated_since=2026-10-19T08:00:00Z&after_id=0&limit=100" \
-H "Authorization: Bearer <ключ>"
Коли менеджер призначить доставку, у замовлення №5120 з’явиться shipping, а
підсумок зросте на її вартість. Коли посилку відправлять, зміниться status,
а в shipping.waybill_number з’явиться номер накладної.
Чого немає
- Доставки, оплати, отримувача й промокоду в запиті: їх призначає менеджер.
- Посилання на сторінку оплати.
- Власної ціни позиції: ціну завжди рахує магазин.
- Пошуку товару за кодом артикула чи штрихкодом у замовленні: лише номери.
- Упаковок і послуг у позиціях.
- Вибору подарунка: подарунки за акцією магазин кладе сам.
- Списання бонусів.
- Редагування й скасування замовлення через API. Щоб змінити чи скасувати замовлення, зв’яжіться з магазином.