fix(payments): enhance YooKassa webhook processing and notification handling

Improve error handling for YooKassa payment events by adding verification for the payment service configuration. Refactor notification sending for expired discounts to batch messages before sending, ensuring better performance and error logging.
This commit is contained in:
kavore
2026-02-11 23:49:58 +03:00
parent 814663a528
commit 799bd01a79
2 changed files with 117 additions and 105 deletions
+7
View File
@@ -626,6 +626,13 @@ async def yookassa_webhook_route(request: web.Request):
async with async_session_factory() as session: async with async_session_factory() as session:
try: try:
if notification_object.event == YOOKASSA_EVENT_PAYMENT_SUCCEEDED: if notification_object.event == YOOKASSA_EVENT_PAYMENT_SUCCEEDED:
if not yookassa_service or not yookassa_service.configured:
logging.critical(
"YooKassa webhook rejected: verification service is not configured for succeeded event (payment_id=%s)",
payment_dict_for_processing.get("id"),
)
return web.Response(status=503, text="yookassa_verification_required")
if payment_dict_for_processing.get( if payment_dict_for_processing.get(
"paid") and payment_dict_for_processing.get( "paid") and payment_dict_for_processing.get(
"status") == "succeeded": "status") == "succeeded":
+16 -11
View File
@@ -81,6 +81,8 @@ class PromoCodeService:
return return
now_utc = datetime.now(timezone.utc) now_utc = datetime.now(timezone.utc)
notifications_to_send: list[tuple[int, str]] = []
async with self._async_session_factory() as session: async with self._async_session_factory() as session:
expired_discounts = await active_discount_dal.get_expired_active_discounts( expired_discounts = await active_discount_dal.get_expired_active_discounts(
session, session,
@@ -116,17 +118,7 @@ class PromoCodeService:
code_part=(f" (<code>{promo_code}</code>)" if promo_code else ""), code_part=(f" (<code>{promo_code}</code>)" if promo_code else ""),
) )
try: notifications_to_send.append((expired.user_id, message_text))
await self.bot.send_message(
chat_id=expired.user_id,
text=message_text,
parse_mode="HTML",
)
except Exception:
logging.exception(
"Failed to send discount expiration message to user %s",
expired.user_id,
)
logging.info( logging.info(
"Expired discount reservation removed: user=%s, promo=%s", "Expired discount reservation removed: user=%s, promo=%s",
@@ -136,6 +128,19 @@ class PromoCodeService:
await session.commit() await session.commit()
for user_id, message_text in notifications_to_send:
try:
await self.bot.send_message(
chat_id=user_id,
text=message_text,
parse_mode="HTML",
)
except Exception:
logging.exception(
"Failed to send discount expiration message to user %s",
user_id,
)
async def apply_promo_code( async def apply_promo_code(
self, self,
session: AsyncSession, session: AsyncSession,