BackendSpace / app /api /routes /stripe_routes.py
2nzi's picture
first commit
cf51ebb verified
raw
history blame
4.87 kB
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import JSONResponse
import stripe
from app.core.config import settings
from pydantic import BaseModel
router = APIRouter()
stripe.api_key = settings.STRIPE_SECRET_KEY
# Utilisation des variables d'environnement pour les price IDs
STRIPE_PRICE_IDS = {
'starter': settings.STRIPE_PRICE_ID_STARTER,
'pro': settings.STRIPE_PRICE_ID_PRO,
'business': settings.STRIPE_PRICE_ID_BUSINESS
}
class SubscriptionRequest(BaseModel):
plan_id: str
user_id: str
class PaymentSuccessRequest(BaseModel):
session_id: str
@router.post("/create-subscription")
async def create_subscription(request: SubscriptionRequest):
try:
price_id = STRIPE_PRICE_IDS.get(request.plan_id)
print(f"Plan ID reçu: {request.plan_id}")
print(f"Price ID trouvé: {price_id}")
print(f"Mode Stripe: {stripe.api_key.startswith('sk_test_') and 'TEST' or 'LIVE'}")
if not price_id:
raise HTTPException(status_code=400, detail=f"Plan non trouvé: {request.plan_id}")
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price': price_id,
'quantity': 1,
}],
mode='subscription',
success_url=f"{settings.FRONTEND_URL}/generate?session_id={{CHECKOUT_SESSION_ID}}",
cancel_url=f"{settings.FRONTEND_URL}/tokens",
metadata={
'user_id': request.user_id,
'plan_id': request.plan_id
}
)
return {"sessionId": session.id}
except Exception as e:
print(f"Erreur complète: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
@router.post("/webhook")
async def stripe_webhook(request: Request):
payload = await request.body()
sig_header = request.headers.get("stripe-signature")
try:
event = stripe.Webhook.construct_event(
payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
)
if event["type"] == "checkout.session.completed":
session = event["data"]["object"]
user_id = session["metadata"]["user_id"]
plan_id = session["metadata"]["plan_id"]
# Au lieu de mettre à jour Firebase, on renvoie les informations
return {
"status": "success",
"user_id": user_id,
"plan_id": plan_id
}
return {"status": "success"}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.post("/create-webhook")
async def create_webhook_endpoint():
try:
endpoint = stripe.WebhookEndpoint.create(
url=f"{settings.FRONTEND_URL}/api/webhook",
enabled_events=[
"checkout.session.completed",
"customer.subscription.created",
"customer.subscription.deleted",
"invoice.paid",
"invoice.payment_failed"
],
description="Endpoint pour la gestion des abonnements"
)
# Sauvegarder la clé secrète dans les variables d'environnement
webhook_secret = endpoint.secret
return {
"status": "success",
"endpoint_id": endpoint.id,
"webhook_secret": webhook_secret # À stocker dans .env
}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.post("/payment-success")
async def handle_payment_success(request: PaymentSuccessRequest):
try:
print("=== Début du traitement payment-success ===")
print(f"Session ID reçu: {request.session_id}")
session = stripe.checkout.Session.retrieve(request.session_id)
print(f"Status du paiement: {session.payment_status}")
print(f"Customer: {session.customer}")
print(f"Metadata complète: {session.metadata}")
user_id = session.metadata.get('user_id')
plan_id = session.metadata.get('plan_id')
if not user_id or not plan_id:
raise HTTPException(
status_code=400,
detail="Metadata manquante: user_id ou plan_id non trouvé"
)
print(f"User ID extrait: {user_id}")
print(f"Plan ID extrait: {plan_id}")
return {
"status": "success",
"user_id": user_id,
"plan_id": plan_id
}
except Exception as e:
print(f"Erreur lors du traitement: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))