Документація

Замовлення дропшипера з власного сайту

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

На цій сторінці

Ця сторінка для програміста сайту дропшипера. Дропшипер працює з магазином за програмою плагіна «Дропшипінг». Він продає товари магазину своїм покупцям, а посилки їм відправляє магазин. Свої замовлення він може оформлювати не лише в кабінеті на сайті магазину, а й безпосередньо зі свого сайту через API. Як програму влаштовано для магазину, описано на сторінці «Дропшипінг».

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

Адреси, ключ повтору Idempotency-Key, номер external_id, загальні коди помилок і поля замовлення працюють так само, як у звичайного партнера. Їх описано на сторінках «Замовлення партнера» і «Замовлення: адреси й поля».

Ключ

Ключ дропшипер видає собі сам. У кабінеті на сайті магазину (/dropship) він відкриває розділ «Підключення» й натискає «Видати ключ». Кнопка доступна, коли магазин схвалив заявку дропшипера. Магазин показує ключ один раз, тому скопіюйте його одразу. Там же стоїть «Адреса API» магазину, наприклад https://shop.example.ua/api/v1.

Права ключа дропшипер не вибирає. Магазин видає ключ із цими правами, а власник магазину може їх звузити або обмежити строк ключа. Якщо ключ видати заново, права й строк, які задав власник, зберігаються.

Право Що відкриває
shop:read довідники магазину, зокрема способи доставки й оплати
catalog:read товари, категорії й характеристики
prices:read ціни дропшипера
inventory:read залишки
orders:read замовлення дропшипера, зокрема оформлені в кабінеті
orders:create перевірка й створення замовлення

Кнопка «Видати ключ заново» випускає новий ключ, і попередній перестає працювати одразу. Кнопка «Відкликати ключ» вимикає його, і пізніше ключ можна видати знову. Власник магазину бачить ключ у своїй панелі під назвою «Дропшипер: ім’я» і теж може його відкликати. Ключ, який відкликав магазин, дропшипер сам заново не видасть. У розділі «Підключення» з’явиться повідомлення «Магазин відкликав ваш ключ. Щоб підключити сайт знову, зверніться до магазину.» Так само не можна видати ключ заново, якщо минув строк, який задав власник. В обох випадках новий ключ видає магазин. Якщо магазин закрив роботу з дропшипером, ключ відкликається сам.

Таке саме тіло приймає будь-який ключ, прив’язаний до дропшипера, зокрема ключ, який йому видав власник магазину. Поки заявка чекає рішення, а також коли роботу призупинено чи закрито, магазин відповідає на замовлення відмовою not_active.

Тіло замовлення

POST /api/v1/orders/check і POST /api/v1/orders приймають одне й те саме тіло. Спершу надішліть його на перевірку, потім те саме на створення.

{
    "external_id": "SITE-1024",
    "scheme": "a",
    "items": [
        { "product_id": 1045, "sku_id": 2108, "qty": "2", "sale_price": "1200" }
    ],
    "recipient": {
        "last_name": "Шевченко",
        "first_name": "Олена",
        "phone": "+380671234567"
    },
    "delivery": {
        "method_id": 3,
        "city": "Київ",
        "point_ref": "1ec09d88-e1c2-11e3-8c4a-0050568002cf",
        "point_type": "warehouse"
    },
    "payment": { "method_id": 1 },
    "comment": "Зателефонувати перед відправленням",
    "expected_total": "2470.00"
}

Поля тіла

Поле Тип Потрібне Що означає
items список так позиції замовлення, як у звичайного партнера, плюс поле sale_price
recipient об’єкт так отримувач посилки, ваш покупець. Описано нижче
delivery об’єкт так доставка у відділення чи поштомат. Описано нижче
scheme рядок ні схема розрахунку a або b. Описано нижче
payment об’єкт ні оплата. Описано нижче
cod_amount рядок або число ні скільки кур’єр візьме з покупця, лише в схемі b
external_id рядок ні ваш номер замовлення, до 64 знаків
expected_total рядок або число ні підсумок, який ви очікуєте. Він містить доставку
comment рядок ні коментар для магазину, до 2000 знаків
storefront_id ціле ні замовлення дропшиперів приймає одна вітрина, яку вибрав власник. Поле можна не передавати, а якщо передати, то лише номер цієї вітрини
locale рядок ні мова замовлення, одна з мов цієї вітрини. Якщо не передати, береться її основна мова

