"""Paid orders. Local development payment only; no provider is wired yet.""" from datetime import datetime, timedelta, timezone from uuid import UUID, uuid4 from fastapi import APIRouter, Depends, HTTPException from psycopg.types.json import Jsonb from ..core import db from ..core.auth import owner from ..core.models import Pay from ..runtime import ENVIRONMENT, enqueue, payment, upload_row from ..scanning import require_clean router = APIRouter() @router.post('/api/orders/dev-paid') def dev_paid(body: Pay, session_id=Depends(owner)): if ENVIRONMENT != 'local': raise HTTPException(503, 'Checkout is not configured yet') with db.connect() as c: row = c.execute('SELECT * FROM dtf_local.quotes WHERE id=%s AND owner=%s FOR UPDATE', (body.quote_id,session_id)).fetchone() if not row: raise HTTPException(404, 'Quote not found') existing = c.execute('SELECT * FROM dtf_local.orders WHERE quote_id=%s', (body.quote_id,)).fetchone() if existing: return existing if not row['approved']: raise HTTPException(409, 'An operator must verify length and grade first') if row['approved_at'] < datetime.now(timezone.utc)-timedelta(hours=24): raise HTTPException(409, 'Quote expired; request a new quote') approved = row['approved'] for item in approved['items']: for upload_id in item['uploads']: require_clean(upload_row(c, UUID(upload_id), session_id)) paid = payment.pay(str(body.quote_id), approved['total_cents']) result = c.execute('INSERT INTO dtf_local.orders(id,quote_id,owner,snapshot,payment) VALUES(%s,%s,%s,%s,%s) RETURNING *', (uuid4(),body.quote_id,session_id,Jsonb(approved),Jsonb(paid))).fetchone() for provider in ('tiny','whatsapp'): enqueue(c, f"{result['id']}:paid:{provider}", provider, {'order_id': str(result['id']), 'number': result['number'], 'event': 'payment_approved', 'order': approved}) return result