63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
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,
|
|
)
|