Пробіли по краях рядків магазин відкидає. На поле, якого він не знає, надходить помилка 422 validation_failed, як і у звичайного партнера.

Причини відмови й попередження надходять мовою запиту із заголовка Accept-Language. Саме замовлення магазин записує мовою з поля locale.

Отримувач recipient

Поле Потрібне Що означає
last_name так прізвище, до 190 знаків
first_name так ім’я, до 190 знаків
middle_name ні по батькові, до 190 знаків
phone так телефон, до 32 знаків, наприклад +380671234567

Магазин відправить посилку на ім’я цієї людини. Замовником у замовленні залишається дропшипер.

Доставка delivery

Поле Потрібне Що означає
method_id так номер способу доставки, ціле число або рядок із цифр
city так місто відділення, до 190 знаків. Підходить українська або російська назва, наприклад Київ або Киев
point_ref так код відділення чи поштомата в перевізника, до 64 знаків. Для «Нова Пошта» це Ref
point_type ні warehouse для відділення або postomat для поштомата. Якщо не передати, магазин шукає серед відділень

Магазин сам знаходить у способу доставки потрібне поле й перевіряє, що таке відділення є в списку, який він порахував для цього міста й цієї посилки. У «Нова Пошта» поштомат шукається лише за "point_type": "postomat", серед відділень його немає. Доставки за адресою кур’єром через API немає.

Схема розрахунку scheme

Значення Як рахуються гроші
a покупець платить магазину вашу ціну продажу й доставку. Коли покупець забере посилку, різниця між ціною продажу та вашою ціною надійде вам на баланс
b ви платите магазину свою ціну й доставку самі. Якщо кур’єр бере гроші з покупця (cod_amount), після викупу ця сума надходить вам на баланс

Якщо поле не передати, магазин вибере a, коли ваш рівень її дозволяє, а інакше b. На схему, якої немає у вашого рівня, магазин відповість відмовою scheme_not_allowed.

Ціна продажу items[].sale_price. Лише для схеми a. Це ціна однієї одиниці для покупця у валюті вітрини, до двох знаків після крапки. Якщо її не передати, товар продається за рекомендованою ціною магазину, тобто за роздрібною. Вона не може бути нижчою за вашу ціну, інакше надійде відмова below_drop. Продавати нижче за роздрібну можна. Замовлення приймуть із попередженням below_retail, і магазин цю позначку теж побачить. Знижки кошика магазину до замовлення не застосовуються.

У схемі b позиції йдуть за вашою ціною, і sale_price передавати не можна.

Оплата payment

Вигляд Що означає
{ "method_id": 1 } спосіб оплати магазину. У схемі a так платить покупець, наприклад під час отримання. У схемі b так платите ви, а способи з оплатою під час отримання в цій схемі не приймаються
{ "balance": true } магазин спише підсумок замовлення з вашого балансу під час оформлення. Лише в схемі b

Поле можна не передавати, якщо для цього замовлення в магазину підходить рівно один спосіб оплати. Тоді магазин підставить його сам. Якщо відповідних способів кілька, буде відмова payment_required.

Під час оплати з балансу магазин не витрачає гроші, на які ви вже попросили виплату. Якщо їх не вистачає, буде відмова not_enough_balance. Якщо в схемі b ви вибрали звичайний спосіб оплати, посилання на сторінку оплати API не віддає. Якщо в способу є сторінка оплати, оплатити замовлення можна в кабінеті кнопкою «Оплатити» в замовленні.

Накладений платіж cod_amount. Це сума, більша за нуль, яку кур’єр візьме з покупця, у валюті вітрини, до двох знаків після крапки. Поле працює лише в схемі b. Якщо його не передати, кур’єр нічого з покупця не бере.

