Invalidate all incomplete payments when creating a new one, not just those in "checkout" state.

Looking at prod data; when a checkout submission fails due to something like a card being out of date, the payment's state seems to be "pending" and not "checkout", which means this mechanism fro invalidating old payments is potentially not working where it should.
This commit is contained in:
Matt-Yorkley
2022-02-11 16:22:12 +00:00
parent 6e2c4a385a
commit e5818955ff
2 changed files with 13 additions and 1 deletions

View File

@@ -206,7 +206,7 @@ module Spree
# Makes newly entered payments invalidate previously entered payments so the most recent payment
# is used by the gateway.
def invalidate_old_payments
order.payments.with_state('checkout').where.not(id: id).each do |payment|
order.payments.incomplete.where.not(id: id).each do |payment|
# Using update_column skips validations and so it skips validate_source. As we are just
# invalidating past payments here, we don't want to validate all of them at this stage.
payment.update_columns(

View File

@@ -49,6 +49,18 @@ describe Spree::Payment do
end
end
context "creating a new payment alongside other incomplete payments" do
let(:order) { create(:order_with_totals) }
let!(:incomplete_payment) { create(:payment, order: order, state: "pending") }
let(:new_payment) { create(:payment, order: order, state: "checkout") }
it "invalidates other incomplete payments on the order" do
new_payment
expect(incomplete_payment.reload.state).to eq "invalid"
end
end
# Regression test for https://github.com/spree/spree/pull/2224
context 'failure' do
it 'should transition to failed from pending state' do