Files
payment-processing-test/app/payments.py
T

50 lines
1.4 KiB
Python

import uuid
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from app.models import OutboxEvent, Payment
from app.schemas import PaymentCreate, PaymentCreatedEvent
async def create_payment(
session: AsyncSession,
request: PaymentCreate,
idempotency_key: str,
) -> Payment:
payment_id = uuid.uuid4()
payment = Payment(
id=payment_id,
amount=request.amount,
currency=request.currency,
description=request.description,
metadata_=request.metadata,
idempotency_key=idempotency_key,
webhook_url=str(request.webhook_url),
)
event = PaymentCreatedEvent(payment_id=payment_id)
outbox_event = OutboxEvent(
aggregate_id=payment_id,
event_type="payment.created",
payload=event.model_dump(mode="json"),
)
session.add_all((payment, outbox_event))
try:
await session.commit()
except IntegrityError:
await session.rollback()
existing = await session.scalar(
select(Payment).where(Payment.idempotency_key == idempotency_key)
)
if existing is None:
raise
return existing
return payment
async def get_payment(session: AsyncSession, payment_id: uuid.UUID) -> Payment | None:
return await session.get(Payment, payment_id)