lib/active_merchant/billing/response.rb
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
class Error < ActiveMerchantError #:nodoc:
end
class Response
attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization, :network_transaction_id
def success?
@success
end
def failure?
!success?
end
def test?
@test
end
def fraud_review?
@fraud_review
end
def initialize(success, message, params = {}, options = {})
@success, @message, @params = success, message, params.stringify_keys
@test = options[:test] || false
@authorization = options[:authorization]
@fraud_review = options[:fraud_review]
@error_code = options[:error_code]
@emv_authorization = options[:emv_authorization]
@network_transaction_id = options[:network_transaction_id]
@avs_result = if options[:avs_result].kind_of?(AVSResult)
options[:avs_result].to_hash
else
AVSResult.new(options[:avs_result]).to_hash
end
@cvv_result = if options[:cvv_result].kind_of?(CVVResult)
options[:cvv_result].to_hash
else
CVVResult.new(options[:cvv_result]).to_hash
end
end
end
class MultiResponse < Response
def self.run(use_first_response = false, &block)
new(use_first_response).tap(&block)
end
attr_reader :responses, :primary_response
def initialize(use_first_response = false)
@responses = []
@use_first_response = use_first_response
@primary_response = nil
end
def process(ignore_result = false)
return unless success?
response = yield
self << response
unless ignore_result
if @use_first_response && response.success?
@primary_response ||= response
else
@primary_response = response
end
end
end
def <<(response)
if response.is_a?(MultiResponse)
response.responses.each { |r| @responses << r }
else
@responses << response
end
end
def success?
(primary_response ? primary_response.success? : true)
end
def avs_result
return @primary_response.try(:avs_result) if @use_first_response
result = responses.reverse.find { |r| r.avs_result['code'].present? }
result.try(:avs_result) || responses.last.try(:avs_result)
end
def cvv_result
return @primary_response.try(:cvv_result) if @use_first_response
result = responses.reverse.find { |r| r.cvv_result['code'].present? }
result.try(:cvv_result) || responses.last.try(:cvv_result)
end
%w(params message test authorization error_code emv_authorization test? fraud_review?).each do |m|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
def #{m}
(@responses.empty? ? nil : primary_response.#{m})
end
RUBY
end
end
end
end