Промоакции

В текущем API промоакция — это запись справочника с названием, изображением и датой создания. Её можно использовать как внутреннюю метку источника или кампании и связать с заказом либо мероприятием через promotion_id.

Промоакция не рассчитывает скидку и не меняет стоимость заказа. Для скидок по коду используйте промокоды и методы /api/discounts.

Маршруты, параметры, авторизация и опубликованные HTTP-ответы сверены с публичным синхронизированным OpenAPI-контрактом. Фактические обёртки ответов и связь с заказами и мероприятиями сверены с PromotionController, Promotion, DictionaryCollection, DictionaryResource, Order\StoreRequest, Order\UpdateRequest, Event\StoreRequest, Event\UpdateRequest, OrderResource и EventResource.

Результат

После завершения сценария вы:

  • получите список промоакций своего проекта;
  • выберете promotion_id;
  • свяжете промоакцию с внутренним заказом или мероприятием;
  • проверите связь в поле promotion ответа;
  • не перепутаете промоакцию с промокодом и ценовой скидкой.

Промоакция и промокод — разные сущности

ЗадачаПромоакцияПромокод
API/api/promotions/api/discounts
Поле в заказеpromotion_idpromo_code и discount_id
Назначениевнутренняя классификация или атрибуция заказа и мероприятиярасчёт скидки для клиентского заказа
Влияет на ценунетда
Доступные операциичтение списка и одной записисоздание, изменение, активация, пауза, архивирование, статистика

Не передавайте ID промоакции в promo_code. Не используйте promotion_id как доказательство скидки, оплаты или права клиента на специальную цену.

Перед началом

Подготовьте:

  • User Bearer сотрудника или внутреннего сервиса;
  • counterparty_id и manager_id, если создаёте заказ;
  • дополнительно event_type_id, если создаёте мероприятие;
  • существующую промоакцию из списка текущего проекта.

Через опубликованный API нельзя создать, изменить или удалить промоакцию. OpenAPI содержит только GET /api/promotions и GET /api/promotions/{promotion}.

Как это работает

  1. Получите список промоакций текущего проекта.
  2. Сохраните выбранный id как promotion_id.
  3. Передайте promotion_id при создании или изменении внутреннего заказа либо мероприятия.
  4. Проверьте объект promotion в ответе ресурса.
  5. Для удаления связи передайте promotion_id: null.
GET /api/promotions
        ↓
выбрать promotion_id
        ↓
POST или PUT /api/orders ─────→ order.promotion
        │
        └─ POST или PUT /api/events ─→ event.promotion

Быстрый старт

Шаг 1. Получите список промоакций

GET /api/promotions HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json

Ответ содержит массив promotions и количество promotionsCount. Выберите ID только из этого списка.

Шаг 2. Свяжите промоакцию с заказом

Добавьте promotion_id в обычный запрос создания внутреннего заказа:

POST /api/orders HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json
Content-Type: application/json

{
    "counterparty_id": 56,
    "manager_id": 14,
    "promotion_id": 7
}

counterparty_id и manager_id обязательны по текущему контракту создания заказа. Остальные поля добавляйте по своему сценарию. Полный контракт находится в разделе «Заказы и исполнение».

Шаг 3. Проверьте связь

В ответе заказа проверьте поле promotion:

{
    "order": {
        "id": 418,
        "promotion": {
            "id": "7",
            "name": "Летняя выставка",
            "avatar": "https://api.gigma.ru/storage/uploads/default.svg",
            "created_at": "2026-08-24T08:00:00.000000Z"
        },
        "promo_code": null,
        "promo_discount_amount": null
    }
}

Наличие promotion не означает, что к заказу применена скидка. Ценовые поля рассчитываются независимо.

Шаг 4. Измените или удалите связь

Чтобы заменить промоакцию, передайте новый ID. Чтобы удалить связь, передайте null:

PUT /api/orders/418 HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json
Content-Type: application/json

{
    "promotion_id": null
}

Передавайте именно null. Middleware также превращает 0 и "0" в null, но значение 0 хуже выражает намерение и не должно использоваться в новом клиентском коде.

Связать промоакцию с мероприятием

Промоакцию можно указать в POST /api/events:

POST /api/events HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json
Content-Type: application/json

{
    "counterparty_id": 56,
    "manager_id": 14,
    "event_type_id": 3,
    "name": "Монтаж на выставке",
    "promotion_id": 7
}

Для создания мероприятия обязательны counterparty_id, manager_id и event_type_id.

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

PUT /api/events/91 HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json
Content-Type: application/json

{
    "event_type_id": 3,
    "promotion_id": null
}

