Spaces:
Sleeping
Sleeping
File size: 5,152 Bytes
0068f7d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
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 ===")
# Récupérer la session Stripe
session = stripe.checkout.Session.retrieve(request.session_id)
# Vérifier que le paiement n'a pas déjà été traité
if session.metadata.get('processed') == 'true':
return {
"status": "already_processed",
"message": "Ce paiement a déjà été traité"
}
# Vérifier que le paiement est bien complété
if session.payment_status != 'paid':
raise HTTPException(
status_code=400,
detail="Le paiement n'est pas complété"
)
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="Informations utilisateur manquantes"
)
# Marquer la session comme traitée
stripe.checkout.Session.modify(
session.id,
metadata={'processed': 'true'}
)
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))
|