Files

83 lines
2.8 KiB
Python
Raw Permalink Normal View History

"""Escrow endpoints (гарант)."""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.core.database import get_db
from app.schemas.escrow import EscrowCreate, EscrowRelease
from app.models.escrow import EscrowTransaction
from app.models.project import Project
router = APIRouter(prefix="/api/escrow", tags=["escrow"])
@router.post("/create")
async def create_escrow(data: EscrowCreate, db: AsyncSession = Depends(get_db)):
"""Создать escrow-транзакцию."""
result = await db.execute(select(Project).where(Project.id == data.project_id))
project = result.scalar_one_or_none()
if not project:
raise HTTPException(status_code=404, detail="Проект не найден")
transaction = EscrowTransaction(
project_id=data.project_id,
client_id=data.client_id,
freelancer_id=data.freelancer_id,
amount=data.amount,
status="pending",
)
db.add(transaction)
await db.commit()
await db.refresh(transaction)
return {
"id": str(transaction.id),
"status": transaction.status,
"amount": float(transaction.amount),
"payment_url": f"https://stripe.com/pay/{transaction.id}", # Stripe redirect
}
@router.post("/release")
async def release_escrow(data: EscrowRelease, db: AsyncSession = Depends(get_db)):
"""Освободить средства фрилансеру."""
result = await db.execute(select(EscrowTransaction).where(EscrowTransaction.id == data.transaction_id))
transaction = result.scalar_one_or_none()
if not transaction or transaction.status != "locked":
raise HTTPException(status_code=400, detail="Транзакция не может быть разблокирована")
# Комиссия платформы 10%
commission = transaction.amount * 0.10
freelancer_amount = transaction.amount - commission
transaction.status = "released"
await db.commit()
return {
"id": str(transaction.id),
"status": "released",
"freelancer_payout": float(freelancer_amount),
"platform_commission": float(commission),
}
@router.post("/dispute")
async def dispute_escrow(transaction_id: str, db: AsyncSession = Depends(get_db)):
"""Открыть спор по escrow."""
result = await db.execute(select(EscrowTransaction).where(EscrowTransaction.id == transaction_id))
transaction = result.scalar_one_or_none()
if not transaction:
raise HTTPException(status_code=404, detail="Транзакция не найдена")
transaction.status = "disputed"
await db.commit()
return {"status": "dispute_opened", "transaction_id": str(transaction.id)}