fix(billing): narrow attribution metadata changes

This commit is contained in:
Sojan Jose
2026-04-28 20:07:30 +05:30
parent df0daebc99
commit bfdd5d2642
4 changed files with 12 additions and 53 deletions
@@ -2,7 +2,7 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController
include BillingHelper
before_action :fetch_account
before_action :check_authorization
before_action :check_cloud_env, only: [:limits, :toggle_deletion]
before_action :check_cloud_env, only: [:checkout, :limits, :toggle_deletion]
def subscription
if stripe_customer_id.blank? && @account.custom_attributes['is_creating_customer'].blank?
@@ -33,7 +33,7 @@ class Enterprise::Billing::CreateStripeCustomerService
def stripe_metadata
{
chatwoot_account_id: account.id
}.merge(provider_attribution_metadata.presence || existing_provider_attribution_metadata)
}.merge(provider_attribution_metadata)
end
def provider_attribution_metadata
@@ -43,17 +43,6 @@ class Enterprise::Billing::CreateStripeCustomerService
}.compact
end
def existing_provider_attribution_metadata
customer_id = account.custom_attributes['stripe_customer_id']
return {} if customer_id.blank?
customer = Stripe::Customer.retrieve(customer_id)
(customer.metadata || {}).to_h.symbolize_keys.slice(:datafast_visitor_id, :datafast_session_id)
rescue Stripe::StripeError => e
Rails.logger.warn("Failed to retrieve Stripe customer metadata for account #{account.id}: #{e.class} - #{e.message}")
{}
end
def default_quantity
default_plan['default_quantity'] || DEFAULT_QUANTITY
end
@@ -5,6 +5,10 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
let!(:admin) { create(:user, account: account, role: :administrator) }
let!(:agent) { create(:user, account: account, role: :agent) }
before do
allow(GlobalConfig).to receive(:get_value).and_call_original
end
describe 'POST /enterprise/api/v1/accounts/{account.id}/subscription' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
@@ -26,10 +30,6 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
end
context 'when it is an admin' do
before do
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
end
it 'enqueues a job' do
expect do
post "/enterprise/api/v1/accounts/#{account.id}/subscription",
@@ -96,7 +96,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when it is an admin and the stripe customer id is not present' do
before do
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('cloud')
end
it 'returns error' do
@@ -112,7 +112,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when it is an admin and the stripe customer is present' do
before do
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('cloud')
end
it 'calls create session' do
@@ -146,7 +146,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when it is an authenticated user' do
before do
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('cloud')
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_initialize.update!(value: [{ 'name' => 'Hacker' }])
end
@@ -182,7 +182,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
before do
create(:conversation, account: account)
create(:channel_api, account: account)
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('cloud')
InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_initialize.update!(value: [{ 'name' => 'Hacker' }])
end
@@ -299,7 +299,6 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when it is an admin' do
before do
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
account.update!(
custom_attributes: { plan_name: 'Business', stripe_customer_id: stripe_customer_id },
limits: { 'captain_responses' => 1000 }
@@ -368,7 +367,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when deployment environment is not cloud' do
before do
# Set deployment environment to something other than cloud
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'self_hosted')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('self_hosted')
end
it 'returns not found' do
@@ -385,7 +384,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do
context 'when it is an admin' do
before do
# Create the installation config for cloud environment
InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud')
allow(GlobalConfig).to receive(:get_value).with('DEPLOYMENT_ENV').and_return('cloud')
end
it 'marks the account for deletion when action is delete' do
@@ -64,7 +64,6 @@ describe Enterprise::Billing::CreateStripeCustomerService do
account.update!(custom_attributes: { stripe_customer_id: 'cus_random_number' })
allow(subscriptions_list).to receive(:data).and_return([])
allow(Stripe::Customer).to receive(:create)
allow(Stripe::Customer).to receive(:retrieve).with('cus_random_number').and_return(instance_double(Stripe::Customer, metadata: {}))
allow(Stripe::Subscription).to receive(:list).and_return(subscriptions_list)
allow(Stripe::Subscription).to receive(:create).and_return(created_subscription)
@@ -134,34 +133,6 @@ describe Enterprise::Billing::CreateStripeCustomerService do
.to have_received(:create)
.with({ customer: customer.id, items: [{ price: 'price_hacker_random', quantity: 2 }], metadata: expected_metadata })
end
it 'reuses provider attribution metadata from an existing Stripe customer when attribution is not provided' do
account.update!(custom_attributes: { stripe_customer_id: 'cus_random_number' })
expected_metadata = {
chatwoot_account_id: account.id,
datafast_visitor_id: 'visitor-123',
datafast_session_id: 'session-123'
}
stripe_customer = instance_double(
Stripe::Customer,
metadata: {
'datafast_visitor_id' => 'visitor-123',
'datafast_session_id' => 'session-123',
'ignored' => 'value'
}
)
allow(subscriptions_list).to receive(:data).and_return([])
allow(Stripe::Subscription).to receive(:list).and_return(subscriptions_list)
allow(Stripe::Customer).to receive(:retrieve).with('cus_random_number').and_return(stripe_customer)
allow(Stripe::Subscription).to receive(:create).and_return(created_subscription)
create_stripe_customer_service.new(account: account).perform
expect(Stripe::Subscription)
.to have_received(:create)
.with({ customer: 'cus_random_number', items: [{ price: 'price_hacker_random', quantity: 2 }], metadata: expected_metadata })
end
end
describe 'when checking for existing subscriptions' do