Update routes/subscription.py
Browse files- routes/subscription.py +24 -23
routes/subscription.py
CHANGED
@@ -837,7 +837,6 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
837 |
if not user_token:
|
838 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
839 |
|
840 |
-
# 1. Validar o token e obter user_id
|
841 |
user_id = verify_token(user_token)
|
842 |
logger.info(f"🔹 User verified. user_id: {user_id}")
|
843 |
|
@@ -845,13 +844,11 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
845 |
emergency_price = data.emergency_price
|
846 |
consultations = data.consultations
|
847 |
|
848 |
-
# 2. Verificar se os valores estão dentro dos limites permitidos
|
849 |
if not (500 <= amount <= 99900):
|
850 |
raise HTTPException(status_code=400, detail="Amount must be between $5 and $999")
|
851 |
if not (500 <= emergency_price <= 99900):
|
852 |
raise HTTPException(status_code=400, detail="Emergency price must be between $5 and $999")
|
853 |
|
854 |
-
# 3. Consultations precisa ser 0 obrigatoriamente se não for definido
|
855 |
if consultations is None:
|
856 |
consultations = 0
|
857 |
elif consultations < 0:
|
@@ -859,7 +856,6 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
859 |
|
860 |
logger.info(f"🔹 Validated amounts: amount = {amount}, emergency_price = {emergency_price}, consultations = {consultations}")
|
861 |
|
862 |
-
# 4. Buscar price_id, name, avatar e bio do usuário no Supabase
|
863 |
supabase_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
|
864 |
headers = {
|
865 |
"Authorization": f"Bearer {user_token}",
|
@@ -880,22 +876,19 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
880 |
user_full_name = user.get("name", "Unknown User")
|
881 |
user_avatar = user.get("avatar", None)
|
882 |
|
883 |
-
# Criar nome abreviado do usuário
|
884 |
name_parts = user_full_name.split()
|
885 |
if len(name_parts) > 1:
|
886 |
abbreviated_name = f"{name_parts[0]} {name_parts[1][0]}."
|
887 |
else:
|
888 |
abbreviated_name = name_parts[0]
|
889 |
-
|
890 |
product_name = f"{abbreviated_name} Subscription"
|
891 |
-
|
892 |
logger.info(f"🔹 Existing price_id: {existing_price_id}, user_name: {abbreviated_name}")
|
893 |
|
894 |
-
# 5. Criar produto no Stripe
|
895 |
product_data = {
|
896 |
"name": product_name,
|
897 |
}
|
898 |
-
|
899 |
if user_avatar:
|
900 |
product_data["images"] = [user_avatar]
|
901 |
|
@@ -903,7 +896,6 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
903 |
product_id = product.id
|
904 |
logger.info(f"✅ New product created: {product_id}")
|
905 |
|
906 |
-
# 6. Criar novo preço no Stripe
|
907 |
price = stripe.Price.create(
|
908 |
unit_amount=amount,
|
909 |
currency="brl",
|
@@ -913,50 +905,59 @@ async def create_price(data: CreatePriceRequest, user_token: str = Header(None,
|
|
913 |
new_price_id = price.id
|
914 |
logger.info(f"✅ New price created: {new_price_id}")
|
915 |
|
916 |
-
#
|
|
|
|
|
917 |
if existing_price_id:
|
918 |
subscriptions = stripe.Subscription.list(status="active")
|
919 |
for sub in subscriptions.auto_paging_iter():
|
920 |
if sub["items"]["data"][0]["price"]["id"] == existing_price_id:
|
921 |
-
|
|
|
|
|
|
|
922 |
stripe.Subscription.modify(sub.id, cancel_at_period_end=True)
|
923 |
-
# Aplicar o novo preço na próxima fatura
|
924 |
stripe.Subscription.modify(
|
925 |
sub.id,
|
926 |
items=[{
|
927 |
"id": sub["items"]["data"][0]["id"],
|
928 |
"price": new_price_id
|
929 |
}],
|
930 |
-
proration_behavior="none"
|
931 |
)
|
932 |
-
logger.info(f"🔹 Subscription {sub.id}
|
|
|
|
|
933 |
|
934 |
-
# 8. Atualizar Supabase com o novo price_id
|
935 |
update_data = {
|
936 |
"price_id": new_price_id,
|
937 |
"price": amount,
|
938 |
"emergency_price": emergency_price,
|
939 |
"consultations": consultations
|
940 |
}
|
941 |
-
|
942 |
update_headers = {
|
943 |
"Authorization": f"Bearer {user_token}",
|
944 |
"apikey": SUPABASE_KEY,
|
945 |
"Content-Type": "application/json"
|
946 |
}
|
947 |
-
|
948 |
update_response = requests.patch(supabase_url, headers=update_headers, json=update_data)
|
949 |
-
|
950 |
if update_response.status_code not in [200, 204]:
|
951 |
raise HTTPException(status_code=500, detail=f"Failed to update Supabase: {update_response.text}")
|
952 |
-
|
953 |
-
logger.info(f"✅ Successfully updated user {user_id} with new price_id
|
954 |
-
return {
|
|
|
|
|
|
|
|
|
955 |
|
956 |
except Exception as e:
|
957 |
logger.error(f"❌ Error creating price: {e}")
|
958 |
raise HTTPException(status_code=500, detail=f"Error creating price: {str(e)}")
|
959 |
-
|
960 |
@router.post("/emergency_checkout_session")
|
961 |
def emergency_checkout_session(
|
962 |
data: EmergencyPaymentRequest,
|
|
|
837 |
if not user_token:
|
838 |
raise HTTPException(status_code=401, detail="Missing User-key header")
|
839 |
|
|
|
840 |
user_id = verify_token(user_token)
|
841 |
logger.info(f"🔹 User verified. user_id: {user_id}")
|
842 |
|
|
|
844 |
emergency_price = data.emergency_price
|
845 |
consultations = data.consultations
|
846 |
|
|
|
847 |
if not (500 <= amount <= 99900):
|
848 |
raise HTTPException(status_code=400, detail="Amount must be between $5 and $999")
|
849 |
if not (500 <= emergency_price <= 99900):
|
850 |
raise HTTPException(status_code=400, detail="Emergency price must be between $5 and $999")
|
851 |
|
|
|
852 |
if consultations is None:
|
853 |
consultations = 0
|
854 |
elif consultations < 0:
|
|
|
856 |
|
857 |
logger.info(f"🔹 Validated amounts: amount = {amount}, emergency_price = {emergency_price}, consultations = {consultations}")
|
858 |
|
|
|
859 |
supabase_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
|
860 |
headers = {
|
861 |
"Authorization": f"Bearer {user_token}",
|
|
|
876 |
user_full_name = user.get("name", "Unknown User")
|
877 |
user_avatar = user.get("avatar", None)
|
878 |
|
|
|
879 |
name_parts = user_full_name.split()
|
880 |
if len(name_parts) > 1:
|
881 |
abbreviated_name = f"{name_parts[0]} {name_parts[1][0]}."
|
882 |
else:
|
883 |
abbreviated_name = name_parts[0]
|
884 |
+
|
885 |
product_name = f"{abbreviated_name} Subscription"
|
|
|
886 |
logger.info(f"🔹 Existing price_id: {existing_price_id}, user_name: {abbreviated_name}")
|
887 |
|
|
|
888 |
product_data = {
|
889 |
"name": product_name,
|
890 |
}
|
891 |
+
|
892 |
if user_avatar:
|
893 |
product_data["images"] = [user_avatar]
|
894 |
|
|
|
896 |
product_id = product.id
|
897 |
logger.info(f"✅ New product created: {product_id}")
|
898 |
|
|
|
899 |
price = stripe.Price.create(
|
900 |
unit_amount=amount,
|
901 |
currency="brl",
|
|
|
905 |
new_price_id = price.id
|
906 |
logger.info(f"✅ New price created: {new_price_id}")
|
907 |
|
908 |
+
# Coletar e logar todos os clientes com assinatura ativa do preço antigo
|
909 |
+
affected_customers = []
|
910 |
+
|
911 |
if existing_price_id:
|
912 |
subscriptions = stripe.Subscription.list(status="active")
|
913 |
for sub in subscriptions.auto_paging_iter():
|
914 |
if sub["items"]["data"][0]["price"]["id"] == existing_price_id:
|
915 |
+
customer_id = sub["customer"]
|
916 |
+
affected_customers.append(customer_id)
|
917 |
+
|
918 |
+
# Cancelar no final do período e atualizar para novo preço
|
919 |
stripe.Subscription.modify(sub.id, cancel_at_period_end=True)
|
|
|
920 |
stripe.Subscription.modify(
|
921 |
sub.id,
|
922 |
items=[{
|
923 |
"id": sub["items"]["data"][0]["id"],
|
924 |
"price": new_price_id
|
925 |
}],
|
926 |
+
proration_behavior="none"
|
927 |
)
|
928 |
+
logger.info(f"🔹 Subscription {sub.id} updated with new price {new_price_id} (customer: {customer_id})")
|
929 |
+
|
930 |
+
logger.info(f"📢 Affected customer IDs with old price: {affected_customers}")
|
931 |
|
|
|
932 |
update_data = {
|
933 |
"price_id": new_price_id,
|
934 |
"price": amount,
|
935 |
"emergency_price": emergency_price,
|
936 |
"consultations": consultations
|
937 |
}
|
938 |
+
|
939 |
update_headers = {
|
940 |
"Authorization": f"Bearer {user_token}",
|
941 |
"apikey": SUPABASE_KEY,
|
942 |
"Content-Type": "application/json"
|
943 |
}
|
944 |
+
|
945 |
update_response = requests.patch(supabase_url, headers=update_headers, json=update_data)
|
946 |
+
|
947 |
if update_response.status_code not in [200, 204]:
|
948 |
raise HTTPException(status_code=500, detail=f"Failed to update Supabase: {update_response.text}")
|
949 |
+
|
950 |
+
logger.info(f"✅ Successfully updated user {user_id} with new price_id and prices")
|
951 |
+
return {
|
952 |
+
"message": "Price created and user updated successfully!",
|
953 |
+
"price_id": new_price_id,
|
954 |
+
"affected_customers": affected_customers
|
955 |
+
}
|
956 |
|
957 |
except Exception as e:
|
958 |
logger.error(f"❌ Error creating price: {e}")
|
959 |
raise HTTPException(status_code=500, detail=f"Error creating price: {str(e)}")
|
960 |
+
|
961 |
@router.post("/emergency_checkout_session")
|
962 |
def emergency_checkout_session(
|
963 |
data: EmergencyPaymentRequest,
|