Skip to content

Commit

Permalink
Merge pull request #4823 from solidusio/elia/payment-processing-refactor
Browse files Browse the repository at this point in the history
Spree::Payment::Processing refactor
  • Loading branch information
kennyadsl authored Jan 20, 2023
2 parents c6050d7 + a5ec43b commit 36340a8
Showing 1 changed file with 58 additions and 55 deletions.
113 changes: 58 additions & 55 deletions core/app/models/spree/payment/processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,36 @@ def process!
end

def authorize!
handle_payment_preconditions { process_authorization }
return unless check_payment_preconditions!

started_processing!

protect_from_connection_error do
response = payment_method.authorize(
money.money.cents,
source,
gateway_options,
)
pend! if handle_response(response)
end
end

# Captures the entire amount of a payment.
def purchase!
handle_payment_preconditions { process_purchase }
return unless check_payment_preconditions!

started_processing!

protect_from_connection_error do
response = payment_method.purchase(
money.money.cents,
source,
gateway_options,
)
complete! if handle_response(response)
end

capture_events.create!(amount: amount)
end

# Takes the amount in cents to capture.
Expand All @@ -62,7 +86,7 @@ def capture!(capture_amount = nil)
money = ::Money.new(capture_amount, currency)
capture_events.create!(amount: money.to_d)
update!(amount: captured_amount)
handle_response(response, :complete, :failure)
complete! if handle_response(response)
end
end

Expand Down Expand Up @@ -139,77 +163,56 @@ def handle_void_response(response)

private

def process_authorization
started_processing!
gateway_action(source, :authorize, :pend)
end
# @raises Spree::Core::GatewayError
def check_payment_preconditions!
return if processing?
return unless payment_method
return unless payment_method.source_required?

def process_purchase
started_processing!
gateway_action(source, :purchase, :complete)
# This won't be called if gateway_action raises a GatewayError
capture_events.create!(amount: amount)
end

def handle_payment_preconditions(&_block)
unless block_given?
raise ArgumentError.new("handle_payment_preconditions must be called with a block")
unless source
gateway_error(I18n.t('spree.payment_processing_failed'))
end

return if payment_method.nil?
return if !payment_method.source_required?

if source
if !processing?
if payment_method.supports?(source)
yield
else
invalidate!
raise Core::GatewayError.new(I18n.t('spree.payment_method_not_supported'))
end
end
else
raise Core::GatewayError.new(I18n.t('spree.payment_processing_failed'))
unless payment_method.supports?(source)
invalidate!
gateway_error(I18n.t('spree.payment_method_not_supported'))
end
end

def gateway_action(source, action, success_state)
protect_from_connection_error do
response = payment_method.send(action, money.money.cents,
source,
gateway_options)
handle_response(response, success_state, :failure)
end
true
end

def handle_response(response, success_state, failure_state)
# @returns true if the response is successful
# @returns false (and calls #failure) if the response is not successful
def handle_response(response)
record_response(response)

if response.success?
unless response.authorization.nil?
self.response_code = response.authorization
self.avs_response = response.avs_result['code']

if response.cvv_result
self.cvv_response_code = response.cvv_result['code']
self.cvv_response_message = response.cvv_result['message']
end
end
send("#{success_state}!")
else
send(failure_state)
unless response.success?
failure
gateway_error(response)
return false
end

unless response.authorization.nil?
self.response_code = response.authorization
self.avs_response = response.avs_result['code']

if response.cvv_result
self.cvv_response_code = response.cvv_result['code']
self.cvv_response_message = response.cvv_result['message']
end
end

true
end

def record_response(response)
log_entries.create!(details: response.to_yaml)
end

def protect_from_connection_error
yield
yield
rescue ActiveMerchant::ConnectionError => error
gateway_error(error)
gateway_error(error)
end

def gateway_error(error)
Expand Down

0 comments on commit 36340a8

Please sign in to comment.