Enhance payment method display logic and localization updates

- Improved the logic for displaying payment method details, including card type and last four digits, to provide a clearer user experience.
- Updated localization strings to reflect changes in payment method terminology, ensuring consistency across user-facing messages.
- Refactored payment method handlers to utilize the new display logic, enhancing the overall management of payment methods.
This commit is contained in:
machka-pasla
2025-09-04 18:14:32 +03:00
parent cf7f0eae51
commit a5aecb0f86
4 changed files with 74 additions and 22 deletions
+29 -6
View File
@@ -140,13 +140,26 @@ async def process_successful_payment(session: AsyncSession, bot: Bot,
payment_method = payment_info_from_webhook.get("payment_method")
if isinstance(payment_method, dict) and payment_method.get("saved", False):
pm_id = payment_method.get("id")
pm_type = payment_method.get("type")
title = payment_method.get("title")
card = payment_method.get("card") or {}
display_network = None
display_last4 = None
# Build generic display for various instrument types
if (pm_type or "").lower() in {"bank_card", "bank-card", "card"}:
display_network = card.get("card_type") or title or "Card"
display_last4 = card.get("last4")
else:
# Wallets, SBP, etc. — use provided title/type; no last4
display_network = title or (pm_type.upper() if pm_type else "Payment method")
display_last4 = None
await user_billing_dal.upsert_yk_payment_method(
session,
user_id=user_id,
payment_method_id=pm_id,
card_last4=card.get("last4"),
card_network=card.get("card_type"),
card_last4=display_last4,
card_network=display_network,
)
except Exception:
logging.exception("Failed to persist YooKassa payment method from webhook")
@@ -463,13 +476,23 @@ async def yookassa_webhook_route(request: web.Request):
user_id = int(user_id_str)
payment_method = payment_dict_for_processing.get("payment_method")
if isinstance(payment_method, dict) and payment_method.get("id"):
pm_type = payment_method.get("type")
title = payment_method.get("title")
card = payment_method.get("card") or {}
display_network = None
display_last4 = None
if (pm_type or "").lower() in {"bank_card", "bank-card", "card"}:
display_network = card.get("card_type") or title or "Card"
display_last4 = card.get("last4")
else:
display_network = title or (pm_type.upper() if pm_type else "Payment method")
display_last4 = None
await user_billing_dal.upsert_yk_payment_method(
session,
user_id=user_id,
payment_method_id=payment_method.get("id"),
card_last4=card.get("last4"),
card_network=card.get("card_type"),
card_last4=display_last4,
card_network=display_network,
)
await session.commit()
# Save multi-card entry and mark default if first
@@ -480,8 +503,8 @@ async def yookassa_webhook_route(request: web.Request):
user_id=user_id,
provider_payment_method_id=payment_method.get("id"),
provider="yookassa",
card_last4=card.get("last4"),
card_network=card.get("card_type"),
card_last4=display_last4,
card_network=display_network,
set_default=True,
)
await session.commit()
+35 -8
View File
@@ -313,12 +313,21 @@ async def pay_yk_callback_handler(
pm = payment_response_yk.get("payment_method")
try:
if pm and pm.get('id'):
pm_type = pm.get('type')
title = pm.get('title')
card = pm.get('card') or {}
if isinstance(card, dict) and (pm_type or '').lower() in {"bank_card", "bank-card", "card"}:
display_network = card.get('card_type') or title or 'Card'
display_last4 = card.get('last4')
else:
display_network = title or (pm_type.upper() if pm_type else 'Payment method')
display_last4 = None
await user_billing_dal.upsert_yk_payment_method(
session,
user_id=user_id,
payment_method_id=pm['id'],
card_last4=pm.get('last4'),
card_network=pm.get('card', {}).get('card_type') if isinstance(pm.get('card'), dict) else None,
card_last4=display_last4,
card_network=display_network,
)
await session.commit()
except Exception:
@@ -604,7 +613,10 @@ async def payment_methods_manage(callback: types.CallbackQuery, settings: Settin
methods = await list_user_payment_methods(session, callback.from_user.id)
cards: List[tuple] = []
for m in methods:
title = get_text("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4 or "????")
if m.card_last4:
title = get_text("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4)
else:
title = get_text("payment_method_generic_title", network=m.card_network or "Payment method")
cards.append((str(m.method_id), title if not m.is_default else f"{title}"))
text = get_text("payment_methods_title")
@@ -683,7 +695,10 @@ async def payment_method_delete(callback: types.CallbackQuery, settings: Setting
text = _("payment_methods_title")
cards = []
for m in methods:
title = _("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4 or "????")
if m.card_last4:
title = _("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4)
else:
title = _("payment_method_generic_title", network=m.card_network or "Payment method")
cards.append((str(m.method_id), title if not m.is_default else f"{title}"))
if not cards:
text += "\n\n" + _("payment_method_none")
@@ -713,7 +728,10 @@ async def payment_method_delete(callback: types.CallbackQuery, settings: Setting
methods = await list_user_payment_methods(session, callback.from_user.id)
cards = []
for m in methods:
title = _("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4 or "????")
if m.card_last4:
title = _("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4)
else:
title = _("payment_method_generic_title", network=m.card_network or "Payment method")
cards.append((str(m.method_id), title if not m.is_default else f"{title}"))
text = _("payment_methods_title")
if not cards:
@@ -743,7 +761,10 @@ async def payment_method_view(callback: types.CallbackQuery, settings: Settings,
pm_id = parts[2] if len(parts) >= 3 else str(methods[0].method_id)
# Map:
sel = next((m for m in methods if str(m.method_id) == pm_id or m.provider_payment_method_id == pm_id), methods[0])
title = _("payment_method_card_title", network=sel.card_network or "Card", last4=sel.card_last4 or "????")
if sel.card_last4:
title = _("payment_method_card_title", network=sel.card_network or "Card", last4=sel.card_last4)
else:
title = _("payment_method_generic_title", network=sel.card_network or "Payment method")
added_at = sel.created_at.strftime('%Y-%m-%d') if getattr(sel, 'created_at', None) else ""
# Last tx
last_tx = ""
@@ -791,7 +812,10 @@ async def payment_method_view(callback: types.CallbackQuery, settings: Settings,
last_tx = last_payment.created_at.strftime('%Y-%m-%d')
except Exception:
pass
title = _("payment_method_card_title", network=billing.card_network or "Card", last4=billing.card_last4 or "????")
if billing.card_last4:
title = _("payment_method_card_title", network=billing.card_network or "Card", last4=billing.card_last4)
else:
title = _("payment_method_generic_title", network=billing.card_network or "Payment method")
details = f"{title}\n{_('payment_method_added_at', date=added_at)}\n{_('payment_method_last_tx', date=last_tx)}"
await callback.message.edit_text(details, reply_markup=get_payment_method_details_keyboard(billing.yookassa_payment_method_id, current_lang, i18n))
try:
@@ -847,7 +871,10 @@ async def payment_methods_list(callback: types.CallbackQuery, settings: Settings
cards: List[tuple] = []
methods = await list_user_payment_methods(session, callback.from_user.id)
for m in methods:
title = get_text("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4 or "????")
if m.card_last4:
title = get_text("payment_method_card_title", network=m.card_network or "Card", last4=m.card_last4)
else:
title = get_text("payment_method_generic_title", network=m.card_network or "Payment method")
cards.append((str(m.method_id), title if not m.is_default else f"{title}"))
# Parse page