Files
pay-service/src/application/commands/create_payment_command.py
2026-05-11 19:50:25 +03:00

60 lines
2.6 KiB
Python

from __future__ import annotations
from ulid import ULID
from src.application.abstractions import IUnitOfWork
from src.application.contracts import ILogger,IQueueMessanger
from src.application.domain.enums import PaymentStatus
from src.application.domain.exceptions import PaymentMetadataException
from src.infrastructure.config import settings
from src.infrastructure.database.decorators import transactional
from src.presentation.schemas.itpay_payment_models import ItpayPaymentData
class CreatePaymentCommand:
def __init__(self, *, unit_of_work: IUnitOfWork, logger: ILogger, queue_messanger: IQueueMessanger):
self._unit_of_work = unit_of_work
self._logger = logger
self._queue_messanger = queue_messanger
@transactional
async def __call__(self, payment: ItpayPaymentData) -> None:
if str(payment.status).strip().lower() != 'completed':
return
metadata = payment.metadata or {}
order_id = str(metadata.get('order_id') or '')
user_id = str(metadata.get('user_id') or '')
trace_id = str(metadata.get('trace_id') or self._logger.get_trace_id())
self._logger.set_trace_id(trace_id)
if not order_id:
raise PaymentMetadataException(message='Itpay webhook metadata missing order_id')
if not user_id:
raise PaymentMetadataException(message='Itpay webhook metadata missing user_id')
payment_created = await self._unit_of_work.payment_repository.create_completed(
user_id=user_id,
order_id=order_id,
itpay_payment_id=str(payment.id),
itpay_paid_amount=str(payment.amount) if payment.amount is not None else None,
transaction_id=str(payment.transaction_id) if payment.transaction_id is not None else None,
paid_at=str(payment.paid) if payment.paid is not None else None,
expired_date=str(payment.expired_date) if payment.expired_date is not None else None,
)
if not payment_created:
return
message_id = str(ULID())
message: dict[str,str] = {
'order_id': order_id,
'user_id': user_id,
'trace_id': trace_id,
'message_id': message_id,
}
await self._queue_messanger.publish_to_queue(
queue=settings.RABBIT_CRYPTO_TRANSFER_QUEUE,
message=message,
message_id=message_id,
correlation_id=message['trace_id'],
headers={'trace_id': trace_id},
)
await self._unit_of_work.payment_repository.update_status(
order_id=order_id,
status=PaymentStatus.WEB3_PROCESSING,
)