Архитектура

Обновлено: Aug 31, 2026Раздел: Интеграции

Market --- оформление заказа по e-mail (для интеграторов)

Mailoo не хостит вашу витрину. Интеграция Market предоставляет API каталога, опциональные API заказов для простого потока «снимок корзины → заказ по e-mail» и API панели управления для владельца проекта --- список заказов и изменение статуса.

Связанные материалы: каталог и атрибуты --- market-catalog-csv{.interpreted-text role="doc"} / market-catalog-external-api{.interpreted-text role="doc"}. OpenAPI --- https://api.mailoo.app/docs/v1.

Архитектура

  • Корзина / кеш каталога: Храните состояние корзины на сайте интегратора (например, localStorage или клиентское хранилище). Обновляйте цены через ``GET /api/v1/market/.../effective-price?kind=...`` с ключом типа цены (или теми же правилами разрешения) перед отправкой, чтобы итоги совпадали с сервером. См. market-catalog-external-api{.interpreted-text role="doc"} (Типы цен и итоговая цена).
  • Секреты: Все вызовы ``X-API-Key`` выполняются с сервера или BFF, никогда из публичных браузерных сборок.
  • Отправка заказа: Ваш BFF ``POST`` в Mailoo с ``market.order.submit``; Mailoo сохраняет снимок строк и разрешённые цены, отправляет подтверждение по e-mail покупателю, если на этой интеграции Market настроен исходящий SMTP (панель управления Подключение и настройкиИсходящая почта (SMTP) --- тот же outboundMail, что и у интеграций FORM/CONTACT), и возвращает одноразовый ``accessToken`` для чтения заказа. Глобальный платформенный SMTP (GLOBAL_SMTP_*) не используется для этого письма.
  • После отправки: Покупатель (или ваш SPA) может вызвать ``GET /api/v1/market/public/orders/{orderId}?token=`` без API-ключа до истечения токена. Если токен утерян, покупатель располагает только e-mail и id заказа, которые вы отобразили в UI.
  • Бэк-офис: Владелец проекта использует Bearer-маршруты ``/api/v1/projects/{uid}/integrations/{id}/market/orders/...`` для списка заказов, чтения деталей и обновления статуса.

Создание заказа (BFF)

  • ``POST {baseUrl}/api/v1/market/{projectUid}/integrations/{integrationId}/orders``
  • Заголовки: ``X-API-Key`` с ``market.order.submit`` (или FULL)
  • Тело (JSON):
  • ``customerEmail`` (обязательно) --- адрес покупателя (нормализуется в нижний регистр)
  • ``items`` (обязательно, непустой) --- каждый элемент:
  • ``productId`` --- должен быть ``PUBLISHED`` в этой интеграции
  • ``priceKindId`` или ``priceKindKey`` (строго один) --- тип цены. Предпочтительнее ``priceKindKey`` (например, base) для конфигурации интегратора; ``priceKindId`` --- внутренний CUID, если он уже есть (например, из ``GET .../price-lists/...`` строк).
  • ``quantity`` --- положительная десятичная строка (например, "2", "1.5")
  • ``variantId`` --- обязателен если у товара есть варианты, пропускается (или null) если нет
  • ``measurementUnitId`` --- необязательно; по умолчанию используется единица товара + правила разрешения effective-price
  • ``note``, ``metadata`` --- необязательно (определяются интегратором)

Ответ (201): ``data.id``, ``data.status`` (начальный NEW), ``data.accessToken`` (хранить только в сессии покупателя / возвращать клиенту для UX), ``data.accessExpiresAt``, ``data.totalAmount``, ``data.currency`` и ``data.emailToCustomer`` (удалось ли отправить письмо через outboundMail интеграции: SENT / FAILED / NOT_CONFIGURED).

Публичное чтение (покупатель)

  • ``GET {baseUrl}/api/v1/market/public/orders/{orderId}?token={accessToken}``
  • Или ``X-Market-Order-Token: {accessToken}``
  • Без ``X-API-Key``. Невалидный/отсутствующий токен возвращает 404 (то же сообщение, что и при неизвестном заказе), чтобы не раскрывать существование.

TTL токена по умолчанию 72 часа; на хосте API можно задать ``MARKET_ORDER_ACCESS_TOKEN_TTL_HOURS`` (1--720).

Панель владельца (JWT)

Аутентифицированные маршруты (сводка):

  • ``GET .../market/orders`` --- список (опциональный ``limit``, макс. 100)
  • ``GET .../market/orders/{orderId}`` --- полный снимок + ``attributesSnapshot`` строк
  • ``PATCH .../market/orders/{orderId}`` --- ``{ "status": "...", "note"?: "..." }`` (переходы статусов: терминальные состояния ``REJECTED``, ``FULFILLED``, ``CANCELLED`` не могут перейти в другой статус)
  • ``GET .../market/orders/{orderId}/status-events`` --- журнал аудита

Статусы: ``NEW``, ``PROCESSING``, ``CONFIRMED``, ``REJECTED``, ``FULFILLED``, ``CANCELLED``.

Разграничение API-ключей

  • ``market.external-read`` --- только GET каталога; используйте на BFF, который загружает страницы товаров.
  • ``market.order.submit`` --- только ``POST .../orders``; может быть отдельным ограниченным ключом на BFF оформления заказа.
  • Вы можете использовать один ключ FULL только в доверенных бэкендах; для минимальных привилегий разделите чтение и отправку, как выше.

:::: note ::: title Note :::

Панель управления Mailoo --- это администраторская консоль; клиентское оформление заказа работает на вашем сайте и вызывает публичный API Mailoo так же, как любая сторонняя система. ::::