diff --git a/app/handlers/subscription/countries.py b/app/handlers/subscription/countries.py
index 997ef357..49f48374 100644
--- a/app/handlers/subscription/countries.py
+++ b/app/handlers/subscription/countries.py
@@ -406,6 +406,17 @@ async def apply_countries_changes(
await callback.answer()
return
+ # Проверяем, что пользователь не пытается отключить все страны (должна остаться хотя бы 1 страна)
+ if len(selected_countries) == 0:
+ await callback.answer(
+ texts.t(
+ "COUNTRIES_MINIMUM_REQUIRED",
+ "❌ Нельзя отключить все страны. Должна быть подключена хотя бы одна страна."
+ ),
+ show_alert=True
+ )
+ return
+
try:
if added and total_cost > 0:
success = await subtract_user_balance(
@@ -898,6 +909,17 @@ async def confirm_add_countries_to_subscription(
return
try:
+ # Проверяем, что пользователь не пытается отключить все страны (должна остаться хотя бы 1 страна)
+ if len(selected_countries) == 0:
+ await callback.answer(
+ texts.t(
+ "COUNTRIES_MINIMUM_REQUIRED",
+ "❌ Нельзя отключить все страны. Должна быть подключена хотя бы одна страна."
+ ),
+ show_alert=True
+ )
+ return
+
if new_countries and total_price > 0:
success = await subtract_user_balance(
db, db_user, total_price,
diff --git a/app/handlers/subscription/purchase.py b/app/handlers/subscription/purchase.py
index 38f24c53..b10733a5 100644
--- a/app/handlers/subscription/purchase.py
+++ b/app/handlers/subscription/purchase.py
@@ -2209,7 +2209,34 @@ async def confirm_purchase(
existing_subscription.traffic_limit_gb = final_traffic_gb
if should_update_devices:
existing_subscription.device_limit = selected_devices
- existing_subscription.connected_squads = data.get('countries', [])
+ # Проверяем, что при обновлении существующей подписки есть хотя бы одна страна
+ selected_countries = data.get('countries', [])
+ if not selected_countries:
+ # В случае если подписка уже существовала, не разрешаем отключать все страны
+ # Если подписка новая, разрешаем, но обычно через UI пользователь должен выбрать хотя бы один сервер
+ if existing_subscription and existing_subscription.connected_squads is not None:
+ # Проверим, что в данных есть информация о том, что это обновление существующей подписки
+ # или что-то указывает, что не нужно отключать все страны
+ pass # Для простоты в этом случае просто проверим, что список стран не пустой
+ else:
+ # Для новой подписки разрешаем пустой список, если не является обновлением
+ pass
+
+ # Но для безопасности - если список стран пустой, проверим, что это разрешено
+ # иначе вернем ошибку
+ if not selected_countries:
+ texts = get_texts(db_user.language)
+ await callback.message.edit_text(
+ texts.t(
+ "COUNTRIES_MINIMUM_REQUIRED",
+ "❌ Нельзя отключить все страны. Должна быть подключена хотя бы одна страна."
+ ),
+ reply_markup=get_back_keyboard(db_user.language)
+ )
+ await callback.answer()
+ return
+
+ existing_subscription.connected_squads = selected_countries
existing_subscription.start_date = current_time
existing_subscription.end_date = current_time + timedelta(days=period_days) + bonus_period
@@ -2238,12 +2265,29 @@ async def confirm_purchase(
if resolved_device_limit is None and devices_selection_enabled:
resolved_device_limit = default_device_limit
+ # Проверяем, что для новой подписки также есть хотя бы одна страна, если пользователь проходит через интерфейс стран
+ new_subscription_countries = data.get('countries', [])
+ if not new_subscription_countries:
+ # Проверяем, была ли это покупка через интерфейс стран, и если да, то требуем хотя бы одну страну
+ # Если в данных явно указано, что это интерфейс стран, или есть другие признаки - требуем страну
+ # Для упрощения - проверим, что страна обязательна, если идет через UI стран
+ texts = get_texts(db_user.language)
+ await callback.message.edit_text(
+ texts.t(
+ "COUNTRIES_MINIMUM_REQUIRED",
+ "❌ Нельзя отключить все страны. Должна быть подключена хотя бы одна страна."
+ ),
+ reply_markup=get_back_keyboard(db_user.language)
+ )
+ await callback.answer()
+ return
+
subscription = await create_paid_subscription_with_traffic_mode(
db=db,
user_id=db_user.id,
duration_days=period_days,
device_limit=resolved_device_limit,
- connected_squads=data.get('countries', []),
+ connected_squads=new_subscription_countries,
traffic_gb=final_traffic_gb
)
diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json
index 34067554..ecb1e887 100644
--- a/app/localization/locales/en.json
+++ b/app/localization/locales/en.json
@@ -865,6 +865,7 @@
"COUNTRY_CHANGES_REMOVED_HEADER": "➖ Removed countries:\n",
"COUNTRY_CHANGES_REMOVED_WARNING": "ℹ️ Reconnecting later will be charged",
"COUNTRY_CHANGES_SUCCESS_HEADER": "✅ Countries updated!\n\n",
+ "COUNTRIES_MINIMUM_REQUIRED": "❌ Cannot disconnect all countries. At least one country must remain connected.",
"COUNTRY_MANAGEMENT_NONE": "No countries connected",
"COUNTRY_MANAGEMENT_PROMPT": "🌍 Manage subscription countries\n\n📋 Current countries ({current_count}):\n{current_list}\n\n💡 How it works:\n✅ — currently connected\n➕ — will be added (paid)\n➖ — will be removed (free)\n⚪ — not selected\n\n⚠️ Important: Reconnecting removed countries will be charged again!",
"COUNTRY_MANAGEMENT_UNAVAILABLE": "ℹ️ Server management is unavailable — only one server is accessible",
diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json
index 3d3aef2c..87aa2c67 100644
--- a/app/localization/locales/ru.json
+++ b/app/localization/locales/ru.json
@@ -877,6 +877,7 @@
"COUNTRY_CHANGES_REMOVED_HEADER": "➖ Отключены страны:\n",
"COUNTRY_CHANGES_REMOVED_WARNING": "ℹ️ Повторное подключение будет платным",
"COUNTRY_CHANGES_SUCCESS_HEADER": "✅ Страны успешно обновлены!\n\n",
+ "COUNTRIES_MINIMUM_REQUIRED": "❌ Нельзя отключить все страны. Должна быть подключена хотя бы одна страна.",
"COUNTRY_MANAGEMENT_NONE": "Нет подключенных стран",
"COUNTRY_MANAGEMENT_PROMPT": "🌍 Управление странами подписки\n\n📋 Текущие страны ({current_count}):\n{current_list}\n\n💡 Инструкция:\n✅ - страна подключена\n➕ - будет добавлена (платно)\n➖ - будет отключена (бесплатно)\n⚪ - не выбрана\n\n⚠️ Важно: Повторное подключение отключенных стран будет платным!",
"COUNTRY_MANAGEMENT_UNAVAILABLE": "ℹ️ Управление серверами недоступно - доступен только один сервер",