diff --git a/app/config.py b/app/config.py index f8694c51..27c3e1e4 100644 --- a/app/config.py +++ b/app/config.py @@ -462,6 +462,7 @@ class Settings(BaseSettings): PLATEGA_FAILED_URL: str | None = None PLATEGA_CURRENCY: str = 'RUB' PLATEGA_ACTIVE_METHODS: str = '2,10,11,12,13' + PLATEGA_INLINE_METHODS: bool = True PLATEGA_MIN_AMOUNT_KOPEKS: int = 10000 PLATEGA_MAX_AMOUNT_KOPEKS: int = 100000000 PLATEGA_WEBHOOK_PATH: str = '/platega-webhook' diff --git a/app/handlers/balance/main.py b/app/handlers/balance/main.py index 6a34fc04..2102f727 100644 --- a/app/handlers/balance/main.py +++ b/app/handlers/balance/main.py @@ -565,7 +565,16 @@ async def handle_topup_amount_callback( try: # Особые случаи, требующие специальной логики - if method == 'platega': + if method.startswith('platega_m'): + from app.database.database import AsyncSessionLocal + + from .platega import process_platega_payment_amount + + platega_method_code = int(method[len('platega_m'):]) + await state.update_data(payment_method='platega', platega_method=platega_method_code) + async with AsyncSessionLocal() as db: + await process_platega_payment_amount(callback.message, db_user, db, amount_kopeks, state) + elif method == 'platega': from app.database.database import AsyncSessionLocal from .platega import process_platega_payment_amount, start_platega_payment @@ -635,13 +644,17 @@ def register_balance_handlers(dp: Dispatcher): F.data.startswith('pal24_method_'), ) - from .platega import handle_platega_method_selection, start_platega_payment + from .platega import handle_platega_method_selection, start_platega_direct_method, start_platega_payment dp.callback_query.register(start_platega_payment, F.data == 'topup_platega') dp.callback_query.register( handle_platega_method_selection, F.data.startswith('platega_method_'), ) + dp.callback_query.register( + start_platega_direct_method, + F.data.regexp(r'^topup_platega_m\d+$'), + ) from .yookassa import check_yookassa_payment_status diff --git a/app/handlers/balance/platega.py b/app/handlers/balance/platega.py index 1922ddb8..f496e988 100644 --- a/app/handlers/balance/platega.py +++ b/app/handlers/balance/platega.py @@ -191,6 +191,55 @@ async def handle_platega_method_selection( await callback.answer() +@error_handler +async def start_platega_direct_method( + callback: types.CallbackQuery, + db_user: User, + state: FSMContext, +): + """Handle direct Platega method selection from the main payment screen (inline mode).""" + texts = get_texts(db_user.language) + + try: + method_code = int(callback.data.removeprefix('topup_platega_m')) + except (ValueError, IndexError): + await callback.answer('❌ Некорректный способ оплаты', show_alert=True) + return + + if getattr(db_user, 'restriction_topup', False): + reason = html.escape(getattr(db_user, 'restriction_reason', None) or 'Действие ограничено администратором') + support_url = settings.get_support_contact_url() + keyboard = [] + if support_url: + keyboard.append([types.InlineKeyboardButton(text='🆘 Обжаловать', url=support_url)]) + keyboard.append([types.InlineKeyboardButton(text=texts.BACK, callback_data='menu_balance')]) + + await callback.message.edit_text( + f'🚫 Пополнение ограничено\n\n{reason}\n\n' + 'Если вы считаете это ошибкой, вы можете обжаловать решение.', + reply_markup=types.InlineKeyboardMarkup(inline_keyboard=keyboard), + ) + await callback.answer() + return + + if not settings.is_platega_enabled(): + await callback.answer( + texts.t( + 'PLATEGA_TEMPORARILY_UNAVAILABLE', + '❌ Оплата через Platega временно недоступна', + ), + show_alert=True, + ) + return + + if method_code not in _get_active_methods(): + await callback.answer('⚠️ Этот способ сейчас недоступен', show_alert=True) + return + + await _prompt_amount(callback.message, db_user, state, method_code) + await callback.answer() + + @error_handler async def process_platega_payment_amount( message: types.Message, diff --git a/app/keyboards/inline.py b/app/keyboards/inline.py index d9700b06..c5eaa64a 100644 --- a/app/keyboards/inline.py +++ b/app/keyboards/inline.py @@ -1612,14 +1612,26 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN if settings.is_platega_enabled() and settings.get_platega_active_methods(): platega_name = settings.get_platega_display_name() - keyboard.append( - [ - InlineKeyboardButton( - text=texts.t('PAYMENT_PLATEGA', f'💳 {platega_name}'), - callback_data=_build_callback('platega'), + if settings.PLATEGA_INLINE_METHODS: + for method_code in settings.get_platega_active_methods(): + title = settings.get_platega_method_display_title(method_code) + keyboard.append( + [ + InlineKeyboardButton( + text=f'{title} ({platega_name})', + callback_data=_build_callback(f'platega_m{method_code}'), + ) + ] ) - ] - ) + else: + keyboard.append( + [ + InlineKeyboardButton( + text=texts.t('PAYMENT_PLATEGA', f'💳 {platega_name}'), + callback_data=_build_callback('platega'), + ) + ] + ) has_direct_payment_methods = True if settings.is_cryptobot_enabled(): diff --git a/app/utils/payment_utils.py b/app/utils/payment_utils.py index c4c9c1d6..53d297aa 100644 --- a/app/utils/payment_utils.py +++ b/app/utils/payment_utils.py @@ -113,15 +113,28 @@ def get_available_payment_methods() -> list[dict[str, str]]: if settings.is_platega_enabled() and settings.get_platega_active_methods(): platega_name = settings.get_platega_display_name() - methods.append( - { - 'id': 'platega', - 'name': 'Банковская карта', - 'icon': '💳', - 'description': f'через {platega_name} (карты + СБП)', - 'callback': 'topup_platega', - } - ) + if settings.PLATEGA_INLINE_METHODS: + for method_code in settings.get_platega_active_methods(): + info = settings.get_platega_method_definitions().get(method_code, {}) + methods.append( + { + 'id': f'platega_m{method_code}', + 'name': info.get('name', f'Метод {method_code}'), + 'icon': info.get('title', '💳').split(' ', 1)[0] if info.get('title') else '💳', + 'description': f'через {platega_name}', + 'callback': f'topup_platega_m{method_code}', + } + ) + else: + methods.append( + { + 'id': 'platega', + 'name': 'Банковская карта', + 'icon': '💳', + 'description': f'через {platega_name} (карты + СБП)', + 'callback': 'topup_platega', + } + ) if settings.is_cloudpayments_enabled(): cloudpayments_name = settings.get_cloudpayments_display_name() @@ -282,6 +295,14 @@ def is_payment_method_available(method_id: str) -> bool: return settings.is_heleket_enabled() if method_id == 'platega': return settings.is_platega_enabled() and bool(settings.get_platega_active_methods()) + if method_id.startswith('platega_m'): + if not settings.is_platega_enabled(): + return False + try: + code = int(method_id[len('platega_m'):]) + except ValueError: + return False + return code in settings.get_platega_active_methods() if method_id == 'cloudpayments': return settings.is_cloudpayments_enabled() if method_id == 'freekassa':