Files
bakery-ia/services/tenant/app/api/webhooks.py
2025-09-25 14:30:47 +02:00

134 lines
5.0 KiB
Python

"""
Webhook endpoints for handling payment provider events
These endpoints receive events from payment providers like Stripe
"""
import structlog
from fastapi import APIRouter, Depends, HTTPException, status, Request
from typing import Dict, Any
from app.services.payment_service import PaymentService
from shared.auth.decorators import get_current_user_dep
from shared.monitoring.metrics import track_endpoint_metrics
logger = structlog.get_logger()
router = APIRouter()
def get_payment_service():
try:
return PaymentService()
except Exception as e:
logger.error("Failed to create payment service", error=str(e))
raise HTTPException(status_code=500, detail="Payment service initialization failed")
@router.post("/webhooks/stripe")
async def stripe_webhook(
request: Request,
payment_service: PaymentService = Depends(get_payment_service)
):
"""
Stripe webhook endpoint to handle payment events
"""
try:
# Get the payload
payload = await request.body()
sig_header = request.headers.get('stripe-signature')
# In a real implementation, you would verify the signature
# using the webhook signing secret
# event = stripe.Webhook.construct_event(
# payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
# )
# For now, we'll just log the event
logger.info("Received Stripe webhook", payload=payload.decode('utf-8'))
# Process different types of events
# event_type = event['type']
# event_data = event['data']['object']
# Example processing for different event types:
# if event_type == 'checkout.session.completed':
# # Handle successful checkout
# pass
# elif event_type == 'customer.subscription.created':
# # Handle new subscription
# pass
# elif event_type == 'customer.subscription.updated':
# # Handle subscription update
# pass
# elif event_type == 'customer.subscription.deleted':
# # Handle subscription cancellation
# pass
# elif event_type == 'invoice.payment_succeeded':
# # Handle successful payment
# pass
# elif event_type == 'invoice.payment_failed':
# # Handle failed payment
# pass
return {"success": True}
except Exception as e:
logger.error("Error processing Stripe webhook", error=str(e))
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Webhook error"
)
@router.post("/webhooks/generic")
async def generic_webhook(
request: Request,
payment_service: PaymentService = Depends(get_payment_service)
):
"""
Generic webhook endpoint that can handle events from any payment provider
"""
try:
# Get the payload
payload = await request.json()
# Log the event for debugging
logger.info("Received generic webhook", payload=payload)
# Process the event based on its type
event_type = payload.get('type', 'unknown')
event_data = payload.get('data', {})
# Process different types of events
if event_type == 'subscription.created':
# Handle new subscription
logger.info("Processing new subscription event", subscription_id=event_data.get('id'))
# Update database with new subscription
elif event_type == 'subscription.updated':
# Handle subscription update
logger.info("Processing subscription update event", subscription_id=event_data.get('id'))
# Update database with subscription changes
elif event_type == 'subscription.deleted':
# Handle subscription cancellation
logger.info("Processing subscription cancellation event", subscription_id=event_data.get('id'))
# Update database with cancellation
elif event_type == 'payment.succeeded':
# Handle successful payment
logger.info("Processing successful payment event", payment_id=event_data.get('id'))
# Update payment status in database
elif event_type == 'payment.failed':
# Handle failed payment
logger.info("Processing failed payment event", payment_id=event_data.get('id'))
# Update payment status and notify user
elif event_type == 'invoice.created':
# Handle new invoice
logger.info("Processing new invoice event", invoice_id=event_data.get('id'))
# Store invoice information
else:
logger.warning("Unknown event type received", event_type=event_type)
return {"success": True}
except Exception as e:
logger.error("Error processing generic webhook", error=str(e))
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Webhook error"
)