refactor: keep provider presentation self-contained in spec

This commit is contained in:
3252a8
2026-05-18 15:35:55 +03:00
parent c9c12b9ed6
commit 07b35036e7
14 changed files with 5 additions and 47 deletions
@@ -462,7 +462,7 @@ def get_payment_method_keyboard(
for method in settings.payment_methods_order: for method in settings.payment_methods_order:
spec = get_provider_spec(method) spec = get_provider_spec(method)
if not spec or not spec.button_text_key or not spec.is_enabled(settings): if not spec or not spec.callback_prefix or not spec.is_enabled(settings):
continue continue
callback_data = spec.callback_data( callback_data = spec.callback_data(
value=value_str, value=value_str,
@@ -473,7 +473,7 @@ def get_payment_method_keyboard(
if not callback_data: if not callback_data:
continue continue
builder.button( builder.button(
text=provider_telegram_button_text(spec, settings, _, language=lang), text=provider_telegram_button_text(spec, settings, language=lang),
callback_data=callback_data, callback_data=callback_data,
) )
builder.button( builder.button(
-1
View File
@@ -44,7 +44,6 @@ class PaymentProviderSpec:
pending_status: str pending_status: str
enabled: EnabledPredicate enabled: EnabledPredicate
service_key: Optional[str] = None service_key: Optional[str] = None
button_text_key: Optional[str] = None
callback_prefix: Optional[str] = None callback_prefix: Optional[str] = None
webapp_label: Optional[str] = None webapp_label: Optional[str] = None
webapp_labels: Optional[Mapping[str, str]] = None webapp_labels: Optional[Mapping[str, str]] = None
@@ -365,7 +365,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_cryptopay", pending_status="pending_cryptopay",
enabled=lambda settings: settings.CRYPTOPAY_ENABLED, enabled=lambda settings: settings.CRYPTOPAY_ENABLED,
service_key="cryptopay_service", service_key="cryptopay_service",
button_text_key="pay_with_cryptopay_button",
callback_prefix="pay_crypto", callback_prefix="pay_crypto",
router=router, router=router,
create_service=create_service, create_service=create_service,
@@ -491,7 +491,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_freekassa", pending_status="pending_freekassa",
enabled=lambda settings: settings.FREEKASSA_ENABLED, enabled=lambda settings: settings.FREEKASSA_ENABLED,
service_key="freekassa_service", service_key="freekassa_service",
button_text_key="pay_with_sbp_button",
callback_prefix="pay_fk", callback_prefix="pay_fk",
router=router, router=router,
create_service=create_service, create_service=create_service,
-1
View File
@@ -471,7 +471,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_heleket", pending_status="pending_heleket",
enabled=lambda settings: settings.HELEKET_ENABLED, enabled=lambda settings: settings.HELEKET_ENABLED,
service_key="heleket_service", service_key="heleket_service",
button_text_key="pay_with_heleket_button",
callback_prefix="pay_heleket", callback_prefix="pay_heleket",
router=router, router=router,
create_service=create_service, create_service=create_service,
-2
View File
@@ -499,7 +499,6 @@ SBP_SPEC = PaymentProviderSpec(
pending_status="pending_platega", pending_status="pending_platega",
enabled=lambda settings: settings.PLATEGA_ENABLED and settings.PLATEGA_SBP_ENABLED, enabled=lambda settings: settings.PLATEGA_ENABLED and settings.PLATEGA_SBP_ENABLED,
service_key="platega_service", service_key="platega_service",
button_text_key="pay_with_platega_sbp_button",
callback_prefix="pay_platega_sbp", callback_prefix="pay_platega_sbp",
aliases=("platega",), aliases=("platega",),
router=router, router=router,
@@ -521,7 +520,6 @@ CRYPTO_SPEC = PaymentProviderSpec(
pending_status="pending_platega", pending_status="pending_platega",
enabled=lambda settings: settings.PLATEGA_ENABLED and settings.PLATEGA_CRYPTO_ENABLED, enabled=lambda settings: settings.PLATEGA_ENABLED and settings.PLATEGA_CRYPTO_ENABLED,
service_key="platega_service", service_key="platega_service",
button_text_key="pay_with_platega_crypto_button",
callback_prefix="pay_platega_crypto", callback_prefix="pay_platega_crypto",
create_webapp_payment=create_crypto_webapp_payment, create_webapp_payment=create_crypto_webapp_payment,
) )
+1 -11
View File
@@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional from typing import Any, Dict, Iterable, List, Mapping, Optional
from . import cryptopay, freekassa, heleket, platega, severpay, stars, wata, yookassa from . import cryptopay, freekassa, heleket, platega, severpay, stars, wata, yookassa
from .base import PaymentProviderPresentation, PaymentProviderSpec, ServiceFactoryContext from .base import PaymentProviderPresentation, PaymentProviderSpec, ServiceFactoryContext
@@ -83,7 +83,6 @@ def resolve_provider_presentation(
settings: Any = None, settings: Any = None,
*, *,
language: Optional[str] = None, language: Optional[str] = None,
translate: Optional[Callable[[str], str]] = None,
) -> PaymentProviderPresentation: ) -> PaymentProviderPresentation:
lang = _normalize_language(language, settings) lang = _normalize_language(language, settings)
webapp_label = ( webapp_label = (
@@ -111,14 +110,6 @@ def resolve_provider_presentation(
) )
telegram_emoji = telegram_emoji_override or spec.default_telegram_emoji telegram_emoji = telegram_emoji_override or spec.default_telegram_emoji
if (
not telegram_label_override
and not spec.telegram_labels
and translate
and spec.button_text_key
):
telegram_label = translate(spec.button_text_key)
return PaymentProviderPresentation( return PaymentProviderPresentation(
webapp_label=webapp_label, webapp_label=webapp_label,
webapp_icon=webapp_icon, webapp_icon=webapp_icon,
@@ -131,7 +122,6 @@ def resolve_provider_presentation(
def provider_telegram_button_text( def provider_telegram_button_text(
spec: PaymentProviderSpec, spec: PaymentProviderSpec,
settings: Any, settings: Any,
translate: Callable[[str], str],
*, *,
language: Optional[str] = None, language: Optional[str] = None,
) -> str: ) -> str:
@@ -434,7 +434,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_severpay", pending_status="pending_severpay",
enabled=lambda settings: settings.SEVERPAY_ENABLED, enabled=lambda settings: settings.SEVERPAY_ENABLED,
service_key="severpay_service", service_key="severpay_service",
button_text_key="pay_with_severpay_button",
callback_prefix="pay_severpay", callback_prefix="pay_severpay",
router=router, router=router,
create_service=create_service, create_service=create_service,
-1
View File
@@ -360,7 +360,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_stars", pending_status="pending_stars",
enabled=lambda settings: settings.STARS_ENABLED, enabled=lambda settings: settings.STARS_ENABLED,
service_key="stars_service", service_key="stars_service",
button_text_key="pay_with_stars_button",
callback_prefix="pay_stars", callback_prefix="pay_stars",
router=router, router=router,
create_service=create_service, create_service=create_service,
-1
View File
@@ -440,7 +440,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_wata", pending_status="pending_wata",
enabled=lambda settings: settings.WATA_ENABLED, enabled=lambda settings: settings.WATA_ENABLED,
service_key="wata_service", service_key="wata_service",
button_text_key="pay_with_wata_button",
callback_prefix="pay_wata", callback_prefix="pay_wata",
router=router, router=router,
create_service=create_service, create_service=create_service,
@@ -2514,7 +2514,6 @@ SPEC = PaymentProviderSpec(
pending_status="pending_yookassa", pending_status="pending_yookassa",
enabled=lambda settings: settings.YOOKASSA_ENABLED, enabled=lambda settings: settings.YOOKASSA_ENABLED,
service_key="yookassa_service", service_key="yookassa_service",
button_text_key="pay_with_yookassa_button",
callback_prefix="pay_yk", callback_prefix="pay_yk",
router=router, router=router,
create_service=create_service, create_service=create_service,
-10
View File
@@ -41,7 +41,6 @@
"choose_payment_method": "Choose payment method:", "choose_payment_method": "Choose payment method:",
"choose_payment_method_traffic": "Choose how to pay for the traffic package:", "choose_payment_method_traffic": "Choose how to pay for the traffic package:",
"pay_button": "💳 Pay", "pay_button": "💳 Pay",
"pay_with_yookassa_button": "💳 YooKassa",
"yookassa_autopay_flow_prompt": "Auto-renew is enabled. Choose how you'd like to pay:", "yookassa_autopay_flow_prompt": "Auto-renew is enabled. Choose how you'd like to pay:",
"yookassa_autopay_pay_saved_card_button": "💳 Pay with saved card", "yookassa_autopay_pay_saved_card_button": "💳 Pay with saved card",
"yookassa_autopay_pay_new_card_button": " Pay with new card", "yookassa_autopay_pay_new_card_button": " Pay with new card",
@@ -49,16 +48,7 @@
"yookassa_autopay_no_saved_cards": "No saved cards found. Pay with a new card or link one in Payment Methods.", "yookassa_autopay_no_saved_cards": "No saved cards found. Pay with a new card or link one in Payment Methods.",
"back_to_autopay_method_choice_button": "⬅️ Back", "back_to_autopay_method_choice_button": "⬅️ Back",
"yookassa_autopay_charge_initiated": "Charge request sent to the selected card. We'll notify you once the payment completes.", "yookassa_autopay_charge_initiated": "Charge request sent to the selected card. We'll notify you once the payment completes.",
"pay_with_sbp_button": "📱 SBP",
"pay_with_platega_button": "💳 Platega (SBP/Cards)",
"pay_with_platega_sbp_button": "🏦 Pay via SBP",
"pay_with_platega_crypto_button": "🪙 Pay with crypto",
"pay_with_severpay_button": "💳 SeverPay",
"pay_with_wata_button": "Wata",
"pay_with_heleket_button": "🪙 Heleket",
"back_to_payment_methods_button": "⬅️ Back", "back_to_payment_methods_button": "⬅️ Back",
"pay_with_cryptopay_button": "💎 CryptoBot",
"pay_with_stars_button": "🌟 Telegram Stars",
"connect_button": "🔗 Connect", "connect_button": "🔗 Connect",
"cancel_button": "❌ Cancel", "cancel_button": "❌ Cancel",
"devices_button": "📱 My Devices ({current_devices}/{max_devices})", "devices_button": "📱 My Devices ({current_devices}/{max_devices})",
-10
View File
@@ -41,7 +41,6 @@
"choose_payment_method": "Выберите способ оплаты:", "choose_payment_method": "Выберите способ оплаты:",
"choose_payment_method_traffic": "Выберите способ оплаты пакета трафика:", "choose_payment_method_traffic": "Выберите способ оплаты пакета трафика:",
"pay_button": "💳 Оплатить", "pay_button": "💳 Оплатить",
"pay_with_yookassa_button": "💳 ЮKassa",
"yookassa_autopay_flow_prompt": "Автопродление включено. Выберите, как оплатить подписку:", "yookassa_autopay_flow_prompt": "Автопродление включено. Выберите, как оплатить подписку:",
"yookassa_autopay_pay_saved_card_button": "💳 Оплата привязанной картой", "yookassa_autopay_pay_saved_card_button": "💳 Оплата привязанной картой",
"yookassa_autopay_pay_new_card_button": "➕ Оплата новой картой", "yookassa_autopay_pay_new_card_button": "➕ Оплата новой картой",
@@ -49,16 +48,7 @@
"yookassa_autopay_no_saved_cards": "Сохранённых карт нет. Оплатите новой картой или привяжите карту в разделе «Способы оплаты».", "yookassa_autopay_no_saved_cards": "Сохранённых карт нет. Оплатите новой картой или привяжите карту в разделе «Способы оплаты».",
"back_to_autopay_method_choice_button": "⬅️ Назад", "back_to_autopay_method_choice_button": "⬅️ Назад",
"yookassa_autopay_charge_initiated": "Запрос на списание с выбранной карты отправлен. Сообщим, как только платёж завершится.", "yookassa_autopay_charge_initiated": "Запрос на списание с выбранной карты отправлен. Сообщим, как только платёж завершится.",
"pay_with_sbp_button": "📱 СБП",
"pay_with_platega_button": "💳 Platega (СБП/карты)",
"pay_with_platega_sbp_button": "🏦 Оплата через СБП",
"pay_with_platega_crypto_button": "🪙 Оплата криптой",
"pay_with_severpay_button": "💳 SeverPay",
"pay_with_wata_button": "Wata",
"pay_with_heleket_button": "🪙 Heleket",
"back_to_payment_methods_button": "⬅️ Назад", "back_to_payment_methods_button": "⬅️ Назад",
"pay_with_cryptopay_button": "💎 CryptoBot",
"pay_with_stars_button": "🌟 Звезды Telegram",
"connect_button": "🔗 Подключиться", "connect_button": "🔗 Подключиться",
"devices_button": "📱 Мои устройства ({current_devices}/{max_devices})", "devices_button": "📱 Мои устройства ({current_devices}/{max_devices})",
"my_devices_details": "📱 <b>Список ваших устройств ({current_devices}/{max_devices})</b>\n\n{devices}\n\nВы можете отключить устройство, выбрав его в списке ниже.\n<blockquote><i>Примечание: Если вы отключили устройство, оно будет автоматически подключено заново при следующем использовании. Перед удалением убедитесь, что вы удалили подписку из приложения.</i></blockquote>", "my_devices_details": "📱 <b>Список ваших устройств ({current_devices}/{max_devices})</b>\n\n{devices}\n\nВы можете отключить устройство, выбрав его в списке ниже.\n<blockquote><i>Примечание: Если вы отключили устройство, оно будет автоматически подключено заново при следующем использовании. Перед удалением убедитесь, что вы удалили подписку из приложения.</i></blockquote>",
+2 -4
View File
@@ -75,7 +75,6 @@ def test_wata_is_registered_as_single_provider_module():
assert spec is not None assert spec is not None
assert spec.service_key == "wata_service" assert spec.service_key == "wata_service"
assert spec.pending_status == "pending_wata" assert spec.pending_status == "pending_wata"
assert spec.button_text_key == "pay_with_wata_button"
assert spec.callback_prefix == "pay_wata" assert spec.callback_prefix == "pay_wata"
assert spec.router is not None assert spec.router is not None
assert spec.create_service is not None assert spec.create_service is not None
@@ -175,15 +174,14 @@ def test_provider_telegram_button_text_uses_provider_defaults_until_customized()
spec = get_provider_spec("wata") spec = get_provider_spec("wata")
assert spec is not None assert spec is not None
translate = lambda key: f"i18n:{key}"
assert ( assert (
provider_telegram_button_text(spec, SimpleNamespace(), translate, language="en") provider_telegram_button_text(spec, SimpleNamespace(), language="en")
== f"{spec.default_telegram_emoji} Wata" == f"{spec.default_telegram_emoji} Wata"
) )
settings = SimpleNamespace(PAYMENT_WATA_TELEGRAM_LABEL_EN="Pay Wata") settings = SimpleNamespace(PAYMENT_WATA_TELEGRAM_LABEL_EN="Pay Wata")
assert ( assert (
provider_telegram_button_text(spec, settings, translate, language="en") provider_telegram_button_text(spec, settings, language="en")
== f"{spec.default_telegram_emoji} Pay Wata" == f"{spec.default_telegram_emoji} Pay Wata"
) )