Де взяти номери

  • Товар і артикул беруться з каталогу /products або /skus, як у звичайного партнера. Ваші ціни віддає /prices, залишки віддає /inventory.
  • Спосіб доставки й спосіб оплати беруться з GET /api/v1/shipping_methods і GET /api/v1/payment_methods, поле id. Ці адреси віддають усі способи магазину, а власник може залишити дропшиперам лише частину. Якщо спосіб вам недоступний або не возить посилку в місто отримувача, надійде відмова delivery_not_allowed.
  • Ref відділення чи поштомата «Нова Пошта» береться з довідника самої «Нова Пошта». Це поле Ref у відповіді її методу Address.getWarehouses. Власної адреси зі списком відділень в API магазину немає.

POST /api/v1/orders/check

Рахує замовлення, нічого не створюючи. Право: orders:create. Відповідь 200 надходить, навіть коли замовлення створити не можна, тому дивіться на can_place і problems. Помилки форми тіла надходять відповіддю 422 validation_failed.

curl https://shop.example.ua/api/v1/orders/check \
  -X POST \
  -H "Authorization: Bearer <ключ>" \
  -H "Content-Type: application/json" \
  -d @order.json

Відповідь на тіло з прикладу вище. Роздрібна ціна товару 1000 грн, знижка рівня 20%, доставка 70 грн:

{
    "data": {
        "can_place": true,
        "storefront_id": 1,
        "locale": "uk",
        "currency": "UAH",
        "rate": "1.000000",
        "base_currency": "UAH",
        "items": [
            {
                "index": 0,
                "product_id": 1045,
                "sku_id": 2108,
                "name": "Крем для рук 50 мл",
                "qty_requested": "2.000",
                "qty": "2.000",
                "price": "1200.00",
                "compare_price": null,
                "total": "2400.00",
                "is_gift": false,
                "problems": []
            }
        ],
        "discounts": [],
        "totals": {
            "items_total": "2400.00",
            "services_total": "0.00",
            "discount_total": "0.00",
            "shipping_total": "70.00",
            "total": "2470.00"
        },
        "problems": [],
        "extensions": {
            "dropshipping": {
                "scheme": "a",
                "shipping": { "method_id": 3, "option_id": "3:nova_poshta", "name": "Нова Пошта" },
                "currency": "UAH",
                "lines_currency": "UAH",
                "drop_total": "1600.00",
                "margin": "800.00",
                "balance": "350.00",
                "lines": [
                    { "sku_id": 2108, "sale_price": "1200.00", "drop_price": "800.00", "retail": "1000.00", "below_retail": false }
                ]
            }
        }
    }
}

Від відповіді звичайного партнера вона відрізняється в кількох місцях.

  • У totals є shipping_total, і total містить доставку. З цим підсумком порівнюється expected_total.
  • price позиції в схемі a дорівнює ціні продажу, у схемі b вашій ціні. compare_price тут завжди null.
  • Знижок кошика в замовленні дропшипера немає, тому discounts порожній.
  • В extensions.dropshipping лежать ваші суми.
Поле extensions.dropshipping Що означає
scheme схема, за якою пораховано замовлення
shipping спосіб доставки, який магазин знайшов за method_id, з полями method_id, option_id і name. null, якщо доставку підібрати не вдалося
currency основна валюта магазину. У ній надходять drop_total, margin і balance, як у вашому журналі грошей
lines_currency валюта замовлення. У ній надходять ціни в lines
drop_total товари за вашою ціною
margin ваша різниця в схемі a. У схемі b завжди "0.00"
balance ваш баланс зараз. Гроші, на які ви вже попросили виплату, з нього не вираховано
lines для кожної позиції sku_id, ціна продажу sale_price, ваша ціна drop_price, роздрібна ціна retail і below_retail, чи продаєте ви дешевше за роздрібну

POST /api/v1/orders

Створює замовлення. Право: orders:create. Потрібен заголовок Idempotency-Key, як у звичайного партнера.

curl https://shop.example.ua/api/v1/orders \
  -X POST \
  -H "Authorization: Bearer <ключ>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: site-SITE-1024" \
  -d @order.json

