Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 802225d

Browse files
handle plan upgrade flow
1 parent e1389b3 commit 802225d

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

billing/views.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ def customer_created(self, customer: stripe.Customer) -> None:
296296

297297
# handler for Stripe event customer.subscription.created
298298
def customer_subscription_created(self, subscription: stripe.Subscription) -> None:
299+
log.info(
300+
"Customer subscription created",
301+
extra=dict(
302+
customer_id=subscription["customer"], subscription_id=subscription["id"]
303+
),
304+
)
299305
sub_item_plan_id = subscription.plan.id
300306

301307
if not sub_item_plan_id:
@@ -332,11 +338,31 @@ def customer_subscription_created(self, subscription: stripe.Subscription) -> No
332338
quantity=subscription.quantity,
333339
),
334340
)
341+
# add the subscription_id and customer_id to the owner
335342
owner = Owner.objects.get(ownerid=subscription.metadata.get("obo_organization"))
336343
owner.stripe_subscription_id = subscription.id
337344
owner.stripe_customer_id = subscription.customer
338345
owner.save()
339346

347+
# check if the subscription has a pending_update attribute, if so, don't upgrade the plan yet
348+
print("subscription what are you", subscription)
349+
# Check if subscription has a default payment method
350+
has_default_payment = subscription.default_payment_method is not None
351+
352+
# If no default payment, check for any pending verification methods
353+
if not has_default_payment:
354+
payment_methods = get_unverified_payment_methods(subscription.customer)
355+
if payment_methods:
356+
log.info(
357+
"Subscription has pending payment verification",
358+
extra=dict(
359+
subscription_id=subscription.id,
360+
customer_id=subscription.customer,
361+
payment_methods=payment_methods,
362+
),
363+
)
364+
return
365+
340366
plan_service = PlanService(current_org=owner)
341367
plan_service.expire_trial_when_upgrading()
342368

@@ -356,6 +382,13 @@ def customer_subscription_created(self, subscription: stripe.Subscription) -> No
356382

357383
# handler for Stripe event customer.subscription.updated
358384
def customer_subscription_updated(self, subscription: stripe.Subscription) -> None:
385+
log.info(
386+
"Customer subscription updated",
387+
extra=dict(
388+
customer_id=subscription["customer"], subscription_id=subscription["id"]
389+
),
390+
)
391+
359392
owners: QuerySet[Owner] = Owner.objects.filter(
360393
stripe_subscription_id=subscription.id,
361394
stripe_customer_id=subscription.customer,
@@ -371,6 +404,25 @@ def customer_subscription_updated(self, subscription: stripe.Subscription) -> No
371404
)
372405
return
373406

407+
# check if the subscription has a pending_update attribute, if so, don't upgrade the plan yet
408+
print("subscription what are you", subscription)
409+
# Check if subscription has a default payment method
410+
has_default_payment = subscription.default_payment_method is not None
411+
412+
# If no default payment, check for any pending verification methods
413+
if not has_default_payment:
414+
payment_methods = get_unverified_payment_methods(subscription.customer)
415+
if payment_methods:
416+
log.info(
417+
"Subscription has pending payment verification",
418+
extra=dict(
419+
subscription_id=subscription.id,
420+
customer_id=subscription.customer,
421+
payment_methods=payment_methods,
422+
),
423+
)
424+
return
425+
374426
indication_of_payment_failure = getattr(subscription, "pending_update", None)
375427
if indication_of_payment_failure:
376428
# payment failed, raise this to user by setting as delinquent

services/billing.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,51 @@ def update_plan(self, owner, desired_plan):
887887
plan_service.set_default_plan_data()
888888
elif desired_plan["value"] in PAID_PLANS:
889889
if owner.stripe_subscription_id is not None:
890+
# If there's already a pending subscription, return its checkout session
891+
subscription = self.payment_service.get_subscription(owner)
892+
if subscription and subscription.status == "incomplete":
893+
# Get the latest invoice and payment intent for this subscription
894+
latest_invoice = subscription.latest_invoice
895+
if latest_invoice and latest_invoice.payment_intent:
896+
payment_intent = stripe.PaymentIntent.retrieve(
897+
latest_invoice.payment_intent
898+
)
899+
# Check if payment intent requires verification
900+
if payment_intent.status == "requires_action":
901+
log.info(
902+
"Subscription has pending payment verification",
903+
extra=dict(
904+
subscription_id=subscription.id,
905+
payment_intent_id=payment_intent.id,
906+
payment_intent_status=payment_intent.status,
907+
),
908+
)
909+
910+
# Delete the existing subscription and payment intent
911+
try:
912+
stripe.PaymentIntent.cancel(payment_intent.id)
913+
stripe.Subscription.delete(subscription.id)
914+
log.info(
915+
"Deleted incomplete subscription and payment intent",
916+
extra=dict(
917+
subscription_id=subscription.id,
918+
payment_intent_id=payment_intent.id,
919+
),
920+
)
921+
except Exception as e:
922+
log.error(
923+
"Failed to delete subscription and payment intent",
924+
extra=dict(
925+
subscription_id=subscription.id,
926+
payment_intent_id=payment_intent.id,
927+
error=str(e),
928+
),
929+
)
930+
931+
return self.payment_service.create_checkout_session(
932+
owner, desired_plan
933+
)
934+
890935
self.payment_service.modify_subscription(owner, desired_plan)
891936
else:
892937
return self.payment_service.create_checkout_session(owner, desired_plan)

0 commit comments

Comments
 (0)