feat: add SberPay as KassaAI sub-method (payment_system_id=43)

Adds SberPay alongside existing SBP (44) and Card (36) sub-methods.

Changes across all 8 required files:
- config.py: KASSA_AI_SBERPAY_ENABLED, display name, helper methods
- kassa_ai_service.py: payment_system_id=43 in KASSA_AI_SUB_METHODS
- kassa_ai.py handler: method config + start_kassa_ai_sberpay_topup
- main.py: route tuple, import, handler registration
- payment_service.py: guest purchase flow method check
- cabinet/balance.py: KASSA_AI_OPTION_MAP sberpay=43
- payment_method_config_service.py: sub_option for admin panel
- inline.py: keyboard button + fallback condition guard

Env vars: KASSA_AI_SBERPAY_ENABLED, KASSA_AI_SBERPAY_DISPLAY_NAME
This commit is contained in:
Fringg
2026-04-02 06:47:40 +03:00
parent c4c5d330be
commit 9d63635502
8 changed files with 48 additions and 3 deletions
+1 -1
View File
@@ -699,7 +699,7 @@ async def create_topup(
)
# Use payment_option to select sbp or card
KASSA_AI_OPTION_MAP = {'sbp': 44, 'card': 36}
KASSA_AI_OPTION_MAP = {'sbp': 44, 'card': 36, 'sberpay': 43}
option = (request.payment_option or '').strip().lower()
ps_id = KASSA_AI_OPTION_MAP.get(option) # None = use env default
+12
View File
@@ -558,6 +558,8 @@ class Settings(BaseSettings):
KASSA_AI_SBP_DISPLAY_NAME: str = 'СБП (KassaAI)'
KASSA_AI_CARD_ENABLED: bool = False # Карты РФ — payment_system_id=36
KASSA_AI_CARD_DISPLAY_NAME: str = 'Карта (KassaAI)'
KASSA_AI_SBERPAY_ENABLED: bool = False # SberPay — payment_system_id=43
KASSA_AI_SBERPAY_DISPLAY_NAME: str = 'SberPay (KassaAI)'
# RioPay (api.riopay.online) v2.0.1
RIOPAY_ENABLED: bool = False
@@ -1980,6 +1982,16 @@ class Settings(BaseSettings):
def get_kassa_ai_card_display_name_html(self) -> str:
return html.escape(self.get_kassa_ai_card_display_name())
def is_kassa_ai_sberpay_enabled(self) -> bool:
return self.KASSA_AI_SBERPAY_ENABLED and self.is_kassa_ai_enabled()
def get_kassa_ai_sberpay_display_name(self) -> str:
name = (self.KASSA_AI_SBERPAY_DISPLAY_NAME or '').strip()
return name if name else 'SberPay (KassaAI)'
def get_kassa_ai_sberpay_display_name_html(self) -> str:
return html.escape(self.get_kassa_ai_sberpay_display_name())
def is_payment_verification_auto_check_enabled(self) -> bool:
return self.PAYMENT_VERIFICATION_AUTO_CHECK_ENABLED
+16
View File
@@ -39,6 +39,11 @@ _KASSA_AI_METHOD_CONFIG = {
'display_name': settings.get_kassa_ai_card_display_name,
'unavailable_text': 'KassaAI Карта временно недоступна',
},
'kassa_ai_sberpay': {
'is_enabled': settings.is_kassa_ai_sberpay_enabled,
'display_name': settings.get_kassa_ai_sberpay_display_name,
'unavailable_text': 'KassaAI SberPay временно недоступен',
},
}
@@ -350,3 +355,14 @@ async def start_kassa_ai_card_topup(
):
"""Start KassaAI Card top-up process."""
await _start_kassa_ai_sub_topup(callback, db_user, db, state, 'kassa_ai_card')
@error_handler
async def start_kassa_ai_sberpay_topup(
callback: types.CallbackQuery,
db_user: User,
db: AsyncSession,
state: FSMContext,
):
"""Start KassaAI SberPay top-up process."""
await _start_kassa_ai_sub_topup(callback, db_user, db, state, 'kassa_ai_sberpay')
+3 -1
View File
@@ -133,7 +133,7 @@ async def route_payment_by_method(
)
return True
if payment_method in ('kassa_ai', 'kassa_ai_sbp', 'kassa_ai_card'):
if payment_method in ('kassa_ai', 'kassa_ai_sbp', 'kassa_ai_card', 'kassa_ai_sberpay'):
from .kassa_ai import process_kassa_ai_payment_amount
async with AsyncSessionLocal() as db:
@@ -701,6 +701,7 @@ def register_balance_handlers(dp: Dispatcher):
from .kassa_ai import (
start_kassa_ai_card_topup,
start_kassa_ai_sberpay_topup,
start_kassa_ai_sbp_topup,
start_kassa_ai_topup,
)
@@ -708,6 +709,7 @@ def register_balance_handlers(dp: Dispatcher):
dp.callback_query.register(start_kassa_ai_topup, F.data == 'topup_kassa_ai')
dp.callback_query.register(start_kassa_ai_sbp_topup, F.data == 'topup_kassa_ai_sbp')
dp.callback_query.register(start_kassa_ai_card_topup, F.data == 'topup_kassa_ai_card')
dp.callback_query.register(start_kassa_ai_sberpay_topup, F.data == 'topup_kassa_ai_sberpay')
from .riopay import start_riopay_topup
+13
View File
@@ -1755,10 +1755,23 @@ def get_payment_methods_keyboard(amount_kopeks: int, language: str = DEFAULT_LAN
)
has_direct_payment_methods = True
if settings.is_kassa_ai_sberpay_enabled():
sberpay_name = settings.get_kassa_ai_sberpay_display_name()
keyboard.append(
[
InlineKeyboardButton(
text=texts.t('PAYMENT_KASSA_AI_SBERPAY', f'💳 {sberpay_name}'),
callback_data=_build_callback('kassa_ai_sberpay'),
)
]
)
has_direct_payment_methods = True
if (
settings.is_kassa_ai_enabled()
and not settings.is_kassa_ai_sbp_enabled()
and not settings.is_kassa_ai_card_enabled()
and not settings.is_kassa_ai_sberpay_enabled()
):
kassa_ai_name = settings.get_kassa_ai_display_name()
keyboard.append(
+1
View File
@@ -18,6 +18,7 @@ logger = structlog.get_logger(__name__)
KASSA_AI_SUB_METHODS = {
'kassa_ai_sbp': {'payment_system_id': 44},
'kassa_ai_card': {'payment_system_id': 36},
'kassa_ai_sberpay': {'payment_system_id': 43},
}
# Кэш для публичного IP
@@ -129,6 +129,7 @@ def _get_method_defaults() -> dict:
'available_sub_options': [
{'id': 'sbp', 'name': 'СБП'},
{'id': 'card', 'name': 'Карта'},
{'id': 'sberpay', 'name': 'SberPay'},
],
},
'riopay': {
+1 -1
View File
@@ -703,7 +703,7 @@ class PaymentService(
return None
# --- KassaAI ----------------------------------------------------------
if payment_method in ('kassa_ai', 'kassa_ai_sbp', 'kassa_ai_card'):
if payment_method in ('kassa_ai', 'kassa_ai_sbp', 'kassa_ai_card', 'kassa_ai_sberpay'):
if not settings.is_kassa_ai_enabled():
logger.warning('KassaAI is not enabled, cannot create guest payment')
return None