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

Заказы партнёра

Как магазин принимает заказ дропшиппера: на кого он записывается, по каким ценам считается, когда магазин отказывает и как не создать заказ дважды.

На этой странице

Через 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. Чтобы изменить или отменить заказ, свяжитесь с магазином.
Обновлено 19 октября 2026