handle cancellation properly
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user