from fastapi import APIRouter, Request, Header import asyncpg from fastapi import Depends from app.core.responses import ok from app.dependencies import get_db from app.exceptions import PaymentError from app.services import stripe_service, order_service, booking_service router = APIRouter(prefix="/payments", tags=["Payments"]) @router.post("/webhook") async def stripe_webhook( request: Request, stripe_signature: str = Header(None, alias="stripe-signature"), db: asyncpg.Connection = Depends(get_db), ): payload = await request.body() if not stripe_signature: raise PaymentError("Missing signature") event = stripe_service.verify_webhook(payload, stripe_signature) intent = event.get("data", {}).get("object", {}) metadata = intent.get("metadata", {}) entity_type = metadata.get("entity_type") entity_id = metadata.get("entity_id") payment_intent_id = intent.get("id") if not entity_type or not entity_id or entity_id == "pending": return ok({"received": True}) if event["type"] == "payment_intent.succeeded": if entity_type == "order": await order_service.handle_payment_succeeded(db, payment_intent_id, entity_id) elif entity_type == "booking": await booking_service.handle_payment_succeeded(db, payment_intent_id, entity_id) elif event["type"] == "payment_intent.payment_failed": if entity_type == "order": await order_service.handle_payment_failed(db, payment_intent_id, entity_id) elif entity_type == "booking": await booking_service.handle_payment_failed(db, payment_intent_id, entity_id) return ok({"received": True})