pounce/backend/app/api/webhooks.py
yves.gugger 6b6ec01484 feat: Add missing features - Stripe payments, password reset, rate limiting, contact form, newsletter
Backend:
- Add Stripe API endpoints (checkout, portal, webhook) in subscription.py
- Add password reset (forgot-password, reset-password) in auth.py
- Add email verification endpoints
- Add rate limiting with slowapi
- Add contact form and newsletter API (contact.py)
- Add webhook endpoint for Stripe (webhooks.py)
- Add NewsletterSubscriber model
- Extend User model with password reset and email verification tokens
- Extend email_service with new templates (password reset, verification, contact, newsletter)
- Update env.example with all new environment variables

Frontend:
- Add /forgot-password page
- Add /reset-password page with token handling
- Add /verify-email page with auto-verification
- Add forgot password link to login page
- Connect contact form to API
- Add API methods for all new endpoints

Documentation:
- Update README with new API endpoints
- Update environment variables documentation
- Update pages overview
2025-12-08 14:37:42 +01:00

74 lines
2.1 KiB
Python

"""
Webhook endpoints for external service integrations.
- Stripe payment webhooks
- Future: Other payment providers, notification services, etc.
"""
import logging
from fastapi import APIRouter, HTTPException, Request, Header, status
from app.database import get_db
from app.services.stripe_service import StripeService
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/stripe")
async def stripe_webhook(
request: Request,
stripe_signature: str = Header(None, alias="Stripe-Signature"),
):
"""
Handle Stripe webhook events.
This endpoint receives events from Stripe when:
- Payment succeeds or fails
- Subscription is updated or cancelled
- Invoice is created or paid
The webhook must be configured in Stripe Dashboard to point to:
https://your-domain.com/api/webhooks/stripe
Required Header:
- Stripe-Signature: Stripe's webhook signature for verification
"""
if not stripe_signature:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Missing Stripe-Signature header",
)
if not StripeService.is_configured():
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Stripe not configured",
)
# Get raw body for signature verification
payload = await request.body()
try:
async for db in get_db():
result = await StripeService.handle_webhook(
payload=payload,
sig_header=stripe_signature,
db=db,
)
return result
except ValueError as e:
logger.error(f"Webhook validation error: {e}")
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
except Exception as e:
logger.error(f"Webhook processing error: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Webhook processing failed",
)