Обзор
Тарифы — готовые пакеты подписок с фиксированными параметрами. Используются при SALES_MODE=tariffs (по умолчанию). В отличие от режима конструктора, пользователь выбирает тариф целиком, а не собирает параметры по шагам.
Управление тарифами доступно из админ-панели бота в Telegram и через Cabinet Admin API. При первом запуске бот автоматически создает тариф “Стандартный” с ценами из .env.
Создание тарифа
Через админ-панель бота
Мастер создания (6 шагов):
Шаг 1: Название
- 2-50 символов
- Примеры: “Базовый”, “Премиум”, “Бизнес”
Шаг 2: Трафик
- Целое число в ГБ
0 = безлимитный трафик
Шаг 3: Устройства
- Количество устройств (минимум 1)
Шаг 4: Уровень тарифа (tier)
- Число от 1 до 10
- Влияет только на визуальное отображение (1 = базовый)
Шаг 5: Тип тарифа
- Периодический — оплата за период (30/90/180/360 дней)
- Суточный — ежедневное списание
Шаг 6: Цены
- Для периодического: формат
дни:цена_в_копейках через запятую
30:9900, 90:24900, 180:44900, 360:79900
- Для суточного: цена в рублях за день (например,
50 или 99.90)
После создания тариф сразу активен и доступен пользователям.
Через Cabinet Admin API
POST /cabinet/admin/tariffs
Принимает JSON со всеми полями тарифа.
Поля тарифа
Основные
| Поле | Тип | Описание |
|---|
name | строка | Название (2-50 символов) |
description | текст | Описание (отображается пользователю) |
display_order | число | Порядок сортировки (меньше = выше в списке) |
is_active | bool | Активен ли тариф |
tier_level | 1-10 | Визуальный уровень |
Параметры подписки
| Поле | Тип | Описание |
|---|
traffic_limit_gb | число | Лимит трафика (0 = безлимит) |
device_limit | число | Количество устройств |
device_price_kopeks | число/null | Цена доп. устройства. null = покупка недоступна |
max_device_limit | число/null | Максимум устройств. null = без ограничения |
Серверы
| Поле | Тип | Описание |
|---|
allowed_squads | JSON список | UUID доступных серверов. Пустой = все серверы |
Ценообразование
| Поле | Тип | Описание |
|---|
period_prices | JSON объект | Цены за периоды: {"30": 9900, "90": 24900} (дни: копейки) |
Суточный тариф
| Поле | Тип | Описание |
|---|
is_daily | bool | Суточный режим (устанавливается при создании) |
daily_price_kopeks | число | Цена за сутки в копейках |
Тип тарифа (периодический/суточный) выбирается при создании и не может быть изменен после.
Пользовательский выбор дней
| Поле | Тип | Описание |
|---|
custom_days_enabled | bool | Разрешить выбор произвольного срока |
price_per_day_kopeks | число | Цена за день |
min_days | число | Минимальный срок (по умолчанию 1) |
max_days | число | Максимальный срок (по умолчанию 365) |
При включении пользователь видит кнопки +/- для выбора срока вместо фиксированных периодов. Цена = price_per_day_kopeks * количество_дней.
Пользовательский выбор трафика
| Поле | Тип | Описание |
|---|
custom_traffic_enabled | bool | Разрешить выбор объема трафика |
traffic_price_per_gb_kopeks | число | Цена за 1 ГБ |
min_traffic_gb | число | Минимум ГБ (по умолчанию 1) |
max_traffic_gb | число | Максимум ГБ (по умолчанию 1000) |
Стоимость трафика прибавляется к стоимости периода:
итого = цена_периода + (цена_за_гб * количество_гб)
Докупка трафика
| Поле | Тип | Описание |
|---|
traffic_topup_enabled | bool | Разрешить докупку трафика на этом тарифе |
traffic_topup_packages | JSON объект | Пакеты: {"5": 5000, "10": 9000} (ГБ: копейки) |
max_topup_traffic_gb | число | Максимум докупленного трафика (0 = без лимита) |
Сброс трафика
| Поле | Тип | Описание |
|---|
traffic_reset_mode | строка/null | DAY, WEEK, MONTH, NO_RESET или null (глобальная настройка) |
Триал
| Поле | Тип | Описание |
|---|
is_trial_available | bool | Использовать для триальных подписок |
Только один тариф может быть триальным. При назначении тарифа триальным флаг автоматически снимается со всех остальных.
Ограничение по промо-группам
Тарифы можно ограничить для определенных промо-групп:
- Если у тарифа нет привязанных промо-групп — он доступен всем
- Если у тарифа есть привязанные промо-группы — он виден только пользователям из этих групп
Настройка через кнопку Промо-группы на странице тарифа в админке. Можно включать/выключать отдельные группы.
Редактирование
На странице тарифа в админке доступны кнопки для редактирования каждого поля:
| Действие | Описание |
|---|
| Название | Изменить название (2-50 символов) |
| Описание | Изменить или удалить описание |
| Трафик | Изменить лимит (0 = безлимит) |
| Устройства | Изменить количество |
| Цены | Изменить цены за периоды (только для периодических) |
| Уровень | Изменить tier (1-10) |
| Цена устройства | Цена доп. устройства (0 = отключить) |
| Макс. устройств | Максимальный лимит (0 = без ограничения) |
| Докупка трафика | Включить/выключить, настроить пакеты и лимит |
| Сброс трафика | Выбрать режим (глобальный/день/неделя/месяц/без сброса) |
| Серверы | Выбрать доступные серверы |
| Промо-группы | Ограничить доступ по промо-группам |
| Суточная цена | Изменить цену за сутки (только для суточных) |
| Сделать триальным | Назначить для триальных подписок |
| Активировать/Деактивировать | Скрыть или показать тариф |
| Удалить | Удалить с подтверждением |
Сортировка
Тарифы отображаются в порядке display_order (по возрастанию). Для изменения порядка:
- Cabinet Admin API:
PUT /cabinet/admin/tariffs/order с массивом ID в нужном порядке
- Админ-панель бота: редактирование
display_order каждого тарифа
Удаление
При удалении тарифа:
- Показывается предупреждение с количеством активных подписок на этом тарифе
- Требуется подтверждение
- Подписки не удаляются — у них обнуляется привязка к тарифу (
tariff_id = NULL)
Отображение пользователю
В списке тарифов пользователь видит:
- Название тарифа
- Трафик и количество устройств
- Минимальную цену (с учетом скидок промо-группы)
Примеры:
Базовый — 100ГБ / 3 устройства от 179₽
Премиум — Безлимит / 10 устройств от 499₽
Суточный — 50ГБ / 1 устройство 50₽/день
Скидки промо-групп
Если пользователь состоит в промо-группе со скидками за период, скидки отображаются на кнопках выбора периода:
30 дней — 179₽
90 дней — 449₽ -15%
180 дней — 799₽ -25%
Формула цены
Периодический тариф
итого = цена_периода - скидка_промогруппы
С пользовательским выбором дней:
итого = (цена_за_день * дни) - скидка
С пользовательским выбором трафика:
итого = цена_периода + (цена_за_гб * гб) - скидка
Суточный тариф
ежедневное_списание = daily_price_kopeks
Списание происходит автоматически каждый день. При недостатке баланса подписка ставится на паузу (is_daily_paused).
Синхронизация цен
После любого изменения тарифов (создание, редактирование, удаление, переключение активности) глобальный словарь PERIOD_PRICES автоматически пересчитывается из БД. Перезапуск бота не требуется.
Связанные настройки
| Переменная | Описание |
|---|
SALES_MODE | tariffs (по умолчанию) или classic |
TRIAL_TARIFF_ID | ID триального тарифа (устаревшее, используйте is_trial_available) |