Відповідь 201 Created із замовленням повністю. Поля замовлення описано на сторінці «Замовлення: адреси й поля». На відміну від звичайного партнера, у вашого замовлення одразу заповнені recipient, shipping і payment, а доставка входить у підсумок. Канал замовлення називається «Дропшипер: ім’я».

{
    "data": {
        "id": 5120,
        "number": "#1005120",
        "external_id": "SITE-1024",
        "status": "new",
        "...": "усі поля замовлення",
        "extensions": {
            "dropshipping": {
                "scheme": "a",
                "state": "waiting",
                "source": "api",
                "external_id": "SITE-1024",
                "currency": "UAH",
                "buyer_total": "2470.00",
                "drop_total": "1600.00",
                "margin": "800.00",
                "from_balance": false,
                "below_retail": false,
                "returning": false,
                "returned_at": null,
                "supplier_fault": false
            }
        }
    },
    "warnings": []
}

Блок extensions.dropshipping надходить і в GET /orders та GET /orders/{id}, зокрема в замовлень, які ви оформили в кабінеті. У звичайних замовлень поля extensions немає.

Поле Що означає
scheme схема розрахунку, a або b
state що з вашими грошима за замовленням: waiting — чекає викупу, credited — викуплено й гроші нараховано, refused — покупець відмовився від посилки, canceled — скасовано або гроші покупцю повернули
source звідки надійшло замовлення, api з вашого сайту або cabinet з кабінету
external_id ваш номер замовлення або null
currency основна валюта магазину. Усі суми блоку в ній
buyer_total у схемі a скільки платить покупець, у схемі b скільки кур’єр візьме з покупця
drop_total товари за вашою ціною
margin ваша різниця в схемі a, у схемі b "0.00"
from_balance замовлення оплачено з вашого балансу
below_retail ви продали дешевше за роздрібну ціну магазину
returning відмовна посилка їде назад на склад, а гроші за товар чекають її повернення
returned_at коли відмовна посилка повернулася на склад, або null
supplier_fault магазин визнав відмову своєю виною й нічого за неї не утримав

Попередження

Замовлення з попередженням усе одно створюється. Крім попередження backorder, яке буває й у звичайного партнера, у вас буває below_retail.

code Поля Коли
below_retail sku_id, sale_price, retail і currency, валюта обох цін. Це валюта замовлення позицію продано дешевше за роздрібну ціну магазину. Текст: «Позицію продано дешевше за роздрібну ціну магазину. Замовлення прийнято, магазин бачить цю позначку.»

Помилки

Спершу магазин перевіряє поля, які є в будь-якого партнера, а потім ваші. Тому після виправлення першої порції помилок може надійти друга.

422 validation_failed

Помилки у ваших полях надходять усі одразу. Ключ кожної помилки — шлях до поля, наприклад recipient.phone.

Поле в errors Повідомлення
recipient, delivery, recipient.last_name, recipient.first_name, recipient.phone, delivery.city, delivery.point_ref «Поле обов’язкове.»
recipient, delivery, payment, якщо передано не об’єкт «Очікується об’єкт.»
recipient.nickname та інші зайві поля в об’єкті «Невідоме поле. Допустимі: last_name, first_name, middle_name, phone.» зі списком полів цього об’єкта
рядок, довший за межу, або не рядок «Очікується рядок не довший за 190 знаків.» з межею поля
delivery.method_id «Очікується номер способу доставки з /shipping_methods.»
delivery.point_type «point_type приймає warehouse (відділення) або postomat (поштомат).»
scheme «Вкажіть схему a або b.»
payment «Вкажіть method_id способу оплати або balance: true.»
payment.balance «З балансу можна платити лише в схемі b.»
cod_amount, якщо схема не b «cod_amount передають лише в схемі b.»
items.N.sale_price, якщо схема не a «sale_price передають лише в схемі a. У схемі b покупець сплачує при отриманні суму з cod_amount.»
cod_amount, items.N.sale_price з неправильною сумою «Очікується сума більша за нуль, до двох знаків після крапки.»
storefront_id «Замовлення дропшиперів приймає одна вітрина магазину. Не передавайте storefront_id або передайте її номер.»
locale «Мова замовлення — одна з мов вітрини: uk, ru.» зі списком мов вітрини

