diff --git a/.env.example b/.env.example index 2f6ce399..32a757b0 100644 --- a/.env.example +++ b/.env.example @@ -253,6 +253,8 @@ YOOKASSA_QUICK_AMOUNT_SELECTION_ENABLED=true # Отключить отображение кнопок выбора суммы пополнения (оставить только ввод вручную) DISABLE_TOPUP_BUTTONS=false +# Отключить пополнение баланса через поддержку +SUPPORT_TOPUP_ENABLED=true # Автоматическая проверка зависших пополнений и повторные обращения к провайдерам PAYMENT_VERIFICATION_AUTO_CHECK_ENABLED=false diff --git a/app/config.py b/app/config.py index 14f6bffe..b3861efb 100644 --- a/app/config.py +++ b/app/config.py @@ -194,6 +194,7 @@ class Settings(BaseSettings): YOOKASSA_MAX_AMOUNT_KOPEKS: int = 1000000 YOOKASSA_QUICK_AMOUNT_SELECTION_ENABLED: bool = False DISABLE_TOPUP_BUTTONS: bool = False + SUPPORT_TOPUP_ENABLED: bool = True PAYMENT_VERIFICATION_AUTO_CHECK_ENABLED: bool = False PAYMENT_VERIFICATION_AUTO_CHECK_INTERVAL_MINUTES: int = 10 @@ -931,9 +932,12 @@ class Settings(BaseSettings): return value def is_yookassa_enabled(self) -> bool: - return (self.YOOKASSA_ENABLED and - self.YOOKASSA_SHOP_ID is not None and + return (self.YOOKASSA_ENABLED and + self.YOOKASSA_SHOP_ID is not None and self.YOOKASSA_SECRET_KEY is not None) + + def is_support_topup_enabled(self) -> bool: + return bool(self.SUPPORT_TOPUP_ENABLED) def get_yookassa_return_url(self) -> str: if self.YOOKASSA_RETURN_URL: diff --git a/app/handlers/balance/main.py b/app/handlers/balance/main.py index dc5ec261..72669dd6 100644 --- a/app/handlers/balance/main.py +++ b/app/handlers/balance/main.py @@ -421,7 +421,17 @@ async def request_support_topup( db_user: User ): texts = get_texts(db_user.language) - + + if not settings.is_support_topup_enabled(): + await callback.answer( + texts.t( + "SUPPORT_TOPUP_DISABLED", + "Пополнение через поддержку отключено. Попробуйте другой способ оплаты.", + ), + show_alert=True, + ) + return + support_text = f""" 🛠️ Пополнение через поддержку diff --git a/app/keyboards/inline.py b/app/keyboards/inline.py index 8cb6208d..a01189c3 100644 --- a/app/keyboards/inline.py +++ b/app/keyboards/inline.py @@ -758,6 +758,7 @@ def get_subscription_keyboard( texts = get_texts(language) keyboard = [] + has_direct_payment_methods = False if has_subscription: subscription_link = get_display_subscription_link(subscription) if subscription else None @@ -1146,6 +1147,7 @@ def get_balance_keyboard(language: str = DEFAULT_LANGUAGE) -> InlineKeyboardMark def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LANGUAGE) -> InlineKeyboardMarkup: texts = get_texts(language) keyboard = [] + has_direct_payment_methods = False amount_kopeks = max(0, int(amount_kopeks or 0)) @@ -1161,6 +1163,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("stars") ) ]) + has_direct_payment_methods = True if settings.is_yookassa_enabled(): if settings.YOOKASSA_SBP_ENABLED: @@ -1170,6 +1173,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("yookassa_sbp"), ) ]) + has_direct_payment_methods = True keyboard.append([ InlineKeyboardButton( @@ -1177,6 +1181,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("yookassa"), ) ]) + has_direct_payment_methods = True if settings.TRIBUTE_ENABLED: keyboard.append([ @@ -1185,6 +1190,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("tribute") ) ]) + has_direct_payment_methods = True if settings.is_mulenpay_enabled(): mulenpay_name = settings.get_mulenpay_display_name() @@ -1197,6 +1203,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("mulenpay") ) ]) + has_direct_payment_methods = True if settings.is_wata_enabled(): keyboard.append([ @@ -1205,6 +1212,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("wata") ) ]) + has_direct_payment_methods = True if settings.is_pal24_enabled(): keyboard.append([ @@ -1213,6 +1221,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("pal24") ) ]) + has_direct_payment_methods = True if settings.is_platega_enabled() and settings.get_platega_active_methods(): keyboard.append([ @@ -1221,6 +1230,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("platega"), ) ]) + has_direct_payment_methods = True if settings.is_cryptobot_enabled(): keyboard.append([ @@ -1229,6 +1239,7 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("cryptobot") ) ]) + has_direct_payment_methods = True if settings.is_heleket_enabled(): keyboard.append([ @@ -1237,15 +1248,24 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN callback_data=_build_callback("heleket") ) ]) + has_direct_payment_methods = True - keyboard.append([ - InlineKeyboardButton( - text=texts.t("PAYMENT_VIA_SUPPORT", "🛠️ Через поддержку"), - callback_data="topup_support" - ) - ]) + if settings.is_support_topup_enabled(): + keyboard.append([ + InlineKeyboardButton( + text=texts.t("PAYMENT_VIA_SUPPORT", "🛠️ Через поддержку"), + callback_data="topup_support" + ) + ]) - if len(keyboard) == 1: + if not keyboard: + keyboard.append([ + InlineKeyboardButton( + text=texts.t("PAYMENTS_TEMPORARILY_UNAVAILABLE", "⚠️ Способы оплаты временно недоступны"), + callback_data="payment_methods_unavailable" + ) + ]) + elif not has_direct_payment_methods and settings.is_support_topup_enabled(): keyboard.insert(0, [ InlineKeyboardButton( text=texts.t("PAYMENTS_TEMPORARILY_UNAVAILABLE", "⚠️ Способы оплаты временно недоступны"), diff --git a/app/localization/default_locales/en.yml b/app/localization/default_locales/en.yml index 95bb4709..ca737dc1 100644 --- a/app/localization/default_locales/en.yml +++ b/app/localization/default_locales/en.yml @@ -32,3 +32,12 @@ RULES_TEXT: | 2. Do not distribute spam or malicious content. 3. Respect other community members. +PAYMENT_METHODS_NONE_AVAILABLE: | + 💳 Balance top-up methods + + ⚠️ Payment methods are temporarily unavailable. + Please try again later. + + Choose a top-up option: +SUPPORT_TOPUP_DISABLED: "Top-ups via support are disabled. Please use another payment method." + diff --git a/app/localization/default_locales/ru.yml b/app/localization/default_locales/ru.yml index fc173e56..03cbff5e 100644 --- a/app/localization/default_locales/ru.yml +++ b/app/localization/default_locales/ru.yml @@ -32,3 +32,12 @@ RULES_TEXT: | 2. Не распространяйте спам и вредоносный контент. 3. Уважайте других пользователей. +PAYMENT_METHODS_NONE_AVAILABLE: | + 💳 Способы пополнения баланса + + ⚠️ В данный момент способы оплаты временно недоступны. + Попробуйте позже. + + Выберите способ пополнения: +SUPPORT_TOPUP_DISABLED: "Пополнение через поддержку отключено. Попробуйте другой способ оплаты." + diff --git a/app/services/system_settings_service.py b/app/services/system_settings_service.py index 16e3492e..c8426e21 100644 --- a/app/services/system_settings_service.py +++ b/app/services/system_settings_service.py @@ -254,6 +254,7 @@ class BotConfigurationService: "SIMPLE_SUBSCRIPTION_TRAFFIC_GB": "SIMPLE_SUBSCRIPTION", "SIMPLE_SUBSCRIPTION_SQUAD_UUID": "SIMPLE_SUBSCRIPTION", "DISABLE_TOPUP_BUTTONS": "PAYMENT", + "SUPPORT_TOPUP_ENABLED": "PAYMENT", "ENABLE_NOTIFICATIONS": "NOTIFICATIONS", "NOTIFICATION_RETRY_ATTEMPTS": "NOTIFICATIONS", "NOTIFICATION_CACHE_HOURS": "NOTIFICATIONS", diff --git a/app/utils/payment_utils.py b/app/utils/payment_utils.py index ef9c16ea..aee67085 100644 --- a/app/utils/payment_utils.py +++ b/app/utils/payment_utils.py @@ -100,14 +100,14 @@ def get_available_payment_methods() -> List[Dict[str, str]]: "callback": "topup_platega", }) - # Поддержка всегда доступна - methods.append({ - "id": "support", - "name": "Через поддержку", - "icon": "🛠️", - "description": "другие способы", - "callback": "topup_support" - }) + if settings.is_support_topup_enabled(): + methods.append({ + "id": "support", + "name": "Через поддержку", + "icon": "🛠️", + "description": "другие способы", + "callback": "topup_support" + }) return methods @@ -118,7 +118,18 @@ def get_payment_methods_text(language: str) -> str: texts = get_texts(language) methods = get_available_payment_methods() - if len(methods) <= 1: # Только поддержка + if not methods: + return texts.t( + "PAYMENT_METHODS_NONE_AVAILABLE", + """💳 Способы пополнения баланса + +⚠️ В данный момент способы оплаты временно недоступны. +Попробуйте позже. + +Выберите способ пополнения:""", + ) + + if len(methods) == 1 and methods[0]["id"] == "support": return texts.t( "PAYMENT_METHODS_ONLY_SUPPORT", """💳 Способы пополнения баланса @@ -186,7 +197,7 @@ def is_payment_method_available(method_id: str) -> bool: elif method_id == "platega": return settings.is_platega_enabled() and bool(settings.get_platega_active_methods()) elif method_id == "support": - return True # Поддержка всегда доступна + return settings.is_support_topup_enabled() else: return False @@ -204,7 +215,7 @@ def get_payment_method_status() -> Dict[str, bool]: "cryptobot": settings.is_cryptobot_enabled(), "heleket": settings.is_heleket_enabled(), "platega": settings.is_platega_enabled() and bool(settings.get_platega_active_methods()), - "support": True + "support": settings.is_support_topup_enabled() } def get_enabled_payment_methods_count() -> int: