Update routes/subscription.py
Browse files- routes/subscription.py +48 -11
routes/subscription.py
CHANGED
@@ -41,7 +41,6 @@ SUPABASE_ROLE_HEADERS = {
|
|
41 |
|
42 |
class UpdateSubscriptionRequest(BaseModel):
|
43 |
subscription_id: str # ID da assinatura a ser modificada
|
44 |
-
new_price_id: str # Novo preço para a assinatura
|
45 |
|
46 |
class EmergencyPaymentRequest(BaseModel):
|
47 |
id: str # ID do estilista
|
@@ -61,6 +60,32 @@ class CreatePriceRequest(BaseModel):
|
|
61 |
emergency_price: int # Valor de emergência (ex: 500 para R$5,00)
|
62 |
consultations: int # Número de consultas (ex: 3)
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
def verify_token(user_token: str) -> str:
|
65 |
"""
|
66 |
Valida o token JWT no Supabase e retorna o user_id se for válido.
|
@@ -102,32 +127,44 @@ async def update_subscription(
|
|
102 |
if not user_token:
|
103 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
104 |
|
|
|
105 |
user_id = verify_token(user_token)
|
106 |
logger.info(f"🔹 User verified. user_id: {user_id}")
|
107 |
|
108 |
subscription_id = data.subscription_id
|
109 |
-
new_price_id = data.new_price_id
|
110 |
|
111 |
-
# 🔹
|
112 |
-
|
|
|
|
|
113 |
|
114 |
-
|
115 |
-
|
116 |
|
117 |
-
# 🔹
|
118 |
-
if
|
119 |
raise HTTPException(status_code=403, detail="You are not authorized to modify this subscription.")
|
120 |
|
121 |
-
# 🔹
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
if subscription.status == "canceled" or subscription.cancel_at_period_end:
|
123 |
stripe.Subscription.modify(subscription_id, cancel_at_period_end=False)
|
124 |
logger.info(f"✅ Subscription {subscription_id} reactivated.")
|
125 |
|
126 |
-
# 🔹
|
127 |
updated_subscription = stripe.Subscription.modify(
|
128 |
subscription_id,
|
129 |
items=[{"id": subscription["items"]["data"][0]["id"], "price": new_price_id}],
|
130 |
-
proration_behavior="none"
|
131 |
)
|
132 |
|
133 |
logger.info(f"✅ Subscription {subscription_id} updated to new price {new_price_id}")
|
|
|
41 |
|
42 |
class UpdateSubscriptionRequest(BaseModel):
|
43 |
subscription_id: str # ID da assinatura a ser modificada
|
|
|
44 |
|
45 |
class EmergencyPaymentRequest(BaseModel):
|
46 |
id: str # ID do estilista
|
|
|
60 |
emergency_price: int # Valor de emergência (ex: 500 para R$5,00)
|
61 |
consultations: int # Número de consultas (ex: 3)
|
62 |
|
63 |
+
def get_subscription_from_db(subscription_id: str):
|
64 |
+
"""
|
65 |
+
Busca a assinatura na tabela 'Subscriptions' com base no subscription_id.
|
66 |
+
"""
|
67 |
+
response = requests.get(
|
68 |
+
f"{SUPABASE_URL}/rest/v1/Subscriptions?sub_id=eq.{subscription_id}",
|
69 |
+
headers=SUPABASE_ROLE_HEADERS
|
70 |
+
)
|
71 |
+
|
72 |
+
if response.status_code == 200 and response.json():
|
73 |
+
return response.json()[0] # Retorna o primeiro resultado encontrado
|
74 |
+
return None
|
75 |
+
|
76 |
+
def get_new_price_id(stylist_id: str):
|
77 |
+
"""
|
78 |
+
Busca o novo price_id da tabela 'User' com base no stylist_id.
|
79 |
+
"""
|
80 |
+
response = requests.get(
|
81 |
+
f"{SUPABASE_URL}/rest/v1/User?id=eq.{stylist_id}",
|
82 |
+
headers=SUPABASE_ROLE_HEADERS
|
83 |
+
)
|
84 |
+
|
85 |
+
if response.status_code == 200 and response.json():
|
86 |
+
return response.json()[0].get("price_id")
|
87 |
+
return None
|
88 |
+
|
89 |
def verify_token(user_token: str) -> str:
|
90 |
"""
|
91 |
Valida o token JWT no Supabase e retorna o user_id se for válido.
|
|
|
127 |
if not user_token:
|
128 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
129 |
|
130 |
+
# 🔹 1. Validar o token e obter user_id
|
131 |
user_id = verify_token(user_token)
|
132 |
logger.info(f"🔹 User verified. user_id: {user_id}")
|
133 |
|
134 |
subscription_id = data.subscription_id
|
|
|
135 |
|
136 |
+
# 🔹 2. Buscar assinatura no banco de dados
|
137 |
+
subscription_db = get_subscription_from_db(subscription_id)
|
138 |
+
if not subscription_db:
|
139 |
+
raise HTTPException(status_code=404, detail="Subscription not found in database.")
|
140 |
|
141 |
+
stylist_id = subscription_db.get("stylist_id")
|
142 |
+
customer_id = subscription_db.get("customer_id")
|
143 |
|
144 |
+
# 🔹 3. Verificar se a assinatura pertence ao usuário logado
|
145 |
+
if customer_id != user_id:
|
146 |
raise HTTPException(status_code=403, detail="You are not authorized to modify this subscription.")
|
147 |
|
148 |
+
# 🔹 4. Obter o novo price_id da tabela User
|
149 |
+
new_price_id = get_new_price_id(stylist_id)
|
150 |
+
if not new_price_id:
|
151 |
+
raise HTTPException(status_code=404, detail="New price_id not found for stylist.")
|
152 |
+
|
153 |
+
# 🔹 5. Buscar assinatura no Stripe
|
154 |
+
subscription = stripe.Subscription.retrieve(subscription_id)
|
155 |
+
if not subscription:
|
156 |
+
raise HTTPException(status_code=404, detail="Subscription not found in Stripe.")
|
157 |
+
|
158 |
+
# 🔹 6. Reativar a assinatura se estiver cancelada
|
159 |
if subscription.status == "canceled" or subscription.cancel_at_period_end:
|
160 |
stripe.Subscription.modify(subscription_id, cancel_at_period_end=False)
|
161 |
logger.info(f"✅ Subscription {subscription_id} reactivated.")
|
162 |
|
163 |
+
# 🔹 7. Atualizar assinatura para o novo preço sem proration
|
164 |
updated_subscription = stripe.Subscription.modify(
|
165 |
subscription_id,
|
166 |
items=[{"id": subscription["items"]["data"][0]["id"], "price": new_price_id}],
|
167 |
+
proration_behavior="none"
|
168 |
)
|
169 |
|
170 |
logger.info(f"✅ Subscription {subscription_id} updated to new price {new_price_id}")
|