422 cannot_place

Замовлення зібрати не можна. Причини надходять списком problems, у кожної є field, code і message. Перевіряйте в програмі code, бо текст може змінюватися. У відповіді /orders/check причини стоять у problems, а причини позицій ще й у problems самої позиції.

Перевірка називає ті самі причини, що й створення замовлення, зокрема схему, спосіб оплати, гроші на балансі й обов’язкові поля способу доставки. Якщо є хоч одна причина, у відповіді стоїть "can_place": false. Гроші на балансі перевірка звіряє із сумою, на яку ви ще не попросили виплату, а остаточно магазин перевіряє їх під час списання.

Коди причин у ключа дропшипера свої й відрізняються від кодів звичайного партнера.

code field Коли
not_active partner магазин ще не схвалив заявку, призупинив або закрив роботу з вами
scheme_not_allowed scheme цієї схеми немає у вашого рівня
external_id_taken external_id лише у відповіді /orders/check: у вас уже є замовлення з цим номером, зокрема оформлене в кабінеті
not_found items.N товару немає в каталозі, його не опубліковано або артикул належить іншому товару
not_for_sale items.N артикул зараз не продається
out_of_stock items.N на складі менше, ніж у замовленні. Скільки є, сказано в тексті
qty_not_allowed items.N кількість менша за мінімальну або не кратна кроку. Мінімум і крок сказано в тексті
below_drop items.N.sale_price ціна продажу нижча за вашу ціну
delivery_not_allowed delivery.method_id способу з таким номером немає серед доступних вам або він не возить цю посилку в це місто
point_not_found delivery.point_ref відділення з таким кодом немає в цьому місті серед відділень чи поштоматів способу
field_required delivery.city або delivery.point_ref у способу доставки залишилося незаповненим обов’язкове поле. Його назву сказано в тексті
shipping_required, shipping_not_allowed delivery.method_id доставку підібрати не вдалося або вона недоступна дропшиперам
payment_required payment оплату не передали, а відповідних способів більше ніж один або немає жодного
payment_not_allowed payment цей спосіб оплати недоступний дропшиперам або не підходить схемі
not_enough_balance payment на балансі не вистачає грошей. Скільки є й скільки потрібно, сказано в тексті
stock_reserve_failed items буває лише під час створення, якщо поки замовлення оформлювалося, частина товару закінчилася. У полі products для кожного артикула sku_id, name і short_qty
invalid поле, якого стосується відмова буває лише під час створення, якщо магазин не прийняв замовлення з іншої причини. Причину названо в тексті
{
    "type": "https://cartixx.com/docs/api/errors#cannot-place",
    "title": "Дані не пройшли перевірку",
    "status": 422,
    "detail": "Замовлення не створено. Причини перелічено в полі problems.",
    "code": "cannot_place",
    "request_id": "P8W3NB2Z",
    "problems": [
        {
            "field": "delivery.point_ref",
            "code": "point_not_found",
            "message": "У цього способу доставки немає відділення 1ec09d88-e1c2-11e3-8c4a-0050568002cf у місті «Львів». Перевірте Ref і point_type."
        }
    ]
}

Під час створення відмова point_not_found або delivery_not_allowed надходить одна, без інших причин, бо без доставки решту магазин не перевіряє. Перевірка /orders/check називає її разом з іншими причинами, але не дублює її причинами за полями delivery.

409 total_mismatch

Якщо ви передали expected_total, а підсумок магазину з доставкою інший, замовлення не створюється. Відповідь та сама, що у звичайного партнера, підсумок магазину в полі actual_total. У відповіді /orders/check розбіжність надходить причиною total_mismatch у problems.

Номер замовлення й повтор

Якщо external_id уже зайнятий вашим замовленням, переданим через API чи оформленим у кабінеті, відповідь буде 409 external_id_taken з номером цього замовлення в order_id, як у звичайного партнера. Перевірка /orders/check повідомляє про такий номер причиною external_id_taken у problems.

