diff --git a/handlers/admin/tariffs/tariffs_handler.py b/handlers/admin/tariffs/tariffs_handler.py
index f4a939da..f2160296 100644
--- a/handlers/admin/tariffs/tariffs_handler.py
+++ b/handlers/admin/tariffs/tariffs_handler.py
@@ -103,7 +103,8 @@ async def start_tariff_creation(callback: CallbackQuery, state: FSMContext):
"Специальные группы:\n"
"• discounts — тарифы со скидкой\n"
"• discounts_max — тарифы с максимальной скидкой\n"
- "• gifts — тарифы для подарков",
+ "• gifts — тарифы для подарков\n"
+ "• trial — тариф для пробного периода",
reply_markup=build_cancel_kb(),
)
@@ -276,6 +277,7 @@ async def show_tariff_groups(callback: CallbackQuery, session: AsyncSession):
"discounts": "🔻 Скидки",
"discounts_max": "🔻 Макс. скидки",
"gifts": "🎁 Подарки",
+ "trial": "🚀 Пробный период",
}
text = "📋 Выберите тарифную группу:\n\n"
diff --git a/handlers/keys/key_freeze.py b/handlers/keys/key_freeze.py
index 8b03fe32..a0bad251 100644
--- a/handlers/keys/key_freeze.py
+++ b/handlers/keys/key_freeze.py
@@ -7,7 +7,6 @@ from aiogram.types import CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy import text
-from config import TRIAL_CONFIG
from database import (
get_key_details,
get_servers,
@@ -89,9 +88,9 @@ async def process_callback_unfreeze_subscription_confirm(callback_query: Callbac
tariff = await get_tariff_by_id(session, record["tariff_id"]) if record.get("tariff_id") else None
if not tariff:
- logger.info("[Unfreeze] Тариф не найден — возможно ключ триальный. Применяем дефолтные значения.")
- total_gb = TRIAL_CONFIG["traffic_limit_gb"]
- hwid_limit = TRIAL_CONFIG["hwid_limit"]
+ logger.info("[Unfreeze] Тариф не найден — применяем дефолтные значения.")
+ total_gb = 0
+ hwid_limit = 0
else:
total_gb = int(tariff.get("traffic_limit") or 0)
hwid_limit = int(tariff.get("device_limit") or 0)
diff --git a/handlers/keys/key_mode/key_cluster_mode.py b/handlers/keys/key_mode/key_cluster_mode.py
index c70844e3..8dca9aa3 100644
--- a/handlers/keys/key_mode/key_cluster_mode.py
+++ b/handlers/keys/key_mode/key_cluster_mode.py
@@ -15,7 +15,7 @@ from aiogram.types import (
from aiogram.utils.keyboard import InlineKeyboardBuilder
from bot import bot
-from config import CONNECT_PHONE_BUTTON, SUPPORT_CHAT_URL, TRIAL_CONFIG
+from config import CONNECT_PHONE_BUTTON, SUPPORT_CHAT_URL
from database import (
get_key_details,
get_tariff_by_id,
@@ -23,6 +23,7 @@ from database import (
update_balance,
update_trial,
)
+
from handlers.buttons import (
CONNECT_DEVICE,
CONNECT_PHONE,
@@ -84,10 +85,7 @@ async def key_cluster_mode(
device_limit = 0
traffic_limit_gb = 0
- if is_trial:
- device_limit = TRIAL_CONFIG.get("hwid_limit", 0)
- traffic_limit_gb = TRIAL_CONFIG.get("traffic_limit_gb", 100)
- elif plan:
+ if plan:
tariff = await get_tariff_by_id(session, plan)
if tariff:
if tariff.get("device_limit") is not None:
@@ -182,30 +180,16 @@ async def key_cluster_mode(
if plan:
tariff_info = await get_tariff_by_id(session, plan)
- if is_trial:
- trial_days = TRIAL_CONFIG.get("duration_days", 1)
- if trial_days >= 30:
- months = trial_days // 30
- tariff_duration = format_months(months)
- else:
- tariff_duration = format_days(trial_days)
- key_message_text = key_message_success(
- final_link,
- tariff_name=tariff_duration,
- traffic_limit=TRIAL_CONFIG.get("traffic_limit_gb", 100),
- device_limit=TRIAL_CONFIG.get("hwid_limit", 0),
- )
- else:
- tariff_duration = tariff_info["name"]
- subgroup_title = tariff_info.get("subgroup_title", "") if tariff_info else ""
+ tariff_duration = tariff_info["name"]
+ subgroup_title = tariff_info.get("subgroup_title", "") if tariff_info else ""
- key_message_text = key_message_success(
- final_link,
- tariff_name=tariff_duration,
- traffic_limit=tariff_info.get("traffic_limit", 0) if tariff_info else 0,
- device_limit=tariff_info.get("device_limit", 0) if tariff_info else 0,
- subgroup_title=subgroup_title,
- )
+ key_message_text = key_message_success(
+ final_link,
+ tariff_name=tariff_duration,
+ traffic_limit=tariff_info.get("traffic_limit", 0) if tariff_info else 0,
+ device_limit=tariff_info.get("device_limit", 0) if tariff_info else 0,
+ subgroup_title=subgroup_title,
+ )
default_media_path = "img/pic.jpg"
if safe_to_edit:
diff --git a/handlers/keys/key_mode/key_country_mode.py b/handlers/keys/key_mode/key_country_mode.py
index 9c994211..2f469026 100644
--- a/handlers/keys/key_mode/key_country_mode.py
+++ b/handlers/keys/key_mode/key_country_mode.py
@@ -24,7 +24,6 @@ from config import (
REMNAWAVE_LOGIN,
REMNAWAVE_PASSWORD,
SUPPORT_CHAT_URL,
- TRIAL_CONFIG,
)
from database import (
add_user,
@@ -34,7 +33,9 @@ from database import (
get_trial,
update_balance,
update_trial,
+ get_tariff_by_id,
)
+
from database.models import Key, Server, Tariff
from handlers.buttons import BACK, CONNECT_DEVICE, CONNECT_PHONE, MAIN_MENU, MY_SUB, PC_BUTTON, SUPPORT, TV_BUTTON
from handlers.keys.key_utils import create_client_on_server
@@ -335,10 +336,7 @@ async def finalize_key_creation(
data = await state.get_data() if state else {}
is_trial = data.get("is_trial", False)
- if is_trial:
- traffic_limit_bytes = int(TRIAL_CONFIG.get("traffic_limit_gb", 100)) * 1024**3
- device_limit = TRIAL_CONFIG.get("hwid_limit", 0)
- elif data.get("tariff_id") or tariff_id:
+ if data.get("tariff_id") or tariff_id:
tariff_id = data.get("tariff_id") or tariff_id
result = await session.execute(select(Tariff).where(Tariff.id == tariff_id))
tariff = result.scalar_one_or_none()
@@ -511,30 +509,16 @@ async def finalize_key_creation(
result = await session.execute(select(Tariff).where(Tariff.id == tariff_id))
tariff_info = result.scalar_one_or_none()
- if is_trial:
- trial_days = TRIAL_CONFIG.get("duration_days", 1)
- if trial_days >= 30:
- months = trial_days // 30
- tariff_duration = format_months(months)
- else:
- tariff_duration = format_days(trial_days)
- key_message_text = key_message_success(
- link_to_show,
- tariff_name=tariff_duration,
- traffic_limit=TRIAL_CONFIG.get("traffic_limit_gb", 100),
- device_limit=TRIAL_CONFIG.get("hwid_limit", 0),
- )
- else:
- tariff_duration = tariff_info["name"] if tariff_info else None
- subgroup_title = tariff_info.get("subgroup_title", "") if tariff_info else ""
+ tariff_duration = tariff_info["name"]
+ subgroup_title = tariff_info.get("subgroup_title", "") if tariff_info else ""
- key_message_text = key_message_success(
- link_to_show,
- tariff_name=tariff_duration,
- traffic_limit=tariff_info.get("traffic_limit", 0) if tariff_info else 0,
- device_limit=tariff_info.get("device_limit", 0) if tariff_info else 0,
- subgroup_title=subgroup_title,
- )
+ key_message_text = key_message_success(
+ link_to_show,
+ tariff_name=tariff_duration,
+ traffic_limit=tariff_info.get("traffic_limit", 0) if tariff_info else 0,
+ device_limit=tariff_info.get("device_limit", 0) if tariff_info else 0,
+ subgroup_title=subgroup_title,
+ )
await edit_or_send_message(
target_message=callback_query.message,
diff --git a/handlers/keys/key_mode/key_create.py b/handlers/keys/key_mode/key_create.py
index 7510c270..e8cc269d 100644
--- a/handlers/keys/key_mode/key_create.py
+++ b/handlers/keys/key_mode/key_create.py
@@ -14,7 +14,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
from config import (
NOTIFY_EXTRA_DAYS,
- TRIAL_CONFIG,
TRIAL_TIME_DISABLE,
USE_COUNTRY_SELECTION,
USE_NEW_PAYMENT_FLOW,
@@ -29,7 +28,7 @@ from database import (
get_trial,
)
from database.models import Admin
-from database.tariffs import create_subgroup_hash, find_subgroup_by_hash
+from database.tariffs import create_subgroup_hash, find_subgroup_by_hash, get_tariffs
from handlers.admin.panel.keyboard import AdminPanelCallback
from handlers.buttons import MAIN_MENU, PAYMENT
from handlers.payments.robokassa_pay import handle_custom_amount_input
@@ -90,7 +89,21 @@ async def handle_key_creation(
if not TRIAL_TIME_DISABLE:
trial_status = await get_trial(session, tg_id)
if trial_status in [0, -1]:
- base_days = TRIAL_CONFIG["duration_days"]
+ trial_tariffs = await get_tariffs(session, group_code="trial")
+ if not trial_tariffs:
+ await edit_or_send_message(
+ target_message=(
+ message_or_query.message if isinstance(message_or_query, CallbackQuery) else message_or_query
+ ),
+ text="❌ Пробная подписка временно недоступна.",
+ reply_markup=InlineKeyboardBuilder()
+ .row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
+ .as_markup(),
+ )
+ return
+
+ trial_tariff = trial_tariffs[0]
+ base_days = trial_tariff["duration_days"]
extra_days = NOTIFY_EXTRA_DAYS if trial_status == -1 else 0
total_days = base_days + extra_days
expiry_time = current_time + timedelta(days=total_days)
@@ -105,8 +118,8 @@ async def handle_key_creation(
reply_markup=None,
)
- await state.update_data(is_trial=True)
- await create_key(tg_id, expiry_time, state, session, message_or_query)
+ await state.update_data(is_trial=True, plan=trial_tariff["id"])
+ await create_key(tg_id, expiry_time, state, session, message_or_query, plan=trial_tariff["id"])
return
try:
diff --git a/handlers/keys/key_renew.py b/handlers/keys/key_renew.py
index 760bf1e6..62782f9d 100644
--- a/handlers/keys/key_renew.py
+++ b/handlers/keys/key_renew.py
@@ -92,7 +92,7 @@ async def process_callback_renew_key(callback_query: CallbackQuery, state: FSMCo
if tariff_id:
if await check_tariff_exists(session, tariff_id):
current_tariff = await get_tariff_by_id(session, tariff_id)
- if current_tariff["group_code"] not in ["discounts", "discounts_max", "gifts"]:
+ if current_tariff["group_code"] not in ["discounts", "discounts_max", "gifts", "trial"]:
group_code = current_tariff["group_code"]
tariffs = await get_tariffs(session, group_code=group_code)
diff --git a/handlers/keys/key_utils.py b/handlers/keys/key_utils.py
index 7ebea152..5391b7f5 100644
--- a/handlers/keys/key_utils.py
+++ b/handlers/keys/key_utils.py
@@ -6,8 +6,9 @@ from typing import Any
from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
-from config import PUBLIC_LINK, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE, TRIAL_CONFIG
+from config import PUBLIC_LINK, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE
from database import delete_notification, get_servers, get_tariff_by_id, store_key
+
from database.models import Key, Server, Tariff
from handlers.utils import check_server_key_limit, get_least_loaded_cluster
from logger import logger
@@ -220,11 +221,7 @@ async def create_client_on_server(
total_gb_value = 0
device_limit_value = 0
- if is_trial:
- total_gb_value = TRIAL_CONFIG.get("traffic_limit_gb", 0)
- device_limit_value = TRIAL_CONFIG.get("hwid_limit")
- logger.info(f"[Trial] Используются параметры триала: {total_gb_value} GB, {device_limit_value} устройств")
- elif plan is not None:
+ if plan is not None:
tariff = await get_tariff_by_id(session, plan)
logger.info(f"[Tariff Debug] Получен тариф: {tariff}")
if not tariff:
diff --git a/handlers/notifications/general_notifications.py b/handlers/notifications/general_notifications.py
index 1b3a387f..b3983575 100644
--- a/handlers/notifications/general_notifications.py
+++ b/handlers/notifications/general_notifications.py
@@ -476,7 +476,7 @@ async def process_auto_renew_or_notify(
else:
if await check_tariff_exists(conn, tariff_id):
current_tariff = await get_tariff_by_id(conn, tariff_id)
- if current_tariff["group_code"] in ["discounts", "discounts_max", "gifts"]:
+ if current_tariff["group_code"] in ["discounts", "discounts_max", "gifts", "trial"]:
cluster_tariffs = [t for t in tariffs if t["is_active"] and balance >= t["price_rub"]]
if cluster_tariffs:
cluster_tariffs_31 = [t for t in cluster_tariffs if t["duration_days"] <= 31]
diff --git a/handlers/notifications/special_notifications.py b/handlers/notifications/special_notifications.py
index 7b21db83..5aad9898 100644
--- a/handlers/notifications/special_notifications.py
+++ b/handlers/notifications/special_notifications.py
@@ -13,7 +13,6 @@ from config import (
NOTIFY_INACTIVE,
NOTIFY_INACTIVE_TRAFFIC,
SUPPORT_CHAT_URL,
- TRIAL_CONFIG,
)
from database import (
add_notification,
@@ -22,6 +21,7 @@ from database import (
update_key_notified,
)
from database.models import Key
+from database.tariffs import get_tariffs
from handlers.buttons import CONNECT_DEVICE, CONNECT_PHONE, MAIN_MENU, PC_BUTTON, TV_BUTTON
from handlers.keys.key_utils import get_user_traffic
from handlers.notifications.notify_utils import send_messages_with_limit
@@ -44,7 +44,12 @@ async def notify_inactive_trial_users(bot: Bot, session: AsyncSession):
logger.info(f"Найдено {len(users)} неактивных пользователей для уведомления.")
messages = []
- trial_days = TRIAL_CONFIG["duration_days"]
+ trial_tariffs = await get_tariffs(session, group_code="trial")
+ if not trial_tariffs:
+ logger.error("[Notifications] Триальный тариф не найден")
+ return
+
+ trial_days = trial_tariffs[0]["duration_days"]
for user in users:
tg_id = user["tg_id"]
diff --git a/handlers/refferal.py b/handlers/refferal.py
index 29b26ad4..ec7d49cd 100644
--- a/handlers/refferal.py
+++ b/handlers/refferal.py
@@ -20,15 +20,7 @@ from sqlalchemy import desc, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from bot import bot
-from config import (
- ADMIN_ID,
- INLINE_MODE,
- REFERRAL_BONUS_PERCENTAGES,
- REFERRAL_QR,
- TOP_REFERRAL_BUTTON,
- TRIAL_CONFIG,
- USERNAME_BOT,
-)
+from config import ADMIN_ID, INLINE_MODE, REFERRAL_BONUS_PERCENTAGES, TOP_REFERRAL_BUTTON, USERNAME_BOT, REFERRAL_QR
from database import (
add_referral,
add_user,
@@ -37,6 +29,7 @@ from database import (
get_referral_stats,
)
from database.models import Referral
+from database.tariffs import get_tariffs
from handlers.buttons import BACK, INVITE, MAIN_MENU, QR, TOP_FIVE
from handlers.texts import (
INVITE_MESSAGE_TEMPLATE,
@@ -118,9 +111,15 @@ async def invite_handler(callback_query_or_message: Message | CallbackQuery, ses
@router.inline_query(F.query.in_(["referral", "ref", "invite"]))
-async def inline_referral_handler(inline_query: InlineQuery):
+async def inline_referral_handler(inline_query: InlineQuery, session: AsyncSession):
referral_link = f"https://t.me/{USERNAME_BOT}?start=referral_{inline_query.from_user.id}"
- trial_days = TRIAL_CONFIG["duration_days"]
+
+ trial_tariffs = await get_tariffs(session, group_code="trial")
+ if not trial_tariffs:
+ await inline_query.answer(results=[], cache_time=0)
+ return
+
+ trial_days = trial_tariffs[0]["duration_days"]
trial_time_formatted = format_days(trial_days)
results: list[InlineQueryResultArticle] = []