connect / routes /subscription.py
habulaj's picture
Update routes/subscription.py
01ccbf3 verified
raw
history blame
5.95 kB
import stripe
import logging
import json
import os
import requests
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
router = APIRouter()
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
stripe.api_key = "sk_test_51N6K5JB9VMe0qzbOjlJvMEsfdQyrFgV49vRaeErtmhrzHV3Cu3f5jMDJmrhKdI5uqvpHubjkmwDQgMOtCEmz19t800AouH7W6g"
stripe.api_version = "2023-10-16"
# 🔥 Supabase Configuração
SUPABASE_URL = "https://ussxqnifefkgkaumjann.supabase.co"
SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InVzc3hxbmlmZWZrZ2thdW1qYW5uIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Mzc2NTE2MjMsImV4cCI6MjA1MzIyNzYyM30.SWb6lh3foBp8MrZaHpjt5kKkzXNyBYh3vgfayIM7bzs"
SUPABASE_HEADERS = {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/json"
}
class SubscriptionRequest(BaseModel):
user_id: str # ID do usuário que está comprando
stylist_id: str # ID do estilista (será usado para buscar os dados)
@router.post("/create_checkout_session")
def create_checkout_session(data: SubscriptionRequest):
try:
# 🔹 1. Buscar estilista no Supabase
response = requests.get(
f"{SUPABASE_URL}/rest/v1/User?id=eq.{data.stylist_id}",
headers=SUPABASE_HEADERS
)
stylist_data = response.json()
if not stylist_data:
raise HTTPException(status_code=404, detail="Stylist not found")
stylist = stylist_data[0] # Pega o primeiro resultado
# 🔹 2. Extrair informações do estilista
stylist_name = stylist["name"]
stylist_price = stylist["price"]
stylist_avatar = stylist["avatar"]
consultations = stylist["consultations"]
if not stylist_price or not consultations:
raise HTTPException(status_code=400, detail="Stylist has not set up their pricing or consultations")
# 🔹 3. Criar Checkout Session no Stripe
session = stripe.checkout.Session.create(
success_url="https://yourdomain.com/success",
cancel_url="https://yourdomain.com/cancel",
payment_method_types=["card"],
mode="subscription",
line_items=[
{
"price_data": {
"currency": "brl",
"product_data": {
"name": f"{stylist_name}'s Subscription",
"description": f"✔ {consultations} video call consultations per month",
"images": [stylist_avatar],
},
"unit_amount": stylist_price,
"recurring": {"interval": "month"}
},
"quantity": 1
}
],
subscription_data={
"metadata": {
"user_id": data.user_id,
"stylist_id": data.stylist_id,
"consultations_per_month": consultations
}
}
)
return {
"message": "Checkout session created successfully!",
"checkout_url": session.url
}
except Exception as e:
logger.error(f"Error creating checkout session: {e}")
raise HTTPException(status_code=500, detail="Error creating checkout session.")
### **WEBHOOK TO PROCESS PAYMENTS & TRANSFER FUNDS** ###
@router.post("/webhook")
async def stripe_webhook(request: Request):
payload = await request.body()
headers = dict(request.headers)
event = None
try:
event = stripe.Event.construct_from(json.loads(payload), stripe.api_key)
except Exception as e:
logger.error(f"⚠️ Error processing webhook: {e}")
raise HTTPException(status_code=400, detail="Webhook error")
logger.info(f"🔹 Event received: {event['type']}")
if event["type"] == "invoice.payment_succeeded":
invoice = event["data"]["object"]
subscription_id = invoice.get("subscription")
subscription = stripe.Subscription.retrieve(subscription_id)
user_id = subscription.metadata.get("user_id")
stylist_id = subscription.metadata.get("stylist_id")
amount = invoice["amount_paid"]
stylist_share = int(amount * 0.8) # 80% for stylist
platform_share = amount - stylist_share # 20% for platform
# 🔹 Transfer the funds to the stylist
try:
transfer = stripe.Transfer.create(
amount=stylist_share,
currency="brl",
destination=stylist_id,
description=f"Payment for stylist {stylist_id} - Subscription",
)
logger.info(f"💸 Transfer successful: R${stylist_share / 100:.2f} BRL to {stylist_id}")
transfer_status = "Completed"
except Exception as e:
logger.error(f"🚨 Transfer error for stylist {stylist_id}: {e}")
transfer_status = "Failed"
return {
"status": "Payment processed successfully!",
"user_id": user_id,
"stylist_id": stylist_id,
"total_paid": amount / 100,
"stylist_share": stylist_share / 100,
"platform_share": platform_share / 100,
"transfer_status": transfer_status
}
return {"status": "Event received, no action needed."}
### **CANCEL SUBSCRIPTION** ###
@router.post("/cancel_subscription")
def cancel_subscription(data: CancelSubscriptionRequest):
try:
subscription = stripe.Subscription.modify(
data.subscription_id,
cancel_at_period_end=True,
)
return {"status": "Subscription will be canceled at period end"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))