added gb packets selling

This commit is contained in:
machka pasla
2025-12-11 12:47:32 +03:00
parent 061fdeb72b
commit 22171eb66f
24 changed files with 798 additions and 246 deletions
+53 -16
View File
@@ -40,11 +40,15 @@ async def display_subscription_options(event: Union[types.Message, types.Callbac
return
currency_symbol_val = settings.DEFAULT_CURRENCY_SYMBOL
text_content = get_text("select_subscription_period") if settings.subscription_options else get_text("no_subscription_options_available")
traffic_mode = bool(getattr(settings, "traffic_sale_mode", False))
options = settings.traffic_packages if traffic_mode else settings.subscription_options
text_content = (
get_text("select_traffic_package") if traffic_mode else get_text("select_subscription_period")
) if options else get_text("no_subscription_options_available")
reply_markup = (
get_subscription_options_keyboard(settings.subscription_options, currency_symbol_val, current_lang, i18n)
if settings.subscription_options
get_subscription_options_keyboard(options, currency_symbol_val, current_lang, i18n, traffic_mode=traffic_mode)
if options
else get_back_to_main_menu_markup(current_lang, i18n)
)
@@ -125,17 +129,50 @@ async def my_subscription_command_handler(
end_date = active.get("end_date")
days_left = (end_date.date() - datetime.now().date()).days if end_date else 0
text = get_text(
"my_subscription_details",
end_date=end_date.strftime("%Y-%m-%d") if end_date else "N/A",
days_left=max(0, days_left),
status=active.get("status_from_panel", get_text("status_active")).capitalize(),
config_link=active.get("config_link") or get_text("config_link_not_available"),
traffic_limit=(f"{active['traffic_limit_bytes'] / 2**30:.2f} GB" if active.get("traffic_limit_bytes") else get_text("traffic_unlimited")),
traffic_used=(
f"{active['traffic_used_bytes'] / 2**30:.2f} GB" if active.get("traffic_used_bytes") is not None else get_text("traffic_na")
),
)
traffic_mode = bool(getattr(settings, "traffic_sale_mode", False))
def _fmt_gb(val: Optional[float]) -> str:
if val is None:
return get_text("traffic_na")
try:
if isinstance(val, (int, float)):
val_gb = float(val) / (2**30)
return f"{val_gb:.2f} GB"
except Exception:
pass
return str(val)
if traffic_mode:
limit_display = _fmt_gb(active.get("traffic_limit_bytes"))
used_display = _fmt_gb(active.get("traffic_used_bytes"))
remaining_display = get_text("traffic_na")
try:
limit_val = active.get("traffic_limit_bytes") or 0
used_val = active.get("traffic_used_bytes") or 0
remaining_val = max(0, float(limit_val) - float(used_val))
remaining_display = _fmt_gb(remaining_val)
except Exception:
pass
text = get_text(
"my_traffic_details",
status=active.get("status_from_panel", get_text("status_active")).capitalize(),
end_date=end_date.strftime("%Y-%m-%d") if end_date else get_text("traffic_no_expiry"),
traffic_limit=limit_display,
traffic_used=used_display,
traffic_left=remaining_display,
config_link=active.get("config_link") or get_text("config_link_not_available"),
)
else:
text = get_text(
"my_subscription_details",
end_date=end_date.strftime("%Y-%m-%d") if end_date else "N/A",
days_left=max(0, days_left),
status=active.get("status_from_panel", get_text("status_active")).capitalize(),
config_link=active.get("config_link") or get_text("config_link_not_available"),
traffic_limit=(f"{active['traffic_limit_bytes'] / 2**30:.2f} GB" if active.get("traffic_limit_bytes") else get_text("traffic_unlimited")),
traffic_used=(
f"{active['traffic_used_bytes'] / 2**30:.2f} GB" if active.get("traffic_used_bytes") is not None else get_text("traffic_na")
),
)
base_markup = get_back_to_main_menu_markup(current_lang, i18n)
kb = base_markup.inline_keyboard
@@ -214,7 +251,7 @@ async def my_subscription_command_handler(
])
# 2) Auto-renew toggle (YooKassa only)
if local_sub and local_sub.provider == "yookassa" and settings.yookassa_autopayments_active:
if not traffic_mode and local_sub and local_sub.provider == "yookassa" and settings.yookassa_autopayments_active:
toggle_text = (
get_text("autorenew_disable_button") if local_sub.auto_renew_enabled else get_text("autorenew_enable_button")
)
@@ -226,7 +263,7 @@ async def my_subscription_command_handler(
])
# 3) Payment methods management (when autopayments enabled)
if settings.yookassa_autopayments_active:
if not traffic_mode and settings.yookassa_autopayments_active:
prepend_rows.append([
InlineKeyboardButton(text=get_text("payment_methods_manage_button"), callback_data="pm:manage")
])
@@ -390,8 +390,15 @@ async def payment_method_history(callback: types.CallbackQuery, settings: Settin
await callback.message.edit_text(_("payment_method_no_history"), reply_markup=back_markup)
return
traffic_mode = getattr(settings, "traffic_sale_mode", False)
def _format_item(p: Payment) -> str:
title = p.description or _("subscription_purchase_title", months=p.subscription_duration_months or 1)
if traffic_mode:
units_val = p.subscription_duration_months or 0
units_display = str(int(units_val)) if float(units_val).is_integer() else f"{units_val:g}"
title = p.description or _("traffic_purchase_title", traffic_gb=units_display)
else:
title = p.description or _("subscription_purchase_title", months=p.subscription_duration_months or 1)
date_str = p.created_at.strftime('%Y-%m-%d') if p.created_at else "N/A"
return f"{date_str}{title}{p.amount:.2f} {p.currency}"
@@ -455,4 +462,3 @@ async def payment_methods_list(callback: types.CallbackQuery, settings: Settings
except Exception:
pass
@@ -39,9 +39,10 @@ async def pay_crypto_callback_handler(
try:
_, data_payload = callback.data.split(":", 1)
months_str, price_str = data_payload.split(":")
months = int(months_str)
price_amount = float(price_str)
parts = data_payload.split(":")
months = float(parts[0])
price_amount = float(parts[1])
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except (ValueError, IndexError):
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
@@ -50,7 +51,12 @@ async def pay_crypto_callback_handler(
return
user_id = callback.from_user.id
payment_description = get_text("payment_description_subscription", months=months)
human_value = str(int(months)) if float(months).is_integer() else f"{months:g}"
payment_description = (
get_text("payment_description_traffic", traffic_gb=human_value)
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
invoice_url = await cryptopay_service.create_invoice(
session=session,
@@ -58,17 +64,22 @@ async def pay_crypto_callback_handler(
months=months,
amount=price_amount,
description=payment_description,
sale_mode=sale_mode,
)
if invoice_url:
try:
await callback.message.edit_text(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
invoice_url,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -76,12 +87,16 @@ async def pay_crypto_callback_handler(
except Exception:
try:
await callback.message.answer(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
invoice_url,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -47,9 +47,10 @@ async def pay_fk_callback_handler(
try:
_, data_payload = callback.data.split(":", 1)
months_str, price_str = data_payload.split(":")
months = int(months_str)
price_rub = float(price_str)
parts = data_payload.split(":")
months = float(parts[0])
price_rub = float(parts[1])
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except (ValueError, IndexError):
logging.error(f"Invalid pay_fk data in callback: {callback.data}")
try:
@@ -59,7 +60,12 @@ async def pay_fk_callback_handler(
return
user_id = callback.from_user.id
payment_description = get_text("payment_description_subscription", months=months)
human_value = str(int(months)) if float(months).is_integer() else f"{months:g}"
payment_description = (
get_text("payment_description_traffic", traffic_gb=human_value)
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
currency_code = getattr(freekassa_service, "default_currency", None) or settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
payment_record_payload = {
@@ -68,7 +74,7 @@ async def pay_fk_callback_handler(
"currency": currency_code,
"status": "pending_freekassa",
"description": payment_description,
"subscription_duration_months": months,
"subscription_duration_months": int(months),
"provider": "freekassa",
}
@@ -135,12 +141,16 @@ async def pay_fk_callback_handler(
)
try:
await callback.message.edit_text(
f"{order_info_text}\n\n" + get_text(key="payment_link_message", months=months),
f"{order_info_text}\n\n" + get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
location,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -149,12 +159,16 @@ async def pay_fk_callback_handler(
logging.warning(f"FreeKassa: failed to display payment link ({e_edit}), sending new message.")
try:
await callback.message.answer(
f"{order_info_text}\n\n" + get_text(key="payment_link_message", months=months),
f"{order_info_text}\n\n" + get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
location,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -47,9 +47,10 @@ async def pay_platega_callback_handler(
try:
_, data_payload = callback.data.split(":", 1)
months_str, price_str = data_payload.split(":")
months = int(months_str)
price_rub = float(price_str)
parts = data_payload.split(":")
months = float(parts[0])
price_rub = float(parts[1])
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except (ValueError, IndexError):
logging.error(f"Invalid pay_platega data in callback: {callback.data}")
try:
@@ -59,7 +60,12 @@ async def pay_platega_callback_handler(
return
user_id = callback.from_user.id
payment_description = get_text("payment_description_subscription", months=months)
human_value = str(int(months)) if float(months).is_integer() else f"{months:g}"
payment_description = (
get_text("payment_description_traffic", traffic_gb=human_value)
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
currency_code = settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
payment_record_payload = {
@@ -68,7 +74,7 @@ async def pay_platega_callback_handler(
"currency": currency_code,
"status": "pending_platega",
"description": payment_description,
"subscription_duration_months": months,
"subscription_duration_months": int(months),
"provider": "platega",
}
@@ -96,6 +102,7 @@ async def pay_platega_callback_handler(
"payment_db_id": payment_record.payment_id,
"user_id": user_id,
"months": months,
"sale_mode": sale_mode,
}
)
@@ -136,12 +143,16 @@ async def pay_platega_callback_handler(
try:
await callback.message.edit_text(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
redirect_url,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -150,12 +161,16 @@ async def pay_platega_callback_handler(
logging.warning(f"Platega: failed to display payment link ({e_edit}), sending new message.")
try:
await callback.message.answer(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
redirect_url,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -46,9 +46,10 @@ async def pay_severpay_callback_handler(
try:
_, data_payload = callback.data.split(":", 1)
months_str, price_str = data_payload.split(":")
months = int(months_str)
price_rub = float(price_str)
parts = data_payload.split(":")
months = float(parts[0])
price_rub = float(parts[1])
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except (ValueError, IndexError):
logging.error(f"Invalid pay_severpay data in callback: {callback.data}")
try:
@@ -58,7 +59,12 @@ async def pay_severpay_callback_handler(
return
user_id = callback.from_user.id
payment_description = get_text("payment_description_subscription", months=months)
human_value = str(int(months)) if float(months).is_integer() else f"{months:g}"
payment_description = (
get_text("payment_description_traffic", traffic_gb=human_value)
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
currency_code = settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
payment_record_payload = {
@@ -67,7 +73,7 @@ async def pay_severpay_callback_handler(
"currency": currency_code,
"status": "pending_severpay",
"description": payment_description,
"subscription_duration_months": months,
"subscription_duration_months": int(months),
"provider": "severpay",
}
@@ -126,12 +132,16 @@ async def pay_severpay_callback_handler(
if payment_link:
try:
await callback.message.edit_text(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
payment_link,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -140,12 +150,16 @@ async def pay_severpay_callback_handler(
logging.warning(f"SeverPay: failed to display payment link ({e_edit}), sending new message.")
try:
await callback.message.answer(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=get_payment_url_keyboard(
payment_link,
current_lang,
i18n,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{human_value}",
back_text_key="back_to_payment_methods_button",
),
disable_web_page_preview=False,
@@ -40,9 +40,10 @@ async def pay_stars_callback_handler(
try:
_, data_payload = callback.data.split(":", 1)
months_str, stars_price_str = data_payload.split(":")
months = int(months_str)
stars_price = int(stars_price_str)
parts = data_payload.split(":")
months = float(parts[0])
stars_price = int(float(parts[1]))
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except (ValueError, IndexError):
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
@@ -51,7 +52,12 @@ async def pay_stars_callback_handler(
return
user_id = callback.from_user.id
payment_description = get_text("payment_description_subscription", months=months)
human_value = str(int(months)) if float(months).is_integer() else f"{months:g}"
payment_description = (
get_text("payment_description_traffic", traffic_gb=human_value)
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
payment_db_id = await stars_service.create_invoice(
session=session,
@@ -59,16 +65,21 @@ async def pay_stars_callback_handler(
months=months,
stars_price=stars_price,
description=payment_description,
sale_mode=sale_mode,
)
if payment_db_id:
try:
await callback.message.edit_text(
get_text("payment_invoice_sent_message", months=months),
get_text(
"payment_invoice_sent_message_traffic" if sale_mode == "traffic" else "payment_invoice_sent_message",
months=int(months),
traffic_gb=human_value,
),
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(
text=get_text("back_to_payment_methods_button"),
callback_data=f"subscribe_period:{months}",
callback_data=f"subscribe_period:{human_value}",
)]
]),
)
@@ -106,9 +117,10 @@ async def handle_successful_stars_payment(
payload = (message.successful_payment.invoice_payload
if message and message.successful_payment else "")
try:
payment_db_id_str, months_str = (payload or "").split(":", 1)
payment_db_id = int(payment_db_id_str)
months = int(months_str)
parts = (payload or "").split(":")
payment_db_id = int(parts[0])
months = float(parts[1]) if len(parts) > 1 else 0
sale_mode = parts[2] if len(parts) > 2 else "subscription"
except Exception:
return
@@ -120,4 +132,5 @@ async def handle_successful_stars_payment(
months=months,
stars_amount=stars_amount,
i18n_data=i18n_data,
sale_mode=sale_mode,
)
@@ -29,8 +29,9 @@ async def select_subscription_period_callback_handler(
pass
return
traffic_mode = bool(getattr(settings, "traffic_sale_mode", False))
try:
months = int(callback.data.split(":")[-1])
months = float(callback.data.split(":")[-1])
except (ValueError, IndexError):
logging.error(f"Invalid subscription period in callback_data: {callback.data}")
try:
@@ -39,10 +40,13 @@ async def select_subscription_period_callback_handler(
pass
return
price_rub = settings.subscription_options.get(months)
price_source = settings.traffic_packages if traffic_mode else settings.subscription_options
stars_price_source = settings.stars_traffic_packages if traffic_mode else settings.stars_subscription_options
price_rub = price_source.get(months)
if price_rub is None:
logging.error(
f"Price not found for {months} months subscription period in settings.subscription_options."
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)
@@ -51,8 +55,8 @@ async def select_subscription_period_callback_handler(
return
currency_symbol_val = settings.DEFAULT_CURRENCY_SYMBOL
text_content = get_text("choose_payment_method")
stars_price = settings.stars_subscription_options.get(months)
text_content = get_text("choose_payment_method_traffic") if traffic_mode else get_text("choose_payment_method")
stars_price = stars_price_source.get(months)
reply_markup = get_payment_method_keyboard(
months,
price_rub,
@@ -61,6 +65,7 @@ async def select_subscription_period_callback_handler(
current_lang,
i18n,
settings,
sale_mode="traffic" if traffic_mode else "subscription",
)
try:
@@ -18,10 +18,17 @@ from db.dal import payment_dal, user_billing_dal
router = Router(name="user_subscription_payments_yookassa_router")
def _parse_months_and_price(payload: str) -> Optional[Tuple[int, float]]:
def _format_value(val: float) -> str:
return str(int(val)) if float(val).is_integer() else f"{val:g}"
def _parse_offer_payload(payload: str) -> Optional[Tuple[float, float, str]]:
try:
months_str, price_str = payload.split(":")
return int(months_str), float(price_str)
parts = payload.split(":")
value = float(parts[0])
price = float(parts[1])
sale_mode = parts[2] if len(parts) > 2 else "subscription"
return value, price, sale_mode
except (ValueError, IndexError):
return None
@@ -64,19 +71,24 @@ async def _initiate_yk_payment(
back_callback: str,
payment_method_id: Optional[str] = None,
selected_method_internal_id: Optional[int] = None,
sale_mode: str = "subscription",
) -> bool:
"""Create payment record and initiate YooKassa payment (new card or saved card)."""
if not callback.message:
return False
payment_description = get_text("payment_description_subscription", months=months)
payment_description = (
get_text("payment_description_traffic", traffic_gb=_format_value(months))
if sale_mode == "traffic"
else get_text("payment_description_subscription", months=int(months))
)
payment_record_data = {
"user_id": user_id,
"amount": price_rub,
"currency": currency_code_for_yk,
"status": "pending_yookassa",
"description": payment_description,
"subscription_duration_months": months,
"subscription_duration_months": int(months),
}
db_payment_record = None
@@ -109,7 +121,10 @@ async def _initiate_yk_payment(
"user_id": str(user_id),
"subscription_months": str(months),
"payment_db_id": str(db_payment_record.payment_id),
"sale_mode": sale_mode,
}
if sale_mode == "traffic":
yookassa_metadata["traffic_gb"] = str(months)
if payment_method_id:
yookassa_metadata["used_saved_payment_method_id"] = payment_method_id
@@ -198,7 +213,11 @@ async def _initiate_yk_payment(
try:
await callback.message.edit_text(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=_format_value(months),
),
reply_markup=get_payment_url_keyboard(
payment_response_yk["confirmation_url"],
current_lang,
@@ -214,7 +233,11 @@ async def _initiate_yk_payment(
)
try:
await callback.message.answer(
get_text(key="payment_link_message", months=months),
get_text(
key="payment_link_message_traffic" if sale_mode == "traffic" else "payment_link_message",
months=int(months),
traffic_gb=_format_value(months),
),
reply_markup=get_payment_url_keyboard(
payment_response_yk["confirmation_url"],
current_lang,
@@ -328,7 +351,7 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
pass
return
parsed = _parse_months_and_price(data_payload)
parsed = _parse_offer_payload(data_payload)
if not parsed:
logging.error(f"Invalid pay_yk payload structure: {callback.data}")
try:
@@ -337,10 +360,10 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
pass
return
months, price_rub = parsed
months, price_rub, sale_mode = parsed
user_id = callback.from_user.id
currency_code_for_yk = "RUB"
autopay_enabled = bool(settings.yookassa_autopayments_active)
autopay_enabled = bool(settings.yookassa_autopayments_active and sale_mode != "traffic" and not settings.traffic_sale_mode)
autopay_require_binding = bool(
getattr(settings, 'YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING', True)
)
@@ -364,6 +387,7 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
current_lang,
i18n,
has_saved_cards=True,
sale_mode=sale_mode,
),
)
except Exception as e_edit:
@@ -377,6 +401,7 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
current_lang,
i18n,
has_saved_cards=True,
sale_mode=sale_mode,
),
)
except Exception:
@@ -400,7 +425,8 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
price_rub=price_rub,
currency_code_for_yk=currency_code_for_yk,
save_payment_method=autopay_enabled and autopay_require_binding,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{_format_value(months)}",
sale_mode=sale_mode,
)
try:
await callback.answer()
@@ -443,7 +469,7 @@ async def pay_yk_new_card_handler(callback: types.CallbackQuery, settings: Setti
pass
return
parsed = _parse_months_and_price(data_payload)
parsed = _parse_offer_payload(data_payload)
if not parsed:
logging.error(f"Invalid pay_yk_new payload structure: {callback.data}")
try:
@@ -452,10 +478,10 @@ async def pay_yk_new_card_handler(callback: types.CallbackQuery, settings: Setti
pass
return
months, price_rub = parsed
months, price_rub, sale_mode = parsed
user_id = callback.from_user.id
currency_code_for_yk = "RUB"
autopay_enabled = bool(settings.yookassa_autopayments_active)
autopay_enabled = bool(settings.yookassa_autopayments_active and sale_mode != "traffic" and not settings.traffic_sale_mode)
autopay_require_binding = bool(
getattr(settings, 'YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING', True)
)
@@ -473,7 +499,8 @@ async def pay_yk_new_card_handler(callback: types.CallbackQuery, settings: Setti
price_rub=price_rub,
currency_code_for_yk=currency_code_for_yk,
save_payment_method=autopay_enabled and autopay_require_binding,
back_callback=f"subscribe_period:{months}",
back_callback=f"subscribe_period:{_format_value(months)}",
sale_mode=sale_mode,
)
try:
await callback.answer()
@@ -494,14 +521,6 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
pass
return
autopay_enabled = bool(settings.yookassa_autopayments_active)
if not autopay_enabled:
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
try:
_, data_payload = callback.data.split(":", 1)
except ValueError:
@@ -522,9 +541,10 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
return
try:
months = int(parts[0])
months = float(parts[0])
price_rub = float(parts[1])
page = int(parts[2]) if len(parts) > 2 else 0
sale_mode = parts[3] if len(parts) > 3 else "subscription"
except (ValueError, IndexError):
logging.error(f"pay_yk_saved_list payload parsing error: {callback.data}")
try:
@@ -533,6 +553,14 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
pass
return
autopay_enabled = bool(settings.yookassa_autopayments_active and sale_mode != "traffic" and not settings.traffic_sale_mode)
if not autopay_enabled:
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
user_id = callback.from_user.id
try:
saved_methods = await user_billing_dal.list_user_payment_methods(
@@ -552,6 +580,7 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
current_lang,
i18n,
has_saved_cards=False,
sale_mode=sale_mode,
),
)
except Exception as e_edit:
@@ -565,6 +594,7 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
current_lang,
i18n,
has_saved_cards=False,
sale_mode=sale_mode,
),
)
except Exception:
@@ -596,6 +626,7 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
current_lang,
i18n,
page=page,
sale_mode=sale_mode,
),
)
except Exception as e_edit:
@@ -610,6 +641,7 @@ async def pay_yk_saved_list_handler(callback: types.CallbackQuery, settings: Set
current_lang,
i18n,
page=page,
sale_mode=sale_mode,
),
)
except Exception:
@@ -633,14 +665,6 @@ async def pay_yk_use_saved_handler(callback: types.CallbackQuery, settings: Sett
pass
return
autopay_enabled = bool(settings.yookassa_autopayments_active)
if not autopay_enabled:
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
if not yookassa_service or not yookassa_service.configured:
logging.error("YooKassa service unavailable for pay_yk_use_saved.")
try:
@@ -673,8 +697,9 @@ async def pay_yk_use_saved_handler(callback: types.CallbackQuery, settings: Sett
return
try:
months = int(parts[0])
months = float(parts[0])
price_rub = float(parts[1])
sale_mode = parts[3] if len(parts) > 3 else "subscription"
except (ValueError, IndexError):
logging.error(f"pay_yk_use_saved months/price parsing error: {callback.data}")
try:
@@ -683,6 +708,14 @@ async def pay_yk_use_saved_handler(callback: types.CallbackQuery, settings: Sett
pass
return
autopay_enabled = bool(settings.yookassa_autopayments_active and sale_mode != "traffic" and not settings.traffic_sale_mode)
if not autopay_enabled:
try:
await callback.answer(get_text("error_try_again"), show_alert=True)
except Exception:
pass
return
method_identifier = parts[2]
user_id = callback.from_user.id
@@ -727,9 +760,10 @@ async def pay_yk_use_saved_handler(callback: types.CallbackQuery, settings: Sett
price_rub=price_rub,
currency_code_for_yk=currency_code_for_yk,
save_payment_method=False,
back_callback=f"pay_yk_saved_list:{months}:{price_rub}",
back_callback=f"pay_yk_saved_list:{_format_value(months)}:{price_rub}:{sale_mode}",
payment_method_id=selected_method.provider_payment_method_id,
selected_method_internal_id=selected_method.method_id,
sale_mode=sale_mode,
)
try:
await callback.answer()