mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
96 lines
2.7 KiB
Ruby
96 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module PaymentGateways
|
|
class StripeController < BaseController
|
|
include OrderStockCheck
|
|
include OrderCompletion
|
|
|
|
before_action :load_checkout_order, only: :confirm
|
|
before_action :validate_payment_intent, only: :confirm
|
|
before_action -> { check_order_cycle_expiry(should_empty_order: false) }, only: :confirm
|
|
|
|
def confirm
|
|
validate_stock
|
|
|
|
return redirect_to order_failed_route if @any_out_of_stock == true
|
|
|
|
process_payment_completion!
|
|
end
|
|
|
|
def authorize
|
|
load_order_for_authorization
|
|
|
|
return unless params.key?("payment_intent")
|
|
|
|
result = ProcessPaymentIntent.new(params["payment_intent"], @order).call!
|
|
|
|
unless result.success?
|
|
flash.now[:error] = "#{I18n.t('payment_could_not_process')}. #{result.error}"
|
|
end
|
|
|
|
redirect_to order_path(@order)
|
|
end
|
|
|
|
private
|
|
|
|
def load_order_for_authorization
|
|
require_order_authentication!
|
|
|
|
session[:access_token] ||= params[:order_token]
|
|
@order = Spree::Order.find_by(number: params[:order_number]) || current_order
|
|
|
|
if @order
|
|
authorize! :edit, @order, session[:access_token]
|
|
else
|
|
authorize! :create, Spree::Order
|
|
end
|
|
end
|
|
|
|
def require_order_authentication!
|
|
return if session[:access_token] || params[:order_token] || spree_current_user
|
|
|
|
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
|
|
redirect_to root_path(anchor: "login", after_login: request.original_fullpath)
|
|
end
|
|
|
|
def validate_stock
|
|
return if sufficient_stock?
|
|
|
|
cancel_incomplete_payments
|
|
handle_insufficient_stock
|
|
end
|
|
|
|
def validate_payment_intent
|
|
return if valid_payment_intent?
|
|
|
|
processing_failed
|
|
redirect_to order_failed_route
|
|
end
|
|
|
|
def valid_payment_intent?
|
|
@valid_payment_intent ||= params["payment_intent"]&.starts_with?("pi_") &&
|
|
order_and_payment_valid?
|
|
end
|
|
|
|
def order_and_payment_valid?
|
|
@order.state.in?(["payment", "confirmation"]) &&
|
|
last_payment&.state == "requires_authorization" &&
|
|
last_payment&.response_code == params["payment_intent"]
|
|
end
|
|
|
|
def last_payment
|
|
@last_payment ||= Orders::FindPaymentService.new(@order).last_payment
|
|
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.incomplete.each do |payment|
|
|
payment.void_transaction!
|
|
payment.adjustment&.update_columns(eligible: false, state: "finalized")
|
|
end
|
|
flash[:notice] = I18n.t("checkout.payment_cancelled_due_to_stock")
|
|
end
|
|
end
|
|
end
|