mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-20 04:59:16 +00:00
Check stock before completing order after Taler payment
This commit is contained in:
@@ -2,15 +2,36 @@
|
||||
|
||||
module PaymentGateways
|
||||
class TalerController < BaseController
|
||||
include OrderStockCheck
|
||||
include OrderCompletion
|
||||
|
||||
class StockError < StandardError
|
||||
end
|
||||
|
||||
# The Taler merchant backend has taken the payment.
|
||||
# Now we just need to confirm that and update our local database
|
||||
# before finalising the order.
|
||||
def confirm
|
||||
payment = Spree::Payment.find(params[:payment_id])
|
||||
|
||||
# Process payment early because it's probably paid already.
|
||||
# We want to capture that before any validations raise errors.
|
||||
unless payment.process!
|
||||
return redirect_to order_failed_route(step: "payment")
|
||||
end
|
||||
|
||||
@order = payment.order
|
||||
process_payment_completion!
|
||||
OrderLocker.lock_order_and_variants(@order) do
|
||||
raise StockError unless sufficient_stock?
|
||||
|
||||
process_payment_completion!
|
||||
end
|
||||
rescue Spree::Core::GatewayError => e
|
||||
flash[:notice] = e.message
|
||||
redirect_to order_failed_route(step: "payment")
|
||||
rescue StockError
|
||||
flash[:notice] = t("checkout.payment_cancelled_due_to_stock")
|
||||
redirect_to main_app.checkout_step_path(step: "details")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,16 +3,19 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe "/payment_gateways/taler/:id" do
|
||||
it "completes the order", :vcr do
|
||||
shop = create(:distributor_enterprise)
|
||||
taler = Spree::PaymentMethod::Taler.create!(
|
||||
let(:shop) { create(:distributor_enterprise) }
|
||||
let(:taler) {
|
||||
Spree::PaymentMethod::Taler.create!(
|
||||
name: "Taler",
|
||||
environment: "test",
|
||||
distributors: [shop],
|
||||
preferred_backend_url: "https://backend.demo.taler.net/instances/sandbox",
|
||||
preferred_api_key: "sandbox",
|
||||
)
|
||||
order = create(:order_ready_for_confirmation, payment_method: taler)
|
||||
}
|
||||
let!(:order) { create(:order_ready_for_confirmation, payment_method: taler) }
|
||||
|
||||
it "completes the order", :vcr do
|
||||
payment = Spree::Payment.last
|
||||
payment.update!(
|
||||
source: taler,
|
||||
@@ -30,4 +33,47 @@ RSpec.describe "/payment_gateways/taler/:id" do
|
||||
payment.reload
|
||||
expect(payment.state).to eq "completed"
|
||||
end
|
||||
|
||||
it "redirects when payment failed" do
|
||||
payment = Spree::Payment.last
|
||||
payment.update!(
|
||||
source: taler,
|
||||
payment_method: taler,
|
||||
response_code: "2026.020-03R3ETNZZ0DVA",
|
||||
)
|
||||
|
||||
allow_any_instance_of(Taler::Order)
|
||||
.to receive(:fetch).with("order_status").and_return("claimed")
|
||||
|
||||
get payment_gateways_confirm_taler_path(payment_id: payment.id)
|
||||
expect(response).to redirect_to "/checkout/payment"
|
||||
|
||||
payment.reload
|
||||
expect(payment.state).to eq "failed"
|
||||
|
||||
order.reload
|
||||
expect(order.state).to eq "confirmation"
|
||||
end
|
||||
|
||||
it "handles all variants going out of stock" do
|
||||
payment = Spree::Payment.last
|
||||
payment.update!(
|
||||
source: taler,
|
||||
payment_method: taler,
|
||||
response_code: "2026.020-03R3ETNZZ0DVA",
|
||||
)
|
||||
|
||||
allow_any_instance_of(Taler::Order)
|
||||
.to receive(:fetch).with("order_status").and_return("paid")
|
||||
order.line_items[0].variant.on_hand = 0
|
||||
|
||||
get payment_gateways_confirm_taler_path(payment_id: payment.id)
|
||||
expect(response).to redirect_to "/checkout/details"
|
||||
|
||||
payment.reload
|
||||
expect(payment.state).to eq "completed"
|
||||
|
||||
order.reload
|
||||
expect(order.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user