diff --git a/app/models/spree/payment/processing.rb b/app/models/spree/payment/processing.rb index a40a0798da..b59f3663ff 100644 --- a/app/models/spree/payment/processing.rb +++ b/app/models/spree/payment/processing.rb @@ -13,7 +13,11 @@ module Spree return unless validate! return if authorization_action_required? - charge_offline! + if preauthorized? + capture! + else + charge_offline! + end end def authorize!(return_url = nil) @@ -184,6 +188,10 @@ module Spree private + def preauthorized? + response_code.presence&.match("pi_") + end + def validate! return false unless payment_method&.source_required? diff --git a/spec/factories/payment_factory.rb b/spec/factories/payment_factory.rb index 96b71bd0e4..2919b00c7c 100644 --- a/spec/factories/payment_factory.rb +++ b/spec/factories/payment_factory.rb @@ -14,7 +14,7 @@ FactoryBot.define do association(:source, factory: :credit_card) order state { 'checkout' } - response_code { '12345' } + response_code { nil } payment_method { FactoryBot.create(:payment_method, distributors: [distributor]) } end diff --git a/spec/jobs/subscription_confirm_job_spec.rb b/spec/jobs/subscription_confirm_job_spec.rb index 39bec020b1..1a03217ae4 100644 --- a/spec/jobs/subscription_confirm_job_spec.rb +++ b/spec/jobs/subscription_confirm_job_spec.rb @@ -158,12 +158,19 @@ describe SubscriptionConfirmJob do allow(order).to receive(:pending_payments) { [stripe_sca_payment] } allow(stripe_sca_payment_method).to receive(:provider) { provider } allow(stripe_sca_payment_method.provider).to receive(:purchase) { true } + allow(stripe_sca_payment_method.provider).to receive(:capture) { true } end it "runs the charges in offline mode" do job.send(:confirm_order!, order) expect(stripe_sca_payment_method.provider).to have_received(:purchase) end + + it "uses #capture if the payment is already authorized" do + allow(stripe_sca_payment).to receive(:preauthorized?) { true } + expect(stripe_sca_payment_method.provider).to receive(:capture) + job.send(:confirm_order!, order) + end end context "Stripe Connect" do diff --git a/spec/models/spree/gateway/stripe_sca_spec.rb b/spec/models/spree/gateway/stripe_sca_spec.rb index 43844a3763..8ddfe99373 100644 --- a/spec/models/spree/gateway/stripe_sca_spec.rb +++ b/spec/models/spree/gateway/stripe_sca_spec.rb @@ -16,6 +16,7 @@ describe Spree::Gateway::StripeSCA, type: :model do amount: order.total, payment_method: subject, source: credit_card, + response_code: "12345" ) } let(:gateway_options) { diff --git a/spec/models/spree/payment_spec.rb b/spec/models/spree/payment_spec.rb index 2820316bd0..03eb892b53 100644 --- a/spec/models/spree/payment_spec.rb +++ b/spec/models/spree/payment_spec.rb @@ -97,6 +97,29 @@ describe Spree::Payment do expect { payment.process! }.to raise_error(Spree::Core::GatewayError) expect(payment.state).to eq('invalid') end + + context "the payment is already authorized" do + before do + allow(payment).to receive(:response_code) { "pi_123" } + end + + it "should call purchase" do + expect(payment).to receive(:purchase!) + payment.process! + end + end + end + + context "#process_offline when payment is already authorized" do + before do + allow(payment).to receive(:response_code) { "pi_123" } + end + + it "should call capture if the payment is already authorized" do + expect(payment).to receive(:capture!) + expect(payment).to_not receive(:purchase!) + payment.process_offline! + end end context "#authorize" do