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