diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb index 4160b24bcc..8bc7e4cb9e 100644 --- a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb @@ -18,7 +18,7 @@ module OrderManagement private def ensure_payment_source - return if !card_required? || card_set? + return unless stripe_payment_method? && !card_set? if saved_credit_card.present? && allow_charges? use_saved_credit_card @@ -27,17 +27,13 @@ module OrderManagement end end - def card_required? + def stripe_payment_method? [Spree::Gateway::StripeConnect, Spree::Gateway::StripeSCA].include? @payment.payment_method.class end def card_set? - @payment.source is_a? Spree::CreditCard - end - - def use_saved_credit_card - @payment.update_attributes(source: saved_credit_card) + @payment.source.is_a? Spree::CreditCard end def saved_credit_card @@ -47,6 +43,10 @@ module OrderManagement def allow_charges? @order.customer.allow_charges? end + + def use_saved_credit_card + @payment.update_attributes(source: saved_credit_card) + end end end end diff --git a/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb new file mode 100644 index 0000000000..c928ddd95b --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe StripePaymentSetup do + let(:order) { create(:order) } + let(:payment_setup) { OrderManagement::Subscriptions::StripePaymentSetup.new(order) } + + describe "#call!" do + context "when no pending payments are present" do + before do + allow(order).to receive(:pending_payments).once { [] } + end + + it "does nothing" do + expect(payment_setup.call!).to eq nil + end + end + + context "when a payment is present" do + let(:payment) { create(:payment, payment_method: payment_method, amount: 10) } + + before { allow(order).to receive(:pending_payments).once { [payment] } } + + context "when the payment method is not a stripe payment method" do + let(:payment_method) { create(:payment_method) } + + it "returns the pending payment with no change" do + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + end + end + + context "when the payment method is a stripe payment method" do + let(:payment_method) { create(:stripe_payment_method) } + + context "and the card is already set (the payment source is a credit card)" do + it "returns the pending payment with no change" do + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + end + end + + context "and the card is not set (the payment source is not a credit card)" do + before { payment.update_attribute :source, nil } + + context "and no default credit card has been saved by the customer" do + before do + allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } + end + + it "adds an error to the order and does not update the payment" do + payment_setup.call! + + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + expect(order.errors[:base].first).to eq "There are no authorised "\ + "credit cards available to charge" + end + end + + context "and a default credit card has been saved by the customer" do + let(:saved_credit_card) { create(:credit_card) } + + before do + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: saved_credit_card) + } + end + + context "but the customer has not authorised the shop to charge credit cards" do + before do + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: false) + } + end + + it "adds an error to the order and does not update the payment" do + payment_setup.call! + + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + expect(order.errors[:base].first).to eq "There are no authorised "\ + "credit cards available to charge" + end + end + + context "and the customer has authorised the shop to charge credit cards" do + before do + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: true) + } + end + + it "uses the saved credit card as the source for the payment" do + payment_setup.call! + expect(payment.source).to eq saved_credit_card + end + end + end + end + end + end + end + end + end +end