diff --git a/enterprise/app/services/enterprise/billing/topup_checkout_service.rb b/enterprise/app/services/enterprise/billing/topup_checkout_service.rb index e11269110..d0ec3e372 100644 --- a/enterprise/app/services/enterprise/billing/topup_checkout_service.rb +++ b/enterprise/app/services/enterprise/billing/topup_checkout_service.rb @@ -73,8 +73,13 @@ class Enterprise::Billing::TopupCheckoutService description: description ) - Stripe::Invoice.finalize_invoice(invoice.id, { auto_advance: false }) - Stripe::Invoice.pay(invoice.id) + finalize_and_pay(invoice.id) + end + + def finalize_and_pay(invoice_id) + Stripe::Invoice.finalize_invoice(invoice_id, { auto_advance: false }) + invoice = Stripe::Invoice.retrieve(invoice_id) + Stripe::Invoice.pay(invoice_id) unless invoice.status == 'paid' end def fulfill_credits(credits, topup_option) diff --git a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb index 9089b089a..b2a920b07 100644 --- a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb +++ b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb @@ -281,6 +281,7 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do allow(Stripe::Invoice).to receive(:create).and_return(stripe_invoice) allow(Stripe::InvoiceItem).to receive(:create) allow(Stripe::Invoice).to receive(:finalize_invoice) + allow(Stripe::Invoice).to receive(:retrieve).and_return(Struct.new(:status).new('open')) allow(Stripe::Invoice).to receive(:pay) allow(Stripe::Billing::CreditGrant).to receive(:create) end diff --git a/spec/enterprise/services/enterprise/billing/topup_checkout_service_spec.rb b/spec/enterprise/services/enterprise/billing/topup_checkout_service_spec.rb index 24c7889de..fa4c052a1 100644 --- a/spec/enterprise/services/enterprise/billing/topup_checkout_service_spec.rb +++ b/spec/enterprise/services/enterprise/billing/topup_checkout_service_spec.rb @@ -24,6 +24,7 @@ describe Enterprise::Billing::TopupCheckoutService do allow(Stripe::Invoice).to receive(:create).and_return(stripe_invoice) allow(Stripe::InvoiceItem).to receive(:create) allow(Stripe::Invoice).to receive(:finalize_invoice) + allow(Stripe::Invoice).to receive(:retrieve).and_return(Struct.new(:status).new('open')) allow(Stripe::Invoice).to receive(:pay) allow(Stripe::Billing::CreditGrant).to receive(:create) end @@ -58,5 +59,19 @@ describe Enterprise::Billing::TopupCheckoutService do expect(error.message).to eq(I18n.t('errors.topup.plan_not_eligible')) end end + + it 'calls pay when invoice is open after finalization' do + service.create_checkout_session(credits: 1000) + + expect(Stripe::Invoice).to have_received(:pay).with('inv_test123') + end + + it 'skips pay when invoice is already paid via Stripe credits' do + allow(Stripe::Invoice).to receive(:retrieve).and_return(Struct.new(:status).new('paid')) + + service.create_checkout_session(credits: 1000) + + expect(Stripe::Invoice).not_to have_received(:pay) + end end end