Update routes/subscription.py
Browse files- routes/subscription.py +25 -89
routes/subscription.py
CHANGED
@@ -140,6 +140,31 @@ async def create_price(
|
|
140 |
logger.error(f"❌ Error creating/updating price: {e}")
|
141 |
raise HTTPException(status_code=500, detail="Error creating/updating price.")
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
@router.post("/create_checkout_session")
|
144 |
def create_checkout_session(
|
145 |
data: SubscriptionRequest,
|
@@ -225,95 +250,6 @@ def create_checkout_session(
|
|
225 |
logger.error(f"Error creating checkout session: {e}")
|
226 |
raise HTTPException(status_code=500, detail="Error creating checkout session.")
|
227 |
|
228 |
-
### **WEBHOOK PARA PROCESSAR PAGAMENTOS**
|
229 |
-
@router.post("/webhook")
|
230 |
-
async def stripe_webhook(request: Request):
|
231 |
-
payload = await request.body()
|
232 |
-
headers = dict(request.headers)
|
233 |
-
event = None
|
234 |
-
|
235 |
-
try:
|
236 |
-
# Tenta construir o evento Stripe a partir do payload recebido
|
237 |
-
event = stripe.Event.construct_from(json.loads(payload), stripe.api_key)
|
238 |
-
except Exception as e:
|
239 |
-
logger.error(f"⚠️ Error processing webhook: {e}")
|
240 |
-
raise HTTPException(status_code=400, detail="Webhook error")
|
241 |
-
|
242 |
-
logger.info(f"🔹 Event received: {event['type']}")
|
243 |
-
|
244 |
-
if event["type"] == "checkout.session.completed":
|
245 |
-
session = event["data"]["object"]
|
246 |
-
payment_intent_id = session.get("payment_intent")
|
247 |
-
|
248 |
-
# Verifica se o PaymentIntent ID está presente
|
249 |
-
if not payment_intent_id:
|
250 |
-
logger.error("⚠️ No PaymentIntent ID found in session.")
|
251 |
-
# Verifica se a sessão de checkout tem um PaymentIntent associado
|
252 |
-
if "subscription" in session:
|
253 |
-
subscription_id = session["subscription"]
|
254 |
-
subscription = stripe.Subscription.retrieve(subscription_id)
|
255 |
-
payment_intent_id = subscription.latest_invoice.payment_intent
|
256 |
-
logger.info(f"🔹 Found PaymentIntent from subscription: {payment_intent_id}")
|
257 |
-
else:
|
258 |
-
raise HTTPException(status_code=400, detail="PaymentIntent ID missing.")
|
259 |
-
|
260 |
-
try:
|
261 |
-
# Recupera o PaymentIntent associado à sessão
|
262 |
-
payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
|
263 |
-
except Exception as e:
|
264 |
-
logger.error(f"⚠️ Error retrieving PaymentIntent: {e}")
|
265 |
-
raise HTTPException(status_code=400, detail="Error retrieving PaymentIntent")
|
266 |
-
|
267 |
-
# Extrai os dados do metadata
|
268 |
-
user_id = session.metadata.get("user_id") # ID do cliente
|
269 |
-
stylist_id = session.metadata.get("stylist_id") # ID do estilista no Stripe
|
270 |
-
consultations_per_month = session.metadata.get("consultations_per_month") # Consultas por mês
|
271 |
-
|
272 |
-
# Verifica o valor pago
|
273 |
-
amount = payment_intent["amount_received"]
|
274 |
-
|
275 |
-
# Define a divisão do pagamento entre a plataforma e o estilista
|
276 |
-
stylist_share = int(amount * 0.8) # 80% para o estilista
|
277 |
-
platform_share = amount - stylist_share # 20% para a plataforma
|
278 |
-
|
279 |
-
# Realizando a transferência para o estilista
|
280 |
-
try:
|
281 |
-
transfer = stripe.Transfer.create(
|
282 |
-
amount=stylist_share, # Montante para o estilista (80%)
|
283 |
-
currency="brl", # Moeda
|
284 |
-
destination=stylist_id, # Conta do estilista
|
285 |
-
description="Payment for styling service"
|
286 |
-
)
|
287 |
-
logger.info(f"💸 Transfer to stylist {stylist_id} successful: R${stylist_share / 100:.2f} BRL.")
|
288 |
-
except Exception as e:
|
289 |
-
logger.error(f"⚠️ Error transferring funds to stylist: {e}")
|
290 |
-
raise HTTPException(status_code=500, detail="Error transferring funds to stylist.")
|
291 |
-
|
292 |
-
# Transferência para a plataforma
|
293 |
-
try:
|
294 |
-
transfer_platform = stripe.Transfer.create(
|
295 |
-
amount=platform_share, # Montante para a plataforma (20%)
|
296 |
-
currency="brl", # Moeda
|
297 |
-
destination="your_platform_stripe_account_id", # Substitua com sua conta Stripe da plataforma
|
298 |
-
description="Platform share"
|
299 |
-
)
|
300 |
-
logger.info(f"💸 Transfer to platform successful: R${platform_share / 100:.2f} BRL.")
|
301 |
-
except Exception as e:
|
302 |
-
logger.error(f"⚠️ Error transferring funds to platform: {e}")
|
303 |
-
raise HTTPException(status_code=500, detail="Error transferring funds to platform.")
|
304 |
-
|
305 |
-
return {
|
306 |
-
"status": "Payment processed successfully!",
|
307 |
-
"user_id": user_id,
|
308 |
-
"stylist_id": stylist_id,
|
309 |
-
"consultations_per_month": consultations_per_month,
|
310 |
-
"total_paid": amount / 100,
|
311 |
-
"stylist_share": stylist_share / 100,
|
312 |
-
"platform_share": platform_share / 100
|
313 |
-
}
|
314 |
-
|
315 |
-
return {"status": "Event received, no action needed."}
|
316 |
-
|
317 |
### **CANCELAMENTO DE ASSINATURA**
|
318 |
class CancelSubscriptionRequest(BaseModel):
|
319 |
subscription_id: str
|
|
|
140 |
logger.error(f"❌ Error creating/updating price: {e}")
|
141 |
raise HTTPException(status_code=500, detail="Error creating/updating price.")
|
142 |
|
143 |
+
@router.post("/webhook")
|
144 |
+
async def stripe_webhook(request: Request):
|
145 |
+
try:
|
146 |
+
payload = await request.json()
|
147 |
+
|
148 |
+
event_type = payload.get("type")
|
149 |
+
if event_type == "invoice.payment_succeeded":
|
150 |
+
invoice = payload.get("data", {}).get("object", {})
|
151 |
+
amount_paid = invoice.get("amount_paid", 0) # Valor total pago (em centavos)
|
152 |
+
|
153 |
+
# Cálculo de divisão
|
154 |
+
stylist_amount = int(amount_paid * 0.8) # 80% para o estilista
|
155 |
+
platform_amount = int(amount_paid * 0.2) # 20% para a plataforma
|
156 |
+
|
157 |
+
# Logando os valores
|
158 |
+
logger.info(f"✅ Pagamento bem-sucedido! Valor total: R$ {amount_paid / 100:.2f}")
|
159 |
+
logger.info(f"💰 Estilista recebe: R$ {stylist_amount / 100:.2f}")
|
160 |
+
logger.info(f"🏛️ Plataforma fica com: R$ {platform_amount / 100:.2f}")
|
161 |
+
|
162 |
+
return {"status": "success"}
|
163 |
+
|
164 |
+
except Exception as e:
|
165 |
+
logger.error(f"❌ Erro no webhook: {str(e)}")
|
166 |
+
return {"status": "error", "message": str(e)}
|
167 |
+
|
168 |
@router.post("/create_checkout_session")
|
169 |
def create_checkout_session(
|
170 |
data: SubscriptionRequest,
|
|
|
250 |
logger.error(f"Error creating checkout session: {e}")
|
251 |
raise HTTPException(status_code=500, detail="Error creating checkout session.")
|
252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
### **CANCELAMENTO DE ASSINATURA**
|
254 |
class CancelSubscriptionRequest(BaseModel):
|
255 |
subscription_id: str
|