from collections.abc import Iterable from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup from aiogram.utils.keyboard import InlineKeyboardBuilder from config import RENEWAL_PRICES from handlers.buttons import BACK, CUSTOM_AMOUNT from handlers.payments.currency_rates import format_for_user async def payment_options_for_user( db_session, tg_id: int, language_code: str | None, *, force_currency: str | None = None, ) -> list[dict]: items = [] for price_rub in RENEWAL_PRICES.values(): txt = await format_for_user( db_session, tg_id, price_rub, language_code, force_currency=force_currency, ) items.append({"text": txt, "callback_data": f"amount|{int(price_rub)}"}) return items def payment_options(currency: str = "RUB") -> list[dict]: return [{"text": f"{price} {currency}", "callback_data": f"amount|{price}"} for price in RENEWAL_PRICES.values()] def build_amounts_keyboard( *, prefix: str, pattern: str, back_cb: str = "balance", custom_cb: str | tuple[str, str] | None = None, per_row: int = 2, opts: Iterable[dict] | None = None, ) -> InlineKeyboardMarkup: items = list(opts) if opts is not None else payment_options() b = InlineKeyboardBuilder() row = [] for i, item in enumerate(items, 1): row.append( InlineKeyboardButton( text=item["text"], callback_data=pattern.format(prefix=prefix, price=item["callback_data"].split("|", 1)[-1]), ) ) if i % per_row == 0: b.row(*row) row = [] if row: b.row(*row) if custom_cb: cb = custom_cb[1] if isinstance(custom_cb, tuple) else custom_cb b.row(InlineKeyboardButton(text=CUSTOM_AMOUNT, callback_data=cb)) b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb)) return b.as_markup() def parse_amount_from_callback(data: str, *, prefixes: list[str]) -> int | None: for p in prefixes: if data.startswith(f"{p}_amount|"): try: return int(data.split("|", 1)[1]) except Exception: return None if data.startswith(f"{p}|amount|"): try: return int(data.rsplit("|", 1)[-1]) except Exception: return None if data.startswith(f"{p}|"): try: return int(data.split("|", 1)[1]) except Exception: return None return None def pay_keyboard(url: str, *, pay_text: str, back_cb: str) -> InlineKeyboardMarkup: b = InlineKeyboardBuilder() b.row(InlineKeyboardButton(text=pay_text, url=url)) b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb)) return b.as_markup() def back_keyboard(back_cb: str) -> InlineKeyboardMarkup: b = InlineKeyboardBuilder() b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb)) return b.as_markup()