2nzi commited on
Commit
0068f7d
·
verified ·
1 Parent(s): 408d959

update stripe routes

Browse files
Files changed (1) hide show
  1. app/api/routes/stripe_routes.py +150 -135
app/api/routes/stripe_routes.py CHANGED
@@ -1,135 +1,150 @@
1
- from fastapi import APIRouter, HTTPException, Request
2
- from fastapi.responses import JSONResponse
3
- import stripe
4
- from app.core.config import settings
5
- from pydantic import BaseModel
6
-
7
- router = APIRouter()
8
- stripe.api_key = settings.STRIPE_SECRET_KEY
9
-
10
- # Utilisation des variables d'environnement pour les price IDs
11
- STRIPE_PRICE_IDS = {
12
- 'starter': settings.STRIPE_PRICE_ID_STARTER,
13
- 'pro': settings.STRIPE_PRICE_ID_PRO,
14
- 'business': settings.STRIPE_PRICE_ID_BUSINESS
15
- }
16
-
17
- class SubscriptionRequest(BaseModel):
18
- plan_id: str
19
- user_id: str
20
-
21
- class PaymentSuccessRequest(BaseModel):
22
- session_id: str
23
-
24
- @router.post("/create-subscription")
25
- async def create_subscription(request: SubscriptionRequest):
26
- try:
27
- price_id = STRIPE_PRICE_IDS.get(request.plan_id)
28
- print(f"Plan ID reçu: {request.plan_id}")
29
- print(f"Price ID trouvé: {price_id}")
30
- print(f"Mode Stripe: {stripe.api_key.startswith('sk_test_') and 'TEST' or 'LIVE'}")
31
-
32
- if not price_id:
33
- raise HTTPException(status_code=400, detail=f"Plan non trouvé: {request.plan_id}")
34
-
35
- session = stripe.checkout.Session.create(
36
- payment_method_types=['card'],
37
- line_items=[{
38
- 'price': price_id,
39
- 'quantity': 1,
40
- }],
41
- mode='subscription',
42
- success_url=f"{settings.FRONTEND_URL}/generate?session_id={{CHECKOUT_SESSION_ID}}",
43
- cancel_url=f"{settings.FRONTEND_URL}/tokens",
44
- metadata={
45
- 'user_id': request.user_id,
46
- 'plan_id': request.plan_id
47
- }
48
- )
49
- return {"sessionId": session.id}
50
- except Exception as e:
51
- print(f"Erreur complète: {str(e)}")
52
- raise HTTPException(status_code=400, detail=str(e))
53
-
54
- @router.post("/webhook")
55
- async def stripe_webhook(request: Request):
56
- payload = await request.body()
57
- sig_header = request.headers.get("stripe-signature")
58
-
59
- try:
60
- event = stripe.Webhook.construct_event(
61
- payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
62
- )
63
-
64
- if event["type"] == "checkout.session.completed":
65
- session = event["data"]["object"]
66
- user_id = session["metadata"]["user_id"]
67
- plan_id = session["metadata"]["plan_id"]
68
-
69
- # Au lieu de mettre à jour Firebase, on renvoie les informations
70
- return {
71
- "status": "success",
72
- "user_id": user_id,
73
- "plan_id": plan_id
74
- }
75
-
76
- return {"status": "success"}
77
- except Exception as e:
78
- raise HTTPException(status_code=400, detail=str(e))
79
-
80
- @router.post("/create-webhook")
81
- async def create_webhook_endpoint():
82
- try:
83
- endpoint = stripe.WebhookEndpoint.create(
84
- url=f"{settings.FRONTEND_URL}/api/webhook",
85
- enabled_events=[
86
- "checkout.session.completed",
87
- "customer.subscription.created",
88
- "customer.subscription.deleted",
89
- "invoice.paid",
90
- "invoice.payment_failed"
91
- ],
92
- description="Endpoint pour la gestion des abonnements"
93
- )
94
-
95
- # Sauvegarder la clé secrète dans les variables d'environnement
96
- webhook_secret = endpoint.secret
97
- return {
98
- "status": "success",
99
- "endpoint_id": endpoint.id,
100
- "webhook_secret": webhook_secret # À stocker dans .env
101
- }
102
- except Exception as e:
103
- raise HTTPException(status_code=400, detail=str(e))
104
-
105
- @router.post("/payment-success")
106
- async def handle_payment_success(request: PaymentSuccessRequest):
107
- try:
108
- print("=== Début du traitement payment-success ===")
109
- print(f"Session ID reçu: {request.session_id}")
110
-
111
- session = stripe.checkout.Session.retrieve(request.session_id)
112
- print(f"Status du paiement: {session.payment_status}")
113
- print(f"Customer: {session.customer}")
114
- print(f"Metadata complète: {session.metadata}")
115
-
116
- user_id = session.metadata.get('user_id')
117
- plan_id = session.metadata.get('plan_id')
118
-
119
- if not user_id or not plan_id:
120
- raise HTTPException(
121
- status_code=400,
122
- detail="Metadata manquante: user_id ou plan_id non trouvé"
123
- )
124
-
125
- print(f"User ID extrait: {user_id}")
126
- print(f"Plan ID extrait: {plan_id}")
127
-
128
- return {
129
- "status": "success",
130
- "user_id": user_id,
131
- "plan_id": plan_id
132
- }
133
- except Exception as e:
134
- print(f"Erreur lors du traitement: {str(e)}")
135
- raise HTTPException(status_code=400, detail=str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException, Request
2
+ from fastapi.responses import JSONResponse
3
+ import stripe
4
+ from app.core.config import settings
5
+ from pydantic import BaseModel
6
+
7
+ router = APIRouter()
8
+ stripe.api_key = settings.STRIPE_SECRET_KEY
9
+
10
+ # Utilisation des variables d'environnement pour les price IDs
11
+ STRIPE_PRICE_IDS = {
12
+ 'starter': settings.STRIPE_PRICE_ID_STARTER,
13
+ 'pro': settings.STRIPE_PRICE_ID_PRO,
14
+ 'business': settings.STRIPE_PRICE_ID_BUSINESS
15
+ }
16
+
17
+ class SubscriptionRequest(BaseModel):
18
+ plan_id: str
19
+ user_id: str
20
+
21
+ class PaymentSuccessRequest(BaseModel):
22
+ session_id: str
23
+
24
+ @router.post("/create-subscription")
25
+ async def create_subscription(request: SubscriptionRequest):
26
+ try:
27
+ price_id = STRIPE_PRICE_IDS.get(request.plan_id)
28
+ print(f"Plan ID reçu: {request.plan_id}")
29
+ print(f"Price ID trouvé: {price_id}")
30
+ print(f"Mode Stripe: {stripe.api_key.startswith('sk_test_') and 'TEST' or 'LIVE'}")
31
+
32
+ if not price_id:
33
+ raise HTTPException(status_code=400, detail=f"Plan non trouvé: {request.plan_id}")
34
+
35
+ session = stripe.checkout.Session.create(
36
+ payment_method_types=['card'],
37
+ line_items=[{
38
+ 'price': price_id,
39
+ 'quantity': 1,
40
+ }],
41
+ mode='subscription',
42
+ success_url=f"{settings.FRONTEND_URL}/generate?session_id={{CHECKOUT_SESSION_ID}}",
43
+ cancel_url=f"{settings.FRONTEND_URL}/tokens",
44
+ metadata={
45
+ 'user_id': request.user_id,
46
+ 'plan_id': request.plan_id
47
+ }
48
+ )
49
+ return {"sessionId": session.id}
50
+ except Exception as e:
51
+ print(f"Erreur complète: {str(e)}")
52
+ raise HTTPException(status_code=400, detail=str(e))
53
+
54
+ @router.post("/webhook")
55
+ async def stripe_webhook(request: Request):
56
+ payload = await request.body()
57
+ sig_header = request.headers.get("stripe-signature")
58
+
59
+ try:
60
+ event = stripe.Webhook.construct_event(
61
+ payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
62
+ )
63
+
64
+ if event["type"] == "checkout.session.completed":
65
+ session = event["data"]["object"]
66
+ user_id = session["metadata"]["user_id"]
67
+ plan_id = session["metadata"]["plan_id"]
68
+
69
+ # Au lieu de mettre à jour Firebase, on renvoie les informations
70
+ return {
71
+ "status": "success",
72
+ "user_id": user_id,
73
+ "plan_id": plan_id
74
+ }
75
+
76
+ return {"status": "success"}
77
+ except Exception as e:
78
+ raise HTTPException(status_code=400, detail=str(e))
79
+
80
+ @router.post("/create-webhook")
81
+ async def create_webhook_endpoint():
82
+ try:
83
+ endpoint = stripe.WebhookEndpoint.create(
84
+ url=f"{settings.FRONTEND_URL}/api/webhook",
85
+ enabled_events=[
86
+ "checkout.session.completed",
87
+ "customer.subscription.created",
88
+ "customer.subscription.deleted",
89
+ "invoice.paid",
90
+ "invoice.payment_failed"
91
+ ],
92
+ description="Endpoint pour la gestion des abonnements"
93
+ )
94
+
95
+ # Sauvegarder la clé secrète dans les variables d'environnement
96
+ webhook_secret = endpoint.secret
97
+ return {
98
+ "status": "success",
99
+ "endpoint_id": endpoint.id,
100
+ "webhook_secret": webhook_secret # À stocker dans .env
101
+ }
102
+ except Exception as e:
103
+ raise HTTPException(status_code=400, detail=str(e))
104
+
105
+ @router.post("/payment-success")
106
+ async def handle_payment_success(request: PaymentSuccessRequest):
107
+ try:
108
+ print("=== Début du traitement payment-success ===")
109
+
110
+ # Récupérer la session Stripe
111
+ session = stripe.checkout.Session.retrieve(request.session_id)
112
+
113
+ # Vérifier que le paiement n'a pas déjà été traité
114
+ if session.metadata.get('processed') == 'true':
115
+ return {
116
+ "status": "already_processed",
117
+ "message": "Ce paiement a déjà été traité"
118
+ }
119
+
120
+ # Vérifier que le paiement est bien complété
121
+ if session.payment_status != 'paid':
122
+ raise HTTPException(
123
+ status_code=400,
124
+ detail="Le paiement n'est pas complété"
125
+ )
126
+
127
+ user_id = session.metadata.get('user_id')
128
+ plan_id = session.metadata.get('plan_id')
129
+
130
+ if not user_id or not plan_id:
131
+ raise HTTPException(
132
+ status_code=400,
133
+ detail="Informations utilisateur manquantes"
134
+ )
135
+
136
+ # Marquer la session comme traitée
137
+ stripe.checkout.Session.modify(
138
+ session.id,
139
+ metadata={'processed': 'true'}
140
+ )
141
+
142
+ return {
143
+ "status": "success",
144
+ "user_id": user_id,
145
+ "plan_id": plan_id
146
+ }
147
+
148
+ except Exception as e:
149
+ print(f"Erreur lors du traitement: {str(e)}")
150
+ raise HTTPException(status_code=400, detail=str(e))