fix: freekassa OP-SP-7 error and missing telegram notification

- Replace test@example.com fallback with pool of 20 random emails
  to avoid OP-SP-7 duplicate email errors from payment provider
- Fix metadata_json parsing: handle both dict (SQLAlchemy JSON column)
  and string cases to prevent json.loads crash on dict input
- Add TypeError to exception handler for robustness
This commit is contained in:
Fringg
2026-02-27 01:00:50 +03:00
parent 59f0e42be7
commit 200f91ef17
2 changed files with 42 additions and 4 deletions
+34 -2
View File
@@ -16,6 +16,38 @@ from app.config import settings
logger = structlog.get_logger(__name__)
# Email-заглушки для Freekassa API (test@example.com вызывает ошибку OP-SP-7)
_FALLBACK_EMAILS = [
'ivan.petrov@mail.ru',
'user.alex@yandex.ru',
'sergei.k@gmail.com',
'dmitry.v@inbox.ru',
'anna.s@bk.ru',
'maxim.ivanov@list.ru',
'elena.p@rambler.ru',
'artem.n@mail.ru',
'nikita.z@yandex.ru',
'olga.m@gmail.com',
'roman.t@inbox.ru',
'svetlana.d@bk.ru',
'kirill.a@mail.ru',
'marina.b@yandex.ru',
'pavel.g@list.ru',
'tatiana.l@gmail.com',
'andrey.f@rambler.ru',
'natalia.e@inbox.ru',
'vladislav.r@mail.ru',
'yulia.h@yandex.ru',
]
def _get_fallback_email() -> str:
"""Возвращает случайный email-заглушку из списка."""
import random
return random.choice(_FALLBACK_EMAILS)
# Кэш для публичного IP
_cached_public_ip: str | None = None
_ip_fetch_lock = asyncio.Lock()
@@ -190,7 +222,7 @@ class FreekassaService:
# Определяем IP (важно для API запроса) - здесь синхронно, поэтому лучше иметь передачу IP
# Если IP не передан, используем fallback
target_ip = ip or '185.92.183.173'
target_email = email or 'test@example.com'
target_email = email or _get_fallback_email()
params = {
'shopId': self.shop_id,
@@ -278,7 +310,7 @@ class FreekassaService:
# Используем payment_system_id из настроек, если не передан явно
ps_id = payment_system_id or settings.FREEKASSA_PAYMENT_SYSTEM_ID or 1
target_email = email or 'test@example.com'
target_email = email or _get_fallback_email()
# Определяем публичный IP сервера
server_ip = ip or await get_public_ip()
+8 -2
View File
@@ -350,13 +350,19 @@ class FreekassaPaymentMixin:
# Resolve display name from payment metadata (sub-method aware)
display_name = settings.get_freekassa_display_name_html()
try:
meta = json.loads(payment.metadata_json) if payment.metadata_json else {}
raw = payment.metadata_json
if isinstance(raw, dict):
meta = raw
elif raw:
meta = json.loads(raw)
else:
meta = {}
pm = meta.get('payment_method', 'freekassa')
if pm == 'freekassa_sbp':
display_name = settings.get_freekassa_sbp_display_name_html()
elif pm == 'freekassa_card':
display_name = settings.get_freekassa_card_display_name_html()
except (json.JSONDecodeError, AttributeError):
except (json.JSONDecodeError, AttributeError, TypeError):
pass
await self.bot.send_message(
user.telegram_id,