Skip to content

Commit

Permalink
handle plan upgrade flow
Browse files Browse the repository at this point in the history
  • Loading branch information
suejung-sentry committed Jan 24, 2025
1 parent e1389b3 commit 802225d
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
52 changes: 52 additions & 0 deletions billing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ def customer_created(self, customer: stripe.Customer) -> None:

# handler for Stripe event customer.subscription.created
def customer_subscription_created(self, subscription: stripe.Subscription) -> None:
log.info(
"Customer subscription created",
extra=dict(
customer_id=subscription["customer"], subscription_id=subscription["id"]
),
)
sub_item_plan_id = subscription.plan.id

if not sub_item_plan_id:
Expand Down Expand Up @@ -332,11 +338,31 @@ def customer_subscription_created(self, subscription: stripe.Subscription) -> No
quantity=subscription.quantity,
),
)
# add the subscription_id and customer_id to the owner
owner = Owner.objects.get(ownerid=subscription.metadata.get("obo_organization"))
owner.stripe_subscription_id = subscription.id
owner.stripe_customer_id = subscription.customer
owner.save()

# check if the subscription has a pending_update attribute, if so, don't upgrade the plan yet
print("subscription what are you", subscription)
# Check if subscription has a default payment method
has_default_payment = subscription.default_payment_method is not None

# If no default payment, check for any pending verification methods
if not has_default_payment:
payment_methods = get_unverified_payment_methods(subscription.customer)
if payment_methods:
log.info(

Check warning on line 356 in billing/views.py

View check run for this annotation

Codecov Notifications / codecov/patch

billing/views.py#L354-L356

Added lines #L354 - L356 were not covered by tests
"Subscription has pending payment verification",
extra=dict(
subscription_id=subscription.id,
customer_id=subscription.customer,
payment_methods=payment_methods,
),
)
return

Check warning on line 364 in billing/views.py

View check run for this annotation

Codecov Notifications / codecov/patch

billing/views.py#L364

Added line #L364 was not covered by tests

plan_service = PlanService(current_org=owner)
plan_service.expire_trial_when_upgrading()

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

# handler for Stripe event customer.subscription.updated
def customer_subscription_updated(self, subscription: stripe.Subscription) -> None:
log.info(
"Customer subscription updated",
extra=dict(
customer_id=subscription["customer"], subscription_id=subscription["id"]
),
)

owners: QuerySet[Owner] = Owner.objects.filter(
stripe_subscription_id=subscription.id,
stripe_customer_id=subscription.customer,
Expand All @@ -371,6 +404,25 @@ def customer_subscription_updated(self, subscription: stripe.Subscription) -> No
)
return

# check if the subscription has a pending_update attribute, if so, don't upgrade the plan yet
print("subscription what are you", subscription)
# Check if subscription has a default payment method
has_default_payment = subscription.default_payment_method is not None

# If no default payment, check for any pending verification methods
if not has_default_payment:
payment_methods = get_unverified_payment_methods(subscription.customer)
if payment_methods:
log.info(

Check warning on line 416 in billing/views.py

View check run for this annotation

Codecov Notifications / codecov/patch

billing/views.py#L414-L416

Added lines #L414 - L416 were not covered by tests
"Subscription has pending payment verification",
extra=dict(
subscription_id=subscription.id,
customer_id=subscription.customer,
payment_methods=payment_methods,
),
)
return

Check warning on line 424 in billing/views.py

View check run for this annotation

Codecov Notifications / codecov/patch

billing/views.py#L424

Added line #L424 was not covered by tests

indication_of_payment_failure = getattr(subscription, "pending_update", None)
if indication_of_payment_failure:
# payment failed, raise this to user by setting as delinquent
Expand Down
45 changes: 45 additions & 0 deletions services/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,51 @@ def update_plan(self, owner, desired_plan):
plan_service.set_default_plan_data()
elif desired_plan["value"] in PAID_PLANS:
if owner.stripe_subscription_id is not None:
# If there's already a pending subscription, return its checkout session
subscription = self.payment_service.get_subscription(owner)
if subscription and subscription.status == "incomplete":
# Get the latest invoice and payment intent for this subscription
latest_invoice = subscription.latest_invoice
if latest_invoice and latest_invoice.payment_intent:
payment_intent = stripe.PaymentIntent.retrieve(

Check warning on line 896 in services/billing.py

View check run for this annotation

Codecov Notifications / codecov/patch

services/billing.py#L894-L896

Added lines #L894 - L896 were not covered by tests
latest_invoice.payment_intent
)
# Check if payment intent requires verification
if payment_intent.status == "requires_action":
log.info(

Check warning on line 901 in services/billing.py

View check run for this annotation

Codecov Notifications / codecov/patch

services/billing.py#L900-L901

Added lines #L900 - L901 were not covered by tests
"Subscription has pending payment verification",
extra=dict(
subscription_id=subscription.id,
payment_intent_id=payment_intent.id,
payment_intent_status=payment_intent.status,
),
)

# Delete the existing subscription and payment intent
try:
stripe.PaymentIntent.cancel(payment_intent.id)
stripe.Subscription.delete(subscription.id)
log.info(

Check warning on line 914 in services/billing.py

View check run for this annotation

Codecov Notifications / codecov/patch

services/billing.py#L911-L914

Added lines #L911 - L914 were not covered by tests
"Deleted incomplete subscription and payment intent",
extra=dict(
subscription_id=subscription.id,
payment_intent_id=payment_intent.id,
),
)
except Exception as e:
log.error(

Check warning on line 922 in services/billing.py

View check run for this annotation

Codecov Notifications / codecov/patch

services/billing.py#L921-L922

Added lines #L921 - L922 were not covered by tests
"Failed to delete subscription and payment intent",
extra=dict(
subscription_id=subscription.id,
payment_intent_id=payment_intent.id,
error=str(e),
),
)

return self.payment_service.create_checkout_session(

Check warning on line 931 in services/billing.py

View check run for this annotation

Codecov Notifications / codecov/patch

services/billing.py#L931

Added line #L931 was not covered by tests
owner, desired_plan
)

self.payment_service.modify_subscription(owner, desired_plan)
else:
return self.payment_service.create_checkout_session(owner, desired_plan)
Expand Down

0 comments on commit 802225d

Please sign in to comment.