Заказы: адреса и поля
Тело заказа поле за полем, проверка и создание заказа, список заказов, все поля ответа, причины отказа и коды ошибок.
На этой странице
Здесь описаны адреса заказов: тело заказа поле за полем, ответы, коды ошибок и все причины, по которым магазин не принимает заказ. Как магазин принимает заказ партнёра, по каким ценам его считает и как не создать заказ дважды, описано на странице «Заказы партнёра».
| Адрес | Право | Список |
|---|---|---|
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 |
нет |
В примерах адрес магазина shop.example.ua, ключ выдан контакту «Коваленко
Олег» (номер 418), а витрина №1 продаёт в гривнах на украинском языке.
Тело заказа
POST /orders/check и POST /orders принимают одно и то же тело: объект
JSON. Сначала отправьте его на проверку, потом то же самое на создание.
Проверка тоже принимает external_id и заранее сообщает, не занят ли этот
номер.
Магазин читает тело как JSON, какой бы ни был заголовок Content-Type. Если
тело не объект JSON (непустой список, строка, разметка с ошибкой), ответ 400 с
кодом bad_json. Пустое тело и пустой список [] считаются пустым объектом,
и на них придёт 422 с сообщением, что нет позиций.
У этих двух адресов в строке запроса можно передать только locale, язык
текстов ошибок. Любой другой параметр, например ?storefront_id=2, получает
422 с кодом validation_failed: все данные заказа передаются в теле.
{
"storefront_id": 1,
"external_id": "A-1024",
"items": [
{ "product_id": 1045, "sku_id": 2108, "qty": "2" }
],
"comment": "Упакуйте подарком",
"expected_total": "416.64",
"locale": "uk"
}
Поля тела
| Поле | Тип | Нужно | Что значит |
|---|---|---|---|
items |
список | да | позиции заказа, от 1 до 100, описаны ниже |
comment |
строка или null |
нет | комментарий к заказу, до 2000 знаков. Менеджер видит его в заказе |
external_id |
строка или null |
нет | номер заказа в вашей системе, до 64 знаков. Уникален в пределах ключа API, подробнее на странице «Заказы партнёра» |
expected_total |
строка или число | нет | итог, который вы ожидаете, в валюте витрины, до двух знаков после точки: "416.64". Если итог магазина другой, заказ не создаётся, подробнее на странице «Заказы партнёра» |
storefront_id |
целое | нет | номер витрины заказа. От витрины зависят валюта и язык. Если не передать, заказ пойдёт на основную витрину, а если она выключена, на первую включённую. Номера витрин отдаёт /storefronts |
locale |
строка | нет | язык заказа, один из языков витрины. На нём в заказ записываются названия товаров. Если не передать, берётся основной язык витрины |
Других полей нет. Доставку (shipping), способ оплаты (payment_method_id),
получателя (recipient) и промокод (coupon) через API не передают, их
назначает менеджер в панели. Такие поля получают 422, как любое неизвестное
поле.
Учтите несколько правил:
- Номера (
storefront_id,product_id,sku_id) принимаются целым числом или строкой из цифр:5и"5". Номер с точкой ("5.0") не подходит. - Строки обрезаются по краям от пробелов. Пустая строка в
external_idиcommentзначит то же, что поле не передано. - Поле, которого магазин не знает, — ошибка, а не пропуск. Магазин отвечает 422 и перечисляет допустимые поля.
- Язык заказа (
localeв теле) и язык ответа (?locale=в адресе или заголовокAccept-Language) — разные вещи. Язык ответа влияет только на тексты ошибок, причин отказа и предупреждений. - Витрину магазин проверяет первой. Если
storefront_idневерный, ответ называет только эту ошибку, остальные поля не проверяются.
Позиция items
| Поле | Тип | Нужно | Что значит |
|---|---|---|---|
product_id |
целое | да | номер товара, поле id товара в /products |
sku_id |
целое | да | номер артикула этого товара, поле id артикула в /products или /skus |
qty |
строка или число | да | количество в единицах продажи товара (поле unit), больше нуля и не больше 1 000 000, до трёх знаков после точки: "2", "1.5", "0.250" |
Оба номера обязательны, и артикул должен принадлежать товару. Код артикула
(sku) или штрихкод вместо номера магазин не принимает: найдите номер через
/skus с параметром sku или
barcode.
Один артикул — одна позиция. Если передать артикул дважды, магазин ответит 422 и назовёт позицию, где он уже есть: сложите количества сами. Других полей у позиции нет: цену, упаковку или услугу передать нельзя.
Количество должно подходить под правила продажи артикула: не меньше его
qty_min и от минимума кратно qty_step. Оба поля есть у артикула в
каталоге. Если количество не подходит,
магазин не округляет его, а отказывает с причиной qty_not_allowed и
называет ближайшее подходящее количество.
Ошибки тела
На ошибки в теле магазин отвечает 422 с кодом validation_failed. В поле
errors приходят все ошибки сразу, по пути к полю: items.2.qty,
items.0.product_id. Ключ повтора при такой ошибке не занимается, и
исправленный запрос можно отправить с тем же Idempotency-Key.
{
"type": "https://cartixx.com/docs/api/errors#validation-failed",
"title": "Данные не прошли проверку",
"status": 422,
"detail": "Данные не прошли проверку. Подробности в поле errors.",
"code": "validation_failed",
"request_id": "K2M7QX4D",
"errors": {
"shipping": ["Такого поля здесь нет. Допустимые поля: storefront_id, external_id, items, comment, expected_total, locale."],
"items.0.sku_id": ["В поле sku_id нужен номер из адреса /products, целое число больше нуля. Код артикула и штрихкод магазин здесь не принимает."],
"items.1.product_id": ["Передайте поле product_id. Этот номер отдаёт адрес /products."]
}
}
| Когда | Поле в errors |
Сообщение |
|---|---|---|
параметр в строке адреса, кроме locale |
имя параметра | «Такого параметра у этого адреса нет. Допустимые параметры: locale.» |
поле, которого нет в теле, в том числе shipping, payment_method_id, recipient, coupon |
имя поля | «Такого поля здесь нет. Допустимые поля: storefront_id, external_id, items, comment, expected_total, locale.» |
| поле, которого нет в позиции | путь к полю, например items.1.price |
«Такого поля здесь нет. Допустимые поля: product_id, sku_id, qty.» |
| витрины с таким номером нет или она выключена | storefront_id |
«Витрины с таким номером нет или она выключена. Номера витрин отдаёт адрес /storefronts.» |
| у магазина нет ни одной включённой витрины | storefront_id |
«У магазина нет ни одной включённой витрины.» |
items нет, он пустой или не список |
items |
«Передайте позиции заказа списком items: от 1 до 100 позиций.» |
| позиций больше 100 | items |
«В одном заказе может быть не больше 100 позиций.» |
| позиция не объект | items.N |
«Здесь нужен объект JSON.» |
product_id или sku_id не передан или равен null |
items.N.product_id, items.N.sku_id |
«Передайте поле product_id. Этот номер отдаёт адрес /products.» с именем поля |
product_id или sku_id не целое положительное число, например код артикула |
items.N.product_id, items.N.sku_id |
«В поле sku_id нужен номер из адреса /products, целое число больше нуля. Код артикула и штрихкод магазин здесь не принимает.» с именем поля |
| артикул уже есть в другой позиции | items.N.sku_id |
«Этот артикул уже есть в items.0. Передайте его одной позицией с общим количеством.» |
| неверное количество | items.N.qty |
«Количество — число больше нуля и не больше 1000000, до трёх знаков после точки, например "2" или "1.5".» |
| языка нет у витрины | locale |
«Этого языка у витрины нет. Допустимые языки: uk, ru.» |
external_id или comment не строка |
имя поля | «Значение должно быть одной строкой.» |
external_id длиннее 64 знаков, comment длиннее 2000 |
имя поля | «Значение должно быть не длиннее 64 знаков.» с пределом поля |
expected_total не сумма |
expected_total |
«Сумма — число не меньше нуля, до двух знаков после точки, например "1250.00".» |
POST /api/v1/orders/check
Считает заказ, ничего не создавая. Право: orders:create. Отвечает ценами
позиций для вашего контакта, скидками, подарками по акции и итогом. Главное в
ответе — поле can_place и список problems: можно ли создать такой заказ, а
если нельзя, то почему.
Проверка не оставляет в магазине ничего: ни заказа, ни корзины, ни занятого
номера external_id. Товар она не резервирует, поэтому can_place: true не
обещает, что товар никто не купит раньше вас. Заголовок Idempotency-Key
проверке не нужен.
Тело то же, что у POST /orders, и проверяется так же строго: ошибки в полях
тела приходят ответом 422 validation_failed, а не в problems. Если поля
тела прошли проверку, ответ всегда 200, даже когда заказ создать нельзя.
Доставки, оплаты, получателя и промокода в расчёте нет: их назначает менеджер в панели, и в итог доставка не входит.
curl https://shop.example.ua/api/v1/orders/check \
-X POST \
-H "Authorization: Bearer <ключ>" \
-H "Content-Type: application/json" \
-d @order.json
Ответ на тело из примера выше. Скидок на этот товар в магазине нет, поэтому
итог равен сумме товаров и совпадает с expected_total:
{
"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": "208.32",
"compare_price": "320.00",
"total": "416.64",
"is_gift": false,
"problems": []
}
],
"discounts": [],
"totals": {
"items_total": "416.64",
"services_total": "0.00",
"discount_total": "0.00",
"total": "416.64"
},
"problems": []
}
}
Поля ответа проверки
| Поле | Тип | Что значит |
|---|---|---|
can_place |
логическое | true — такой заказ POST /orders примет, если до создания в магазине ничего не изменится. false — не примет, причины в problems |
storefront_id |
целое | витрина заказа: из тела или выбранная магазином |
locale |
строка | язык заказа. На нём приходят названия товаров в этом ответе |
currency |
строка | валюта заказа, код ISO 4217. Все суммы ответа в ней |
rate |
строка | курс: сколько единиц основной валюты стоит одна единица валюты заказа, шесть знаков после точки |
base_currency |
строка | основная валюта магазина |
items |
список | позиции, описаны ниже |
discounts |
список | скидки, которые вошли в заказ: name — название скидки, amount — её сумма |
totals |
объект | суммы заказа, описаны ниже |
problems |
список | причины, по которым заказ не принять. Пустой, если can_place равно true. Описаны в разделе «Причины отказа» |
Позиция в items. Сначала идут ваши позиции в порядке запроса, за ними
подарки, которые положил магазин.
| Поле | Тип | Что значит |
|---|---|---|
index |
целое или null |
номер позиции в items запроса, с нуля. null у подарка |
product_id |
целое или null |
номер товара, как в запросе. У подарка — номер товара подарка |
sku_id |
целое или null |
номер артикула, как в запросе. У подарка бывает null |
name |
строка или null |
название позиции на языке заказа. null, если артикула нет в каталоге |
qty_requested |
строка или null |
сколько вы заказали. null у подарка |
qty |
строка | сколько вошло в заказ. "0.000", если позиция в заказ не вошла |
price |
строка или null |
цена одной единицы для вашего контакта. null, если позиция в заказ не вошла |
compare_price |
строка или null |
старая, зачёркнутая цена единицы |
total |
строка | сумма позиции: цена, умноженная на количество, до скидок заказа |
is_gift |
логическое | позицию положил магазин по акции |
problems |
список | причины отказа, которые относятся к этой позиции. Те же, что в общем problems, только без поля field |
Суммы totals. Все в валюте заказа, два знака после точки.
| Поле | Что значит |
|---|---|
items_total |
сумма позиций до скидок заказа |
services_total |
сумма услуг. Через API услуги не передаются, поэтому "0.00" |
discount_total |
сумма скидок заказа |
total |
итог заказа: товары после скидок, без доставки. С ним сравнивается expected_total |
Ниже ответ для случая, когда заказ не принять: заказано пять штук, а на складе две.
{
"data": {
"can_place": false,
"...": "...",
"items": [
{
"index": 0,
"product_id": 1045,
"sku_id": 2108,
"name": "Крем для рук 50 мл",
"qty_requested": "5.000",
"qty": "0.000",
"price": null,
"compare_price": null,
"total": "0.00",
"is_gift": false,
"problems": [
{ "code": "out_of_stock", "product_id": 1045, "sku_id": 2108, "available": "2.000", "message": "На складе меньше, чем в заказе: доступно 2.000." }
]
}
],
"problems": [
{ "field": "items.0.qty", "code": "out_of_stock", "product_id": 1045, "sku_id": 2108, "available": "2.000", "message": "На складе меньше, чем в заказе: доступно 2.000." }
]
}
}
POST /api/v1/orders
Создаёт заказ. Право: orders:create. Тело описано выше.
Заказ создаётся без доставки, оплаты и получателя: их назначает менеджер в
панели.
| Заголовок запроса | Нужен | Что даёт |
|---|---|---|
Idempotency-Key |
всегда | строка до 255 печатных знаков ASCII, своя у каждого заказа. По ней магазин узнаёт повтор и не создаёт заказ дважды. Подробно на странице «Заказы партнёра» |
Content-Type: application/json |
желательно | тело — JSON |
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 @order.json
Ответ 201 Created:
| Заголовок ответа | Что значит |
|---|---|
Location |
полный адрес заказа в API: https://shop.example.ua/api/v1/orders/5120 |
Idempotent-Replayed: true |
приходит, если это повтор запроса и заказ был создан раньше. У первого ответа заголовка нет |
{
"data": {
"id": 5120,
"number": "#1005120",
"external_id": "A-1024",
"status": "new",
"...": "все поля заказа"
},
"warnings": []
}
В data приходит заказ целиком, его поля описаны в разделе
«Поля заказа». Ответ приходит и ключу без права
orders:read.
В warnings магазин сообщает, что вам стоит знать о принятом заказе. Заказ при
этом создан.
code |
Дополнительные поля | Когда |
|---|---|---|
backorder |
sku_id, qty |
часть товара ждёт поступления на склад: в магазине разрешён заказ сверх остатка. qty — сколько ждёт. Пример текста: «Артикул 2108 в количестве 3.000 ждёт поступления на склад.» |
У каждого предупреждения есть и поле message с текстом на языке ответа. У
ответа на повтор warnings всегда пустой список.
В каком порядке проверяется запрос
Если в запросе несколько проблем, ответ называет первую по порядку:
- Общие проверки ключа и магазина, как у всех адресов (см. «Ошибки и их коды»).
- В строке адреса нет параметров, кроме
locale(422validation_failed). - Заголовок
Idempotency-Keyесть и верный. Если его нет или в нём одни пробелы, ответ 428idempotency_key_required. Если он неверного вида, ответ 400bad_idempotency_key. - Тело — объект JSON (400
bad_json). - Ключ повтора. Если первый запрос с этим ключом ещё оформляется, ответ 409
idempotency_in_progress, какое бы ни было тело. Иначе магазин сравнивает тело с первым запросом: другое тело получит 422idempotency_key_reused. Если тело то же и заказ уже создан, магазин сразу отдаёт этот заказ, ничего больше не проверяя. Если заказ ключу больше не виден — 409idempotency_order_hidden. - Поля тела (422
validation_failed). - Номер
external_idне занят (409external_id_taken,external_id_in_progress). - Заказ можно собрать ровно как прислан (422
cannot_place). - Итог совпадает с
expected_total(409total_mismatch). - Оформление. Здесь магазин ещё раз считает заказ, сверяет итог и
резервирует товар (422
cannot_place, 409total_mismatch, 409order_busy). Изредка здесь же приходит 409idempotency_in_progressилиexternal_id_in_progressс заголовкомRetry-After: 2: пока заказ оформлялся, ключ повтора или номерexternal_idзабрал другой запрос, потому что этот шёл дольше 10 минут.
GET /api/v1/orders
Заказы контакта, которому выдан ключ, из всех каналов. Право: orders:read.
Порядок: по номеру заказа, по возрастанию. Можно листать по offset или по
after_id, как описано на странице
«Запросы и ответы».
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
status |
строка | нет | заказы с этим статусом. Коды статусов отдаёт /order_statuses |
storefront_id |
целое | нет | только заказы этой витрины. В отличие от каталога, параметр не меняет валюту: суммы приходят в валюте заказа |
external_id |
строка | нет | заказ с этим вашим номером, принятый этим ключом. Точное совпадение |
created_since |
дата и время | нет | заказы, созданные начиная с этого момента |
updated_since |
дата и время | нет | заказы, изменённые начиная с этого момента |
limit |
целое | 50 | записей на странице, от 1 до 200 |
offset |
целое | 0 | сколько записей пропустить. Вместе с after_id не передаётся |
after_id |
целое | нет | заказы с номером больше указанного |
locale |
строка | нет | язык текстов ошибок |
Дата и время передаются в формате ISO 8601 с часовым поясом:
2026-10-19T08:00:00Z или 2026-10-19T11:00:00+03:00. Знак + в адресе
нужно записывать как %2B, но магазин поймёт и неэкранированный. Граница
включается: заказ, изменённый ровно в указанную секунду, попадёт в ответ.
Время изменения заказа сдвигается при смене статуса, при оплате и при
правке заказа в панели: состава, сумм, адреса, доставки. Поэтому сюда
попадает и заказ, которому менеджер назначил доставку, оплату или
получателя. Чтобы забирать только изменения, запоминайте время начала
прошлого запроса и передавайте его в updated_since.
curl "https://shop.example.ua/api/v1/orders?updated_since=2026-10-19T08:00:00Z&after_id=0&limit=100" \
-H "Authorization: Bearer <ключ>"
{
"data": [
{ "id": 5120, "number": "#1005120", "external_id": "A-1024", "status": "shipped", "...": "..." }
],
"meta": { "total": 1, "limit": 100, "after_id": 0 },
"links": { "next": null, "prev": null }
}
| Ошибка 422 | Поле в errors |
Сообщение |
|---|---|---|
| неизвестный параметр | имя параметра | «Такого параметра у этого адреса нет. Допустимые параметры: …» |
| статуса с таким кодом нет | status |
«Такого статуса заказа нет. Коды статусов отдаёт адрес /order_statuses.» |
storefront_id не целое положительное число |
storefront_id |
«Нужен номер записи — целое положительное число.» |
external_id или status передан списком |
имя параметра | «Значение должно быть одной строкой.» |
| неверная дата | created_since или updated_since |
«Нужны дата и время в формате ISO 8601, например 2026-10-17T09:00:00Z.» |
неверный limit, offset, after_id, или offset вместе с after_id |
имя параметра | как на странице «Запросы и ответы» |
Номер витрины, которой нет, ошибкой не считается: придёт пустой список.
GET /api/v1/orders/{id}
Один заказ по его номеру в магазине (поле id). Право: orders:read.
curl https://shop.example.ua/api/v1/orders/5120 \
-H "Authorization: Bearer <ключ>"
Ответ — {"data": {…}} с заказом, поля описаны ниже. Если заказа нет или он
принадлежит другому контакту, ответ 404 с кодом not_found. Номер длиннее 18
цифр тоже получает 404.
Адрес принимает только параметр locale. Любой другой параметр, в том числе
storefront_id, limit и offset, получает 422 с сообщением «Такого
параметра у этого адреса нет. Допустимые параметры: locale.»
Поля заказа
Заказ выглядит одинаково в ответе на создание, в списке и в карточке. Суммы приходят в валюте заказа и по его курсу. Цены, курс и состав заказа записываются в момент оформления и потом сами не пересчитываются.
Доставка, оплата и получатель в заказе только для чтения: их назначает
менеджер в панели. В только что созданном заказе shipping и recipient
равны null, у payment есть только состояние оплаты, а доставка в итоге
равна нулю. Пример ниже показывает заказ после того, как менеджер назначил
доставку Новой Почтой, оплату при получении и получателя.
{
"id": 5120,
"number": "#1005120",
"external_id": "A-1024",
"status": "new",
"payment_status": "pending",
"storefront_id": 1,
"locale": "uk",
"currency": "UAH",
"rate": "1.000000",
"base_currency": "UAH",
"channel": { "type": "api", "api_client_id": 3, "name": "API: Сайт партнёра" },
"customer": {
"contact_id": 418,
"name": "Коваленко Олег",
"phone": "+380501112233",
"email": "kovalenko@example.ua",
"company": null
},
"recipient": {
"phone": "+380671234567",
"last_name": "Коваль",
"first_name": "Ірина",
"is_company": false
},
"items": [
{
"id": 9311,
"product_id": 1045,
"sku_id": 2108,
"sku": "730601",
"name": "Крем для рук 50 мл",
"qty": "2.000",
"unit": "pcs",
"price": "208.32",
"compare_price": "320.00",
"discount": "0.00",
"services_total": "0.00",
"total": "416.64",
"is_gift": false,
"backorder_qty": "0.000"
}
],
"totals": {
"items_total": "416.64",
"services_total": "0.00",
"discount_total": "0.00",
"shipping_total": "85.00",
"bonus_total": "0.00",
"tax_total": "0.00",
"total": "501.64",
"paid_total": "0.00",
"due": "501.64"
},
"shipping": {
"method_id": 3,
"option_id": "3:nova_poshta",
"name": "Нова Пошта",
"price": "85.00",
"type": "warehouse",
"city": "Київ",
"point": {
"ref": "1ec09d88-e1c2-11e3-8c4a-0050568002cf",
"number": "1",
"name": "Відділення №1: вул. Пирогівський шлях, 135",
"address": "вул. Пирогівський шлях, 135"
},
"address": {
"country": null,
"region": null,
"city": "Київ",
"street": null,
"building": null,
"apartment": null,
"zip": null
},
"waybill_number": null
},
"payment": {
"method_id": 1,
"name": "Оплата під час отримання",
"status": "pending"
},
"comment": "Упакуйте подарком",
"placed_at": "2026-10-19T08:12:40Z",
"created_at": "2026-10-19T08:12:40Z",
"updated_at": "2026-10-19T09:30:02Z"
}
Тот же заказ сразу после создания:
{
"id": 5120,
"...": "...",
"recipient": null,
"totals": { "items_total": "416.64", "shipping_total": "0.00", "total": "416.64", "due": "416.64", "...": "..." },
"shipping": null,
"payment": { "method_id": null, "name": null, "status": "pending" }
}
| Поле | Тип | Что значит |
|---|---|---|
id |
целое | номер заказа в магазине. По нему заказ открывается в /orders/{id} |
number |
строка | номер заказа так, как его видят в магазине и называют покупателю, например "#1005120". Вид номера задаёт владелец |
external_id |
строка или null |
ваш номер заказа, если заказ пришёл через API с external_id. У заказов из других каналов null |
status |
строка | код статуса заказа. Названия и переходы отдаёт /order_statuses |
payment_status |
строка | состояние оплаты: pending — не оплачен, partial — оплачен частично, paid — оплачен, authorized — деньги заблокированы на карте и спишутся позже, failed — оплата не прошла, refunded — деньги вернули |
storefront_id |
целое или null |
витрина заказа |
locale |
строка или null |
язык заказа |
currency |
строка | валюта заказа, код ISO 4217 |
rate |
строка | курс в момент оформления: сколько единиц основной валюты стоит одна единица валюты заказа, шесть знаков после точки |
base_currency |
строка | основная валюта магазина сейчас |
channel |
объект | откуда пришёл заказ, описан ниже |
customer |
объект | заказчик, описан ниже |
recipient |
объект или null |
получатель, которого назначил менеджер. Набор полей зависит от формы получателя в магазине: код поля и значение строкой, а также признак компании is_company. null, пока получателя нет |
items |
список | позиции заказа, описаны ниже |
totals |
объект | суммы заказа, описаны ниже |
shipping |
объект или null |
доставка, которую назначил менеджер, описана ниже. null, пока доставки нет |
payment |
объект | оплата, описана ниже |
comment |
строка или null |
комментарий к заказу |
placed_at |
дата или null |
когда заказ оформлен |
created_at |
дата | когда заказ появился в магазине |
updated_at |
дата | когда заказ последний раз менялся |
Канал channel.
| Поле | Тип | Что значит |
|---|---|---|
type |
строка | api — пришёл через API, marketplace — с площадки, например Rozetka или Prom, admin — оформил менеджер в панели, storefront — оформлен на витрине |
api_client_id |
целое или null |
номер ключа API, который прислал заказ. Есть только у type: api |
name |
строка или null |
подпись канала. У заказов через API — «API: название ключа», с площадки — её название, из панели и с витрины — название витрины |
Заказчик customer. Данные из карточки контакта на момент оформления.
| Поле | Тип | Что значит |
|---|---|---|
contact_id |
целое или null |
номер контакта заказчика. У заказов по ключу это контакт ключа |
name |
строка или null |
имя заказчика |
phone |
строка или null |
телефон заказчика |
email |
строка или null |
почта заказчика |
company |
строка или null |
компания заказчика. У заказов по ключу приходит, только если карточка контакта — компания |
Позиция в items.
| Поле | Тип | Что значит |
|---|---|---|
id |
целое | номер позиции в заказе |
product_id |
целое или null |
номер товара. null, если товар удалили из каталога |
sku_id |
целое или null |
номер артикула. null, если артикул удалили |
sku |
строка или null |
код артикула в момент оформления |
name |
строка | название позиции в заказе, на языке заказа |
qty |
строка | количество в единицах unit, три знака после точки |
unit |
строка или null |
единица продажи товара, как в каталоге: pcs, m, kg и другие. Если у товара единица не задана, pcs. null, если товар удалили |
price |
строка | цена одной единицы |
compare_price |
строка или null |
старая, зачёркнутая цена единицы |
discount |
строка | доля скидок заказа, которая пришлась на эту позицию. Если магазин хранит скидку заказа одной суммой, а не раскладывает по позициям, здесь "0.00", и скидка видна только в totals.discount_total |
services_total |
строка | сумма услуг позиции |
total |
строка | цена, умноженная на количество, плюс услуги, до скидок заказа |
is_gift |
логическое | позицию положил магазин, это подарок по акции |
backorder_qty |
строка | сколько из количества ждёт поступления на склад. "0.000", если весь товар есть |
Суммы totals. Все в валюте заказа, два знака после точки.
| Поле | Что значит |
|---|---|
items_total |
сумма позиций до скидок |
services_total |
сумма услуг |
discount_total |
скидки заказа |
shipping_total |
стоимость доставки. "0.00", пока менеджер не назначил доставку |
bonus_total |
оплачено бонусами |
tax_total |
налог сверх цен. Обычно "0.00": налог уже входит в цены товаров |
total |
итог заказа |
paid_total |
сколько уже оплачено |
due |
сколько осталось оплатить: итог минус оплаченное, не меньше нуля |
Доставка shipping. null, пока менеджер не назначил доставку.
| Поле | Тип | Что значит |
|---|---|---|
method_id |
целое или null |
номер способа доставки из /shipping_methods |
option_id |
строка или null |
вариант доставки вида <номер способа>:<код варианта> |
name |
строка или null |
название доставки в заказе |
price |
строка | стоимость доставки, та же, что totals.shipping_total |
type |
строка или null |
вид отправления у перевозчика: warehouse — отделение, postomat — почтомат, courier — по адресу. null, если способ вида не называет |
city |
строка или null |
город доставки. Если менеджер поправил адрес, здесь новый город |
point |
объект или null |
отделение или почтомат: ref — код точки у перевозчика, number — номер, name — название, address — адрес. null при доставке по адресу |
address |
объект или null |
адрес доставки: country, region, city, street, building, apartment, zip. При доставке в точку улица, дом и квартира — null |
waybill_number |
строка или null |
номер накладной перевозчика, когда магазин её создал |
Оплата payment.
| Поле | Тип | Что значит |
|---|---|---|
method_id |
целое или null |
номер способа оплаты из /payment_methods. null, пока менеджер не назначил способ |
name |
строка или null |
название способа в заказе. null, пока способа нет |
status |
строка | то же, что payment_status |
API не отдаёт служебные данные заказа: ссылку на страницу оплаты, IP-адрес и браузер покупателя, ответственного сотрудника, историю заказа, номер платежа в банке и закупочные цены.
Причины отказа
Причины приходят списком problems в ответе /orders/check и в ответе 422
cannot_place на POST /orders. У каждой причины есть поля:
| Поле | Что значит |
|---|---|
field |
к какому полю запроса относится причина: items.0.qty, items.1.product_id, items. В problems позиции ответа проверки этого поля нет |
code |
код причины. Ваша программа проверяет именно его, текст message может меняться |
message |
объяснение на языке ответа |
| другие поля | подробности причины, перечислены в таблице |
{
"type": "https://cartixx.com/docs/api/errors#cannot-place",
"title": "Данные не прошли проверку",
"status": 422,
"detail": "Заказ не создан. Причины перечислены в поле problems.",
"code": "cannot_place",
"request_id": "P8W3NB2Z",
"problems": [
{
"field": "items.0.sku_id",
"code": "sku_not_in_product",
"product_id": 1045,
"sku_id": 2240,
"message": "Артикул 2240 не относится к товару 1045. Возьмите product_id и sku_id из одного товара в /products."
},
{
"field": "items.1.qty",
"code": "qty_not_allowed",
"product_id": 1050,
"sku_id": 2251,
"min": "2.000",
"step": "2.000",
"suggested": "4.000",
"message": "Такое количество не продаётся: минимум 2.000, шаг 2.000. Ближайшее подходящее количество — 4.000."
}
]
}
У каждой позиции бывает не больше одной причины. Магазин проверяет позицию в таком порядке: товар, артикул, принадлежность артикула товару, продажа, количество, остаток. На первой же причине проверка позиции останавливается.
У причин позиций всегда есть product_id и sku_id из запроса.
code |
field |
Подробности | Текст | Что делать |
|---|---|---|---|---|
product_not_found |
items.N.product_id |
product_id, sku_id |
«Товара 1045 нет в каталоге или он не опубликован.» Товар черновик, скрыт, в архиве или такого номера нет | уберите позицию, сверьте каталог через /products/ids |
sku_not_found |
items.N.sku_id |
product_id, sku_id |
«Артикула 2108 нет в каталоге.» | возьмите номер артикула из /products |
sku_not_in_product |
items.N.sku_id |
product_id, sku_id |
«Артикул 2240 не относится к товару 1045. Возьмите product_id и sku_id из одного товара в /products.» | передайте номера товара и артикула из одной записи /products |
sku_not_for_sale |
items.N.sku_id |
product_id, sku_id |
«Артикул 2108 снят с продажи.» | уберите позицию |
qty_not_allowed |
items.N.qty |
product_id, sku_id, min, step, suggested |
«Такое количество не продаётся: минимум 2.000, шаг 2.000. Ближайшее подходящее количество — 4.000.» Количество меньше минимума или не кратно шагу, а у товара «только упаковками» не кратно упаковке. suggested — ближайшее подходящее количество, не меньше запрошенного |
закажите suggested или другое подходящее количество |
out_of_stock |
items.N.qty |
product_id, sku_id, available |
«На складе меньше, чем в заказе: доступно 2.000.» На складах, по которым магазин считает наличие для ключа (выбранных в ключе, а если не выбраны — на складах витрины), меньше, чем в заказе, а предзаказ в магазине запрещён. available — сколько можно заказать |
уменьшите количество до available |
external_id_taken |
external_id |
external_id, order_id |
«Заказ с external_id A-1024 уже принят, в магазине у него номер 5120.» Только в проверке | не отправляйте заказ повторно |
total_mismatch |
expected_total |
expected_total, actual_total |
«Итог заказа 416.64 отличается от ожидаемого 400.00.» Только в проверке | сверьте цены и скидки |
stock_reserve_failed |
items |
products |
«Пока заказ оформлялся, часть товара закончилась на складе. Каких артикулов не хватило, указано в поле products. Проверьте наличие и отправьте заказ ещё раз.» Только при создании: товар забрал другой заказ. В products для каждого артикула: sku_id, name и short_qty — сколько не хватило |
проверьте наличие и отправьте заказ ещё раз |
order_rejected |
поле, к которому относится отказ | нет | «Магазин не принял заказ. Сообщите магазину код из поля request_id, по нему найдут ваш запрос.» Только при создании: заказ отклонило дополнение магазина или правило, которое API не умеет назвать | сообщите магазину код из request_id, настоящая причина записана в журнал магазина под этим кодом |
Коды ошибок заказов
Общий вид ответа об ошибке и общие коды описаны на странице «Ошибки и их коды». Здесь собраны коды, которые бывают только у заказов.
| HTTP | code |
Адрес | Когда | Что делать |
|---|---|---|---|---|
| 400 | bad_json |
оба POST |
тело не объект JSON | отправьте объект JSON |
| 400 | bad_idempotency_key |
POST /orders |
ключ повтора длиннее 255 знаков, с кириллицей или переводом строки | используйте латиницу, цифры и знаки препинания, удобнее всего UUID |
| 428 | idempotency_key_required |
POST /orders |
нет заголовка Idempotency-Key |
добавьте заголовок |
| 422 | validation_failed |
все | неверное поле тела или параметр, подробности в errors |
исправьте поля из errors |
| 422 | cannot_place |
POST /orders |
заказ нельзя собрать ровно как прислан, причины в problems |
исправьте заказ по причинам |
| 422 | idempotency_key_reused |
POST /orders |
с этим ключом повтора уже пришёл заказ с другим телом | дайте новому заказу новый ключ |
| 409 | idempotency_in_progress |
POST /orders |
заказ с этим ключом ещё оформляется. Есть Retry-After: 2 |
повторите тот же запрос через 2 секунды |
| 409 | idempotency_order_hidden |
POST /orders |
заказ по этому ключу повтора создан, но ключ API с тех пор привязали к другому контакту | не отправляйте заказ заново, свяжитесь с магазином |
| 409 | external_id_taken |
POST /orders |
заказ с этим external_id уже принят. Номер заказа в order_id, ваш номер в external_id |
не отправляйте заказ заново. Посмотреть его можно в /orders/{order_id}. Если ключ с тех пор привязали к другому контакту, заказ остался у прежнего, и адрес ответит 404 |
| 409 | external_id_in_progress |
POST /orders |
заказ с этим external_id ещё оформляется другим запросом. Есть Retry-After: 2 |
повторите через 2 секунды |
| 409 | total_mismatch |
POST /orders |
итог не совпал с expected_total. Ваш итог в expected_total, итог магазина в actual_total |
проверьте заказ через /orders/check и отправьте с новым итогом |
| 409 | order_busy |
POST /orders |
магазин в эту секунду оформляет другие заказы с теми же товарами. Есть Retry-After: 2 |
повторите тот же запрос с тем же ключом через 2 секунды |
| 404 | not_found |
GET /orders/{id} |
заказа нет или он чужой | проверьте номер |
{
"type": "https://cartixx.com/docs/api/errors#total-mismatch",
"title": "Конфликт",
"status": 409,
"detail": "Итог заказа не совпал с expected_total, поэтому заказ не создан. Итог по расчёту магазина — в поле actual_total.",
"code": "total_mismatch",
"request_id": "B6R1TZ9Q",
"expected_total": "400.00",
"actual_total": "416.64"
}
{
"type": "https://cartixx.com/docs/api/errors#external-id-taken",
"title": "Конфликт",
"status": 409,
"detail": "Заказ с этим external_id уже принят. Его номер в магазине — в поле order_id.",
"code": "external_id_taken",
"request_id": "H4N8CW2L",
"external_id": "A-1024",
"order_id": 5120
}
Ни один отказ из этой таблицы не создаёт заказ. После отказа ключ повтора
свободен, и исправленный запрос можно отправить с тем же Idempotency-Key.
Исключения — idempotency_key_reused, idempotency_order_hidden и
idempotency_in_progress: ключ занят другим запросом или заказом, который по
нему уже создан.