> ## Documentation Index
> Fetch the complete documentation index at: https://faq.exode.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Промокоды и скидки

> Создание промокодов и скидок: процентные и фиксированные, ограничения по использованию и срокам, применение к продуктам

Промокоды и скидки позволяют снижать цену продуктов для учеников — по коду или автоматически. Скидки
привязаны к продукту (курсу) и настраиваются в разделе скидок продукта.

Точки входа:

* **Управление → Курс → Скидки** (`/manage/course/:courseId/discounts`);
* **Управление → Продукт → Скидки** (`/manage/product/:productId/discounts`).

Обе страницы работают с одной и той же сущностью скидки (`DiscountEntity`).

## Типы скидок

У скидки есть тип (`DiscountType`), определяющий, как считается величина скидки:

| Тип (`DiscountType`) | Значение                      | Единица      |
| -------------------- | ----------------------------- | ------------ |
| `Amount`             | Фиксированная скидка на сумму | Валюта школы |
| `Percent`            | Процентная скидка             | %            |

Величина задаётся в поле `value`: для `Amount` — это сумма в валюте школы, для `Percent` — процент.

<img src="https://mintlify.s3.us-west-1.amazonaws.com/exode-faq/images/online-schools/sales-payments/discount-form.png" alt="Форма создания промокода с выбором типа скидки и величины" />

## Создание промокода

<Steps>
  <Step title="Откройте скидки продукта">
    Перейдите в раздел скидок нужного курса или продукта и создайте новую скидку.
  </Step>

  <Step title="Выберите тип и величину">
    Укажите тип (`Amount` или `Percent`) и значение скидки. Для `Amount` рядом показывается валюта школы,
    для `Percent` — знак «%».
  </Step>

  <Step title="Задайте код">
    Введите код промокода (до 12 символов, без пробелов) или сгенерируйте случайный кнопкой «Сгенерировать».
    Код должен быть уникальным — при дублировании форма покажет ошибку.
  </Step>

  <Step title="Настройте ограничения">
    При необходимости укажите лимит применений и период действия (см. ниже).
  </Step>

  <Step title="Активируйте и сохраните">
    Включите переключатель активности и сохраните. Неактивный промокод не применяется при оплате.
  </Step>
</Steps>

## Ограничения и настройки

| Поле                      | Назначение                                                                   |
| ------------------------- | ---------------------------------------------------------------------------- |
| `code`                    | Код промокода (до 12 символов, без пробелов, уникальный)                     |
| `value`                   | Величина скидки (сумма или процент)                                          |
| `maxApplies`              | Максимальное число применений; при исчерпании промокод перестаёт действовать |
| `activeFrom` / `activeTo` | Период действия по дате и времени                                            |
| `active`                  | Включён промокод или нет                                                     |
| `products`                | Дополнительные продукты, на которые распространяется скидка                  |
| `note`                    | Служебная заметка (до 255 символов)                                          |

Дополнительно платформа хранит вычисляемые признаки активности:

* `isActive` — итоговая активность промокода;
* `isActiveByDate` — активен ли по периоду действия;
* `isActiveByCountApplies` — не исчерпан ли лимит применений;
* `countApplies` — сколько раз уже применён;
* `isScheduled` — запланирован ли на будущее.

<Tip>
  Скидка изначально создаётся в контексте одного продукта, но через поле «дополнительные продукты» её можно
  распространить и на другие курсы — тогда один промокод будет действовать сразу на несколько продуктов.
</Tip>

## Применение при оплате

При расчёте корзины промокоды проверяются на сервере. В итоге расчёта (`invoiceCalculateCartTotal`) видно:

* `appliedDiscounts` — какие скидки применились;
* `unAppliedDiscounts` — какие не применились и почему.

Причины неприменения скидки (`DiscountUnAppliedReason`):

| Причина                  | Значение                                                |
| ------------------------ | ------------------------------------------------------- |
| `NotActive`              | Промокод неактивен (выключен, вне периода или исчерпан) |
| `ApplyLimitExceeded`     | Превышен лимит применений                               |
| `NotApplicableToProduct` | Скидка неприменима к этому продукту                     |
| `NotApplicableToPrice`   | Скидка неприменима к выбранной цене                     |

Проверить код отдельно (например, для подсказки ученику) можно запросом `discountCheckCode`, который вернёт
тип, величину и код скидки, если он валиден.

## Архивирование

Ненужный промокод можно архивировать (`archivedAt`) вместо удаления. По умолчанию список скидок скрывает
архивные (фильтр `archived: false`).

<Note>
  Заархивированный промокод нельзя активировать, пока он не разархивирован — переключатель активности в форме
  будет заблокирован с соответствующей подсказкой.
</Note>