Повтор із тим самим Idempotency-Key і тим самим тілом повертає вже створене замовлення й нічого не списує з балансу вдруге. Докладніше на сторінці «Замовлення партнера».

503 order_unavailable

Якщо магазин цієї хвилини не може визначити, за якими правилами приймати замовлення з вашим ключем, він відповідає 503 order_unavailable і замовлення не створює. У полі reference надходить код звернення. Повторіть запит пізніше з тим самим Idempotency-Key. Якщо відповідь повторюється, повідомте магазину цей код.

Повідомлення про замовлення

Щоб не опитувати магазин, увімкніть повідомлення в розділі «Підключення» кабінету, у блоці «Повідомлення на сайт». Вкажіть «Адресу сайту для повідомлень», позначте події й увімкніть «Надсилати повідомлення». Там же є «Секрет підпису», кнопка «Надіслати перевірку» і журнал надсилань.

Подія в кабінеті type повідомлення
«Змінився статус замовлення» order.status_changed
«Замовлення змінилося» order.updated, зокрема коли з’явився чи змінився номер накладної. Тоді в changed є waybill
«Змінилися ціни» prices.changed
«Змінилися залишки» inventory.changed

Отримавши повідомлення про замовлення, запитайте його через GET /orders/{id}. У відповіді будуть новий статус, shipping.waybill_number і блок extensions.dropshipping. Вигляд повідомлень, підпис і повтори описано на сторінці «Повідомлення партнерові (вебхуки)», перевірку підпису — у розділі «Перевірка підпису».

Приклад на PHP

Сайт спершу перевіряє замовлення, а потім створює його з очікуваним підсумком і ключем повтору. Номер замовлення на сайті слугує і external_id, і основою ключа повтору.

function cartixPost(string $path, array $body, string $key, ?string $idempotency = null): array
{
    $headers = [
        'Authorization: Bearer '.$key,
        'Content-Type: application/json',
        'Accept: application/json',
    ];

    if ($idempotency !== null) {
        $headers[] = 'Idempotency-Key: '.$idempotency;
    }

    $ch = curl_init('https://shop.example.ua/api/v1/'.$path);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
    ]);
    $response = json_decode(curl_exec($ch), true);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return [$status, $response];
}

$key = getenv('CARTIX_KEY');
$order = [
    'external_id' => 'SITE-1024',
    'items' => [['product_id' => 1045, 'sku_id' => 2108, 'qty' => '2', 'sale_price' => '1200']],
    'recipient' => ['last_name' => 'Шевченко', 'first_name' => 'Олена', 'phone' => '+380671234567'],
    'delivery' => ['method_id' => 3, 'city' => 'Київ', 'point_ref' => '1ec09d88-e1c2-11e3-8c4a-0050568002cf'],
    'payment' => ['method_id' => 1],
];

[$status, $check] = cartixPost('orders/check', $order, $key);

if ($status !== 200 || ! $check['data']['can_place']) {
    // Помилки форми — у $check['errors'], причини відмови — у problems
    throw new RuntimeException(json_encode($check['errors'] ?? $check['data']['problems'], JSON_UNESCAPED_UNICODE));
}

$order['expected_total'] = $check['data']['totals']['total'];
[$status, $created] = cartixPost('orders', $order, $key, 'site-'.$order['external_id']);

if ($status === 201) {
    $orderId = $created['data']['id'];
} elseif ($status === 409 && $created['code'] === 'external_id_taken') {
    $orderId = $created['order_id']; // замовлення вже прийняте раніше
} else {
    throw new RuntimeException("{$created['code']}: {$created['detail']} (request_id {$created['request_id']})");
}

Чого немає

  • Доставки кур’єром за адресою. Приймається лише відділення чи поштомат.
  • Знижок кошика й промокодів у замовленні дропшипера.
  • Посилання на сторінку оплати у відповідях API.
  • Правки й скасування замовлення через API. Щоб змінити чи скасувати замовлення, зв’яжіться з магазином.
  • Списку відділень перевізника в API магазину.
Оновлено 25 жовтня 2026