habulaj commited on
Commit
ed0d9dd
·
verified ·
1 Parent(s): 15a58fb

Update routes/subscription.py

Browse files
Files changed (1) hide show
  1. routes/subscription.py +23 -48
routes/subscription.py CHANGED
@@ -13,54 +13,22 @@ stripe.api_key = "sk_test_51N6K5JB9VMe0qzbOjlJvMEsfdQyrFgV49vRaeErtmhrzHV3Cu3f5j
13
  stripe.api_version = "2023-10-16"
14
 
15
  ### **DATA MODELS** ###
16
- class PriceRequest(BaseModel):
17
- amount: int # Value in cents (e.g., R$25.00 -> 2500)
18
- stylist_name: str # Name of the stylist
19
-
20
  class SubscriptionRequest(BaseModel):
21
  user_id: str
22
  stylist_id: str # This must be the Stripe connected account ID (acct_xxxxx)
23
- price_id: str # Now using a pre-created price
 
24
 
25
  class CancelSubscriptionRequest(BaseModel):
26
  subscription_id: str
27
 
28
- ### **1️⃣ CREATE DYNAMIC PRICE** ###
29
- @router.post("/create_price")
30
- def create_price(data: PriceRequest):
31
  try:
32
  product_name = f"{data.stylist_name}'s Subscription"
33
  product_description = f"Monthly plan to access exclusive services from {data.stylist_name}."
34
 
