""" Webhook endpoints for handling payment provider events These endpoints receive events from payment providers like Stripe All event processing is handled by SubscriptionOrchestrationService """ import structlog import stripe from fastapi import APIRouter, Depends, HTTPException, status, Request from sqlalchemy.ext.asyncio import AsyncSession from app.services.subscription_orchestration_service import SubscriptionOrchestrationService from app.core.config import settings from app.core.database import get_db logger = structlog.get_logger() router = APIRouter() def get_subscription_orchestration_service( db: AsyncSession = Depends(get_db) ) -> SubscriptionOrchestrationService: """Dependency injection for SubscriptionOrchestrationService""" try: return SubscriptionOrchestrationService(db) except Exception as e: logger.error("Failed to create subscription orchestration service", error=str(e)) raise HTTPException(status_code=500, detail="Service initialization failed") @router.post("/webhooks/stripe") async def stripe_webhook( request: Request, orchestration_service: SubscriptionOrchestrationService = Depends(get_subscription_orchestration_service) ): """ Stripe webhook endpoint to handle payment events This endpoint verifies webhook signatures and processes Stripe events """ try: # Get the payload and signature payload = await request.body() sig_header = request.headers.get('stripe-signature') if not sig_header: logger.error("Missing stripe-signature header") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Missing signature header" ) # Verify the webhook signature try: event = stripe.Webhook.construct_event( payload, sig_header, settings.STRIPE_WEBHOOK_SECRET ) except stripe.error.SignatureVerificationError as e: logger.error("Invalid webhook signature", error=str(e)) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid signature" ) except ValueError as e: logger.error("Invalid payload", error=str(e)) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid payload" ) # Get event type and data event_type = event['type'] event_data = event['data']['object'] logger.info("Processing Stripe webhook event", event_type=event_type, event_id=event.get('id')) # Use orchestration service to handle the event result = await orchestration_service.handle_payment_webhook(event_type, event_data) logger.info("Webhook event processed via orchestration service", event_type=event_type, actions_taken=result.get("actions_taken", [])) return {"success": True, "event_type": event_type, "actions_taken": result.get("actions_taken", [])} except HTTPException: raise except Exception as e: logger.error("Error processing Stripe webhook", error=str(e), exc_info=True) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Webhook processing error" )