from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from config import cfg from core.deps import get_auth_context, get_pally_client from db.session import get_db from external.pally import PallyClient from repositories import AddonsRepository, PricingRepository from repositories.invoices import InvoiceRepository from repositories.orders import OrderRepository from schemas.checkout import CheckoutResponse from schemas.dto import AuthContext from schemas.invoices import InvoiceStatus from schemas.plans import OrderDetails from services.plans import calculate_price, get_pricing_model router = APIRouter(prefix="/orders") @router.post("/checkout", response_model=CheckoutResponse, status_code=201) async def checkout( order: OrderDetails, ctx: AuthContext = Depends(get_auth_context), session: AsyncSession = Depends(get_db), pally: PallyClient = Depends(get_pally_client), ): addons_repo = AddonsRepository(session) pricing_repo = PricingRepository(session) invoices_repo = InvoiceRepository(session) orders_repo = OrderRepository(session) order_entry = await orders_repo.create( ctx.user.id, order.devices, order.duration_days, addons=order.addons, ) pricing = await get_pricing_model(addons_repo, pricing_repo) price = await calculate_price(addons_repo=addons_repo, order=order, pricing=pricing) bonus_covered = ctx.user.balance amount_to_pay = max(price - bonus_covered, cfg.minimal_deposit) if bonus_covered < price else 0 if amount_to_pay > 0: invoice = await invoices_repo.create( creator_id=ctx.user.id, amount=amount_to_pay, status=InvoiceStatus.ACTIVE ) bill = await pally.bills.create(amount_to_pay, cfg.pally_shop_id, order_id=invoice.id) payment_link = bill.link_page_url if not payment_link: raise HTTPException(500, detail="failed to create invoice") else: payment_link = None return CheckoutResponse( order_id=order_entry.id, total_amount=price, bonus_paid=bonus_covered, amount_to_pay=amount_to_pay, payment_link=payment_link, )