Completed
Push — master ( 330dad...b4ceb2 )
by
unknown
12s queued 10s
created

Response.transaction()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
module AuthorizeNet::AIM
2
  # The AIM response class. Handles parsing the response from the gateway.
3
  class Response < AuthorizeNet::KeyValueResponse
4
    # Our MD5 digest generator.
5
    @@digest = OpenSSL::Digest.new('md5')
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using a class variable like @@digest is generally not recommended; did you consider
using an class instance variable instead?
Loading history...
6
7
    include AuthorizeNet::AIM::Fields
8
9
    # Fields to convert to/from booleans.
10
    @@boolean_fields = [:tax_exempt]
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using a class variable like @@boolean_fields is generally not recommended; did you consider
using an class instance variable instead?
Loading history...
11
12
    # Fields to convert to/from BigDecimal.
13
    @@decimal_fields = %i[amount tax freight duty requested balance_on_card]
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using a class variable like @@decimal_fields is generally not recommended; did you consider
using an class instance variable instead?
Loading history...
14
15
    # Constructs a new response object from a +raw_response+ and the +transaction+ that generated
16
    # the +raw_response+. You don't typically construct this object yourself, as AuthorizeNet::AIM::Transaction
17
    # will build one for you when it makes the request to the gateway.
18
    def initialize(raw_response, transaction)
19
      @version = transaction.version
20
      raise "AuthorizeNet gem only supports AIM version 3.1" unless @version.to_s == '3.1'
21
      @raw_response = raw_response
22
      @fields = {}
23
      @transaction = transaction
24
      custom_field_names = transaction.custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym)
25
      @custom_fields = {}
26
      split_on = transaction.delimiter
27
      if @raw_response.is_a?(Net::HTTPOK) || @raw_response.is_a?(Nokogiri::XML::Element)
28
        if @raw_response.is_a?(Net::HTTPOK)
29
          raw_data = @raw_response.body
30
        else
31
          raw_data = @raw_response.text
32
        end
33
        unless transaction.encapsulation_character.nil?
34
          split_on = transaction.encapsulation_character + split_on + transaction.encapsulation_character
35
          raw_data = raw_data[1..raw_data.length - 2]
36
        end
37
        raw_data.split(split_on).each_with_index do |field, index|
38
          if transaction.cp_version.nil?
39
            field_desc = FIELDS
40
          else
41
            field_desc = CP_FIELDS
42
          end
43
          if index < field_desc.length
44
            @fields[field_desc[index]] = field
45
          else
46
            @custom_fields[custom_field_names[index - field_desc.length]] = field
47
          end
48
        end
49
        @fields.delete(nil)
50
        @fields.each do |k, v|
51
          if @@boolean_fields.include?(k)
52
            @fields[k] = value_to_boolean(v)
53
          elsif @@decimal_fields.include?(k)
54
            @fields[k] = value_to_decimal(v)
55
          end
56
        end
57
      end
58
    end
59
60
    # Returns True if the MD5 hash found in the response payload validates using
61
    # the supplied api_login and secret merchant_value (THIS IS NOT YOUR API KEY).
62 View Code Duplication
    def valid_md5?(api_login, merchant_value)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
63
      return false if @fields[:md5_hash].nil?
64
      @@digest.hexdigest("#{merchant_value}#{api_login}#{@fields[:transaction_id]}#{@transaction.fields[:amount]}").casecmp(@fields[:md5_hash]).zero?
65
    end
66
67
    # Returns the current API version that we are adhering to.
68
    attr_reader :version
69
70
    # Check to see if the response indicated success. Success is defined as a 200 OK response indicating
71
    # that the transaction was approved.
72
    def success?
73
      !connection_failure? && approved?
74
    end
75
76
    # Returns true if we failed to open a connection to the gateway or got back a non-200 OK HTTP response.
77
    def connection_failure?
78
      !@raw_response.is_a?(Net::HTTPOK) && !@raw_response.is_a?(Nokogiri::XML::Element)
79
    end
80
81
    # Returns the underlying Net::HTTPResponse object. This has the original response body along with
82
    # headers and such. Note that if an exception is generated while making the request (which happens
83
    # if there is no internet connection for example), you will get the exception object here instead of
84
    # a Net::HTTPResponse object.
85
    def raw
86
      @raw_response
87
    end
88
89
    # Returns the AuthorizeNet::Transaction instance that owns this response.
90
    attr_reader :transaction
91
92
    # Returns the transaction's authorization code. This should be shown to the
93
    # end user.
94
    def authorization_code
95
      @fields[:authorization_code]
96
    end
97
98
    # Returns the transaction's authorization id. You will need this for future void, refund
99
    # and prior authorization capture requests.
100
    def transaction_id
101
      @fields[:transaction_id]
102
    end
103
104
    # Returns the customer id from the response.
105
    def customer_id
106
      @fields[:customer_id]
107
    end
108
109
    # Returns a response code (from AVSResponseCode) indicating the result of any Address Verification
110
    # Service checks.
111
    def avs_response
112
      @fields[:avs_response]
113
    end
114
115
    # Returns the credit card type used in the transaction. The values returned can be found in CardType.
116
    def card_type
117
      @fields[:card_type]
118
    end
119
  end
120
end
121