Files
remnawave-minishop/docs/tariffs.md
T
2026-04-28 10:47:59 +03:00

126 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Тарифы
В Minishop два режима тарификации, и они **взаимоисключающие**: бот в каждый момент времени продаёт либо подписку на срок (1 / 3 / 6 / 12 месяцев), либо пакеты трафика. Ниже — что именно настраивается, что происходит при покупке и как переключаться.
## Краткое сравнение
| | Подписка по времени | Пакеты трафика |
| --- | --- | --- |
| Что покупает пользователь | Период доступа (1/3/6/12 мес.) | Объём трафика в ГБ |
| Срок действия в панели | До конца купленного периода | До 01.01.2099 (фактически бессрочно) |
| Лимит трафика | Из `USER_TRAFFIC_LIMIT_GB`, сбрасывается по `USER_TRAFFIC_STRATEGY` | Кумулятивно: каждый платёж **прибавляет** ГБ к лимиту |
| Стратегия сброса | `NO_RESET` / `WEEK` / `MONTH` / `DAY` | Принудительно `NO_RESET` |
| Автопродление YooKassa | Поддерживается | Выключено |
| Реферальные бонусы | Доступны (бонусные дни) | Не выдаются |
| Триал | Доступен (`TRIAL_*`) | Доступен (включается отдельно) |
Бот определяет режим по наличию переменных `TRAFFIC_PACKAGES` или `STARS_TRAFFIC_PACKAGES`: если хотя бы одна из них непустая — включается режим продажи трафика и переменные `*_MONTHS_ENABLED` / `RUB_PRICE_*` игнорируются.
## Режим «Подписка по времени» (по умолчанию)
Используется, когда `TRAFFIC_PACKAGES` и `STARS_TRAFFIC_PACKAGES` пусты.
### Цены и периоды
Для каждого периода настраивается доступность и две цены — в основной валюте (`DEFAULT_CURRENCY_SYMBOL`, по умолчанию RUB) и в Telegram Stars:
| Переменная | Описание |
| --- | --- |
| `1_MONTH_ENABLED` / `3_MONTHS_ENABLED` / `6_MONTHS_ENABLED` / `12_MONTHS_ENABLED` | `true`/`false` — показывать ли период в выборе |
| `RUB_PRICE_1_MONTH` / `RUB_PRICE_3_MONTHS` / `RUB_PRICE_6_MONTHS` / `RUB_PRICE_12_MONTHS` | Цена в рублях. Если не задана — кнопка не появится |
| `STARS_PRICE_1_MONTH` / `STARS_PRICE_3_MONTHS` / `STARS_PRICE_6_MONTHS` / `STARS_PRICE_12_MONTHS` | Цена в Stars. Используется, когда оплата идёт через `STARS_ENABLED` |
Если `RUB_PRICE_*` равно `0` — соответствующий период просто скрывается.
### Трафик пользователя
Лимит трафика и стратегия его сброса настраиваются глобально и применяются ко всем платным пользователям (в том числе при продлении):
| Переменная | Описание |
| --- | --- |
| `USER_TRAFFIC_LIMIT_GB` | Лимит трафика в ГБ. `0` — безлимит |
| `USER_TRAFFIC_STRATEGY` | Когда сбрасывается счётчик: `NO_RESET`, `DAY`, `WEEK`, `MONTH` |
### Что происходит при оплате
1. Если у пользователя ещё нет активной подписки — стартовая дата = «сейчас». Если есть — новая длительность прибавляется к её `end_date` (продление, а не перезапись).
2. К итогу могут добавиться бонусные дни промокода (`promo_codes`) и реферальной программы (`REFERRAL_BONUS_DAYS_*`, `REFEREE_BONUS_DAYS_*`).
3. В панели Remnawave у пользователя обновляются `expireAt`, `trafficLimitBytes` и `trafficLimitStrategy` под текущие настройки.
### Автопродление (только YooKassa)
Включается через `YOOKASSA_AUTOPAYMENTS_ENABLED=true`. Если включено и пользователь сохранил карту, то за `SUBSCRIPTION_NOTIFY_DAYS_BEFORE` дней до окончания бот пытается списать сумму, равную `RUB_PRICE_*` для длительности из последнего платежа. См. `YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING` для управления чекбоксом «сохранить карту».
В режиме трафика автопродление принудительно выключается, даже если YooKassa-настройки разрешают его.
### Уведомления
Управляются `SUBSCRIPTION_NOTIFICATIONS_ENABLED`, `SUBSCRIPTION_NOTIFY_ON_EXPIRE`, `SUBSCRIPTION_NOTIFY_AFTER_EXPIRE`, `SUBSCRIPTION_NOTIFY_DAYS_BEFORE`. Работают по `end_date` подписки — поэтому в режиме трафика, где `end_date` всегда «2099», они эффективно не отправляются.
## Режим «Пакеты трафика»
Включается заданием переменной `TRAFFIC_PACKAGES` (и/или `STARS_TRAFFIC_PACKAGES`) в `.env`.
### Формат
```env
# Пакеты в основной валюте (RUB), формат "<GB>:<цена>", через запятую
TRAFFIC_PACKAGES=10:199,50:799,200:1999
# Пакеты в Telegram Stars (опционально, если включён STARS_ENABLED)
STARS_TRAFFIC_PACKAGES=10:2500,50:9000
```
Для дробных размеров допускается `0.5:99`, `1.5:299` и т. п. Цены допускают `0` (например, для теста).
Если задана только `STARS_TRAFFIC_PACKAGES`, при выборе пакета бот покажет цену в звёздах и автоматически подменит символ валюты на `⭐`. Если фиатные провайдеры (`YOOKASSA_ENABLED`, `FREEKASSA_ENABLED`, `PLATEGA_ENABLED`, `SEVERPAY_ENABLED`, `CRYPTOPAY_ENABLED`) включены, но `TRAFFIC_PACKAGES` не задана — бот сочтёт это ошибкой конфигурации и не пропустит покупку.
### Что происходит при оплате
1. К текущему лимиту трафика пользователя в панели **прибавляется** купленный объём (`new_limit = current_limit + purchase_bytes`). Это работает и для существующих подписчиков.
2. Стратегия сброса принудительно ставится в `NO_RESET` — иначе докупленные ГБ обнулялись бы по расписанию.
3. `end_date` ставится в `2099-01-01 UTC` (или сохраняется более поздняя, если по какой-то причине уже была). Это нужно, чтобы Remnawave не помечал пользователя как просроченного.
4. Реферальные бонусы и автопродление при таких платежах отключены: даже если в `.env` они настроены, в этом режиме бот их не применяет.
5. Поле `subscription_duration_months` в БД и в CSV-выгрузке платежей в этом режиме интерпретируется как «количество ГБ», а не как месяцы. В UI и админке это учитывается, но имейте в виду при ручных запросах к БД.
### Триал в режиме трафика
Триал работает по той же логике, что и в режиме подписок: задаётся `TRIAL_ENABLED`, `TRIAL_DURATION_DAYS`, `TRIAL_TRAFFIC_LIMIT_GB`, `TRIAL_TRAFFIC_STRATEGY`. То есть пробный период всё ещё ограничен по времени, даже если основная продажа — это пакеты трафика.
## Как переключиться между режимами
1. В `.env` либо заполните `TRAFFIC_PACKAGES` (включится режим трафика), либо очистите её (включится режим подписок).
2. Перезапустите контейнер: `docker compose up -d`.
3. Существующие подписчики не теряют доступ:
- При переключении в режим трафика их `end_date` остаётся прежним до следующей покупки. Покупка пакета установит `end_date` = «2099» и переведёт стратегию в `NO_RESET`.
- При обратном переключении следующий платёж задаст обычный `end_date` от «сейчас» (или продлит существующий).
> ⚠️ Одновременно совмещать продажу подписок и трафика бот **не умеет**. Проверка идёт по одному булевому флагу `traffic_sale_mode`.
## Чеки для самозанятых (nalog.ru)
Для каждого режима используется отдельный шаблон названия в чеке:
| Переменная | Назначение |
| --- | --- |
| `NALOGO_RECEIPT_NAME_SUBSCRIPTION` | Шаблон для подписки. Поддерживает `{months}` |
| `NALOGO_RECEIPT_NAME_TRAFFIC` | Шаблон для пакета трафика. Поддерживает `{gb}` |
Пример: `NALOGO_RECEIPT_NAME_TRAFFIC=traffic package {gb} GB`.
## Связанные переменные
| Переменная | Описание |
| --- | --- |
| `DEFAULT_CURRENCY_SYMBOL` | Что показывается рядом с фиатной ценой (`RUB`, `USD`, `EUR`, …) |
| `PAYMENT_METHODS_ORDER` | Порядок кнопок оплаты — общий для обоих режимов |
| `STARS_ENABLED` | Без него Stars-цены не предложатся, даже если заданы |
| `USER_HWID_DEVICE_LIMIT` | Лимит устройств — общий для обоих режимов, к тарификации не относится |
## Где это всё в коде
- Чтение и парсинг переменных: [config/settings.py](../config/settings.py) — `subscription_options`, `traffic_packages`, `stars_traffic_packages`, `traffic_sale_mode`.
- Активация платежа: [bot/services/subscription_service.py](../bot/services/subscription_service.py) — `activate_subscription` (ветка по `sale_mode`) и `_activate_traffic_package`.
- Выбор тарифа в боте: [bot/handlers/user/subscription/core.py](../bot/handlers/user/subscription/core.py) и [bot/handlers/user/subscription/payments_subscription.py](../bot/handlers/user/subscription/payments_subscription.py).
- Web App: [bot/app/web/subscription_webapp.py](../bot/app/web/subscription_webapp.py) — поле `traffic_mode` в payload и логика отображения трафика.