diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 26c566e9a6..47dbfc53b5 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -153,10 +153,12 @@ class CheckoutController < Spree::StoreController end def valid_payment_intent_provided? - params["payment_intent"]&.starts_with?("pi_") && - @order.state == "payment" && - @order.payments.last.state == "pending" && - @order.payments.last.response_code == params["payment_intent"] + return false unless params["payment_intent"]&.starts_with?("pi_") + + last_payment = OrderPaymentFinder.new(@order).last_payment + @order.state == "payment" && + last_payment&.state == "pending" && + last_payment&.response_code == params["payment_intent"] end def handle_redirect_from_stripe diff --git a/app/services/order_payment_finder.rb b/app/services/order_payment_finder.rb index 754be34a0f..54b19654a3 100644 --- a/app/services/order_payment_finder.rb +++ b/app/services/order_payment_finder.rb @@ -6,13 +6,23 @@ class OrderPaymentFinder end def last_payment - # `max_by` avoids additional database queries when payments are loaded - # already. There is usually only one payment and this shouldn't cause - # any overhead compared to `order(:created_at).last`. Using `last` - # without order is not deterministic. - # - # We are not using `updated_at` because all payments are touched when the - # order is updated and then all payments have the same `updated_at` value. - @order.payments.max_by(&:created_at) + last(@order.payments) + end + + def last_pending_payment + last(@order.pending_payments) + end + + private + + # `max_by` avoids additional database queries when payments are loaded + # already. There is usually only one payment and this shouldn't cause + # any overhead compared to `order(:created_at).last`. Using `last` + # without order is not deterministic. + # + # We are not using `updated_at` because all payments are touched when the + # order is updated and then all payments have the same `updated_at` value. + def last(payments) + payments.max_by(&:created_at) end end diff --git a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb index 1824247e37..6d90236466 100644 --- a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb @@ -18,7 +18,7 @@ module OrderManagement private def create_payment - payment = @order.pending_payments.last + payment = OrderPaymentFinder.new(@order).last_pending_payment return payment if payment.present? @order.payments.create( 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 8bc7e4cb9e..37e3a097f3 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 @@ -5,7 +5,7 @@ module OrderManagement class StripePaymentSetup def initialize(order) @order = order - @payment = @order.pending_payments.last + @payment = OrderPaymentFinder.new(@order).last_pending_payment end def call! diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb index da8830ce70..ea4fbe5ce7 100644 --- a/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb @@ -5,7 +5,7 @@ module OrderManagement class StripeScaPaymentAuthorize def initialize(order) @order = order - @payment = @order.pending_payments.last + @payment = OrderPaymentFinder.new(@order).last_pending_payment end def call!