Files
remnawave-minishop/bot/handlers/user/subscription/payments_subscription.py
T

135 lines
4.9 KiB
Python

import logging
from typing import Optional
from aiogram import F, Router, types
from sqlalchemy.ext.asyncio import AsyncSession
from bot.keyboards.inline.user_keyboards import get_payment_method_keyboard
from bot.middlewares.i18n import JsonI18n
from config.settings import Settings
router = Router(name="user_subscription_payments_selection_router")
@router.callback_query(F.data.startswith("subscribe_period:"))
async def select_subscription_period_callback_handler(
callback: types.CallbackQuery,
settings: Settings,
i18n_data: dict,
session: AsyncSession,
promo_code_service=None, # Injected from dispatcher
):
current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE)
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
get_text = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs) if i18n else key
if not i18n or not callback.message:
try:
await callback.answer(get_text("error_occurred_try_again"), show_alert=True)
except Exception:
pass
return
traffic_packages = getattr(settings, "traffic_packages", {}) or {}
stars_traffic_packages = getattr(settings, "stars_traffic_packages", {}) or {}
traffic_mode = bool(getattr(settings, "traffic_sale_mode", False) or stars_traffic_packages)
try:
months = float(callback.data.split(":")[-1])
except (ValueError, IndexError):
logging.error(f"Invalid subscription period in callback_data: {callback.data}")
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
price_source = traffic_packages if traffic_mode else settings.subscription_options
stars_price_source = stars_traffic_packages if traffic_mode else settings.stars_subscription_options
price_rub = price_source.get(months)
stars_price = stars_price_source.get(months)
currency_symbol_val = settings.DEFAULT_CURRENCY_SYMBOL
# Check for active discount and apply if exists
discount_text = ""
if promo_code_service and price_rub:
active_discount_info = await promo_code_service.get_user_active_discount(
session, callback.from_user.id
)
if active_discount_info:
discount_pct, promo_code = active_discount_info
original_price_rub = price_rub
price_rub, discount_amt = promo_code_service.calculate_discounted_price(
price_rub, discount_pct
)
discount_text = get_text(
"active_discount_notice",
code=promo_code,
discount_pct=discount_pct,
original_price=original_price_rub,
discounted_price=price_rub,
discount_amount=discount_amt
)
# Note: Stars prices typically don't get discounts (can be added if needed)
if price_rub is None:
if traffic_mode and not price_source and stars_price is not None:
currency_methods_enabled = any(
[
settings.FREEKASSA_ENABLED,
settings.PLATEGA_ENABLED,
settings.SEVERPAY_ENABLED,
settings.YOOKASSA_ENABLED,
settings.CRYPTOPAY_ENABLED,
]
)
if currency_methods_enabled:
logging.error(
"Currency price missing for traffic option %s while fiat providers are enabled.",
months,
)
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
price_rub = 0.0
currency_symbol_val = "⭐"
else:
logging.error(
f"Price not found for option {months} using {'traffic_packages' if traffic_mode else 'subscription_options'}."
)
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
text_content = get_text("choose_payment_method_traffic") if traffic_mode else get_text("choose_payment_method")
if discount_text:
text_content = f"{discount_text}\n\n{text_content}"
reply_markup = get_payment_method_keyboard(
months,
price_rub,
stars_price,
currency_symbol_val,
current_lang,
i18n,
settings,
sale_mode="traffic" if traffic_mode else "subscription",
)
try:
await callback.message.edit_text(text_content, reply_markup=reply_markup)
except Exception as e_edit:
logging.warning(
f"Edit message for payment method selection failed: {e_edit}. Sending new one."
)
await callback.message.answer(text_content, reply_markup=reply_markup)
try:
await callback.answer()
except Exception:
pass