feat(sub): subscription logic (pre release)

This commit is contained in:
2026-08-02 13:23:50 +07:00
parent cde8ce28f5
commit 24f857ef1b
15 changed files with 469 additions and 42 deletions

View File

@@ -7,15 +7,17 @@ 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 InvoiceResponse, InvoiceStatus
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=InvoiceResponse, status_code=201)
@router.post("/checkout", response_model=CheckoutResponse, status_code=201)
async def checkout(
order: OrderDetails,
ctx: AuthContext = Depends(get_auth_context),
@@ -25,17 +27,36 @@ async def checkout(
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
invoice = await invoices_repo.create(
creator_id=ctx.user.id, amount=price, status=InvoiceStatus.ACTIVE
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,
)
bill = await pally.bills.create(price, cfg.pally_shop_id, order_id=invoice.id)
if not (bill.success and bill.link_page_url):
raise HTTPException(500, detail="Failed to create an invoice.")
return InvoiceResponse(success=True, payment_link=bill.link_page_url, amount=float(price))