diff --git a/.env.example b/.env.example
index cfcab541..36bdac6b 100644
--- a/.env.example
+++ b/.env.example
@@ -491,16 +491,11 @@ YOOKASSA_WEBHOOK_PORT=8082
YOOKASSA_MIN_AMOUNT_KOPEKS=5000
YOOKASSA_MAX_AMOUNT_KOPEKS=1000000
-# Быстрый выбор суммы пополнения через YooKassa
-YOOKASSA_QUICK_AMOUNT_SELECTION_ENABLED=true
-
# Рекуррентные платежи YooKassa (автосохранение карты для автоплатежей)
YOOKASSA_RECURRENT_ENABLED=false
# true = карта сохраняется обязательно, false = пользователь решает (чекбокс на стороне YooKassa)
YOOKASSA_RECURRENT_REQUIRED=true
-# Отключить отображение кнопок выбора суммы пополнения (оставить только ввод вручную)
-DISABLE_TOPUP_BUTTONS=false
# Отключить пополнение баланса через поддержку
SUPPORT_TOPUP_ENABLED=true
diff --git a/app/config.py b/app/config.py
index 751db510..214a6b81 100644
--- a/app/config.py
+++ b/app/config.py
@@ -353,10 +353,8 @@ class Settings(BaseSettings):
YOOKASSA_TRUSTED_PROXY_NETWORKS: str = ''
YOOKASSA_MIN_AMOUNT_KOPEKS: int = 5000
YOOKASSA_MAX_AMOUNT_KOPEKS: int = 1000000
- YOOKASSA_QUICK_AMOUNT_SELECTION_ENABLED: bool = False
YOOKASSA_RECURRENT_ENABLED: bool = False
YOOKASSA_RECURRENT_REQUIRED: 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
@@ -1254,10 +1252,6 @@ class Settings(BaseSettings):
return bool(value)
- def is_quick_amount_buttons_enabled(self) -> bool:
- """Кнопки быстрого выбора суммы пополнения отключены."""
- return False
-
def get_available_languages(self) -> list[str]:
defaults = ['ru', 'en', 'ua', 'zh', 'fa']
diff --git a/app/handlers/balance/cloudpayments.py b/app/handlers/balance/cloudpayments.py
index aa34b137..a04da927 100644
--- a/app/handlers/balance/cloudpayments.py
+++ b/app/handlers/balance/cloudpayments.py
@@ -129,9 +129,9 @@ async def process_cloudpayments_payment_amount(
state: FSMContext,
):
"""
- Process payment amount directly (called from quick_amount handlers).
+ Process payment amount directly.
- Similar to process_heleket_payment_amount and other payment handlers.
+ Similar to other payment amount handlers.
"""
texts = get_texts(db_user.language)
@@ -197,7 +197,7 @@ async def start_cloudpayments_payment(
"""
Start CloudPayments payment flow.
- Shows amount input prompt or quick amount buttons.
+ Shows amount input prompt.
"""
texts = get_texts(db_user.language)
@@ -377,121 +377,3 @@ async def process_cloudpayments_amount(
logger.info('CloudPayments payment created: user amount=₽', telegram_id=db_user.telegram_id, amount_rub=amount_rub)
-@error_handler
-async def handle_cloudpayments_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """
- Handle quick amount selection for CloudPayments.
-
- Called when user clicks a predefined amount button.
- """
- texts = get_texts(db_user.language)
-
- if not settings.is_cloudpayments_enabled():
- await callback.answer(
- texts.t('CLOUDPAYMENTS_NOT_AVAILABLE', 'CloudPayments временно недоступен'),
- show_alert=True,
- )
- return
-
- # Extract amount from callback data: topup_amount|cloudpayments|{amount_kopeks}
- try:
- parts = callback.data.split('|')
- if len(parts) >= 3:
- amount_kopeks = int(parts[2])
- else:
- await callback.answer('Invalid callback data', show_alert=True)
- return
- except (ValueError, IndexError):
- await callback.answer('Invalid amount', show_alert=True)
- return
-
- amount_rub = amount_kopeks / 100
-
- # Validate amount
- if amount_kopeks < settings.CLOUDPAYMENTS_MIN_AMOUNT_KOPEKS:
- await callback.answer(
- texts.t('AMOUNT_TOO_LOW_SHORT', 'Сумма слишком мала'),
- show_alert=True,
- )
- return
-
- if amount_kopeks > settings.CLOUDPAYMENTS_MAX_AMOUNT_KOPEKS:
- await callback.answer(
- texts.t('AMOUNT_TOO_HIGH_SHORT', 'Сумма слишком велика'),
- show_alert=True,
- )
- return
-
- await callback.answer()
-
- # Create payment
- payment_service = PaymentService()
-
- description = settings.PAYMENT_BALANCE_TEMPLATE.format(
- service_name=settings.PAYMENT_SERVICE_NAME,
- description=settings.CLOUDPAYMENTS_DESCRIPTION,
- )
-
- result = await payment_service.create_cloudpayments_payment(
- db=db,
- user_id=db_user.id,
- amount_kopeks=amount_kopeks,
- description=description,
- telegram_id=db_user.telegram_id,
- language=db_user.language,
- )
-
- if not result:
- await callback.message.edit_text(
- texts.t(
- 'PAYMENT_CREATE_ERROR',
- 'Не удалось создать платёж. Попробуйте позже.',
- ),
- reply_markup=get_back_keyboard(db_user.language),
- parse_mode='HTML',
- )
- return
-
- payment_url = result.get('payment_url')
-
- # Create keyboard with payment button
- keyboard = InlineKeyboardMarkup(
- inline_keyboard=[
- [
- InlineKeyboardButton(
- text=texts.t(
- 'PAY_BUTTON',
- '💳 Оплатить {amount}₽',
- ).format(amount=f'{amount_rub:.0f}'),
- url=payment_url,
- )
- ],
- [
- InlineKeyboardButton(
- text=texts.t('BACK_BUTTON', '◀️ Назад'),
- callback_data='menu_balance',
- )
- ],
- ]
- )
-
- await callback.message.edit_text(
- texts.t(
- 'CLOUDPAYMENTS_PAYMENT_CREATED',
- '💳 Оплата банковской картой\n\n'
- 'Сумма: {amount}₽\n\n'
- 'Нажмите кнопку ниже для оплаты.\n'
- 'После успешной оплаты баланс будет пополнен автоматически.',
- ).format(amount=f'{amount_rub:.2f}'),
- reply_markup=keyboard,
- parse_mode='HTML',
- )
-
- logger.info(
- 'CloudPayments payment created (quick): user amount=₽', telegram_id=db_user.telegram_id, amount_rub=amount_rub
- )
diff --git a/app/handlers/balance/cryptobot.py b/app/handlers/balance/cryptobot.py
index 738751fd..916eaeb1 100644
--- a/app/handlers/balance/cryptobot.py
+++ b/app/handlers/balance/cryptobot.py
@@ -53,41 +53,18 @@ async def start_cryptobot_payment(callback: types.CallbackQuery, db_user: User,
available_assets = settings.get_cryptobot_assets()
assets_text = ', '.join(available_assets)
- # Формируем текст сообщения в зависимости от настройки
- if settings.is_quick_amount_buttons_enabled():
- message_text = (
- f'🪙 Пополнение криптовалютой\n\n'
- f'Выберите сумму пополнения или введите вручную сумму '
- f'от 100 до 100,000 ₽:\n\n'
- f'💰 Доступные активы: {assets_text}\n'
- f'⚡ Мгновенное зачисление на баланс\n'
- f'🔒 Безопасная оплата через CryptoBot\n\n'
- f'{rate_text}\n'
- f'Сумма будет автоматически конвертирована в USD для оплаты.'
- )
- else:
- message_text = (
- f'🪙 Пополнение криптовалютой\n\n'
- f'Введите сумму для пополнения от 100 до 100,000 ₽:\n\n'
- f'💰 Доступные активы: {assets_text}\n'
- f'⚡ Мгновенное зачисление на баланс\n'
- f'🔒 Безопасная оплата через CryptoBot\n\n'
- f'{rate_text}\n'
- f'Сумма будет автоматически конвертирована в USD для оплаты.'
- )
+ message_text = (
+ f'🪙 Пополнение криптовалютой\n\n'
+ f'Введите сумму для пополнения от 100 до 100,000 ₽:\n\n'
+ f'💰 Доступные активы: {assets_text}\n'
+ f'⚡ Мгновенное зачисление на баланс\n'
+ f'🔒 Безопасная оплата через CryptoBot\n\n'
+ f'{rate_text}\n'
+ f'Сумма будет автоматически конвертирована в USD для оплаты.'
+ )
- # Создаем клавиатуру
keyboard = get_back_keyboard(db_user.language)
- # Если включен быстрый выбор суммы и не отключены кнопки, добавляем кнопки
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- # Вставляем кнопки быстрого выбора перед кнопкой "Назад"
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(message_text, reply_markup=keyboard, parse_mode='HTML')
await state.set_state(BalanceStates.waiting_for_amount)
diff --git a/app/handlers/balance/freekassa.py b/app/handlers/balance/freekassa.py
index 838dd389..2699e5a4 100644
--- a/app/handlers/balance/freekassa.py
+++ b/app/handlers/balance/freekassa.py
@@ -154,7 +154,7 @@ async def process_freekassa_payment_amount(
payment_method: str | None = None,
):
"""
- Process payment amount directly (called from quick_amount handlers).
+ Process payment amount directly.
payment_method: 'freekassa', 'freekassa_sbp', 'freekassa_card'
"""
texts = get_texts(db_user.language)
@@ -372,125 +372,3 @@ async def process_freekassa_custom_amount(
)
-async def _process_freekassa_quick_amount_impl(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
- payment_method: str,
-):
- """
- Process quick amount selection for Freekassa payment.
- Called when user clicks a predefined amount button.
- payment_method: 'freekassa', 'freekassa_sbp', 'freekassa_card'
- """
- texts = get_texts(db_user.language)
-
- if not settings.is_freekassa_enabled():
- await callback.answer(
- texts.t('FREEKASSA_NOT_AVAILABLE', 'Freekassa временно недоступен'),
- show_alert=True,
- )
- return
-
- if payment_method == 'freekassa_sbp' and not settings.is_freekassa_sbp_enabled():
- await callback.answer(
- texts.t('FREEKASSA_NOT_AVAILABLE', 'Freekassa временно недоступен'),
- show_alert=True,
- )
- return
-
- if payment_method == 'freekassa_card' and not settings.is_freekassa_card_enabled():
- await callback.answer(
- texts.t('FREEKASSA_NOT_AVAILABLE', 'Freekassa временно недоступен'),
- show_alert=True,
- )
- return
-
- # Extract amount from callback data: topup_amount|{method}|{amount_kopeks}
- try:
- parts = callback.data.split('|')
- if len(parts) >= 3:
- amount_kopeks = int(parts[2])
- else:
- await callback.answer('Invalid callback data', show_alert=True)
- return
- except (ValueError, IndexError):
- await callback.answer('Invalid amount', show_alert=True)
- return
-
- # Проверка ограничения на пополнение
- if getattr(db_user, 'restriction_topup', False):
- reason = getattr(db_user, 'restriction_reason', None) or 'Действие ограничено администратором'
- support_url = settings.get_support_contact_url()
- keyboard = []
- if support_url:
- keyboard.append([InlineKeyboardButton(text='🆘 Обжаловать', url=support_url)])
- keyboard.append([InlineKeyboardButton(text=texts.BACK, callback_data='menu_balance')])
-
- await callback.message.edit_text(
- f'🚫 Пополнение ограничено\n\n{reason}',
- parse_mode='HTML',
- reply_markup=InlineKeyboardMarkup(inline_keyboard=keyboard),
- )
- return
-
- # Validate amount
- min_amount = settings.FREEKASSA_MIN_AMOUNT_KOPEKS
- max_amount = settings.FREEKASSA_MAX_AMOUNT_KOPEKS
-
- if amount_kopeks < min_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_LOW_SHORT', 'Сумма слишком мала'),
- show_alert=True,
- )
- return
-
- if amount_kopeks > max_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_HIGH_SHORT', 'Сумма слишком велика'),
- show_alert=True,
- )
- return
-
- await callback.answer()
- await state.clear()
-
- await _create_freekassa_payment_and_respond(
- message_or_callback=callback.message,
- db_user=db_user,
- db=db,
- amount_kopeks=amount_kopeks,
- edit_message=True,
- payment_method=payment_method,
- )
-
-
-@error_handler
-async def process_freekassa_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- await _process_freekassa_quick_amount_impl(callback, db_user, db, state, 'freekassa')
-
-
-@error_handler
-async def process_freekassa_sbp_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- await _process_freekassa_quick_amount_impl(callback, db_user, db, state, 'freekassa_sbp')
-
-
-@error_handler
-async def process_freekassa_card_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- await _process_freekassa_quick_amount_impl(callback, db_user, db, state, 'freekassa_card')
diff --git a/app/handlers/balance/heleket.py b/app/handlers/balance/heleket.py
index 205c3ac8..30082e23 100644
--- a/app/handlers/balance/heleket.py
+++ b/app/handlers/balance/heleket.py
@@ -72,13 +72,6 @@ async def start_heleket_payment(
keyboard = get_back_keyboard(db_user.language)
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_buttons:
- keyboard.inline_keyboard = quick_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(
'\n'.join(filter(None, message_lines)),
reply_markup=keyboard,
diff --git a/app/handlers/balance/kassa_ai.py b/app/handlers/balance/kassa_ai.py
index cce40352..b813a8be 100644
--- a/app/handlers/balance/kassa_ai.py
+++ b/app/handlers/balance/kassa_ai.py
@@ -168,7 +168,7 @@ async def process_kassa_ai_payment_amount(
state: FSMContext,
payment_method: str = 'kassa_ai',
):
- """Process payment amount directly (called from custom_amount and quick_amount handlers)."""
+ """Process payment amount directly (called from custom_amount handlers)."""
texts = get_texts(db_user.language)
# Проверка ограничения на пополнение
@@ -275,54 +275,6 @@ async def _start_kassa_ai_sub_topup(
)
-async def _process_kassa_ai_sub_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
- payment_method: str,
-):
- """Generic quick amount handler for any KassaAI sub-method."""
- cfg = _KASSA_AI_METHOD_CONFIG[payment_method]
- texts = get_texts(db_user.language)
-
- if not cfg['is_enabled']():
- await callback.answer(texts.t('KASSA_AI_NOT_AVAILABLE', cfg['unavailable_text']), show_alert=True)
- return
-
- try:
- parts = callback.data.split('|')
- amount_kopeks = int(parts[2]) if len(parts) >= 3 else None
- if amount_kopeks is None:
- raise ValueError
- except (ValueError, IndexError):
- await callback.answer('Invalid amount', show_alert=True)
- return
-
- if await _check_topup_restriction(callback, db_user):
- return
-
- min_amount = settings.KASSA_AI_MIN_AMOUNT_KOPEKS
- max_amount = settings.KASSA_AI_MAX_AMOUNT_KOPEKS
- if amount_kopeks < min_amount:
- await callback.answer(texts.t('AMOUNT_TOO_LOW_SHORT', 'Сумма слишком мала'), show_alert=True)
- return
- if amount_kopeks > max_amount:
- await callback.answer(texts.t('AMOUNT_TOO_HIGH_SHORT', 'Сумма слишком велика'), show_alert=True)
- return
-
- await callback.answer()
- await state.clear()
- await _create_kassa_ai_payment_and_respond(
- message_or_callback=callback.message,
- db_user=db_user,
- db=db,
- amount_kopeks=amount_kopeks,
- edit_message=True,
- payment_method=payment_method,
- )
-
-
# --- Public handler functions (registered in main.py) ---
@@ -376,17 +328,6 @@ async def process_kassa_ai_custom_amount(
)
-@error_handler
-async def process_kassa_ai_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """Process quick amount selection for KassaAI payment."""
- await _process_kassa_ai_sub_quick_amount(callback, db_user, db, state, 'kassa_ai')
-
-
@error_handler
async def start_kassa_ai_sbp_topup(
callback: types.CallbackQuery,
@@ -398,17 +339,6 @@ async def start_kassa_ai_sbp_topup(
await _start_kassa_ai_sub_topup(callback, db_user, db, state, 'kassa_ai_sbp')
-@error_handler
-async def process_kassa_ai_sbp_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """Process quick amount for KassaAI SBP."""
- await _process_kassa_ai_sub_quick_amount(callback, db_user, db, state, 'kassa_ai_sbp')
-
-
@error_handler
async def start_kassa_ai_card_topup(
callback: types.CallbackQuery,
@@ -420,12 +350,3 @@ async def start_kassa_ai_card_topup(
await _start_kassa_ai_sub_topup(callback, db_user, db, state, 'kassa_ai_card')
-@error_handler
-async def process_kassa_ai_card_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """Process quick amount for KassaAI Card."""
- await _process_kassa_ai_sub_quick_amount(callback, db_user, db, state, 'kassa_ai_card')
diff --git a/app/handlers/balance/main.py b/app/handlers/balance/main.py
index 03a5034d..0e880558 100644
--- a/app/handlers/balance/main.py
+++ b/app/handlers/balance/main.py
@@ -157,102 +157,6 @@ async def route_payment_by_method(
return False
-async def get_quick_amount_buttons(language: str, user: User) -> list:
- """
- Generate quick amount buttons with user-specific pricing and discounts.
-
- Uses PricingEngine as the single source of truth for all price calculations,
- including base period price, devices, servers, traffic, and per-category discounts.
-
- Args:
- language: User's language for formatting
- user: User object to calculate personalized discounts
-
- Returns:
- List of button rows for inline keyboard
- """
- if not settings.is_quick_amount_buttons_enabled():
- return []
-
- from app.database.crud.subscription import get_subscription_by_user_id
- from app.database.database import AsyncSessionLocal
- from app.services.pricing_engine import pricing_engine
-
- texts = get_texts(language)
-
- buttons = []
-
- async with AsyncSessionLocal() as db:
- subscription = await get_subscription_by_user_id(db, user.id)
-
- tariff = None
- tariff_periods = None
- if settings.is_tariffs_mode() and subscription and subscription.tariff_id:
- tariff = subscription.tariff
- if tariff and tariff.period_prices:
- tariff_periods = sorted(int(k) for k in tariff.period_prices.keys())
-
- if tariff_periods:
- periods = tariff_periods[:6]
- else:
- periods = settings.get_available_subscription_periods()[:6]
-
- for period in periods:
- try:
- if tariff and tariff_periods and period in tariff_periods:
- result = await pricing_engine.calculate_tariff_purchase_price(
- tariff,
- period,
- device_limit=subscription.device_limit if subscription else None,
- user=user,
- )
- elif subscription:
- result = await pricing_engine.calculate_renewal_price(db, subscription, period, user=user)
- else:
- result = await pricing_engine.calculate_classic_new_subscription_price(
- db,
- period,
- [],
- 0,
- settings.DEFAULT_DEVICE_LIMIT,
- user=user,
- )
-
- total_price = result.final_total
- original_total = result.original_total
-
- if total_price <= 0:
- continue
-
- callback_data = f'quick_amount_{total_price}'
- period_label = f'{period} дней'
-
- has_discount = original_total > total_price and original_total > 0
- if has_discount:
- discount_pct = round((original_total - total_price) * 100 / original_total)
- if discount_pct > 0:
- button_text = (
- f'{texts.format_price(original_total)} ➜ '
- f'{texts.format_price(total_price)} '
- f'(-{discount_pct}%) • {period_label}'
- )
- else:
- button_text = f'{texts.format_price(total_price)} • {period_label}'
- else:
- button_text = f'{texts.format_price(total_price)} • {period_label}'
-
- buttons.append(types.InlineKeyboardButton(text=button_text, callback_data=callback_data))
- except Exception:
- logger.warning('Failed to calculate price for period', period=period)
- continue
-
- keyboard_rows = []
- for i in range(0, len(buttons), 2):
- keyboard_rows.append(buttons[i : i + 2])
-
- return keyboard_rows
-
-
@error_handler
async def show_balance_menu(callback: types.CallbackQuery, db_user: User, db: AsyncSession):
# Проверяем, доступно ли сообщение
@@ -640,37 +544,6 @@ async def handle_sbp_payment(callback: types.CallbackQuery, db: AsyncSession):
await callback.answer('❌ Ошибка обработки платежа', show_alert=True)
-@error_handler
-async def handle_quick_amount_selection(callback: types.CallbackQuery, db_user: User, state: FSMContext):
- """
- Обработчик выбора суммы через кнопки быстрого выбора
- """
- # Проверяем, что пользователь в правильном состоянии FSM
- current_state = await state.get_state()
- if current_state != BalanceStates.waiting_for_amount:
- await callback.answer('❌ Сначала выберите способ оплаты', show_alert=True)
- return
-
- # Извлекаем сумму из callback_data
- try:
- amount_kopeks = int(callback.data.split('_')[-1])
-
- # Получаем метод оплаты из состояния
- data = await state.get_data()
- payment_method = data.get('payment_method', 'yookassa')
-
- # Роутим платеж на соответствующий обработчик
- if not await route_payment_by_method(callback.message, db_user, amount_kopeks, state, payment_method):
- await callback.answer('❌ Неизвестный способ оплаты', show_alert=True)
- return
-
- except ValueError:
- await callback.answer('❌ Ошибка обработки суммы', show_alert=True)
- except Exception as e:
- logger.error('Ошибка обработки быстрого выбора суммы', error=e)
- await callback.answer('❌ Ошибка обработки запроса', show_alert=True)
-
-
@error_handler
async def handle_topup_amount_callback(
callback: types.CallbackQuery,
@@ -797,52 +670,37 @@ def register_balance_handlers(dp: Dispatcher):
dp.callback_query.register(start_heleket_payment, F.data == 'topup_heleket')
dp.callback_query.register(check_heleket_payment_status, F.data.startswith('check_heleket_'))
- from .cloudpayments import handle_cloudpayments_quick_amount, start_cloudpayments_payment
+ from .cloudpayments import start_cloudpayments_payment
dp.callback_query.register(start_cloudpayments_payment, F.data == 'topup_cloudpayments')
- dp.callback_query.register(handle_cloudpayments_quick_amount, F.data.startswith('topup_amount|cloudpayments|'))
from .freekassa import (
- process_freekassa_card_quick_amount,
- process_freekassa_quick_amount,
- process_freekassa_sbp_quick_amount,
start_freekassa_card_topup,
start_freekassa_sbp_topup,
start_freekassa_topup,
)
dp.callback_query.register(start_freekassa_topup, F.data == 'topup_freekassa')
- dp.callback_query.register(process_freekassa_quick_amount, F.data.startswith('topup_amount|freekassa|'))
dp.callback_query.register(start_freekassa_sbp_topup, F.data == 'topup_freekassa_sbp')
- dp.callback_query.register(process_freekassa_sbp_quick_amount, F.data.startswith('topup_amount|freekassa_sbp|'))
dp.callback_query.register(start_freekassa_card_topup, F.data == 'topup_freekassa_card')
- dp.callback_query.register(process_freekassa_card_quick_amount, F.data.startswith('topup_amount|freekassa_card|'))
from .kassa_ai import (
- process_kassa_ai_card_quick_amount,
- process_kassa_ai_quick_amount,
- process_kassa_ai_sbp_quick_amount,
start_kassa_ai_card_topup,
start_kassa_ai_sbp_topup,
start_kassa_ai_topup,
)
dp.callback_query.register(start_kassa_ai_topup, F.data == 'topup_kassa_ai')
- dp.callback_query.register(process_kassa_ai_quick_amount, F.data.startswith('topup_amount|kassa_ai|'))
dp.callback_query.register(start_kassa_ai_sbp_topup, F.data == 'topup_kassa_ai_sbp')
- dp.callback_query.register(process_kassa_ai_sbp_quick_amount, F.data.startswith('topup_amount|kassa_ai_sbp|'))
dp.callback_query.register(start_kassa_ai_card_topup, F.data == 'topup_kassa_ai_card')
- dp.callback_query.register(process_kassa_ai_card_quick_amount, F.data.startswith('topup_amount|kassa_ai_card|'))
- from .riopay import process_riopay_quick_amount, start_riopay_topup
+ from .riopay import start_riopay_topup
dp.callback_query.register(start_riopay_topup, F.data == 'topup_riopay')
- dp.callback_query.register(process_riopay_quick_amount, F.data.startswith('topup_amount|riopay|'))
- from .severpay import process_severpay_quick_amount, start_severpay_topup
+ from .severpay import start_severpay_topup
dp.callback_query.register(start_severpay_topup, F.data == 'topup_severpay')
- dp.callback_query.register(process_severpay_quick_amount, F.data.startswith('topup_amount|severpay|'))
from .mulenpay import check_mulenpay_payment_status
@@ -862,9 +720,6 @@ def register_balance_handlers(dp: Dispatcher):
dp.callback_query.register(handle_payment_methods_unavailable, F.data == 'payment_methods_unavailable')
- # Регистрируем обработчик для кнопок быстрого выбора суммы
- dp.callback_query.register(handle_quick_amount_selection, F.data.startswith('quick_amount_'))
-
dp.callback_query.register(handle_topup_amount_callback, F.data.startswith('topup_amount|'))
dp.callback_query.register(handle_saved_cards_list, F.data == 'saved_cards_list')
diff --git a/app/handlers/balance/mulenpay.py b/app/handlers/balance/mulenpay.py
index 04f308dd..8098b116 100644
--- a/app/handlers/balance/mulenpay.py
+++ b/app/handlers/balance/mulenpay.py
@@ -65,13 +65,6 @@ async def start_mulenpay_payment(
keyboard = get_back_keyboard(db_user.language)
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(
message_text,
reply_markup=keyboard,
diff --git a/app/handlers/balance/pal24.py b/app/handlers/balance/pal24.py
index f0cafe83..5114afad 100644
--- a/app/handlers/balance/pal24.py
+++ b/app/handlers/balance/pal24.py
@@ -303,13 +303,6 @@ async def start_pal24_payment(
keyboard = get_back_keyboard(db_user.language)
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(
message_text,
reply_markup=keyboard,
diff --git a/app/handlers/balance/platega.py b/app/handlers/balance/platega.py
index 708e125e..50a13e11 100644
--- a/app/handlers/balance/platega.py
+++ b/app/handlers/balance/platega.py
@@ -71,13 +71,6 @@ async def _prompt_amount(
keyboard = get_back_keyboard(db_user.language)
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await message.edit_text(
prompt_template.format(
method_name=method_name,
diff --git a/app/handlers/balance/riopay.py b/app/handlers/balance/riopay.py
index 6b198b69..ab482aab 100644
--- a/app/handlers/balance/riopay.py
+++ b/app/handlers/balance/riopay.py
@@ -136,7 +136,7 @@ async def process_riopay_payment_amount(
state: FSMContext,
):
"""
- Process payment amount directly (called from quick_amount handlers).
+ Process payment amount directly.
"""
texts = get_texts(db_user.language)
@@ -284,73 +284,3 @@ async def process_riopay_custom_amount(
)
-@error_handler
-async def process_riopay_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """
- Process quick amount selection for RioPay payment.
- Called when user clicks a predefined amount button.
- """
- texts = get_texts(db_user.language)
-
- if not settings.is_riopay_enabled():
- await callback.answer(
- texts.t('RIOPAY_NOT_AVAILABLE', 'RioPay временно недоступен'),
- show_alert=True,
- )
- return
-
- # Extract amount from callback data: topup_amount|riopay|{amount_kopeks}
- try:
- parts = callback.data.split('|')
- if len(parts) >= 3:
- amount_kopeks = int(parts[2])
- else:
- await callback.answer('Invalid callback data', show_alert=True)
- return
- except (ValueError, IndexError):
- await callback.answer('Invalid amount', show_alert=True)
- return
-
- restriction_kb = _check_topup_restriction(db_user, texts)
- if restriction_kb:
- reason = getattr(db_user, 'restriction_reason', None) or 'Действие ограничено администратором'
- await callback.message.edit_text(
- f'🚫 Пополнение ограничено\n\n{reason}',
- parse_mode='HTML',
- reply_markup=restriction_kb,
- )
- return
-
- # Validate amount
- min_amount = settings.RIOPAY_MIN_AMOUNT_KOPEKS
- max_amount = settings.RIOPAY_MAX_AMOUNT_KOPEKS
-
- if amount_kopeks < min_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_LOW_SHORT', 'Сумма слишком мала'),
- show_alert=True,
- )
- return
-
- if amount_kopeks > max_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_HIGH_SHORT', 'Сумма слишком велика'),
- show_alert=True,
- )
- return
-
- await callback.answer()
- await state.clear()
-
- await _create_riopay_payment_and_respond(
- message_or_callback=callback.message,
- db_user=db_user,
- db=db,
- amount_kopeks=amount_kopeks,
- edit_message=True,
- )
diff --git a/app/handlers/balance/severpay.py b/app/handlers/balance/severpay.py
index 7282571c..338b77b3 100644
--- a/app/handlers/balance/severpay.py
+++ b/app/handlers/balance/severpay.py
@@ -136,7 +136,7 @@ async def process_severpay_payment_amount(
state: FSMContext,
):
"""
- Process payment amount directly (called from quick_amount handlers).
+ Process payment amount directly.
"""
texts = get_texts(db_user.language)
@@ -245,73 +245,3 @@ async def start_severpay_topup(
)
-@error_handler
-async def process_severpay_quick_amount(
- callback: types.CallbackQuery,
- db_user: User,
- db: AsyncSession,
- state: FSMContext,
-):
- """
- Process quick amount selection for SeverPay payment.
- Called when user clicks a predefined amount button.
- """
- texts = get_texts(db_user.language)
-
- if not settings.is_severpay_enabled():
- await callback.answer(
- texts.t('SEVERPAY_NOT_AVAILABLE', 'SeverPay временно недоступен'),
- show_alert=True,
- )
- return
-
- # Extract amount from callback data: topup_amount|severpay|{amount_kopeks}
- try:
- parts = callback.data.split('|')
- if len(parts) >= 3:
- amount_kopeks = int(parts[2])
- else:
- await callback.answer('Invalid callback data', show_alert=True)
- return
- except (ValueError, IndexError):
- await callback.answer('Invalid amount', show_alert=True)
- return
-
- restriction_kb = _check_topup_restriction(db_user, texts)
- if restriction_kb:
- reason = getattr(db_user, 'restriction_reason', None) or 'Действие ограничено администратором'
- await callback.message.edit_text(
- f'🚫 Пополнение ограничено\n\n{reason}',
- parse_mode='HTML',
- reply_markup=restriction_kb,
- )
- return
-
- # Validate amount
- min_amount = settings.SEVERPAY_MIN_AMOUNT_KOPEKS
- max_amount = settings.SEVERPAY_MAX_AMOUNT_KOPEKS
-
- if amount_kopeks < min_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_LOW_SHORT', 'Сумма слишком мала'),
- show_alert=True,
- )
- return
-
- if amount_kopeks > max_amount:
- await callback.answer(
- texts.t('AMOUNT_TOO_HIGH_SHORT', 'Сумма слишком велика'),
- show_alert=True,
- )
- return
-
- await callback.answer()
- await state.clear()
-
- await _create_severpay_payment_and_respond(
- message_or_callback=callback.message,
- db_user=db_user,
- db=db,
- amount_kopeks=amount_kopeks,
- edit_message=True,
- )
diff --git a/app/handlers/balance/stars.py b/app/handlers/balance/stars.py
index 13ef433c..bc1eb0ff 100644
--- a/app/handlers/balance/stars.py
+++ b/app/handlers/balance/stars.py
@@ -40,24 +40,10 @@ async def start_stars_payment(callback: types.CallbackQuery, db_user: User, stat
await callback.answer()
return
- # Формируем текст сообщения в зависимости от настройки
- if settings.is_quick_amount_buttons_enabled():
- message_text = '⭐ Пополнение через Telegram Stars\n\nВыберите сумму пополнения или введите вручную:'
- else:
- message_text = texts.TOP_UP_AMOUNT
+ message_text = texts.TOP_UP_AMOUNT
- # Создаем клавиатуру
keyboard = get_back_keyboard(db_user.language)
- # Если включен быстрый выбор суммы и не отключены кнопки, добавляем кнопки
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- # Вставляем кнопки быстрого выбора перед кнопкой "Назад"
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(message_text, reply_markup=keyboard)
await state.update_data(
diff --git a/app/handlers/balance/wata.py b/app/handlers/balance/wata.py
index 362bba5c..c086abea 100644
--- a/app/handlers/balance/wata.py
+++ b/app/handlers/balance/wata.py
@@ -61,13 +61,6 @@ async def start_wata_payment(
keyboard = get_back_keyboard(db_user.language)
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(
message_text,
reply_markup=keyboard,
diff --git a/app/handlers/balance/yookassa.py b/app/handlers/balance/yookassa.py
index 08767133..a6f9e025 100644
--- a/app/handlers/balance/yookassa.py
+++ b/app/handlers/balance/yookassa.py
@@ -46,31 +46,13 @@ async def start_yookassa_payment(callback: types.CallbackQuery, db_user: User, s
min_amount_rub = settings.YOOKASSA_MIN_AMOUNT_KOPEKS / 100
max_amount_rub = settings.YOOKASSA_MAX_AMOUNT_KOPEKS / 100
- # Формируем текст сообщения в зависимости от настройки
- if settings.is_quick_amount_buttons_enabled():
- message_text = (
- f'💳 Оплата банковской картой\n\n'
- f'Выберите сумму пополнения или введите вручную сумму '
- f'от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
- )
- else:
- message_text = (
- f'💳 Оплата банковской картой\n\n'
- f'Введите сумму для пополнения от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
- )
+ message_text = (
+ f'💳 Оплата банковской картой\n\n'
+ f'Введите сумму для пополнения от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
+ )
- # Создаем клавиатуру
keyboard = get_back_keyboard(db_user.language)
- # Если включен быстрый выбор суммы и не отключены кнопки, добавляем кнопки
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- # Вставляем кнопки быстрого выбора перед кнопкой "Назад"
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(message_text, reply_markup=keyboard, parse_mode='HTML')
await state.set_state(BalanceStates.waiting_for_amount)
@@ -110,31 +92,13 @@ async def start_yookassa_sbp_payment(callback: types.CallbackQuery, db_user: Use
min_amount_rub = settings.YOOKASSA_MIN_AMOUNT_KOPEKS / 100
max_amount_rub = settings.YOOKASSA_MAX_AMOUNT_KOPEKS / 100
- # Формируем текст сообщения в зависимости от настройки
- if settings.is_quick_amount_buttons_enabled():
- message_text = (
- f'🏦 Оплата через СБП\n\n'
- f'Выберите сумму пополнения или введите вручную сумму '
- f'от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
- )
- else:
- message_text = (
- f'🏦 Оплата через СБП\n\n'
- f'Введите сумму для пополнения от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
- )
+ message_text = (
+ f'🏦 Оплата через СБП\n\n'
+ f'Введите сумму для пополнения от {min_amount_rub:.0f} до {max_amount_rub:,.0f} рублей:'
+ )
- # Создаем клавиатуру
keyboard = get_back_keyboard(db_user.language)
- # Если включен быстрый выбор суммы и не отключены кнопки, добавляем кнопки
- if settings.is_quick_amount_buttons_enabled():
- from .main import get_quick_amount_buttons
-
- quick_amount_buttons = await get_quick_amount_buttons(db_user.language, db_user)
- if quick_amount_buttons:
- # Вставляем кнопки быстрого выбора перед кнопкой "Назад"
- keyboard.inline_keyboard = quick_amount_buttons + keyboard.inline_keyboard
-
await callback.message.edit_text(message_text, reply_markup=keyboard, parse_mode='HTML')
await state.set_state(BalanceStates.waiting_for_amount)
diff --git a/app/services/system_settings_service.py b/app/services/system_settings_service.py
index 063652f5..53b5adb0 100644
--- a/app/services/system_settings_service.py
+++ b/app/services/system_settings_service.py
@@ -275,7 +275,6 @@ class BotConfigurationService:
'SIMPLE_SUBSCRIPTION_DEVICE_LIMIT': 'SIMPLE_SUBSCRIPTION',
'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',