Add check for payment authorization state in StripeScaPaymentAuthorize and corresponding spec

This commit is contained in:
Ahmed Ejaz
2025-10-17 05:25:45 +05:00
parent c4c266246c
commit 9f6c149735
3 changed files with 46 additions and 11 deletions

View File

@@ -18,6 +18,8 @@ module OrderManagement
end
def call!(return_url = off_session_return_url)
# if the payment requires_authorization (3D Secure), can't be authorized again
return payment if payment&.requires_authorization?
return unless payment&.checkout?
payment.authorize!(return_url)

View File

@@ -19,6 +19,15 @@ module OrderManagement
end
end
context "when the payment already requires 3D Secure authorization" do
let(:payment) { create(:payment, amount: 10, state: 'requires_authorization') }
before { allow(order).to receive(:pending_payments).once { [payment] } }
it "returns the payment without authorizing because it has already been authorized" do
expect(payment_authorize.call!).to eq payment
end
end
context "when a payment is present" do
let(:payment) { create(:payment, amount: 10) }

View File

@@ -17,28 +17,52 @@ RSpec.describe Checkout::StripeRedirect do
context "when the payment method is a Stripe method" do
let(:payment_method) { create(:stripe_sca_payment_method) }
let(:stripe_payment) { create(:payment, payment_method_id: payment_method.id) }
let(:test_redirect_url) { "http://stripe_auth_url/" }
before do
order.payments << stripe_payment
end
it "authorizes the payment and returns the redirect path" do
expect(Orders::FindPaymentService).to receive_message_chain(:new, :last_pending_payment).
and_return(stripe_payment)
context "when payment is in checkout state" do
let(:stripe_payment) { create(:payment, payment_method_id: payment_method.id) }
expect(OrderManagement::Order::StripeScaPaymentAuthorize).to receive(:new).and_call_original
it "authorizes the payment and returns the redirect path" do
expect(Orders::FindPaymentService).to receive_message_chain(:new, :last_pending_payment).
and_return(stripe_payment)
expect(stripe_payment).to receive(:authorize!) do
# Authorization moves the payment state from checkout/processing to pending
stripe_payment.state = 'pending'
true
expect(
OrderManagement::Order::StripeScaPaymentAuthorize
).to receive(:new).and_call_original
expect(stripe_payment).to receive(:authorize!) do
# Authorization moves the payment state from checkout/processing to pending
stripe_payment.state = 'pending'
true
end
expect(stripe_payment).to receive(:redirect_auth_url).and_return(test_redirect_url)
expect(service.path).to eq test_redirect_url
end
end
expect(stripe_payment).to receive(:redirect_auth_url).and_return(test_redirect_url)
context "when payment is in requires_authorization state" do
let(:stripe_payment) {
create(
:payment,
payment_method_id: payment_method.id,
state: 'requires_authorization',
redirect_auth_url: test_redirect_url
)
}
expect(service.path).to eq test_redirect_url
it "returns the redirect path without authorizing the payment again" do
expect(Orders::FindPaymentService).to receive_message_chain(:new, :last_pending_payment).
and_return(stripe_payment)
expect(
OrderManagement::Order::StripeScaPaymentAuthorize
).to receive(:new).and_call_original
expect(stripe_payment).not_to receive(:authorize!)
expect(service.path).to eq test_redirect_url
end
end
end
end