В ответе мероприятия связь находится в поле event.promotion.

Методы промоакций

Получить список промоакций

Метод
GET
URL
https://api.gigma.ru/api/promotions
Авторизация
User Bearer
Headers
Authorization: Bearer {user_access_token}; Accept: application/json
Успешный ответ
200

Метод возвращает промоакции текущего проекта. Пагинации нет: API отдаёт всю отфильтрованную коллекцию.

Параметры запроса

  • query (string|null, необязательно) — поиск по названию; от 3 до 255 символов.

Пример запроса

GET /api/promotions?query=выставка HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json

Ответ

{
    "promotions": [
        {
            "id": "7",
            "name": "Летняя выставка",
            "avatar": "https://api.gigma.ru/storage/uploads/default.svg",
            "created_at": "2026-08-24T08:00:00.000000Z"
        }
    ],
    "promotionsCount": 1
}
Описание полей ответа
  • promotions — промоакции проекта после применения поиска;
  • promotionsCount — количество элементов в массиве;
  • promotions[].id — идентификатор для поля promotion_id;
  • promotions[].name — название промоакции;
  • promotions[].avatar — изображение или стандартная картинка;
  • promotions[].created_at — дата создания.

Текущая общая схема DictionaryCollection в OpenAPI не передаёт динамические названия promotions и promotionsCount. Для сгенерированного клиента задайте эту форму ответа вручную, пока backend не опубликует специализированную схему.

DictionaryResource.id описан в OpenAPI как строка, а PHP Resource не приводит значение модели к одному JSON-типу. Принимайте строку или число и нормализуйте ID в строку на границе клиента.

Возможные ошибки

  • 401 Unauthorized — User Bearer отсутствует или недействителен;
  • 422 Unprocessable Entity — query короче 3 или длиннее 255 символов.

Получить промоакцию

Метод
GET
URL
https://api.gigma.ru/api/promotions/{promotion}
Авторизация
User Bearer
Headers
Authorization: Bearer {user_access_token}; Accept: application/json
Успешный ответ
200

Параметры запроса

  • promotion (integer, обязательно) — ID промоакции в пути.

Пример запроса

GET /api/promotions/7 HTTP/1.1
Host: api.gigma.ru
Authorization: Bearer <user_access_token>
Accept: application/json

Фактическая обёртка ответа

PromotionController передаёт имя обёртки promotion:

{
    "promotion": {
        "id": "7",
        "name": "Летняя выставка",
        "avatar": "https://api.gigma.ru/storage/uploads/default.svg",
        "created_at": "2026-08-24T08:00:00.000000Z"
    }
}

Текущий OpenAPI при этом описывает обёртку item. До выравнивания контракта и ответа обработчик может поддерживать оба варианта:

const promotion = response.promotion ?? response.item;

Возможные ошибки

  • 401 Unauthorized — User Bearer отсутствует или недействителен;
  • 404 Not Found — запись с таким ID не найдена.

Границы доступа

Список GET /api/promotions принудительно ограничен project_id текущего пользователя.

Одиночный GET /api/promotions/{promotion} в текущем контроллере не добавляет отдельную проверку проекта. Используйте только ID, полученные из списка своего проекта, и не применяйте этот метод как проверку права доступа. Проверка принадлежности при записи выполняется надёжнее: promotion_id в заказе и мероприятии валидируется внутри проекта текущего пользователя.

Не передавайте User Bearer в публичную клиентскую часть приложения. Промоакции относятся к внутреннему контуру управления, а не к клиентской витрине.

Ошибки и повтор запросов

СитуацияЧто делать
список вернул 401обновить или повторно получить User Bearer
поиск вернул 422проверить длину query
заказ или мероприятие вернуло 422 для promotion_idполучить список заново и проверить принадлежность ID проекту
запись вернула 403проверить роль и permissions пользователя
соединение оборвалось при GETбезопасно повторить запрос
соединение оборвалось при POST /api/orders или POST /api/eventsне повторять создание вслепую; сначала проверить, появился ли ресурс

Для операций создания заказа и мероприятия OpenAPI не публикует поддержку Idempotency-Key. Не включайте автоматический повтор после тайм-аута: сначала проверьте список заказов или мероприятий и сопоставьте результат по известным бизнес-полям.

Проверьте результат

Интеграция готова, когда выполнены все условия:

  1. GET /api/promotions вернул список текущего проекта.
  2. Выбранный ID сохранён как promotion_id.
  3. Заказ или мероприятие создано либо обновлено без 422.
  4. Ответ содержит ожидаемый объект promotion.
  5. Клиент не использует promotion_id для расчёта скидки.

Что делать дальше