35
- product = stripe.Product.create(
36
- name=product_name,
37
- description=product_description,
38
- )
39
-
40
- price = stripe.Price.create(
41
- unit_amount=data.amount,
42
- currency="brl", # Changed to BRL
43
- recurring={"interval": "month"},
44
- product=product.id,
45
- )
46
-
47
- return {
48
- "message": "Price created successfully!",
49
- "price_id": price.id,
50
- "product_id": product.id,
51
- "product_name": product_name,
52
- "product_description": product_description,
53
- "amount": data.amount / 100, # Converting cents to BRL
54
- "currency": "BRL",
55
- }
56
- except Exception as e:
57
- logger.error(f"Error creating price: {e}")
58
- raise HTTPException(status_code=500, detail="Error creating price.")
59
-
60
- ### **2️⃣ CREATE CHECKOUT SESSION** ###
61
- @router.post("/create_checkout_session")
62
- def create_checkout_session(data: SubscriptionRequest):
63
- try:
64
  session = stripe.checkout.Session.create(
65
  success_url="https://yourdomain.com/success",
66
  cancel_url="https://yourdomain.com/cancel",
@@ -68,7 +36,15 @@ def create_checkout_session(data: SubscriptionRequest):
68
  mode="subscription",
69
  line_items=[
70
  {
71
- "price": data.price_id,
 
 
 
 
 
 
 
 
72
  "quantity": 1
73
  }
74
  ],
@@ -88,7 +64,7 @@ def create_checkout_session(data: SubscriptionRequest):
88
  logger.error(f"Error creating checkout session: {e}")
89
  raise HTTPException(status_code=500, detail="Error creating checkout session.")
90
 
91
- ### **3️⃣ WEBHOOK TO PROCESS PAYMENTS & TRANSFER FUNDS** ###
92
  @router.post("/webhook")
93
  async def stripe_webhook(request: Request):
94
  payload = await request.body()
@@ -105,12 +81,11 @@ async def stripe_webhook(request: Request):
105
 
106
  if event["type"] == "invoice.payment_succeeded":
107
  invoice = event["data"]["object"]
108
- subscription_id = invoice.get("subscription") # Get subscription ID
109
 
110
- # Retrieve subscription to get metadata
111
  subscription = stripe.Subscription.retrieve(subscription_id)
112
  user_id = subscription.metadata.get("user_id")
113
- stylist_id = subscription.metadata.get("stylist_id") # Must be a Stripe connected account ID
114
 
115
  amount = invoice["amount_paid"]
116
  stylist_share = int(amount * 0.8) # 80% for stylist
@@ -119,9 +94,9 @@ async def stripe_webhook(request: Request):
119
  # 🔹 Transfer the funds to the stylist
120
  try:
121
  transfer = stripe.Transfer.create(
122
- amount=stylist_share, # Value in CENTS
123
- currency="brl", # Changed to BRL
124
- destination=stylist_id, # The Stripe Connected Account ID (acct_xxxx)
125
  description=f"Payment for stylist {stylist_id} - Subscription",
126
  )
127
  logger.info(f"💸 Transfer successful: R${stylist_share / 100:.2f} BRL to {stylist_id}")
@@ -134,7 +109,7 @@ async def stripe_webhook(request: Request):
134
  "status": "Payment processed successfully!",
135
  "user_id": user_id,
136
  "stylist_id": stylist_id,
137
- "total_paid": amount / 100, # Convert cents to BRL
138
  "stylist_share": stylist_share / 100,
139
  "platform_share": platform_share / 100,
140
  "transfer_status": transfer_status
@@ -142,13 +117,13 @@ async def stripe_webhook(request: Request):
142
 
143
  return {"status": "Event received, no action needed."}
144
 
145
- ### **4️⃣ CANCEL SUBSCRIPTION** ###
146
  @router.post("/cancel_subscription")
147
  def cancel_subscription(data: CancelSubscriptionRequest):
148
  try:
149
  subscription = stripe.Subscription.modify(
150
  data.subscription_id,
151
- cancel_at_period_end=True, # Cancels at the end of the current cycle
152
  )
153
  return {"status": "Subscription will be canceled at period end"}
154
  except Exception as e:
 
13
  stripe.api_version = "2023-10-16"
14
 
15
  ### **DATA MODELS** ###
 
 
 
 
16
  class SubscriptionRequest(BaseModel):
17
  user_id: str
18
  stylist_id: str # This must be the Stripe connected account ID (acct_xxxxx)
19
+ amount: int # Value in cents (e.g., R$25.00 -> 2500)
20
+ stylist_name: str # Name of the stylist
21
 
22
  class CancelSubscriptionRequest(BaseModel):
23
  subscription_id: str
24
 
25
+ ### **CREATE CHECKOUT SESSION** ###
26
+ @router.post("/create_checkout_session")
27
+ def create_checkout_session(data: SubscriptionRequest):
28
  try:
29
  product_name = f"{data.stylist_name}'s Subscription"
30
  product_description = f"Monthly plan to access exclusive services from {data.stylist_name}."
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  session = stripe.checkout.Session.create(
33
  success_url="https://yourdomain.com/success",
34
  cancel_url="https://yourdomain.com/cancel",
 
36
  mode="subscription",
37
  line_items=[
38
  {
39
+ "price_data": {
40
+ "currency": "brl",
41
+ "product_data": {
42
+ "name": product_name,
43
+ "description": product_description
44
+ },
45
+ "unit_amount": data.amount,
46
+ "recurring": {"interval": "month"}
47
+ },
48
  "quantity": 1
49
  }
50
  ],
 
64
  logger.error(f"Error creating checkout session: {e}")
65
  raise HTTPException(status_code=500, detail="Error creating checkout session.")
66
 
67
+ ### **WEBHOOK TO PROCESS PAYMENTS & TRANSFER FUNDS** ###
68
  @router.post("/webhook")
69
  async def stripe_webhook(request: Request):
70
  payload = await request.body()
 
81
 
82
  if event["type"] == "invoice.payment_succeeded":
83
  invoice = event["data"]["object"]
84
+ subscription_id = invoice.get("subscription")
85
 
 
86
  subscription = stripe.Subscription.retrieve(subscription_id)
87
  user_id = subscription.metadata.get("user_id")
88
+ stylist_id = subscription.metadata.get("stylist_id")
89
 
90
  amount = invoice["amount_paid"]
91
  stylist_share = int(amount * 0.8) # 80% for stylist
 
94
  # 🔹 Transfer the funds to the stylist
95
  try:
96
  transfer = stripe.Transfer.create(
97
+ amount=stylist_share,
98
+ currency="brl",
99
+ destination=stylist_id,
100
  description=f"Payment for stylist {stylist_id} - Subscription",
101
  )
102
  logger.info(f"💸 Transfer successful: R${stylist_share / 100:.2f} BRL to {stylist_id}")
 
109
  "status": "Payment processed successfully!",
110
  "user_id": user_id,
111
  "stylist_id": stylist_id,
112
+ "total_paid": amount / 100,
113
  "stylist_share": stylist_share / 100,
114
  "platform_share": platform_share / 100,
115
  "transfer_status": transfer_status
 
117
 
118
  return {"status": "Event received, no action needed."}
119
 
120
+ ### **CANCEL SUBSCRIPTION** ###
121
  @router.post("/cancel_subscription")
122
  def cancel_subscription(data: CancelSubscriptionRequest):
123
  try:
124
  subscription = stripe.Subscription.modify(
125
  data.subscription_id,
126
+ cancel_at_period_end=True,
127
  )
128
  return {"status": "Subscription will be canceled at period end"}
129
  except Exception as e: