diff --git a/.env.example b/.env.example index 0a8b3ea7..51233971 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,19 @@ BOT_TOKEN= ADMIN_IDS= # Ссылка на поддержку: Telegram username (например, @support) или полный URL SUPPORT_USERNAME=@support +# Имя пользователя бота (опционально, автоопределяется) +# BOT_USERNAME= + +# ===== СИСТЕМА ПОДДЕРЖКИ ===== +# Включить меню поддержки в интерфейсе +SUPPORT_MENU_ENABLED=true +# Режим системы поддержки: tickets (тикеты), contact (контакт), both (оба) +SUPPORT_SYSTEM_MODE=both +# SLA для тикетов поддержки +SUPPORT_TICKET_SLA_ENABLED=false +SUPPORT_TICKET_SLA_MINUTES=60 +SUPPORT_TICKET_SLA_CHECK_INTERVAL_SECONDS=300 +SUPPORT_TICKET_SLA_REMINDER_COOLDOWN_MINUTES=30 # ===== ЛИЧНЫЙ КАБИНЕТ (CABINET) ===== # Включить личный кабинет пользователя (веб-интерфейс для управления подпиской) @@ -93,6 +106,8 @@ LOCALES_PATH=./locales # Redis REDIS_URL=redis://redis:6379/0 +# Время жизни корзины пользователя в Redis (секунды, по умолчанию 1 час) +CART_TTL_SECONDS=3600 # ===== REMNAWAVE API ===== REMNAWAVE_API_URL=https://panel.example.com @@ -130,6 +145,17 @@ REMNAWAVE_USER_USERNAME_TEMPLATE="user_{telegram_id}" # disable - только деактивировать пользователя REMNAWAVE_USER_DELETE_MODE=delete +# Автоматическая синхронизация пользователей с панелью Remnawave +REMNAWAVE_AUTO_SYNC_ENABLED=false +# Времена синхронизации (через запятую, формат HH:MM по МСК) +REMNAWAVE_AUTO_SYNC_TIMES=03:00 + +# Теги пользователей в Remnawave (A-Z, 0-9, _, макс. 16 символов) +# Тег для пробных пользователей (опционально) +# TRIAL_USER_TAG=TRIAL +# Тег для платных пользователей (опционально) +# PAID_SUBSCRIPTION_USER_TAG=PAID + # ========= ПОДПИСКИ ========= # ===== РЕЖИМ ПРОДАЖ ===== @@ -183,6 +209,8 @@ FIXED_TRAFFIC_LIMIT_GB=100 # ===== ДОКУПКА ТРАФИКА ===== # Включить/выключить функцию докупки трафика к существующей подписке TRAFFIC_TOPUP_ENABLED=true +# Показывать кнопку "Докупить трафик" в меню +BUY_TRAFFIC_BUTTON_VISIBLE=true # Пакеты для докупки трафика (формат: "гб:цена_в_копейках:enabled") # Пустая строка = использовать TRAFFIC_PACKAGES_CONFIG @@ -235,6 +263,8 @@ BASE_PROMO_GROUP_PERIOD_DISCOUNTS=60:10,90:20,180:40,360:70 # Выводимые пакеты трафика и их цены в копейках TRAFFIC_PACKAGES_CONFIG="5:2000:false,10:3500:false,25:7000:false,50:11000:true,100:15000:true,250:17000:false,500:19000:false,1000:19500:true,0:0:true" +# Цена за безлимитный трафик (в копейках) +PRICE_TRAFFIC_UNLIMITED=20000 # Цена за дополнительное устройство (DEFAULT_DEVICE_LIMIT идет бесплатно!) PRICE_PER_DEVICE=10000 @@ -267,8 +297,34 @@ REFERRAL_COMMISSION_PERCENT=25 REFERRAL_NOTIFICATIONS_ENABLED=true REFERRAL_NOTIFICATION_RETRY_ATTEMPTS=3 +# ===== ВЫВОД РЕФЕРАЛЬНОГО БАЛАНСА ===== +# Включить функцию вывода реферального баланса +REFERRAL_WITHDRAWAL_ENABLED=false +# Минимальная сумма вывода в копейках (по умолчанию 50000 = 500₽) +REFERRAL_WITHDRAWAL_MIN_AMOUNT_KOPEKS=50000 +# Интервал между запросами на вывод (дни) +REFERRAL_WITHDRAWAL_COOLDOWN_DAYS=30 +# Выводить только реферальный баланс (true) или весь баланс (false) +REFERRAL_WITHDRAWAL_ONLY_REFERRAL_BALANCE=true +# ID топика для уведомлений о заявках на вывод (0 = основной чат) +REFERRAL_WITHDRAWAL_NOTIFICATIONS_TOPIC_ID=0 +# Тестовый режим (позволяет админам тестировать функционал) +REFERRAL_WITHDRAWAL_TEST_MODE=false + +# Настройки анализа на подозрительную активность +# Минимальная сумма депозита от реферала для анализа (в копейках) +REFERRAL_WITHDRAWAL_SUSPICIOUS_MIN_DEPOSIT_KOPEKS=100000 +# Максимум пополнений от одного реферала в месяц +REFERRAL_WITHDRAWAL_SUSPICIOUS_MAX_DEPOSITS_PER_MONTH=10 +# Коэффициент подозрительности (пополнено в X раз больше, чем потрачено) +REFERRAL_WITHDRAWAL_SUSPICIOUS_NO_PURCHASES_RATIO=3 + # ===== АВТОПРОДЛЕНИЕ ===== +# Глобально включить/выключить функцию автопродления (false = функция скрыта) +ENABLE_AUTOPAY=false +# Дни до окончания подписки, когда отправлять предупреждение (через запятую) AUTOPAY_WARNING_DAYS=3,1 +# Включить автопродление для новых пользователей по умолчанию DEFAULT_AUTOPAY_ENABLED=true DEFAULT_AUTOPAY_DAYS_BEFORE=3 MIN_BALANCE_FOR_AUTOPAY_KOPEKS=10000 @@ -345,6 +401,8 @@ YOOKASSA_PAYMENT_SUBJECT=service YOOKASSA_WEBHOOK_PATH=/yookassa-webhook YOOKASSA_WEBHOOK_HOST=0.0.0.0 YOOKASSA_WEBHOOK_PORT=8082 +# Доверенные сети для webhook (IP-адреса YooKassa, через запятую) +# YOOKASSA_TRUSTED_PROXY_NETWORKS=185.71.76.0/24,185.71.77.0/24 # Лимиты сумм пополнения через YooKassa (в копейках) YOOKASSA_MIN_AMOUNT_KOPEKS=5000 @@ -421,13 +479,19 @@ MULENPAY_SHOP_ID= # необязательно, есть дефолтные значения MULENPAY_BASE_URL=https://mulenpay.ru/api MULENPAY_WEBHOOK_PATH=/mulenpay-webhook +# Название кнопки в интерфейсе +MULENPAY_DISPLAY_NAME=Mulen Pay MULENPAY_DESCRIPTION="Пополнение баланса" +# Запрещённые ключевые слова в display_name (КАЗИНО, СТАВКИ и т.п. — блокируются Mulenpay) +# DISPLAY_NAME_BANNED_KEYWORDS=КАЗИНО,СТАВКИ,CASINO,BET,1XBET MULENPAY_LANGUAGE=ru MULENPAY_VAT_CODE=0 MULENPAY_PAYMENT_SUBJECT=4 MULENPAY_PAYMENT_MODE=4 MULENPAY_MIN_AMOUNT_KOPEKS=10000 MULENPAY_MAX_AMOUNT_KOPEKS=10000000 +# Ожидаемый origin для iframe (опционально, для безопасности) +# MULENPAY_IFRAME_EXPECTED_ORIGIN=https://mulenpay.ru # PAYPALYCH / PAL24 PAL24_ENABLED=false @@ -451,6 +515,8 @@ PLATEGA_ENABLED=false PLATEGA_MERCHANT_ID= PLATEGA_SECRET= PLATEGA_BASE_URL=https://app.platega.io +# Название кнопки в интерфейсе +PLATEGA_DISPLAY_NAME=Platega PLATEGA_RETURN_URL= PLATEGA_FAILED_URL= PLATEGA_CURRENCY=RUB @@ -483,6 +549,50 @@ FREEKASSA_PAYMENT_SYSTEM_ID= # Использовать API для создания заказов (обязательно для NSPK СБП) FREEKASSA_USE_API=false +# ===== WATA ===== +WATA_ENABLED=false +WATA_BASE_URL=https://api.wata.pro +WATA_ACCESS_TOKEN= +WATA_TERMINAL_PUBLIC_ID= +WATA_PAYMENT_DESCRIPTION=Пополнение баланса +# Тип платежа: card, sbp, all +WATA_PAYMENT_TYPE=all +WATA_SUCCESS_REDIRECT_URL= +WATA_FAIL_REDIRECT_URL= +WATA_LINK_TTL_MINUTES=60 +WATA_MIN_AMOUNT_KOPEKS=10000 +WATA_MAX_AMOUNT_KOPEKS=10000000 +WATA_REQUEST_TIMEOUT=30 +WATA_WEBHOOK_PATH=/wata-webhook +WATA_WEBHOOK_HOST=0.0.0.0 +WATA_WEBHOOK_PORT=8087 +# Кэширование публичного ключа WATA (секунды) +WATA_PUBLIC_KEY_CACHE_SECONDS=3600 +# URL для получения публичного ключа (опционально) +# WATA_PUBLIC_KEY_URL= + +# ===== CLOUDPAYMENTS ===== +CLOUDPAYMENTS_ENABLED=false +CLOUDPAYMENTS_PUBLIC_ID= +CLOUDPAYMENTS_API_SECRET= +# URL API CloudPayments +CLOUDPAYMENTS_API_URL=https://api.cloudpayments.ru +# URL виджета оплаты +CLOUDPAYMENTS_WIDGET_URL=https://widget.cloudpayments.ru/show +CLOUDPAYMENTS_DESCRIPTION=Пополнение баланса +CLOUDPAYMENTS_CURRENCY=RUB +CLOUDPAYMENTS_MIN_AMOUNT_KOPEKS=10000 +CLOUDPAYMENTS_MAX_AMOUNT_KOPEKS=10000000 +CLOUDPAYMENTS_WEBHOOK_PATH=/cloudpayments-webhook +CLOUDPAYMENTS_WEBHOOK_HOST=0.0.0.0 +CLOUDPAYMENTS_WEBHOOK_PORT=8089 +# URL для возврата после оплаты (опционально) +# CLOUDPAYMENTS_RETURN_URL= +# Скин виджета: mini, classic, modern +CLOUDPAYMENTS_SKIN=mini +CLOUDPAYMENTS_REQUIRE_EMAIL=false +CLOUDPAYMENTS_TEST_MODE=false + # ===== ИНТЕРФЕЙС И UX ===== # Включить логотип для всех сообщений (true - с изображением, false - только текст) @@ -491,6 +601,8 @@ LOGO_FILE=vpn_logo.png # Режим главного меню (default - классический режим работы бота, text - режим работы с активным ЛК MiniApp, отключает покупку/управление подпиской в меню, заменяет все кнопками открытия в MiniApp ЛК) MAIN_MENU_MODE=default +# Включить управление меню через API (позволяет динамически менять структуру кнопок) +MENU_LAYOUT_ENABLED=false # Скрыть блок с ссылкой подключения в разделе с информацией о подписке HIDE_SUBSCRIPTION_LINK=false @@ -506,6 +618,8 @@ CONNECT_BUTTON_MODE=guide # URL для режима miniapp_custom (обязателен при CONNECT_BUTTON_MODE=miniapp_custom) MINIAPP_CUSTOM_URL= MINIAPP_STATIC_PATH=miniapp +# URL для редиректа на страницу покупки в мини-приложении (опционально) +# MINIAPP_PURCHASE_URL= MINIAPP_SERVICE_NAME_EN=Bedolaga VPN MINIAPP_SERVICE_NAME_RU=Bedolaga VPN MINIAPP_SERVICE_DESCRIPTION_EN=Secure & Fast Connection @@ -517,6 +631,8 @@ HAPP_DOWNLOAD_LINK_IOS= HAPP_DOWNLOAD_LINK_ANDROID= HAPP_DOWNLOAD_LINK_MACOS= HAPP_DOWNLOAD_LINK_WINDOWS= +# Универсальная ссылка для ПК (если MACOS и WINDOWS не заданы отдельно) +HAPP_DOWNLOAD_LINK_PC= # Кнопка (Подключится) с редиректом (тк ссылки с happ:// тг не поддерживает) - Без установленной ссылки на редирект кнопки (подключится) не будет! Пример: https://sub.domain.sub/redirect-page/?redirect_to= HAPP_CRYPTOLINK_REDIRECT_TEMPLATE= @@ -647,6 +763,8 @@ BOT_RUN_MODE=polling # polling, webhook или both # ===== КОНКУРСНАЯ СИСТЕМА ===== CONTESTS_ENABLED=false CONTESTS_BUTTON_VISIBLE=false +# Реферальные конкурсы (турниры среди рефералов) +REFERRAL_CONTESTS_ENABLED=false # ===== АВТОАКТИВАЦИЯ ПОСЛЕ ПОПОЛНЕНИЯ ===== # Автоматическая покупка из сохранённой корзины после пополнения баланса @@ -654,6 +772,9 @@ AUTO_PURCHASE_AFTER_TOPUP_ENABLED=false # Умная автоактивация: система сама решает — продлить или создать подписку # Работает даже без сохранённой корзины. Выбирает максимальный период <= баланса AUTO_ACTIVATE_AFTER_TOPUP_ENABLED=false +# Показывать предупреждение об активации подписки после пополнения баланса +# Если true - после пополнения показывает сообщение с кнопками: "Активировать", "Продлить", "Добавить устройства" +SHOW_ACTIVATION_PROMPT_AFTER_TOPUP=false # ===== КНОПКА АКТИВАЦИИ ===== ACTIVATE_BUTTON_VISIBLE=false @@ -663,8 +784,25 @@ ACTIVATE_BUTTON_VISIBLE=false WEB_API_ENABLED=false WEB_API_HOST=0.0.0.0 WEB_API_PORT=8080 +# Количество воркеров (для продакшена рекомендуется 2-4) +WEB_API_WORKERS=1 WEB_API_ALLOWED_ORIGINS=* WEB_API_DOCS_ENABLED=false +# Название и версия API (для документации) +WEB_API_TITLE=Remnawave Bot Admin API +WEB_API_VERSION=1.0.0 +# Токен по умолчанию для начальной настройки WEB_API_DEFAULT_TOKEN= WEB_API_DEFAULT_TOKEN_NAME=Bootstrap Token +# Алгоритм хеширования токенов +WEB_API_TOKEN_HASH_ALGORITHM=sha256 +# Логирование запросов +WEB_API_REQUEST_LOGGING=true + +# Внешний админ-токен (для интеграции с другими ботами/системами) +# Токен для доступа через API другого бота +# EXTERNAL_ADMIN_TOKEN= +# ID бота, от которого принимается токен +# EXTERNAL_ADMIN_TOKEN_BOT_ID= + MINIAPP_STATIC_PATH=miniapp diff --git a/app/config.py b/app/config.py index 4589d4d6..58ff2239 100644 --- a/app/config.py +++ b/app/config.py @@ -301,6 +301,11 @@ class Settings(BaseSettings): AUTO_PURCHASE_AFTER_TOPUP_ENABLED: bool = False AUTO_ACTIVATE_AFTER_TOPUP_ENABLED: bool = False + # Показывать предупреждение об активации подписки после пополнения баланса + # Если True - после пополнения показывает большое сообщение с кнопками: + # "Активировать", "Продлить", "Добавить устройства" + SHOW_ACTIVATION_PROMPT_AFTER_TOPUP: bool = False + # Отключение превью ссылок в сообщениях бота DISABLE_WEB_PAGE_PREVIEW: bool = False ACTIVATE_BUTTON_VISIBLE: bool = False diff --git a/app/services/subscription_auto_purchase_service.py b/app/services/subscription_auto_purchase_service.py index f84db5e1..04628830 100644 --- a/app/services/subscription_auto_purchase_service.py +++ b/app/services/subscription_auto_purchase_service.py @@ -745,8 +745,12 @@ async def auto_activate_subscription_after_topup( # Если автоактивация отключена - только отправляем предупреждение if not settings.is_auto_activate_after_topup_enabled(): - # Отправляем предупреждение если нет активной подписки - if bot and (not subscription or subscription.status not in ("active", "ACTIVE")): + # Отправляем предупреждение если включен режим и нет активной подписки + if ( + settings.SHOW_ACTIVATION_PROMPT_AFTER_TOPUP + and bot + and (not subscription or subscription.status not in ("active", "ACTIVE")) + ): try: texts = get_texts(getattr(user, "language", "ru")) warning_message = ( @@ -871,8 +875,12 @@ async def auto_activate_subscription_after_topup( user.telegram_id, balance, ) - # Отправляем предупреждение пользователю если подписки нет - if bot and (not subscription or subscription.status not in ("active", "ACTIVE")): + # Отправляем предупреждение пользователю если включен режим и подписки нет + if ( + settings.SHOW_ACTIVATION_PROMPT_AFTER_TOPUP + and bot + and (not subscription or subscription.status not in ("active", "ACTIVE")) + ): try: texts = get_texts(getattr(user, "language", "ru")) warning_message = (