Заказы

Зал, самовывоз и доставка отправляются одним методом — тип задаётся полем order_type_id. Отдельных эндпоинтов для разных типов нет.

Расчёт корзины

POST /orders/calculate

Возвращает итоговую сумму без создания заказа. Вызывайте перед показом кнопки «Заказать»: здесь же проверяется стоп-лист и стоимость доставки, поэтому вы узнаете о недоступной позиции или недоступном адресе до того, как пользователь нажмёт оплату.

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "items": [
    { "product_id": 777, "quantity": 2, "modifiers": [{ "product_id": 3884, "quantity": 1 }] }
  ]
}
{
  "items": [
    { "product_id": 777, "name": "Fanta 1 l", "quantity": 2, "price": 12000, "total": 24000, "is_modifier": false },
    { "product_id": 3884, "name": "Соус барбекю", "quantity": 1, "price": 2500, "total": 2500, "is_modifier": true }
  ],
  "items_amount": 26500,
  "delivery": null,
  "total_amount": 26500
}

Модификаторы приходят отдельными строками с is_modifier: true — так же, как они попадут в чек.

items_amount — сумма позиций, total_amount — итог к оплате вместе с доставкой.

Расчёт доставки

Чтобы узнать стоимость доставки, добавьте order_type_id: 3 и координаты адреса:

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "order_type_id": 3,
  "address": { "latitude": 41.1568, "longitude": 70.2103 },
  "items": [{ "product_id": 16972, "quantity": 1 }]
}
{
  "items": [ ... ],
  "items_amount": 300000,
  "delivery": {
    "price": 10000,
    "zone_id": 3,
    "zone_name": "shohzone",
    "minutes": 60,
    "min_order_amount": 50000
  },
  "total_amount": 310000
}
ПолеОписание
priceСтоимость доставки по зоне, в которую попал адрес
zone_nameНазвание зоны — можно показать пользователю
minutesОриентировочное время доставки
min_order_amountМинимальная сумма заказа для этой зоны

delivery: null — заказ не доставочный (не передан order_type_id: 3). price: 0 при заполненной зоне — доставка бесплатная.

Создание заказа

POST /orders
{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "order_type_id": 3,
  "payment_type_id": 59,
  "external_id": "my-app-order-1",
  "comment": "Не звонить в домофон",
  "persons": 2,
  "client": { "name": "Азиз", "phone": "998901112233" },
  "address": {
    "street": "Амира Темура 15",
    "apartment": "42",
    "floor": "4",
    "entrance": "2",
    "intercom": "42K",
    "latitude": 41.311,
    "longitude": 69.279
  },
  "items": [
    {
      "product_id": 777,
      "quantity": 2,
      "comment": "без льда",
      "modifiers": [{ "product_id": 3884, "quantity": 1 }]
    }
  ]
}

Параметры

ПолеОбязательноОписание
point_idдаUUID точки из GET /points
order_type_idда1 зал, 2 с собой, 3 доставка
payment_type_idдаИз GET /payment-types для этой точки
client.phoneдаТелефон, только цифры или с +
client.nameнетИмя гостя
itemsдаМинимум одна позиция
items[].product_idдаТовар из меню
items[].quantityдаКоличество, дробное допустимо
items[].commentнетПожелание по позиции, уйдёт на кухню
items[].modifiersнетВыбранные модификаторы
addressдля доставкиОбязателен при order_type_id: 3
address.streetс адресомУлица и дом
external_idнет, но присылайтеВаш идентификатор заказа
order_type_sub_idнетПодтип. По умолчанию — закреплённый за ключом
table_idнетСтол, для заказа в зале
personsнетКоличество гостей, по умолчанию 1
commentнетКомментарий к заказу целиком
scheduled_atнетПредзаказ, ISO-8601 с часовым поясом

Ответ

{
  "order_id": 11537716,
  "external_id": "my-app-order-1",
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "status": "CREATED",
  "status_name": "Создан",
  "order_type_id": 3,
  "order_type_sub_id": 65,
  "payment_type_id": 59,
  "client": { "name": "Азиз", "phone": "998901112233" },
  "persons": 2,
  "comment": "Не звонить в домофон",
  "total_amount": 26500,
  "total_amount_service": 26500,
  "delivery_price": 0,
  "discount": 0,
  "created_at": "2026-08-18 23:06:29",
  "scheduled_at": null,
  "items": [
    {
      "product_id": 777,
      "name": "Fanta 1 l",
      "quantity": 2,
      "price": 12000,
      "total": 24000,
      "comment": "без льда",
      "modifiers": [
        { "product_id": 3884, "name": "Соус барбекю", "quantity": 1, "price": 2500, "total": 2500, "comment": null }
      ]
    }
  ]
}

order_id — идентификатор заказа в Mison, по нему запрашивается статус. В ответе модификаторы вложены в свою позицию, а не идут отдельными строками.

Идемпотентность

Присылайте external_id всегда. Повторный запрос с тем же external_id на ту же точку вернёт уже созданный заказ, а не создаст второй.

Это значит, что при таймауте, обрыве связи или 502 можно спокойно повторить запрос тем же телом — дубля не будет. Без external_id такой защиты нет, и повтор создаст второй заказ.

Цены

Сумма считается по ценам заведения. Если вы пришлёте цену в запросе, она будет проигнорирована — заказ по своей цене отправить нельзя.

Считается ровно тот же прайс, что отдаёт меню для этой точки: прейскурант филиала и действующая на нём колонка цен. Меню и заказ берут цену по одному правилу, поэтому сумма сходится, если меню свежее.

Расхождение вашей суммы с total_amount в ответе означает, что кеш меню устарел — например, у заведения по времени включилась другая колонка цен. Перезагрузите меню.

Стоимость доставки

