mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
For some reason the process is now working correctly, the authorization step succeeds and a redirect link is stored in the payment with state pending. The payment state is correctly left at pending. Here we add a check for the redirect path sent by stripe and fail the authorization if there is one (it means the payment would need an extra auth step only available in the frontoffice now and probably through email to customer at some point in the future). For some reason the flash with the authorization failure message is not showing up for the user
145 lines
4.4 KiB
Ruby
145 lines
4.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Spree
|
|
module Admin
|
|
class PaymentsController < Spree::Admin::BaseController
|
|
before_action :load_order, except: [:show]
|
|
before_action :load_payment, only: [:fire, :show]
|
|
before_action :load_data
|
|
before_action :can_transition_to_payment
|
|
|
|
respond_to :html
|
|
|
|
def index
|
|
@payments = @order.payments
|
|
redirect_to spree.new_admin_order_payment_url(@order) if @payments.empty?
|
|
end
|
|
|
|
def new
|
|
@payment = @order.payments.build
|
|
end
|
|
|
|
def create
|
|
@payment = @order.payments.build(object_params)
|
|
load_payment_source
|
|
|
|
begin
|
|
unless @payment.save
|
|
redirect_to spree.admin_order_payments_path(@order)
|
|
return
|
|
end
|
|
|
|
authorize_stripe_sca_payment
|
|
|
|
if @order.completed?
|
|
@payment.process!
|
|
flash[:success] = flash_message_for(@payment, :successfully_created)
|
|
|
|
redirect_to spree.admin_order_payments_path(@order)
|
|
else
|
|
OrderWorkflow.new(@order).complete!
|
|
|
|
flash[:success] = Spree.t(:new_order_completed)
|
|
redirect_to spree.edit_admin_order_url(@order)
|
|
end
|
|
rescue Spree::Core::GatewayError => e
|
|
flash[:error] = e.message.to_s
|
|
redirect_to spree.new_admin_order_payment_path(@order)
|
|
end
|
|
end
|
|
|
|
# When a user fires an event, take them back to where they came from
|
|
# (we can't use respond_override because Spree no longer uses respond_with)
|
|
def fire
|
|
event = params[:e]
|
|
return unless event && @payment.payment_source
|
|
|
|
# Because we have a transition method also called void, we do this to avoid conflicts.
|
|
event = "void_transaction" if event == "void"
|
|
if @payment.public_send("#{event}!")
|
|
flash[:success] = t(:payment_updated)
|
|
else
|
|
flash[:error] = t(:cannot_perform_operation)
|
|
end
|
|
rescue StandardError => e
|
|
flash[:error] = e.message
|
|
ensure
|
|
redirect_to request.referer
|
|
end
|
|
|
|
private
|
|
|
|
def load_payment_source
|
|
if @payment.payment_method.is_a?(Spree::Gateway) &&
|
|
@payment.payment_method.payment_profiles_supported? &&
|
|
params[:card].present? &&
|
|
(params[:card] != 'new')
|
|
@payment.source = CreditCard.find_by(id: params[:card])
|
|
end
|
|
end
|
|
|
|
def object_params
|
|
if params[:payment] &&
|
|
params[:payment_source] &&
|
|
source_params = params.delete(:payment_source)[params[:payment][:payment_method_id]]
|
|
params[:payment][:source_attributes] = source_params
|
|
end
|
|
|
|
params.require(:payment).permit(
|
|
:amount, :payment_method_id,
|
|
source_attributes: ::PermittedAttributes::PaymentSource.attributes
|
|
)
|
|
end
|
|
|
|
def load_data
|
|
@amount = params[:amount] || load_order.total
|
|
|
|
# Only show payments for the order's distributor
|
|
@payment_methods = PaymentMethod.
|
|
available(:back_end).
|
|
select{ |pm| pm.has_distributor? @order.distributor }
|
|
|
|
@payment_method = if @payment&.payment_method
|
|
@payment.payment_method
|
|
else
|
|
@payment_methods.first
|
|
end
|
|
|
|
@previous_cards = @order.credit_cards.with_payment_profile
|
|
end
|
|
|
|
# At this point admin should have passed through Customer Details step
|
|
# where order.next is called which leaves the order in payment step
|
|
#
|
|
# Orders in complete step also allows to access this controller
|
|
#
|
|
# Otherwise redirect user to that step
|
|
def can_transition_to_payment
|
|
return if @order.payment? || @order.complete?
|
|
|
|
flash[:notice] = Spree.t(:fill_in_customer_info)
|
|
redirect_to spree.edit_admin_order_customer_url(@order)
|
|
end
|
|
|
|
def load_order
|
|
@order = Order.find_by!(number: params[:order_id])
|
|
authorize! action, @order
|
|
@order
|
|
end
|
|
|
|
def load_payment
|
|
@payment = Payment.find(params[:id])
|
|
end
|
|
|
|
def authorize_stripe_sca_payment
|
|
return unless @payment.payment_method.class == Spree::Gateway::StripeSCA
|
|
|
|
@payment.authorize!
|
|
return if @payment.pending? && @payment.cvv_response_message.nil?
|
|
|
|
raise Spree::Core::GatewayError, I18n.t('authorization_failure')
|
|
end
|
|
end
|
|
end
|
|
end
|