Files
remnashop/src/web/endpoints/payments.py
Ilay 9664d7e199 fix: broadcast close button, webhook response, FreeKassa nonce and misc fixes
- added get_close_notification_button helper and CLOSE_BUTTON_ID constant
- added close button as a selectable option in broadcast button picker
- renamed get_goto_buttons to get_broadcast_buttons
- fixed webhook endpoint: moved gateway.build_webhook_response out of finally block
- re-enabled YooKassa webhook verification
- fixed FreeKassa nonce: switched to time.time_ns() for strict monotonicity
- fixed FreeKassa currency: use .upper() instead of .value
- fixed system stats getter: use stats.memory.used instead of active, cpu.cores instead of physical_cores
- fixed node traffic_limit: pass None instead of 0 to i18n_format_bytes_to_unit
- added as_payload to UserDevicesUpdatedEvent and SubscriptionRevokedEvent with user keyboard
- added session.close() in UnitOfWork __aexit__
- added python-multipart dependency
- added DOCS constant, updated update keyboard links to docs instead of GitHub README
- bumped version 0.7.5
2026-04-09 08:50:45 +05:00

55 lines
2.2 KiB
Python

from dishka import FromDishka
from dishka.integrations.fastapi import inject
from fastapi import APIRouter, Request, Response, status
from loguru import logger
from src.application.common import EventPublisher
from src.application.events import ErrorEvent
from src.application.use_cases.gateways.queries.providers import GetPaymentGatewayInstance
from src.core.config import AppConfig
from src.core.constants import API_V1, PAYMENTS_WEBHOOK_PATH
from src.core.enums import PaymentGatewayType
from src.infrastructure.taskiq.tasks.payments import handle_payment_transaction_task
router = APIRouter(prefix=API_V1 + PAYMENTS_WEBHOOK_PATH)
@router.post("/{gateway_type}")
@inject
async def payments_webhook(
gateway_type: str,
request: Request,
config: FromDishka[AppConfig],
event_publisher: FromDishka[EventPublisher],
get_payment_gateway_instance: FromDishka[GetPaymentGatewayInstance],
) -> Response:
try:
gateway_enum = PaymentGatewayType(gateway_type.upper())
except ValueError:
logger.exception(f"Invalid gateway type received: '{gateway_type}'")
return Response(status_code=status.HTTP_404_NOT_FOUND)
gateway = None
try:
gateway = await get_payment_gateway_instance.system(gateway_enum)
if not gateway.data.is_active:
logger.warning(f"Webhook received for disabled payment gateway '{gateway_enum}'")
return Response(status_code=status.HTTP_404_NOT_FOUND)
if not gateway.data.settings.is_configured: # type: ignore[union-attr]
logger.warning(f"Webhook received for unconfigured payment gateway '{gateway_enum}'")
return Response(status_code=status.HTTP_404_NOT_FOUND)
payment_id, payment_status = await gateway.handle_webhook(request)
await handle_payment_transaction_task.kiq(payment_id, payment_status) # type: ignore[call-overload]
except Exception as e:
logger.exception(f"Error processing webhook for '{gateway_type}': {e}")
error_event = ErrorEvent(**config.build.data, exception=e)
await event_publisher.publish(error_event)
if gateway is not None:
return await gateway.build_webhook_response(request)
return Response(status_code=status.HTTP_200_OK)