Обзор
Промо-система включает три связанных механизма:
- Промокоды — одноразовые/многоразовые коды для бонусов
- Промо-группы — тарифные группы со скидками и приоритетами
- Персональные промо-предложения — адресные акции от администратора
Промокоды
5 типов промокодов
| Тип | Что дает |
|---|
| balance | Начисление на баланс (в копейках) |
| subscription_days | Продление/создание платной подписки на N дней |
| trial_subscription | Активация триальной подписки |
| promo_group | Назначение в промо-группу |
| discount | Разовая процентная скидка на следующую покупку |
Создание промокода (админ)
- Выбор типа (5 вариантов)
- Ввод кода (3-20 символов,
[A-Za-z0-9_-], уникальный)
- Параметры в зависимости от типа:
- Balance: сумма в рублях (1-10 000)
- Days / Trial: дни (1-3650)
- Discount: процент (1-100)
- Group: выбор из существующих промо-групп
- Максимум использований (0 = безлимит)
- Срок действия в днях (0 = бессрочно)
- Для discount: длительность скидки в часах (0 = до первой покупки)
Активация пользователем
Пользователь вводит код через кнопку “Промокод” в главном меню.
Проверки перед активацией:
- Формат кода: 3-50 символов,
[A-Za-z0-9_-]
- Rate limiting: максимум 5 неудачных попыток за 5 минут
- Дневной лимит: максимум 5 успешных активаций за 24 часа
- Код существует, активен, не исчерпан
- Пользователь еще не использовал этот код
- Для
first_purchase_only — пользователь не имел платной подписки
Эффекты при активации
| Тип | Действие |
|---|
| balance | Начисление на баланс |
| subscription_days | Если есть подписка — продление. Если нет — создание новой платной подписки с синхронизацией в RemnaWave |
| trial_subscription | Создание триальной подписки (только если нет активной) |
| promo_group | Назначение в указанную промо-группу |
| discount | Установка promo_offer_discount_percent на пользователе. Ошибка, если уже есть активная скидка |
Если у промокода любого типа указан promo_group_id, промо-группа назначается дополнительно при активации.
Управление (админ-панель)
- Список промокодов с пагинацией (10 на страницу)
- Детали: тип, статус, использования, срок
- Редактирование: срок, максимум использований, сумма/дни
- Переключение
first_purchase_only
- Статистика: общее число, сегодня, история активаций с именами
- Удаление с подтверждением
Промо-группы
Что такое промо-группы
Промо-группы — это тарифные уровни, определяющие скидки для пользователей. Каждый пользователь может состоять в нескольких группах, а основная определяется по приоритету (чем выше — тем важнее).
Типы скидок
| Категория | Поле | Описание |
|---|
| Серверы | server_discount_percent | Скидка на серверы (0-100%) |
| Трафик | traffic_discount_percent | Скидка на трафик (0-100%) |
| Устройства | device_discount_percent | Скидка на устройства (0-100%) |
| Период | period_discounts | JSON: скидка за длительный период |
Пример period_discounts: {60: 10, 90: 20, 180: 40, 360: 70} — 10% за 60 дней, 70% за год.
Скидки для базовой группы
Для пользователей без промо-группы (или в группе по умолчанию) доступны базовые скидки за период:
BASE_PROMO_GROUP_PERIOD_DISCOUNTS_ENABLED=true
BASE_PROMO_GROUP_PERIOD_DISCOUNTS=60:10,90:20,180:40,360:70
Ограничение серверов
Промо-группы могут ограничивать доступные серверы через связь с server_squads. Если привязаны серверы — пользователь видит только их.
Скидки на аддоны
Флаг apply_discounts_to_addons (по умолчанию true) определяет, применяются ли скидки группы к дополнительным покупкам (трафик, устройства).
Автоматическое назначение по тратам
Промо-группы с полем auto_assign_total_spent_kopeks автоматически назначаются пользователям при достижении порога трат:
- После каждого платежа проверяется порог
- Система находит лучшую подходящую группу (порог меньше или равен тратам пользователя)
- Группа добавляется (не заменяет другие)
- Администратор получает уведомление
Пример: Промо-группа “VIP” с порогом 50 000 коп. (500 руб.) — автоматически назначается после траты 500+ рублей.
Управление (админ-панель)
- Создание: название, приоритет, скидки (трафик, серверы, устройства), период-скидки, авто-порог
- Редактирование: все поля, переключение скидок на аддоны
- Просмотр участников с пагинацией
- Удаление: с подтверждением, участники переносятся в группу по умолчанию. Группу по умолчанию удалить нельзя.
Персональные промо-предложения
Типы предложений
| Тип | Описание | Сегменты |
|---|
| test_access | Временный доступ к тестовым серверам | Платные активные, триальные активные |
| extend_discount | Скидка на продление подписки | Платные активные |
| purchase_discount | Скидка на покупку подписки | Платные/триальные истекшие, триальные активные |
Как работают
- Администратор выбирает шаблон предложения
- Выбирает сегмент пользователей или конкретного пользователя
- Система создает индивидуальные записи DiscountOffer с ограниченным сроком действия
- Пользователям отправляется сообщение с кнопкой CTA
- Пользователь нажимает кнопку и предложение активируется
Тестовый доступ к серверам
Предложение test_access:
- Указываются серверы (UUID) и длительность (часы)
- При активации создаются записи SubscriptionTemporaryAccess
- Серверы добавляются в подписку пользователя и синхронизируются с RemnaWave
- По истечении срока доступ автоматически убирается фоновой задачей
Шаблоны предложений
Шаблоны содержат:
- Текст сообщения (с плейсхолдерами:
{discount_percent}, {valid_hours}, {test_duration_hours}, {server_name})
- Текст кнопки
- Срок действия предложения (часы)
- Процент скидки или длительность тестового доступа
- Список серверов (для test_access)
Все шаблоны редактируются из админ-панели.
Отправка предложений
По сегменту:
- Выбор шаблона, выбор сегмента, массовая отправка
- Для test_access: фильтруются пользователи, уже подключенные к целевому серверу
- Батчевая отправка: 100 за раз, параллелизм до 20
Индивидуально:
- Поиск пользователя, детальный профиль, подтверждение, отправка
Журнал операций
Все действия логируются в PromoOfferLog:
- claimed — пользователь принял предложение
- consumed — предложение использовано
- disabled — предложение деактивировано (вручную или по истечении)
Настройка
| Переменная | По умолчанию | Описание |
|---|
BASE_PROMO_GROUP_PERIOD_DISCOUNTS_ENABLED | false | Скидки за период для базовой группы |
BASE_PROMO_GROUP_PERIOD_DISCOUNTS | 60:10,90:20,180:40,360:70 | Формат: дни и процент через запятую |