feat: add full pay path

This commit is contained in:
2026-05-01 13:10:13 +03:00
parent d1ac7e8e84
commit bf68aca4fa
53 changed files with 1436 additions and 334 deletions

View File

@@ -0,0 +1,81 @@
from __future__ import annotations
from datetime import datetime, timezone
from decimal import Decimal, ROUND_UP
from ulid import ULID
from src.application.abstractions import IUnitOfWork
from src.application.contracts import ICache, ILogger
from src.application.contracts import IItPayService
from src.application.domain.entities.order import OrderEntity
from src.application.domain.enums import OrderStatus
from src.application.domain.exceptions import ApplicationException
from src.infrastructure.database.decorators import transactional
from src.presentation.schemas.order import CreateOrder
class CreateOrderCommand:
def __init__(
self,
*,
unit_of_work: IUnitOfWork,
logger: ILogger,
cache_local: ICache,
remote_cache: ICache,
itpay_service: IItPayService,
) -> None:
self._unit_of_work = unit_of_work
self._logger = logger
self._cache_local = cache_local
self._remote_cache = remote_cache
self._itpay_service = itpay_service
@transactional
async def __call__(self, payment_data: CreateOrder, user_id: str) -> OrderEntity:
client_payment_id = str(ULID())
rate_raw = await self._remote_cache.hget('tradex:rub:rate','value')
gas_raw = await self._remote_cache.hget('gwei:eth:last','normal_rub')
if rate_raw is None:
self._logger.error('Exchange rate unavailable')
rate_raw = '2.00'
#raise ApplicationException(status_code=503, message='Exchange rate unavailable')
if gas_raw is None:
self._logger.error('Exchange gas unavailable')
gas_raw = '1.00'
#raise ApplicationException(status_code=503, message='Exchange gas unavailable')
actual_gas_fee = Decimal(gas_raw).quantize(Decimal('0.00'), rounding=ROUND_UP)
actual_usdt_exchange_rate = Decimal(rate_raw).quantize(Decimal('0.00'), rounding=ROUND_UP)
actual_service_fee = (payment_data.usdt_amount * actual_usdt_exchange_rate * Decimal('0.04')).quantize(Decimal('0.01'))
actual_total_price = (payment_data.usdt_amount * actual_usdt_exchange_rate + actual_service_fee + actual_gas_fee).quantize(Decimal('0.01'))
if actual_total_price > payment_data.total_price * Decimal('1.01'):
self._logger.error('Price has changed, please refresh and try again')
raise ApplicationException(status_code=409, message='Price has changed, please refresh and try again')
order = OrderEntity(
user_id=user_id,
usdt_amount=payment_data.usdt_amount,
usdt_exchange_rate=actual_usdt_exchange_rate,
gas_fee=actual_gas_fee,
service_fee=actual_service_fee,
total_price=actual_total_price,
status=OrderStatus.PENDING,
created_at=datetime.now(timezone.utc),
client_payment_id=client_payment_id,
)
saved = await self._unit_of_work.order_repository.create(order)
with_itpay = await self._itpay_service.create_payment(saved)
if with_itpay.status in (
OrderStatus.CANCELLED,
OrderStatus.REJECTED,
OrderStatus.ERROR,
):
await self._unit_of_work.order_repository.update_after_itpay_failure(with_itpay)
else:
await self._unit_of_work.order_repository.update_after_itpay_payment_created(with_itpay)
return with_itpay