From 66041061fbe85154b029c84ba2a3462e41c8d1f7 Mon Sep 17 00:00:00 2001 From: Gaetan Craig-Riou Date: Mon, 11 Aug 2025 15:54:58 +1000 Subject: [PATCH] Redeem VINE voucher before redirecting to payment url When using paypal, we need to redeem the voucher before redirecting to the payment gateway url, otherwise the voucher will never get redeemed. --- app/controllers/checkout_controller.rb | 5 ++-- spec/controllers/checkout_controller_spec.rb | 25 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index e68b083351..fdc98e55f4 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -80,8 +80,6 @@ class CheckoutController < BaseController @order.customer.touch :terms_and_conditions_accepted_at - return true if redirect_to_payment_gateway - # Redeem VINE voucher vine_voucher_redeemer = Vine::VoucherRedeemerService.new(order: @order) unless vine_voucher_redeemer.redeem @@ -94,6 +92,9 @@ class CheckoutController < BaseController return false # rubocop:enable Rails/DeprecatedActiveModelErrorsMethods end + + return true if redirect_to_payment_gateway + @order.process_payments! @order.confirm! BackorderJob.check_stock(@order) diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb index 165264f47e..ea6da1b012 100644 --- a/spec/controllers/checkout_controller_spec.rb +++ b/spec/controllers/checkout_controller_spec.rb @@ -625,14 +625,30 @@ RSpec.describe CheckoutController do expect(flash[:error]).to match "There was an error while trying to redeem your voucher" end end + + context "when an external payment gateway is used" do + before do + expect(payment_method).to receive(:external_gateway?) { true } + expect(payment_method).to receive(:external_payment_url) { "https://example.com/pay" } + mock_payment_method_fetcher(payment_method) + end + + it "redeems the voucher and redirect to the payment gateway's URL" do + expect(vine_voucher_redeemer).to receive(:redeem).and_return(true) + + put(:update, params:) + + expect(response.body).to match("https://example.com/pay").and match("redirect") + expect(order.reload.state).to eq "confirmation" + end + end end context "when an external payment gateway is used" do before do - expect(Checkout::PaymentMethodFetcher). - to receive_message_chain(:new, :call) { payment_method } expect(payment_method).to receive(:external_gateway?) { true } expect(payment_method).to receive(:external_payment_url) { "https://example.com/pay" } + mock_payment_method_fetcher(payment_method) end describe "confirming the order" do @@ -693,4 +709,9 @@ RSpec.describe CheckoutController do [{ "url" => "/checkout/details", "operation" => "redirectTo" }].to_json ) end + + def mock_payment_method_fetcher(payment_method) + payment_method_fetcher = instance_double(Checkout::PaymentMethodFetcher, call: payment_method) + expect(Checkout::PaymentMethodFetcher).to receive(:new).and_return(payment_method_fetcher) + end end