enterprise/app/services/enterprise/billing/handle_stripe_event_service.rb
class Enterprise::Billing::HandleStripeEventService
def perform(event:)
ensure_event_context(event)
case @event.type
when 'customer.subscription.updated'
process_subscription_updated
when 'customer.subscription.deleted'
process_subscription_deleted
else
Rails.logger.debug { "Unhandled event type: #{event.type}" }
end
end
private
def process_subscription_updated
plan = find_plan(subscription['plan']['product']) if subscription['plan'].present?
# skipping self hosted plan events
return if plan.blank? || account.blank?
update_account_attributes(subscription, plan)
change_plan_features
end
def update_account_attributes(subscription, plan)
# https://stripe.com/docs/api/subscriptions/object
account.update(
custom_attributes: {
stripe_customer_id: subscription.customer,
stripe_price_id: subscription['plan']['id'],
stripe_product_id: subscription['plan']['product'],
plan_name: plan['name'],
subscribed_quantity: subscription['quantity'],
subscription_status: subscription['status'],
subscription_ends_on: Time.zone.at(subscription['current_period_end'])
}
)
end
def process_subscription_deleted
# skipping self hosted plan events
return if account.blank?
Enterprise::Billing::CreateStripeCustomerService.new(account: account).perform
end
def change_plan_features
if default_plan?
account.disable_features(*features_to_update)
else
account.enable_features(*features_to_update)
end
account.save!
end
def ensure_event_context(event)
@event = event
end
def features_to_update
%w[help_center campaigns team_management channel_twitter channel_facebook channel_email]
end
def subscription
@subscription ||= @event.data.object
end
def account
@account ||= Account.where("custom_attributes->>'stripe_customer_id' = ?", subscription.customer).first
end
def find_plan(plan_id)
installation_config = InstallationConfig.find_by(name: 'CHATWOOT_CLOUD_PLANS')
installation_config.value.find { |config| config['product_id'].include?(plan_id) }
end
def default_plan?
installation_config = InstallationConfig.find_by(name: 'CHATWOOT_CLOUD_PLANS')
default_plan = installation_config.value.first
@account.custom_attributes['plan_name'] == default_plan['name']
end
end