Доставку вы не присылаете — её считает сервер по зонам, которые заведение настроило в своём кабинете. Поэтому её нет в меню: доставка не товар, её цена зависит от адреса, а не от корзины.

Что нужно с вашей стороны — координаты адреса в блоке address. По ним определяется зона и её тариф.

Возможные исходы:

СитуацияЧто происходит
Адрес попал в зонуСтоимость зоны попадает в заказ, total_amount уже с ней
Адрес вне всех зон400 — «Адрес вне зоны доставки этого заведения»
Сумма меньше минимальной для зоны400 — с указанием минимальной суммы
Координат нет, а зоны настроены400 — «Для доставки нужны координаты адреса»
У заведения зоны не настроеныДоставка 0, заказ проходит

Узнать стоимость заранее и показать её пользователю — через POST /orders/calculate с теми же координатами.

Проверяйте адрес до оплаты

Вызывайте calculate сразу после того, как пользователь выбрал адрес. Иначе он соберёт корзину, нажмёт «Оплатить» и только тогда узнает, что заведение туда не доставляет.

Предзаказ

scheduled_at — заказ к определённому времени:

{ "scheduled_at": "2026-08-19T19:30:00+05:00" }

Требования: формат ISO-8601 с указанием часового пояса, время минимум на 30 минут вперёд от текущего. Заказ попадёт в статус PREORDER и уйдёт на кухню ближе к сроку.

Статус заказа

GET /orders/{order_id}

Ответ — тот же объект, что при создании, с актуальными status и составом.

Опрашивайте раз в 30 секунд, пока заказ не придёт в конечное состояние (CLOSED или DELETED). Чаще смысла нет.

Статусы заказа

statusstatus_nameЧто произошло
CREATEDСозданЗаказ принят системой, ждёт кассу
AWAITING_PAYMENTОжидает оплатыОнлайн-оплата не прошла, на кухню не ушёл
AWAITING_CONFIRMATIONОжидает подтвержденияЖдёт оператора заведения
PREORDERПредзаказПринят, ждёт своего времени
UNCONFIRMED_ORDERОжидаетсяКасса приняла заказ
COOKINGГотовитсяУшёл на кухню
PACKEDУпакованГотов к выдаче или передаче курьеру
TAKEN_BY_COURIERВ путиКурьер забрал
DELIVEREDДоставленДоставлен клиенту
CLOSEDЗакрытЗаказ завершён и оплачен
DELETEDУдалёнОтменён

Обычный путь доставки: CREATED → UNCONFIRMED_ORDER → COOKING → PACKED → TAKEN_BY_COURIER → DELIVERED → CLOSED.

Для зала и самовывоза курьерских статусов не будет: CREATED → UNCONFIRMED_ORDER → COOKING → CLOSED.

Порядок не гарантирован: заказ может перескочить статус, если на точке работают быстро. Ориентируйтесь на текущее значение, а не на ожидаемую последовательность.

Статусы вы только читаете

В запросе на создание заказа нет полей статуса: ни статуса заказа, ни статуса позиций, ни признака «отправлено на кухню». Вы присылаете состав и тип заказа, а статусы ведёт Mison сам и отдаёт их в ответе. Если пришлёте такие поля, они будут проигнорированы.

Так задумано намеренно: внутренние статусы Mison могут меняться, а ваша интеграция от этого не должна ломаться. Опирайтесь только на status из таблицы выше.

Когда заказ уходит на кухню

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

Настройка ключаКогда кухня получает заказ
Автоподтверждение включеноСразу, как только касса точки получила заказ. Подтверждать вручную не нужно
Автоподтверждение выключеноПосле того, как кассир подтвердит заказ

Что при этом гарантируется:

  • подтверждение заказа кассиром не печатает бланк второй раз, если кухня его уже получила;
  • повторный запрос с тем же external_id возвращает уже созданный заказ и ничего не отправляет на кухню;
  • заказ, отменённый до того, как кухня его получила, не создаёт на кухне бланк отмены.

Заказ с scheduled_at (предзаказ) на кухню уходит ближе к назначенному времени, а не при создании.

Отмена заказа

POST /orders/{order_id}/cancel
{ "cancel_cause_id": 12, "comment": "Клиент передумал" }

Оба поля необязательны, но cancel_cause_id из GET /cancel-causes лучше передавать: без него отмена не попадёт в отчёт заведения по причинам.

В ответе — заказ со статусом DELETED.

Отмена возможна не всегда

Отменить через API можно, только пока заказ не принят кассой. После этого продукты уже списаны со склада, и отмена делается на самой кассе — API вернёт 409:

{ "message": "Заказ уже принят на точке, отмена возможна только через кассу" }

Повторная отмена уже отменённого заказа тоже даёт 409 с сообщением «Заказ уже отменён».

Заказ в зале и самовывоз

Отличаются от доставки только полями:

Зал (order_type_id: 1) — адрес не нужен, можно указать table_id:

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "order_type_id": 1,
  "payment_type_id": 59,
  "table_id": 14,
  "persons": 4,
  "external_id": "my-app-order-2",
  "client": { "phone": "998901112233" },
  "items": [{ "product_id": 777, "quantity": 1 }]
}

С собой (order_type_id: 2) — ни адреса, ни стола:

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "order_type_id": 2,
  "payment_type_id": 59,
  "external_id": "my-app-order-3",
  "client": { "phone": "998901112233" },
  "items": [{ "product_id": 777, "quantity": 1 }]
}

Клиент

Клиент определяется по телефону: если гость с таким номером у заведения уже есть, заказ привяжется к нему, а имя обновится. Отдельно создавать клиента не нужно.

Телефон присылайте в любом формате — лишние символы отбрасываются. 998901112233 и +998 90 111-22-33 дадут одного и того же клиента.