Update routes/subscription.py
Browse files- routes/subscription.py +14 -24
routes/subscription.py
CHANGED
@@ -41,7 +41,7 @@ class CreatePriceRequest(BaseModel):
|
|
41 |
|
42 |
def verify_token(user_token: str) -> str:
|
43 |
"""
|
44 |
-
Valida o token JWT no Supabase e retorna o
|
45 |
"""
|
46 |
headers = {
|
47 |
"Authorization": f"Bearer {user_token}",
|
@@ -69,7 +69,7 @@ async def create_price(
|
|
69 |
if not user_token:
|
70 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
71 |
|
72 |
-
# 🔹 1. Validar o token e obter
|
73 |
user_id = verify_token(user_token)
|
74 |
|
75 |
amount = data.amount
|
@@ -77,7 +77,7 @@ async def create_price(
|
|
77 |
if not amount:
|
78 |
raise HTTPException(status_code=400, detail="Amount is required")
|
79 |
|
80 |
-
# 🔹 2. Buscar
|
81 |
supabase_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
|
82 |
response = requests.get(supabase_url, headers=SUPABASE_HEADERS)
|
83 |
user_data = response.json()
|
@@ -88,7 +88,7 @@ async def create_price(
|
|
88 |
user = user_data[0]
|
89 |
existing_price_id = user.get("price_id")
|
90 |
|
91 |
-
# 🔹 3. Atualizar ou criar um novo
|
92 |
updated_price_id = None
|
93 |
|
94 |
if existing_price_id:
|
@@ -124,7 +124,7 @@ async def create_price(
|
|
124 |
stripe.Price.modify(existing_price_id, active=False)
|
125 |
logger.info(f"🚫 Price {existing_price_id} deactivated.")
|
126 |
|
127 |
-
# 🔹 5. Atualizar Supabase com o novo
|
128 |
update_response = requests.patch(
|
129 |
supabase_url,
|
130 |
headers=SUPABASE_HEADERS,
|
@@ -149,19 +149,16 @@ def create_checkout_session(
|
|
149 |
if not user_token:
|
150 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
151 |
|
152 |
-
# 🔹 1. Validar o token e obter
|
153 |
user_id = verify_token(user_token)
|
154 |
-
logger.info(f"✅ Token verificado. user_id do token: {user_id}")
|
155 |
|
156 |
# 🔹 2. Buscar estilista no Supabase
|
157 |
response = requests.get(
|
158 |
f"{SUPABASE_URL}/rest/v1/User?id=eq.{data.id}",
|
159 |
headers=SUPABASE_HEADERS
|
160 |
)
|
161 |
-
|
162 |
stylist_data = response.json()
|
163 |
-
logger.info(f"📌 Resposta da API (Stylist): {stylist_data}")
|
164 |
-
|
165 |
if not stylist_data:
|
166 |
raise HTTPException(status_code=404, detail="Stylist not found")
|
167 |
|
@@ -172,8 +169,6 @@ def create_checkout_session(
|
|
172 |
if not consultations or not stylist_stripe_id:
|
173 |
raise HTTPException(status_code=400, detail="Stylist profile is incomplete")
|
174 |
|
175 |
-
logger.info(f"✅ Estilista encontrado. stripe_id do estilista (conta Connect): {stylist_stripe_id}")
|
176 |
-
|
177 |
# 🔹 3. Buscar stripe_id e price_id do usuário autenticado
|
178 |
response_user = requests.get(
|
179 |
f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
|
@@ -181,13 +176,11 @@ def create_checkout_session(
|
|
181 |
)
|
182 |
|
183 |
user_data = response_user.json()
|
184 |
-
logger.info(f"📌 Resposta da API (User): {user_data}")
|
185 |
-
|
186 |
if not user_data:
|
187 |
raise HTTPException(status_code=404, detail="User not found")
|
188 |
|
189 |
user = user_data[0]
|
190 |
-
user_stripe_id = user.get("stripe_id")
|
191 |
price_id = user.get("price_id")
|
192 |
|
193 |
if not user_stripe_id:
|
@@ -195,38 +188,35 @@ def create_checkout_session(
|
|
195 |
if not price_id:
|
196 |
raise HTTPException(status_code=400, detail="User does not have a valid price ID")
|
197 |
|
198 |
-
logger.info(f"✅ Usuário autenticado encontrado. stripe_id do usuário (customer): {user_stripe_id}, price_id: {price_id}")
|
199 |
-
|
200 |
# 🔹 4. Criar Checkout Session no Stripe
|
201 |
session = stripe.checkout.Session.create(
|
202 |
success_url="https://yourdomain.com/success",
|
203 |
cancel_url="https://yourdomain.com/cancel",
|
204 |
payment_method_types=["card"],
|
205 |
mode="subscription",
|
206 |
-
customer=user_stripe_id,
|
207 |
line_items=[
|
208 |
{
|
209 |
"price": price_id,
|
210 |
-
"quantity": 1
|
|
|
211 |
}
|
212 |
],
|
213 |
metadata={
|
214 |
-
"stylist_id": stylist_stripe_id,
|
215 |
"user_id": user_id,
|
216 |
"consultations_per_month": consultations
|
217 |
}
|
218 |
)
|
219 |
|
220 |
-
logger.info(f"✅ Checkout Session criada com sucesso! URL: {session.url}")
|
221 |
-
|
222 |
return {
|
223 |
"message": "Checkout session created successfully!",
|
224 |
"checkout_url": session.url
|
225 |
}
|
226 |
|
227 |
except Exception as e:
|
228 |
-
logger.error(f"
|
229 |
-
raise HTTPException(status_code=500, detail=
|
230 |
|
231 |
### **WEBHOOK PARA PROCESSAR PAGAMENTOS**
|
232 |
@router.post("/webhook")
|
|
|
41 |
|
42 |
def verify_token(user_token: str) -> str:
|
43 |
"""
|
44 |
+
Valida o token JWT no Supabase e retorna o user_id se for válido.
|
45 |
"""
|
46 |
headers = {
|
47 |
"Authorization": f"Bearer {user_token}",
|
|
|
69 |
if not user_token:
|
70 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
71 |
|
72 |
+
# 🔹 1. Validar o token e obter user_id
|
73 |
user_id = verify_token(user_token)
|
74 |
|
75 |
amount = data.amount
|
|
|
77 |
if not amount:
|
78 |
raise HTTPException(status_code=400, detail="Amount is required")
|
79 |
|
80 |
+
# 🔹 2. Buscar price_id do usuário no Supabase
|
81 |
supabase_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
|
82 |
response = requests.get(supabase_url, headers=SUPABASE_HEADERS)
|
83 |
user_data = response.json()
|
|
|
88 |
user = user_data[0]
|
89 |
existing_price_id = user.get("price_id")
|
90 |
|
91 |
+
# 🔹 3. Atualizar ou criar um novo price_id
|
92 |
updated_price_id = None
|
93 |
|
94 |
if existing_price_id:
|
|
|
124 |
stripe.Price.modify(existing_price_id, active=False)
|
125 |
logger.info(f"🚫 Price {existing_price_id} deactivated.")
|
126 |
|
127 |
+
# 🔹 5. Atualizar Supabase com o novo price_id
|
128 |
update_response = requests.patch(
|
129 |
supabase_url,
|
130 |
headers=SUPABASE_HEADERS,
|
|
|
149 |
if not user_token:
|
150 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
151 |
|
152 |
+
# 🔹 1. Validar o token e obter user_id
|
153 |
user_id = verify_token(user_token)
|
|
|
154 |
|
155 |
# 🔹 2. Buscar estilista no Supabase
|
156 |
response = requests.get(
|
157 |
f"{SUPABASE_URL}/rest/v1/User?id=eq.{data.id}",
|
158 |
headers=SUPABASE_HEADERS
|
159 |
)
|
160 |
+
|
161 |
stylist_data = response.json()
|
|
|
|
|
162 |
if not stylist_data:
|
163 |
raise HTTPException(status_code=404, detail="Stylist not found")
|
164 |
|
|
|
169 |
if not consultations or not stylist_stripe_id:
|
170 |
raise HTTPException(status_code=400, detail="Stylist profile is incomplete")
|
171 |
|
|
|
|
|
172 |
# 🔹 3. Buscar stripe_id e price_id do usuário autenticado
|
173 |
response_user = requests.get(
|
174 |
f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
|
|
|
176 |
)
|
177 |
|
178 |
user_data = response_user.json()
|
|
|
|
|
179 |
if not user_data:
|
180 |
raise HTTPException(status_code=404, detail="User not found")
|
181 |
|
182 |
user = user_data[0]
|
183 |
+
user_stripe_id = user.get("stripe_id")
|
184 |
price_id = user.get("price_id")
|
185 |
|
186 |
if not user_stripe_id:
|
|
|
188 |
if not price_id:
|
189 |
raise HTTPException(status_code=400, detail="User does not have a valid price ID")
|
190 |
|
|
|
|
|
191 |
# 🔹 4. Criar Checkout Session no Stripe
|
192 |
session = stripe.checkout.Session.create(
|
193 |
success_url="https://yourdomain.com/success",
|
194 |
cancel_url="https://yourdomain.com/cancel",
|
195 |
payment_method_types=["card"],
|
196 |
mode="subscription",
|
197 |
+
customer=user_stripe_id,
|
198 |
line_items=[
|
199 |
{
|
200 |
"price": price_id,
|
201 |
+
"quantity": 1,
|
202 |
+
"description": "Assinatura personalizada para usuário"
|
203 |
}
|
204 |
],
|
205 |
metadata={
|
206 |
+
"stylist_id": stylist_stripe_id,
|
207 |
"user_id": user_id,
|
208 |
"consultations_per_month": consultations
|
209 |
}
|
210 |
)
|
211 |
|
|
|
|
|
212 |
return {
|
213 |
"message": "Checkout session created successfully!",
|
214 |
"checkout_url": session.url
|
215 |
}
|
216 |
|
217 |
except Exception as e:
|
218 |
+
logger.error(f"Error creating checkout session: {e}")
|
219 |
+
raise HTTPException(status_code=500, detail="Error creating checkout session.")
|
220 |
|
221 |
### **WEBHOOK PARA PROCESSAR PAGAMENTOS**
|
222 |
@router.post("/webhook")
|