Handle Stripe payments when checkout fails due to stock issues

This can occur when stock is reduced after the user is redirected to Stripe and before they are redirected back. The stock is insufficient, the order is not complete, the user is bounced back to the cart, but a *pending* Stripe payment is left on the order.
This commit is contained in:
Matt-Yorkley
2021-06-11 15:08:11 +01:00
parent 9795734dc8
commit 9bcf0d5b38
2 changed files with 18 additions and 3 deletions

View File

@@ -37,7 +37,7 @@ class CheckoutController < ::BaseController
# This is only required because of spree_paypal_express. If we implement
# a version of paypal that uses this controller, and more specifically
# the #action_failed method, then we can remove this call
OrderCheckoutRestart.new(@order).call
reset_order_to_cart
rescue Spree::Core::GatewayError => e
rescue_from_spree_gateway_error(e)
end
@@ -82,7 +82,7 @@ class CheckoutController < ::BaseController
@order = current_order
redirect_to(main_app.shop_path) && return if redirect_to_shop?
redirect_to_cart_path && return unless valid_order_line_items?
handle_invalid_stock && return unless valid_order_line_items?
before_address
setup_for_current_state
@@ -100,7 +100,10 @@ class CheckoutController < ::BaseController
distributes_order_variants?(@order)
end
def redirect_to_cart_path
def handle_invalid_stock
cancel_incomplete_payments if valid_payment_intent_provided?
reset_order_to_cart
respond_to do |format|
format.html do
redirect_to main_app.cart_path
@@ -112,6 +115,17 @@ class CheckoutController < ::BaseController
end
end
def cancel_incomplete_payments
# The checkout could not complete due to stock running out. We void any pending (incomplete)
# Stripe payments here as the order will need to be changed and resubmitted (or abandoned).
@order.payments.pending.each(&:void!)
flash[:notice] = I18n.t("checkout.payment_cancelled_due_to_stock")
end
def reset_order_to_cart
OrderCheckoutRestart.new(@order).call
end
def setup_for_current_state
method_name = :"before_#{@order.state}"
__send__(method_name) if respond_to?(method_name, true)

View File

@@ -1315,6 +1315,7 @@ en:
message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}."
terms_and_conditions: "Terms and Conditions"
failed: "The checkout failed. Please let us know so that we can process your order."
payment_cancelled_due_to_stock: "Payment cancelled: the checkout could not be completed due to stock issues."
shops:
hubs:
show_closed_shops: "Show closed shops"