# Каталог, оформление и отмена заказа Форматы товаров, заказов и параметров находятся в [справочнике](reference.md). ## Загрузка каталога 1. Получите `/api/catalog/version` для выбранного магазина и языка. 2. Если версия неизвестна клиенту, загрузите `/api/catalog/bootstrap/{version}`. 3. Проверьте магазин, язык и версию ответа, затем атомарно сохраните весь снимок. 4. При повторном чтении передайте полученный `ETag` в `If-None-Match` без изменения. Ответ `304` не содержит тела: используйте сохранённый снимок. При `404` версии один раз перечитайте `/version`. При `503` с `CATALOG_NOT_PUBLISHED`, сетевой ошибке или повреждённом ответе сохраняйте последнюю корректную версию. Не заменяйте её частичным результатом. Персональные признаки избранного запрашиваются отдельно от публичного снимка. Успешный `/version` содержит `version`, `etag` и `published_at`. Bootstrap включает `version`, `published_at`, `store_id`, `language`, массивы `menu_categories`, `main_page_categories`, `banners`, `products`, объект `sections` с подборками `top`, `new`, `fresh`, `discounted`, а также `titles` (может быть `null`). Это оболочка публикации витрины; вложенные карточки используют схемы соответствующих категорий, товаров и баннеров. До появления полной схемы bootstrap не считайте пустую схему OpenAPI описанием фактического тела. ## Оформление Выберите магазин, проверьте доступность товаров и способ получения. Для доставки перед оформлением получите оценку стоимости через `POST /api/orders/delivery/price-estimate`. Перед оплатой учитывайте [доступность платёжного метода](payments-loyalty.md). Создайте заказ через `POST /api/orders/`, передав `X-Store-Id` и заранее сохранённый `Idempotency-Key`. Успешный ответ `201` содержит идентификатор заказа. При timeout сохраните исходное тело и ключ: повтор с новым ключом может создать другой заказ. Серверный расчёт является источником итоговой суммы; локальный кэш цены не является подтверждением стоимости заказа. Полное состояние читается через `/api/orders/{order_id}` и `/api/orders/roadmap/{order_id}/detail`. После уведомления перечитывайте HTTP detail. Изменения состава после сборки смотрите в `picking_result`. ## Отмена и доставка UkoJon Доступность отмены определяет серверное `can_cancel`. Запрос покупателя: `POST /api/orders/{order_id}/cancel`. При `409` обновите заказ и покажите серверное сообщение. Если доставка UkoJon уже существует, успешный запрос может лишь поставить отмену в обработку: не подменяйте полученный статус локальным `cancelled`. Различайте состояние покупки `status.value` и доставки `delivery.tracking.state`. Отмена заявки курьера сама по себе не означает отмену покупки или возврат оплаты. Допустимо сочетание покупки `en_route` и доставки `cancelled`. При `cancelled`, `returning` или `returned` удалите живой маркер курьера и его маршрут, покажите серверные `display` и `comment`. Не восстанавливайте старые координаты из кэша. Не обещайте возврат оплаты или поиск нового курьера: для этого требуется новое подтверждённое состояние сервера. Уведомление служит поводом перечитать detail, а не готовым снимком заказа.