| 1 |  |  | module AuthorizeNet::AIM | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |   # The AIM transaction class. Handles building the transaction payload and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |   # transmitting it to the gateway. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |   class Transaction < AuthorizeNet::KeyValueTransaction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |     # The default options for the constructor. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |     @@option_defaults = { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |       transaction_type: Type::AUTHORIZE_AND_CAPTURE, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |       gateway: :production, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |       test: false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |       allow_split: false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |       delimiter: ',', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |       encapsulation_character: nil, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |       verify_ssl: true, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |       device_type: DeviceType::UNKNOWN, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |       market_type: MarketType::RETAIL | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     # Fields to convert to/from booleans. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     @@boolean_fields = %i[tax_exempt test_request recurring_billing allow_partial_auth delim_data email_customer relay_response] | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     # Fields to convert to/from BigDecimal. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     @@decimal_fields = [:amount] | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     # Constructs an AIM transaction. You can use the new AIM transaction object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     # to issue a request to the payment gateway and parse the response into a new | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     # AuthorizeNet::AIM::Response object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     # +api_login_id+:: Your API login ID, as a string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     # +api_transaction_key+:: Your API transaction key, as a string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     # +options+:: A hash of options. See below for values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     # Options | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     # +transaction_type+:: The type of transaction to perform. Defaults to AuthorizeNet::Type::AUTHORIZE_AND_CAPTURE. This value is only used if run is called directly. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     # +gateway+:: The gateway to submit the transaction to. Can be a URL string, an AuthorizeNet::AIM::Transaction::Gateway constant, or one of the convenience symbols :sandbox, :test, :card_present_test, :card_present_live, :card_present_sandbox, :card_present_production, :production, or :live (:test is an alias for :sandbox, :card_present_test is an alias for :card_present_sandbox, :card_present_production is an alias for :card_present_live, and :live is an alias for :production). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     # +test+:: A boolean indicating if the transaction should be run in test mode or not (defaults to false). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |     # +allow_split+:: A boolean indicating if split transactions should be allowed (defaults to false). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     # +delimiter+:: A single character (as a string) that will be used to delimit the response from the gateway. Defaults to ','. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     # +encapsulation_character+:: A single character (as a string) that will be used to encapsulate each field in the response from the gateway. Defaults to nil. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     # +verify_ssl+:: A boolean indicating if the SSL certificate of the +gateway+ should be verified. Defaults to true. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     # +device_type+:: A constant from DeviceType indicating the type of POS device used in a card present transaction. Defaults to DeviceType::UNKNOWN. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     # +market_type+:: A constant from MarketType indicating your industry. Used for card present transactions. Defaults to MarketType::RETAIL. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     def initialize(api_login_id, api_transaction_key, options = {}) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |       ActiveSupport::Deprecation.warn "use AuthorizeNet::API::Transaction" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |       super() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |       options = @@option_defaults.merge(options) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |       @api_login_id = api_login_id | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |       @api_transaction_key = api_transaction_key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |       @test_mode = options[:test] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |       @response ||= nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |       @delimiter = options[:delimiter] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |       @type = options[:transaction_type] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |       @cp_version = nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |       case options[:gateway] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |       when :sandbox, :test | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         @gateway = Gateway::TEST | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |       when :production, :live | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         @gateway = Gateway::LIVE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |       when :card_present_live, :card_present_production | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         @gateway = Gateway::CARD_PRESENT_LIVE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         @cp_version = '1.0' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |       when :card_present_test, :card_present_sandbox | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         @gateway = Gateway::CARD_PRESENT_TEST | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         @cp_version = '1.0' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |       else | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         @gateway = options[:gateway] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |       @allow_split_transaction = options[:allow_split] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |       @encapsulation_character = options[:encapsulation_character] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |       @verify_ssl = options[:verify_ssl] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |       @market_type = options[:market_type] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |       @device_type = options[:device_type] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |       @solution_id = options[:solution_id] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |     # Checks if the transaction has been configured for test mode or not. Return TRUE if the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     # transaction is a test transaction, FALSE otherwise. All transactions run against the sandbox | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |     # are considered test transactions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |     def test? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |       super || @gateway == Gateway::TEST | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 83 |  |  |     # Returns TRUE if split transactions are allowed, FALSE otherwise. | 
            
                                                                        
                            
            
                                    
            
            
                | 84 |  |  |     def split_transaction_allowed? | 
            
                                                                        
                            
            
                                    
            
            
                | 85 |  |  |       !!@allow_split_transaction | 
            
                                                                        
                            
            
                                    
            
            
                | 86 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     # Returns the current encapsulation character unless there is none, in which case Nil is returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |     attr_reader :encapsulation_character | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     # Returns the gateway to be used for this transaction. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |     attr_reader :gateway | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     # Checks to see if the transaction has a response (meaning it has been submitted to the gateway). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |     # Returns TRUE if a response is present, FALSE otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |     def has_response? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |       [email protected]? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |     # Retrieve the response object (or Nil if transaction hasn't been sent to the gateway). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     attr_reader :response | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     # Returns the current delimiter we are using to parse the fields returned by the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     # gateway. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     attr_reader :delimiter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     # Sets the delimiter used to parse the response from the gateway. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |     attr_writer :delimiter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |     # Submits the transaction to the gateway for processing. Returns a response object. If the transaction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |     # has already been run, it will return nil. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     def run | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |       make_request | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |     # Returns the current card present API version that we are adhering to. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |     attr_reader :cp_version | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |     attr_reader :solution_id | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |     #:enddoc: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |     protected | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |     # An internal method that builds the POST body, submits it to the gateway, and constructs a Response object with the response. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |     def make_request | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |       return nil if has_response? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |       url = URI.parse(@gateway) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |       fields = @fields.merge(type: @type, delim_char: @delimiter, delim_data: "TRUE", login: @api_login_id, tran_key: @api_transaction_key, relay_response: "FALSE") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |       if @cp_version.nil? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |         fields[:version] = @version | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |       else | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         fields.merge!(cp_version: @cp_version, market_type: @market_type, device_type: @device_type, response_format: "1") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |       fields[:test_request] = boolean_to_value(@test_mode) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |       fields[:allow_partial_auth] = 'TRUE' if @allow_split_transaction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |       fields[:encap_char] = @encapsulation_character unless @encapsulation_character.nil? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |       fields[:solution_id] = @solution_id unless @solution_id.nil? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |       fields.each do |k, v| | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         if @@boolean_fields.include?(k) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |           fields[k] = boolean_to_value(v) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         elsif @@decimal_fields.include?(k) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |           fields[k] = decimal_to_value(v) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |       data = fields.collect do |key, val| | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         to_param(key, val) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |       custom_field_keys = @custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |       for key in custom_field_keys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |         data += [to_param(key, @custom_fields[key.to_sym], '')] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |       data.flatten! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |       request = Net::HTTP::Post.new(url.path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |       request.content_type = 'application/x-www-form-urlencoded' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |       request.body = data.join("&") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |       connection = Net::HTTP.new(url.host, url.port) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |       connection.use_ssl = true | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |       if @verify_ssl | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         connection.verify_mode = OpenSSL::SSL::VERIFY_PEER | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |       else | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         connection.verify_mode = OpenSSL::SSL::VERIFY_NONE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |       begin | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         @response = AuthorizeNet::AIM::Response.new((connection.start { |http| http.request(request) }), self) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |       rescue StandardError | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |         @response = AuthorizeNet::AIM::Response.new($ERROR_INFO, self) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |       end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |     end | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |   end | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 171 |  |  | end | 
            
                                                        
            
                                    
            
            
                | 172 |  |  |  |