handle cancellation properly

This commit is contained in:
Tanmay Deep Sharma
2025-10-29 15:50:12 +05:30
parent f999112671
commit 6f9f2c32c9
2 changed files with 64 additions and 4 deletions
@@ -7,8 +7,9 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
# Extract details from the subscription
pricing_plan_id = extract_pricing_plan_id(subscription)
quantity = extract_subscription_quantity(subscription)
billing_cadence = extract_billing_cadence(subscription)
# Update account with subscription details
update_subscription_details(subscription_id, pricing_plan_id, quantity)
update_subscription_details(subscription_id, pricing_plan_id, quantity, billing_cadence)
# Provision the subscription: sync credits and enable features
provision_subscription(pricing_plan_id) if pricing_plan_id.present?
@@ -18,6 +19,22 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
{ success: false, message: "Stripe error: #{e.message}" }
end
def refresh
subscription_id = account.custom_attributes['stripe_subscription_id']
return if subscription_id.blank?
subscription_plan = retrieve_pricing_plan_subscription(subscription_id)
servicing_status = servicing_status(subscription_plan)
pricing_plan_id = extract_pricing_plan_id(subscription_plan)
if servicing_status == 'canceled'
cancel_subscription
else
quantity = account.custom_attributes['subscribed_quantity']
billing_cadence = extract_billing_cadence(subscription_plan)
update_subscription_details(subscription_id, pricing_plan_id, quantity, billing_cadence)
end
end
private
def build_success_response(subscription_id, pricing_plan_id, quantity)
@@ -30,6 +47,36 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
}
end
def servicing_status(subscription_plan)
subscription_plan.respond_to?(:servicing_status) ? subscription_plan.servicing_status : subscription_plan['servicing_status']
end
def cancel_subscription
hacker_plan_config = InstallationConfig.find_by(name: 'STRIPE_HACKER_PLAN_ID')
pricing_plan_id = hacker_plan_config.value
# Update subscription status and plan details
attributes = {
'plan_name': 'Hacker',
'stripe_pricing_plan_id': pricing_plan_id,
'subscribed_quantity': 2,
'stripe_subscription_id': nil,
'billing_cadence': nil,
'subscription_status': 'canceled'
}
update_custom_attributes(attributes)
# Sync credits for Hacker plan (0 credits)
sync_plan_credits(pricing_plan_id)
# Disable all premium features and save
disable_all_premium_features
account.save!
# Reset captain usage
reset_captain_usage
end
def retrieve_pricing_plan_subscription(subscription_id)
StripeV2Client.request(
:get,
@@ -44,6 +91,10 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
subscription.respond_to?(:pricing_plan) ? subscription.pricing_plan : subscription['pricing_plan']
end
def extract_billing_cadence(subscription)
subscription.respond_to?(:billing_cadence) ? subscription.billing_cadence : subscription['billing_cadence']
end
def extract_subscription_quantity(_subscription)
# Get quantity from account custom_attributes (set during checkout)
pending_quantity = account.custom_attributes['pending_subscription_quantity']
@@ -59,7 +110,7 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
1
end
def update_subscription_details(subscription_id, pricing_plan_id, quantity)
def update_subscription_details(subscription_id, pricing_plan_id, quantity, billing_cadence)
Rails.logger.info "[V2 Billing] Updating subscription details: subscription_id=#{subscription_id}, " \
"pricing_plan_id=#{pricing_plan_id}, quantity=#{quantity}"
@@ -69,7 +120,8 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
'subscribed_quantity' => quantity,
'subscription_status' => 'active',
'pending_subscription_quantity' => nil,
'pending_subscription_pricing_plan' => nil
'pending_subscription_pricing_plan' => nil,
'billing_cadence' => billing_cadence
}
attributes['stripe_pricing_plan_id'] = pricing_plan_id if pricing_plan_id.present?
@@ -99,7 +151,6 @@ class Enterprise::Billing::V2::SubscriptionProvisioningService < Enterprise::Bil
def sync_plan_credits(pricing_plan_id)
plan_credits = Enterprise::Billing::V2::PlanCatalog.monthly_credits_for(pricing_plan_id)
return unless plan_credits
Enterprise::Billing::V2::CreditManagementService
.new(account: account)
@@ -8,6 +8,9 @@ class Enterprise::Billing::V2::WebhookHandlerService
when 'v2.billing.pricing_plan_subscription.servicing_activated'
Rails.logger.info "Handling subscription servicing activated event: #{@event.related_object.id}"
handle_subscription_servicing_activated(@event.related_object.id)
when 'v2.billing.cadence.billed'
Rails.logger.info "Handling cadence billed event: #{@event.related_object.id}"
refresh_account_subscription_details(@event.related_object.id)
else
{ success: true }
end
@@ -56,6 +59,12 @@ class Enterprise::Billing::V2::WebhookHandlerService
.provision(subscription_id: subscription_id)
end
def refresh_account_subscription_details(_cadence_id)
Enterprise::Billing::V2::SubscriptionProvisioningService
.new(account: account)
.refresh
end
def stripe_api_options
{ api_key: ENV.fetch('STRIPE_SECRET_KEY', nil), stripe_version: '2025-08-27.preview' }
end