diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index b92fe71b4b..48d5cf060a 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -96,6 +96,7 @@ class CheckoutController < ::BaseController def checkout_workflow(shipping_method_id) while @order.state != "complete" if @order.state == "payment" + update_payment_total return if redirect_to_payment_gateway return action_failed if @order.errors.any? @@ -110,6 +111,11 @@ class CheckoutController < ::BaseController update_response end + def update_payment_total + @order.updater.update_totals + @order.updater.update_pending_payment + end + def redirect_to_payment_gateway return unless selected_payment_method.external_gateway? return unless (redirect_url = selected_payment_method.external_payment_url(order: @order)) diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index 5b8a86ebad..776e654192 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -734,16 +734,5 @@ module Spree adjustment.update_adjustment!(force: true) updater.update_totals_and_states end - - # object_params sets the payment amount to the order total, but it does this - # before the shipping method is set. This results in the customer not being - # charged for their order's shipping. To fix this, we refresh the payment - # amount here. - def set_payment_amount! - update_totals - return unless pending_payments.any? - - pending_payments.first.update_attribute :amount, total - end end end diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb index 3671639bcc..01997e676c 100644 --- a/app/models/spree/order/checkout.rb +++ b/app/models/spree/order/checkout.rb @@ -81,7 +81,6 @@ module Spree after_transition to: :complete, do: :finalize! after_transition to: :resumed, do: :after_resume after_transition to: :canceled, do: :after_cancel - after_transition to: :payment, do: :set_payment_amount! end end diff --git a/engines/order_management/app/services/order_management/order/updater.rb b/engines/order_management/app/services/order_management/order/updater.rb index 41d0374047..fc727d7e35 100644 --- a/engines/order_management/app/services/order_management/order/updater.rb +++ b/engines/order_management/app/services/order_management/order/updater.rb @@ -35,6 +35,14 @@ module OrderManagement end persist_totals + update_pending_payment + end + + def update_pending_payment + return unless order.state.in? ["payment", "confirmation"] + return unless order.pending_payments.any? + + order.pending_payments.first.update_attribute :amount, order.total end # Updates the following Order total values: diff --git a/spec/controllers/split_checkout_controller_spec.rb b/spec/controllers/split_checkout_controller_spec.rb index e70836fc02..43d799e9bc 100644 --- a/spec/controllers/split_checkout_controller_spec.rb +++ b/spec/controllers/split_checkout_controller_spec.rb @@ -165,6 +165,7 @@ describe SplitCheckoutController, type: :controller do expect(order.state).to eq "confirmation" expect(order.payments.first.adjustment.amount).to eq 1.23 + expect(order.payments.first.amount).to eq order.item_total + order.adjustment_total expect(order.adjustment_total).to eq 1.23 expect(order.total).to eq order.item_total + order.adjustment_total end diff --git a/spec/controllers/spree/admin/return_authorizations_controller_spec.rb b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb index 982944065a..7c19cfc7d3 100644 --- a/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +++ b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb @@ -7,20 +7,10 @@ module Spree describe ReturnAuthorizationsController, type: :controller do include AuthenticationHelper - let(:order) do - create(:order, :with_line_item, :completed, - distributor: create(:distributor_enterprise) ) - end + let(:order) { create(:shipped_order, distributor: create(:distributor_enterprise)) } before do controller_login_as_admin - - # Pay the order - order.payments.first.complete - order.update_order! - - # Ship the order - order.shipment.ship! end it "creates and updates a return authorization" do diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index bf91d71aae..fe31ab000a 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -1335,54 +1335,6 @@ describe Spree::Order do end end - describe '#set_payment_amount!' do - let(:order) do - shipment = build(:shipment_with, :shipping_method, shipping_method: build(:shipping_method)) - build(:order, shipments: [shipment]) - end - - context 'after transitioning to payment' do - before do - order.state = 'delivery' # payment's previous state - - allow(order).to receive(:payment_required?) { true } - end - - it 'calls #set_payment_amount! and updates totals' do - expect(order).to receive(:set_payment_amount!) - expect(order).to receive(:update_totals).at_least(:once) - - order.next - end - - context "payment's amount" do - let(:failed_payment) { create(:payment, order: order, state: 'failed', amount: 100) } - - before do - allow(order).to receive(:total) { 120 } - end - - it 'is not updated for failed payments' do - failed_payment - - order.next - - expect(failed_payment.reload.amount).to eq 100 - end - - it 'is updated only for pending payments' do - pending_payment = create(:payment, order: order, state: 'pending', amount: 80) - failed_payment - - order.next - - expect(failed_payment.reload.amount).to eq 100 - expect(pending_payment.reload.amount).to eq 120 - end - end - end - end - describe "#ensure_updated_shipments" do before { Spree::Shipment.create!(order: order) } diff --git a/spec/services/process_payment_intent_spec.rb b/spec/services/process_payment_intent_spec.rb index 515ee16065..8693bbba46 100644 --- a/spec/services/process_payment_intent_spec.rb +++ b/spec/services/process_payment_intent_spec.rb @@ -129,6 +129,8 @@ describe ProcessPaymentIntent do it "completes the order, but with failed payment state recorded" do service.call! + order.reload + expect(order.state).to eq("complete") expect(order.payment_state).to eq("failed") expect(order).to have_received(:deliver_order_confirmation_email)