Обзор
Мультитарифный режим позволяет пользователям иметь несколько активных подписок одновременно. Каждый тариф создаёт отдельную подписку со своими серверами, трафиком, устройствами и настройками автопродления.
Мультитарифный режим работает только при SALES_MODE=tariffs. В режиме конструктора (classic) он недоступен.
Включение
SALES_MODE=tariffs
MULTI_TARIFF_ENABLED=true
MAX_ACTIVE_SUBSCRIPTIONS=10
Настройка также доступна в админ-панели бота: Настройки → Подписки → Основные.
Переключатель мультитарифного режима отображается в настройках только при SALES_MODE=tariffs.
Как это работает
Для пользователей
- Каждая покупка тарифа создаёт отдельную подписку
- Экран «Мои подписки» отображает все подписки списком
- У каждой подписки свои: серверы, трафик, устройства, срок действия, автопродление
- Можно одновременно иметь подписки на разные тарифы
- Нельзя купить один и тот же тариф дважды — для существующего доступно только продление или смена тарифа
- Триальная подписка автоматически деактивируется при покупке платного тарифа
В Telegram-боте
- Во всех операциях (трафик, устройства, подключение, колесо фортуны, промокоды) появляется выбор подписки
- Уведомления приходят по каждой подписке отдельно с указанием названия тарифа
- Для истёкших и отключённых подписок доступна кнопка удаления
- Умный fallback: если подписка не указана явно, выбирается лучшая не-суточная подписка
В кабинете (Cabinet)
- Страница
/subscriptions с карточками всех подписок
- Управление каждой подпиской отдельно: продление, устройства, трафик, автопродление
- Ключи подключения и QR-коды для каждой подписки
- Выбор подписки в колесе фортуны
- Удаление истёкших подписок с подтверждением
В админке
- Двухуровневая навигация: список подписок → детали подписки
- Синхронизация с панелью для каждой подписки отдельно
- При создании подписки уже купленные тарифы отфильтрованы
- Эндпоинты синхронизации принимают
subscription_id
Техническая архитектура
Интеграция с RemnaWave
Каждая подписка получает собственного пользователя в RemnaWave:
user_{telegram_id}_{short_id}
| Поле | Описание |
|---|
remnawave_short_id | Уникальный идентификатор подписки (поле модели Subscription) |
| UUID | Собственный UUID для всех операций с панелью |
Синхронизация двунаправленная: изменения в панели отражаются в боте и наоборот, с привязкой по subscription_id.
Миграция с однотарифного режима
Миграция данных не требуется. Переключение на мультитарифный режим происходит без потерь.
- Полная обратная совместимость:
MULTI_TARIFF_ENABLED=false сохраняет прежнее поведение
- Автопривязка: устаревшие UUID на уровне пользователя автоматически привязываются к подпискам при первой синхронизации
- Переход в обе стороны безопасен — данные не теряются
Изоляция корзины
Корзина изолирована по подпискам для предотвращения конфликтов:
user_cart:{user_id}:sub:{subscription_id}
Это исключает «протекание» корзины между подписками — оплата всегда привязана к конкретной подписке.
Ограничения
| Ограничение | Описание |
|---|
MAX_ACTIVE_SUBSCRIPTIONS | Максимум активных подписок (по умолчанию 10) |
| Дубликат тарифа | Нельзя купить один тариф дважды |
| Суточные тарифы | Исключены из колеса фортуны |
| Классические подписки | Подписки без tariff_id не продлеваются в тарифном режиме |
Совместимость
| Функция | Поддержка мультитарифа |
|---|
| Покупка тарифов | Несколько тарифов одновременно |
| Продление | По каждой подписке отдельно |
| Автопродление | По каждой подписке отдельно |
| Промокоды | Выбор подписки |
| Колесо фортуны | Выбор подписки |
| Подарочные подписки | Поддерживается |
| Реферальная программа | Поддерживается |
| Конкурсы | Лучшая не-суточная подписка |
| Лендинги | Поддерживается |
| Суточные тарифы | По каждой подписке отдельно |
| Объединение аккаунтов | Разрешение конфликтов |