feat: update full path payment
This commit is contained in:
@@ -3,7 +3,12 @@ from abc import ABC,abstractmethod
|
|||||||
|
|
||||||
class IPaymentRepository(ABC):
|
class IPaymentRepository(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def create_completed(self,*,user_id:str,order_id:str,itpay_payment_id:str,itpay_paid_amount:str|None,transaction_id:str|None,paid_at:str|None,expired_date:str|None) -> None:
|
async def create_completed(self,*,user_id:str,order_id:str,itpay_payment_id:str,itpay_paid_amount:str|None,transaction_id:str|None,paid_at:str|None,expired_date:str|None) -> bool:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def update_crypto_transfer_completed(self,*,order_id:str,web3_transaction_hash:str|None) -> None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
from src.application.commands.create_order_command import CreateOrderCommand
|
from src.application.commands.create_order_command import CreateOrderCommand
|
||||||
from src.application.commands.create_payment_command import CreatePaymentCommand
|
from src.application.commands.create_payment_command import CreatePaymentCommand
|
||||||
from src.application.commands.create_payment_cloudkassir_command import CreatePaymentCloudkassirCommand
|
from src.application.commands.create_crypto_transfer_completed_command import CreateCryptoTransferCompletedCommand
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from decimal import Decimal
|
||||||
|
from ulid import ULID
|
||||||
|
from src.application.abstractions import IUnitOfWork
|
||||||
|
from src.application.contracts import IReceipt
|
||||||
|
from src.application.domain.exceptions import ApplicationException
|
||||||
|
from src.infrastructure.database.decorators import transactional
|
||||||
|
|
||||||
|
|
||||||
|
class CreateCryptoTransferCompletedCommand:
|
||||||
|
def __init__(self, *, unit_of_work: IUnitOfWork, receipt: IReceipt):
|
||||||
|
self._unit_of_work = unit_of_work
|
||||||
|
self._receipt = receipt
|
||||||
|
|
||||||
|
|
||||||
|
@transactional
|
||||||
|
async def __call__(self, *, order_id: str, user_id: str, web3_transaction_hash: str | None = None) -> None:
|
||||||
|
if not order_id:
|
||||||
|
raise ApplicationException(status_code=400, message='Crypto transfer completed message missing order_id')
|
||||||
|
if not user_id:
|
||||||
|
raise ApplicationException(status_code=400, message='Crypto transfer completed message missing user_id')
|
||||||
|
await self._unit_of_work.payment_repository.update_crypto_transfer_completed(
|
||||||
|
order_id=order_id,
|
||||||
|
web3_transaction_hash=web3_transaction_hash,
|
||||||
|
)
|
||||||
|
user = await self._unit_of_work.user_repository.get(user_id)
|
||||||
|
if user is None:
|
||||||
|
raise ApplicationException(status_code=404, message='User not found')
|
||||||
|
email = str(user.email or '').strip()
|
||||||
|
if not email:
|
||||||
|
raise ApplicationException(status_code=400, message='User email missing')
|
||||||
|
customer_info = ' '.join(
|
||||||
|
part
|
||||||
|
for part in (
|
||||||
|
str(user.last_name or '').strip(),
|
||||||
|
str(user.first_name or '').strip(),
|
||||||
|
str(user.middle_name or '').strip(),
|
||||||
|
)
|
||||||
|
if part
|
||||||
|
)
|
||||||
|
if not customer_info:
|
||||||
|
raise ApplicationException(status_code=400, message='User full name missing')
|
||||||
|
customer_inn = str(user.inn or '').strip()
|
||||||
|
if not customer_inn:
|
||||||
|
raise ApplicationException(status_code=400, message='User inn missing')
|
||||||
|
if user.birth_date is None:
|
||||||
|
raise ApplicationException(status_code=400, message='User birth date missing')
|
||||||
|
customer_birthday = f'{user.birth_date.isoformat()}T12:00:00.000Z'
|
||||||
|
|
||||||
|
order = await self._unit_of_work.order_repository.get_by_id(order_id)
|
||||||
|
if order is None:
|
||||||
|
raise ApplicationException(status_code=404, message='Order not found')
|
||||||
|
if order.total_price is None:
|
||||||
|
raise ApplicationException(status_code=400, message='Order total price missing for receipt')
|
||||||
|
if order.service_fee is None:
|
||||||
|
raise ApplicationException(status_code=400, message='Order service fee missing for receipt')
|
||||||
|
|
||||||
|
total_amount = Decimal(str(order.total_price)).quantize(Decimal('0.01'))
|
||||||
|
service_fee = Decimal(str(order.service_fee)).quantize(Decimal('0.01'))
|
||||||
|
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
|
||||||
|
|
||||||
|
if principal_amount < 0:
|
||||||
|
raise ApplicationException(status_code=400, message='Invalid receipt amounts: principal negative')
|
||||||
|
|
||||||
|
receipt_response = await self._receipt.create_receipt(
|
||||||
|
order_id=order_id,
|
||||||
|
user_id=user_id,
|
||||||
|
email=email,
|
||||||
|
total_amount=total_amount,
|
||||||
|
principal_amount=principal_amount,
|
||||||
|
service_fee=service_fee,
|
||||||
|
customer_info=customer_info,
|
||||||
|
customer_inn=customer_inn,
|
||||||
|
customer_birthday=customer_birthday,
|
||||||
|
request_id=str(ULID()),
|
||||||
|
)
|
||||||
|
receipt_model = receipt_response.get('Model')
|
||||||
|
if not isinstance(receipt_model, dict):
|
||||||
|
receipt_model = {}
|
||||||
|
await self._unit_of_work.payment_repository.update_receipt(
|
||||||
|
order_id=order_id,
|
||||||
|
receipt_cloudekassir_id=str(receipt_model.get('Id') or '') or None,
|
||||||
|
receipt_cloudekassir_link=str(receipt_model.get('ReceiptLocalUrl') or '') or None,
|
||||||
|
)
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from decimal import Decimal
|
|
||||||
from ulid import ULID
|
|
||||||
from src.application.abstractions import IUnitOfWork
|
|
||||||
from src.application.contracts import IReceipt
|
|
||||||
from src.application.domain.exceptions import ApplicationException
|
|
||||||
from src.infrastructure.database.decorators import transactional
|
|
||||||
from src.presentation.schemas.itpay_payment_models import ItpayPaymentData
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_money(val: object | None) -> Decimal | None:
|
|
||||||
if val is None:
|
|
||||||
return None
|
|
||||||
s = str(val).strip()
|
|
||||||
if not s:
|
|
||||||
return None
|
|
||||||
return Decimal(s).quantize(Decimal('0.01'))
|
|
||||||
|
|
||||||
|
|
||||||
class CreatePaymentCloudkassirCommand:
|
|
||||||
def __init__(self, *, unit_of_work: IUnitOfWork, receipt: IReceipt):
|
|
||||||
self._unit_of_work = unit_of_work
|
|
||||||
self._receipt = receipt
|
|
||||||
|
|
||||||
|
|
||||||
@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 '')
|
|
||||||
if not order_id:
|
|
||||||
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing order_id')
|
|
||||||
if not user_id:
|
|
||||||
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing user_id')
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
user = await self._unit_of_work.user_repository.get(user_id)
|
|
||||||
if user is None:
|
|
||||||
raise ApplicationException(status_code=404, message='User not found')
|
|
||||||
email = str(user.email or '').strip()
|
|
||||||
if not email:
|
|
||||||
raise ApplicationException(status_code=400, message='User email missing')
|
|
||||||
customer_info = ' '.join(
|
|
||||||
part
|
|
||||||
for part in (
|
|
||||||
str(user.last_name or '').strip(),
|
|
||||||
str(user.first_name or '').strip(),
|
|
||||||
str(user.middle_name or '').strip(),
|
|
||||||
)
|
|
||||||
if part
|
|
||||||
)
|
|
||||||
if not customer_info:
|
|
||||||
raise ApplicationException(status_code=400, message='User full name missing')
|
|
||||||
customer_inn = str(user.inn or '').strip()
|
|
||||||
if not customer_inn:
|
|
||||||
raise ApplicationException(status_code=400, message='User inn missing')
|
|
||||||
if user.birth_date is None:
|
|
||||||
raise ApplicationException(status_code=400, message='User birth date missing')
|
|
||||||
customer_birthday = f'{user.birth_date.isoformat()}T12:00:00.000Z'
|
|
||||||
|
|
||||||
paid_total = _parse_money(payment.amount)
|
|
||||||
if paid_total is None:
|
|
||||||
paid_total = _parse_money(metadata.get('amount'))
|
|
||||||
if paid_total is None:
|
|
||||||
paid_total = _parse_money(metadata.get('total_amount'))
|
|
||||||
|
|
||||||
meta_principal = _parse_money(metadata.get('principal_amount'))
|
|
||||||
meta_agent = _parse_money(metadata.get('agent_fee'))
|
|
||||||
if meta_agent is None:
|
|
||||||
meta_agent = _parse_money(metadata.get('service_fee'))
|
|
||||||
|
|
||||||
principal_amount: Decimal
|
|
||||||
service_fee: Decimal
|
|
||||||
total_amount: Decimal
|
|
||||||
|
|
||||||
if meta_principal is not None and meta_agent is not None:
|
|
||||||
principal_amount = meta_principal
|
|
||||||
service_fee = meta_agent
|
|
||||||
total_amount = (principal_amount + service_fee).quantize(Decimal('0.01'))
|
|
||||||
else:
|
|
||||||
order = await self._unit_of_work.order_repository.get_by_id(order_id)
|
|
||||||
if order is not None and order.total_price is not None and order.service_fee is not None:
|
|
||||||
total_amount = Decimal(str(order.total_price)).quantize(Decimal('0.01'))
|
|
||||||
service_fee = Decimal(str(order.service_fee)).quantize(Decimal('0.01'))
|
|
||||||
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
|
|
||||||
else:
|
|
||||||
if paid_total is None:
|
|
||||||
raise ApplicationException(status_code=400, message='Payment amount missing for receipt')
|
|
||||||
raw_sf = metadata.get('service_fee')
|
|
||||||
if raw_sf is None:
|
|
||||||
raise ApplicationException(
|
|
||||||
status_code=400,
|
|
||||||
message='Receipt amounts: need principal_amount+agent_fee in metadata, order in DB, or service_fee with paid amount',
|
|
||||||
)
|
|
||||||
service_fee = Decimal(str(raw_sf)).quantize(Decimal('0.01'))
|
|
||||||
total_amount = paid_total
|
|
||||||
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
|
|
||||||
|
|
||||||
if principal_amount < 0:
|
|
||||||
raise ApplicationException(status_code=400, message='Invalid receipt amounts: principal negative')
|
|
||||||
if paid_total is not None and abs(total_amount - paid_total) > Decimal('0.02'):
|
|
||||||
raise ApplicationException(status_code=400, message='Receipt total does not match paid amount')
|
|
||||||
|
|
||||||
receipt_response = await self._receipt.create_receipt(
|
|
||||||
order_id=order_id,
|
|
||||||
user_id=user_id,
|
|
||||||
email=email,
|
|
||||||
total_amount=total_amount,
|
|
||||||
principal_amount=principal_amount,
|
|
||||||
service_fee=service_fee,
|
|
||||||
customer_info=customer_info,
|
|
||||||
customer_inn=customer_inn,
|
|
||||||
customer_birthday=customer_birthday,
|
|
||||||
request_id=str(ULID()),
|
|
||||||
)
|
|
||||||
receipt_model = receipt_response.get('Model')
|
|
||||||
if not isinstance(receipt_model, dict):
|
|
||||||
receipt_model = {}
|
|
||||||
await self._unit_of_work.payment_repository.update_receipt(
|
|
||||||
order_id=order_id,
|
|
||||||
receipt_cloudekassir_id=str(receipt_model.get('Id') or '') or None,
|
|
||||||
receipt_cloudekassir_link=str(receipt_model.get('ReceiptLocalUrl') or '') or None,
|
|
||||||
)
|
|
||||||
@@ -25,7 +25,7 @@ class CreatePaymentCommand:
|
|||||||
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing order_id')
|
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing order_id')
|
||||||
if not user_id:
|
if not user_id:
|
||||||
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing user_id')
|
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing user_id')
|
||||||
await self._unit_of_work.payment_repository.create_completed(
|
payment_created = await self._unit_of_work.payment_repository.create_completed(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
order_id=order_id,
|
order_id=order_id,
|
||||||
itpay_payment_id=str(payment.id),
|
itpay_payment_id=str(payment.id),
|
||||||
@@ -34,6 +34,8 @@ class CreatePaymentCommand:
|
|||||||
paid_at=str(payment.paid) if payment.paid 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,
|
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_id = str(ULID())
|
||||||
message: dict[str,str] = {
|
message: dict[str,str] = {
|
||||||
'order_id': order_id,
|
'order_id': order_id,
|
||||||
|
|||||||
@@ -16,18 +16,18 @@ class PaymentRepository(IPaymentRepository):
|
|||||||
self._logger=logger
|
self._logger=logger
|
||||||
|
|
||||||
|
|
||||||
async def create_completed(self,*,user_id:str,order_id:str,itpay_payment_id:str,itpay_paid_amount:str|None,transaction_id:str|None,paid_at:str|None,expired_date:str|None) -> None:
|
async def create_completed(self,*,user_id:str,order_id:str,itpay_payment_id:str,itpay_paid_amount:str|None,transaction_id:str|None,paid_at:str|None,expired_date:str|None) -> bool:
|
||||||
stmt=select(Payment).where(Payment.order_id==order_id)
|
stmt=select(Payment).where(Payment.order_id==order_id)
|
||||||
existing=await self._session.scalar(stmt)
|
existing=await self._session.scalar(stmt)
|
||||||
if existing is not None:
|
if existing is not None:
|
||||||
return
|
return False
|
||||||
paid_at_dt=datetime.fromisoformat(paid_at.replace('Z','+00:00')) if paid_at else None
|
paid_at_dt=datetime.fromisoformat(paid_at.replace('Z','+00:00')) if paid_at else None
|
||||||
expired_dt=datetime.fromisoformat(expired_date.replace('Z','+00:00')) if expired_date else None
|
expired_dt=datetime.fromisoformat(expired_date.replace('Z','+00:00')) if expired_date else None
|
||||||
paid_amount_dec=Decimal(str(itpay_paid_amount)) if itpay_paid_amount is not None else None
|
paid_amount_dec=Decimal(str(itpay_paid_amount)) if itpay_paid_amount is not None else None
|
||||||
model=Payment(
|
model=Payment(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
order_id=order_id,
|
order_id=order_id,
|
||||||
status=PaymentStatus.PENDING,
|
status=PaymentStatus.MONEY_ACCEPTED,
|
||||||
receipt_cloudekassir_id=None,
|
receipt_cloudekassir_id=None,
|
||||||
receipt_cloudekassir_link=None,
|
receipt_cloudekassir_link=None,
|
||||||
itpay_payment_id=itpay_payment_id,
|
itpay_payment_id=itpay_payment_id,
|
||||||
@@ -38,6 +38,17 @@ class PaymentRepository(IPaymentRepository):
|
|||||||
)
|
)
|
||||||
self._session.add(model)
|
self._session.add(model)
|
||||||
await self._session.flush()
|
await self._session.flush()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def update_crypto_transfer_completed(self,*,order_id:str,web3_transaction_hash:str|None) -> None:
|
||||||
|
stmt=select(Payment).where(Payment.order_id==order_id)
|
||||||
|
model=await self._session.scalar(stmt)
|
||||||
|
if model is None:
|
||||||
|
return
|
||||||
|
model.status=PaymentStatus.USDT_DELIVERED
|
||||||
|
model.web3_transaction_hash=web3_transaction_hash
|
||||||
|
await self._session.flush()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -46,6 +57,7 @@ class PaymentRepository(IPaymentRepository):
|
|||||||
model=await self._session.scalar(stmt)
|
model=await self._session.scalar(stmt)
|
||||||
if model is None:
|
if model is None:
|
||||||
return
|
return
|
||||||
|
model.status=PaymentStatus.COMPLETED
|
||||||
model.receipt_cloudekassir_id=receipt_cloudekassir_id
|
model.receipt_cloudekassir_id=receipt_cloudekassir_id
|
||||||
model.receipt_cloudekassir_link=receipt_cloudekassir_link
|
model.receipt_cloudekassir_link=receipt_cloudekassir_link
|
||||||
await self._session.flush()
|
await self._session.flush()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from src.infrastructure.config import settings
|
|||||||
from src.presentation.handler import application_exception_handler, unhandled_exception_handler
|
from src.presentation.handler import application_exception_handler, unhandled_exception_handler
|
||||||
from src.presentation.messaging import crypto_transfer_router
|
from src.presentation.messaging import crypto_transfer_router
|
||||||
from src.presentation.middleware import TraceIDMiddleware, SecurityHeadersMiddleware
|
from src.presentation.middleware import TraceIDMiddleware, SecurityHeadersMiddleware
|
||||||
from src.presentation.routing import order_router
|
from src.presentation.routing import itpay_router,order_router
|
||||||
|
|
||||||
security = HTTPBasic()
|
security = HTTPBasic()
|
||||||
|
|
||||||
@@ -74,6 +74,7 @@ app.add_exception_handler(ApplicationException, application_exception_handler)
|
|||||||
app.add_exception_handler(Exception, unhandled_exception_handler)
|
app.add_exception_handler(Exception, unhandled_exception_handler)
|
||||||
|
|
||||||
app.include_router(order_router)
|
app.include_router(order_router)
|
||||||
|
app.include_router(itpay_router)
|
||||||
app.include_router(crypto_transfer_router)
|
app.include_router(crypto_transfer_router)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from src.application.abstractions import IUnitOfWork
|
from src.application.abstractions import IUnitOfWork
|
||||||
from src.application.commands import CreateOrderCommand,CreatePaymentCommand,CreatePaymentCloudkassirCommand
|
from src.application.commands import CreateCryptoTransferCompletedCommand,CreateOrderCommand,CreatePaymentCommand
|
||||||
from src.application.contracts import ICache,ILogger,IQueueMessanger,IReceipt
|
from src.application.contracts import ICache,ILogger,IQueueMessanger,IReceipt
|
||||||
from src.application.contracts.i_itpay_service import IItPayService
|
from src.application.contracts.i_itpay_service import IItPayService
|
||||||
from src.infrastructure.cloud_kassir import ClaudeKassirClient
|
from src.infrastructure.cloud_kassir import ClaudeKassirClient
|
||||||
@@ -55,8 +55,8 @@ def get_cloud_kassir_receipt() -> IReceipt:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_create_payment_cloudkassir_command(
|
def get_crypto_transfer_completed_command(
|
||||||
unit_of_work: IUnitOfWork = Depends(get_unit_of_work),
|
unit_of_work: IUnitOfWork = Depends(get_unit_of_work),
|
||||||
receipt: IReceipt = Depends(get_cloud_kassir_receipt),
|
receipt: IReceipt = Depends(get_cloud_kassir_receipt),
|
||||||
) -> CreatePaymentCloudkassirCommand:
|
) -> CreateCryptoTransferCompletedCommand:
|
||||||
return CreatePaymentCloudkassirCommand(unit_of_work=unit_of_work,receipt=receipt)
|
return CreateCryptoTransferCompletedCommand(unit_of_work=unit_of_work,receipt=receipt)
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from faststream.rabbit.fastapi import RabbitMessage,RabbitRouter
|
from faststream.rabbit.fastapi import RabbitMessage,RabbitRouter
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from src.application.commands import CreateCryptoTransferCompletedCommand
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.infrastructure.config import settings
|
from src.infrastructure.config import settings
|
||||||
from src.infrastructure.context_vars import trace_id_var
|
from src.infrastructure.context_vars import trace_id_var
|
||||||
|
from src.presentation.dependencies.commands import get_crypto_transfer_completed_command
|
||||||
from src.presentation.dependencies.logger import get_logger
|
from src.presentation.dependencies.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
@@ -15,12 +17,16 @@ class CryptoTransferCompletedMessage(BaseModel):
|
|||||||
order_id: str
|
order_id: str
|
||||||
trace_id: str
|
trace_id: str
|
||||||
message_id: str
|
message_id: str
|
||||||
|
web3_transaction_hash: str | None = None
|
||||||
|
transaction_hash: str | None = None
|
||||||
|
tx_hash: str | None = None
|
||||||
|
|
||||||
|
|
||||||
@crypto_transfer_router.subscriber(settings.RABBIT_CRYPTO_TRANSFER_COMPLETED_QUEUE)
|
@crypto_transfer_router.subscriber(settings.RABBIT_CRYPTO_TRANSFER_COMPLETED_QUEUE)
|
||||||
async def crypto_transfer_completed_handler(
|
async def crypto_transfer_completed_handler(
|
||||||
msg_body: CryptoTransferCompletedMessage,
|
msg_body: CryptoTransferCompletedMessage,
|
||||||
message: RabbitMessage,
|
message: RabbitMessage,
|
||||||
|
command: CreateCryptoTransferCompletedCommand = Depends(get_crypto_transfer_completed_command),
|
||||||
logger: ILogger = Depends(get_logger),
|
logger: ILogger = Depends(get_logger),
|
||||||
) -> None:
|
) -> None:
|
||||||
trace_id=msg_body.trace_id
|
trace_id=msg_body.trace_id
|
||||||
@@ -33,6 +39,12 @@ async def crypto_transfer_completed_handler(
|
|||||||
'rabbit_message_id':message.message_id,
|
'rabbit_message_id':message.message_id,
|
||||||
'rabbit_correlation_id':message.correlation_id,
|
'rabbit_correlation_id':message.correlation_id,
|
||||||
})
|
})
|
||||||
|
web3_transaction_hash=msg_body.web3_transaction_hash or msg_body.transaction_hash or msg_body.tx_hash
|
||||||
|
await command(
|
||||||
|
order_id=msg_body.order_id,
|
||||||
|
user_id=msg_body.user_id,
|
||||||
|
web3_transaction_hash=web3_transaction_hash,
|
||||||
|
)
|
||||||
finally:
|
finally:
|
||||||
trace_id_var.reset(token)
|
trace_id_var.reset(token)
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
from src.presentation.routing.order import order_router
|
from src.presentation.routing.order import itpay_router,order_router
|
||||||
@@ -3,18 +3,19 @@ import orjson
|
|||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, Depends, Request
|
||||||
from fastapi.responses import ORJSONResponse
|
from fastapi.responses import ORJSONResponse
|
||||||
from src.application.commands import CreateOrderCommand
|
from src.application.commands import CreateOrderCommand
|
||||||
from src.application.commands import CreatePaymentCloudkassirCommand
|
from src.application.commands import CreatePaymentCommand
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.dto import AuthContext
|
from src.application.domain.dto import AuthContext
|
||||||
from src.application.domain.enums import OrderStatus
|
from src.application.domain.enums import OrderStatus
|
||||||
from src.application.domain.exceptions import ConflictException
|
from src.application.domain.exceptions import ConflictException
|
||||||
from src.presentation.decorators import require_access_token, csrf_protect
|
from src.presentation.decorators import require_access_token, csrf_protect
|
||||||
from src.presentation.dependencies.commands import get_create_order_command, get_create_payment_cloudkassir_command
|
from src.presentation.dependencies.commands import get_create_order_command, get_create_payment_command
|
||||||
from src.presentation.dependencies.logger import get_logger
|
from src.presentation.dependencies.logger import get_logger
|
||||||
from src.presentation.schemas.order import CreateOrder,CreateOrderResponse,ErrorResponse,OrderPaymentResponse
|
from src.presentation.schemas.order import CreateOrder,CreateOrderResponse,ErrorResponse,OrderPaymentResponse
|
||||||
from src.presentation.schemas.itpay_payment_models import ItpayPaymentData
|
from src.presentation.schemas.itpay_payment_models import ItpayPaymentData
|
||||||
|
|
||||||
order_router = APIRouter(prefix='/order', tags=['orders'])
|
order_router = APIRouter(prefix='/order', tags=['orders'])
|
||||||
|
itpay_router = APIRouter(prefix='/itpay', tags=['itpay'])
|
||||||
|
|
||||||
|
|
||||||
@order_router.post(
|
@order_router.post(
|
||||||
@@ -86,10 +87,10 @@ async def create_order(
|
|||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
@order_router.post('/webhook/itpay')
|
@itpay_router.post('/webhook')
|
||||||
async def itpay_webhook(
|
async def itpay_webhook(
|
||||||
request: Request,
|
request: Request,
|
||||||
payment_command: CreatePaymentCloudkassirCommand = Depends(get_create_payment_cloudkassir_command),
|
payment_command: CreatePaymentCommand = Depends(get_create_payment_command),
|
||||||
logger: ILogger = Depends(get_logger),
|
logger: ILogger = Depends(get_logger),
|
||||||
) -> ORJSONResponse:
|
) -> ORJSONResponse:
|
||||||
raw = await request.body()
|
raw = await request.body()
|
||||||
|
|||||||
Reference in New Issue
Block a user