Class: Payment::AuthorizeNet

Inherits:
Base
  • Object
show all
Defined in:
lib/payment/authorize_net.rb

Constant Summary collapse

API_VERSION =

version of the gateway’s API

'3.1'
FIELDS =

map the instance variable names to the gateway’s requested variable names

{
	'type' => 'x_Method',
	'login' => 'x_Login',
	'password' => 'x_Password',
	'transaction_key' => 'x_Tran_Key',
	'type' => 'x_Type',
	'description' => 'x_Description',
	'amount' => 'x_Amount',
	'currency_code' => 'x_Currency_Code',
	'invoice_num' => 'x_Invoice_Num',
	'trans_id' => 'x_Trans_ID',
	'auth_code' => 'x_Auth_Code',
	'cust_id' => 'x_Cust_ID',
	'customer_ip' => 'x_Customer_IP',
	'last_name' => 'x_Last_Name',
	'first_name' => 'x_First_Name',
	'company' => 'x_Company',
	'address' => 'x_Address',
	'city' => 'x_City',
	'state' => 'x_State',
	'zip' => 'x_Zip',
	'country' => 'x_Country',
	'ship_to_last_name' => 'x_Ship_To_Last_Name',
	'ship_to_first_name' => 'x_Ship_To_First_Name',
	'ship_to_address' => 'x_Ship_To_Address',
	'ship_to_city' => 'x_Ship_To_City',
	'ship_to_state' => 'x_Ship_To_State',
	'ship_to_zip' => 'x_Ship_To_Zip',
	'ship_to_country' => 'x_Ship_To_Country',
	'phone' => 'x_Phone',
	'fax' => 'x_Fax',
	'email' => 'x_Email',
	'card_number' => 'x_Card_Num',
	'expiration' => 'x_Exp_Date',
	'card_code' => 'x_Card_Code',
	'echeck_type' => 'x_Echeck_Type',
	'account_name' => 'x_Bank_Acct_Name',
	'account_number' => 'x_Bank_Acct_Num',
	'account_type' => 'x_Bank_Acct_Type',
	'bank_name' => 'x_Bank_Name',
	'bank_aba_code' => 'x_Bank_ABA_Code',
	'customer_org' => 'x_Customer_Organization_Type', 
	'customer_ssn' => 'x_Customer_Tax_ID',
	'drivers_license_num' => 'x_Drivers_License_Num',
	'drivers_license_state' => 'x_Drivers_License_State',
	'drivers_license_dob' => 'x_Drivers_License_DOB',
	'recurring_billing' => 'x_Recurring_Billing',
	'test_request' => 'x_Test_Request',
	'adc_delim_data' => 'x_ADC_Delim_Data',
	'adc_url' => 'x_ADC_URL',
	'version' => 'x_Version',
}
ACTIONS =

map the actions to the merchant’s action names

{
	'normal authorization' => 'AUTH_CAPTURE',
	'authorization only'   => 'AUTH_ONLY',
	'credit'               => 'CREDIT',
	'post authorization'   => 'PRIOR_AUTH_CAPTURE',
	'void'                 => 'VOID',
}

Instance Attribute Summary collapse

Attributes inherited from Base

#account_number, #action, #address, #amount, #authorization, #bank_name, #card_number, #city, #country, #customer_id, #description, #email, #error_message, #expiration, #fax, #invoice_number, #login, #name, #password, #phone, #require_avs, #result_code, #routing_code, #state, #strict_ssl, #test_transaction, #transaction_type, #type, #url, #zip

Instance Method Summary collapse

Methods inherited from Base

#success?

Constructor Details

#initialize(options = {}) ⇒ AuthorizeNet

Returns a new instance of AuthorizeNet.



81
82
83
84
85
86
87
88
89
90
# File 'lib/payment/authorize_net.rb', line 81

def initialize(options = {})
	# set some sensible defaults
	@url = 'https://secure.authorize.net/gateway/transact.dll'
	@adc_delim_data = 'TRUE'
	@adc_url = 'FALSE'
	@version = API_VERSION
	
	# include all provided data
	super options
end

Instance Attribute Details

#avs_codeObject (readonly)

Returns the value of attribute avs_code.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def avs_code
  @avs_code
end

#cavv_responseObject (readonly)

Returns the value of attribute cavv_response.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def cavv_response
  @cavv_response
end

#cvv2_responseObject (readonly)

Returns the value of attribute cvv2_response.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def cvv2_response
  @cvv2_response
end

#first_nameObject

Returns the value of attribute first_name.



13
14
15
# File 'lib/payment/authorize_net.rb', line 13

def first_name
  @first_name
end

#last_nameObject

Returns the value of attribute last_name.



13
14
15
# File 'lib/payment/authorize_net.rb', line 13

def last_name
  @last_name
end

#md5Object (readonly)

Returns the value of attribute md5.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def md5
  @md5
end

#order_numberObject (readonly)

Returns the value of attribute order_number.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def order_number
  @order_number
end

#server_responseObject (readonly)

Returns the value of attribute server_response.



12
13
14
# File 'lib/payment/authorize_net.rb', line 12

def server_response
  @server_response
end

#transaction_keyObject

Returns the value of attribute transaction_key.



13
14
15
# File 'lib/payment/authorize_net.rb', line 13

def transaction_key
  @transaction_key
end

Instance Method Details

#post_dataObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/payment/authorize_net.rb', line 137

def post_data
	prepare_data

	post_array = Array.new
	FIELDS.each do |loc_var, gate_var|
		if @@required.include?(loc_var) && eval("@#{loc_var}").nil?
			raise PaymentError, "The required variable '#{loc_var}' was left empty"
		else
			value = eval "CGI.escape(@#{loc_var}.to_s)"
			post_array << "#{gate_var}=#{value}"
		end
	end

	return post_array.join("&")
end

#prepare_dataObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/payment/authorize_net.rb', line 153

def prepare_data
	# make sensible changes to data
	@card_number = @card_number.to_s.gsub(/[^\d]/, "") unless @card_number.nil?
	
	@test_request = @test_transaction == true ? "TRUE" : "FALSE"

	if @recurring_billing.class != String
		if @recurring_billing == true
			@recurring_billing = "YES"
		elsif @recurring_billing == false
			@recurring_billing = "NO"
		end
	end
	
	@expiration = @expiration.strftime "%m/%y" rescue nil # in case a date or time is passed
	
	@type = (@type.nil? && @card_number) ? 'CC' : @type.upcase
	
	# convert the action
	if ACTIONS.include?(@action)
		@action = ACTIONS[@action]
	elsif ! ACTIONS.has_value?(@action)
		raise PaymentError, "The action '#{@action}' is not valid"
	end		
	
	# add some required fields specific to this payment gateway and the provided data
	@@required.concat %w(type action login test_request adc_delim_data adc_url)

	if @transaction_key.nil?
		@@required.concat %w(password)
	else
		@@required.concat %w(transaction_key)
	end
	
	unless @type == 'VOID'
		if @type == 'ECHECK'
			@@required.concat %w(amount routing_code account_number account_type bank_name account_name account_type)
			@@required.concat %w(customer_org customer_ssn) unless @customer_org.nil?
		elsif @type == 'CC'
			@@required.concat %w(amount)
			if @action == 'PRIOR_AUTH_CAPTURE'
				@@required.concat @order_number ? %w(order_number) : %w(card_number expiration)
			else
				@@required.concat %w(last_name first_name card_number expiration)
			end
		else
			raise PaymentError, "Can't handle transaction type: #{@type}"
		end
	end
	
	@@required.uniq!
end

#submitObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/payment/authorize_net.rb', line 92

def submit			
	uri = URI.parse @url
	http = Net::HTTP.new uri.host, uri.port

	http.verify_mode    = OpenSSL::SSL::VERIFY_NONE if @strict_ssl == false
	http.use_ssl        = true
	
	begin
		response  = http.post uri.path, post_data
	rescue
		@is_success = false
		@error_message = "Could not access #{@url}. Error code #{response.code}. #{response.message}"
		return
	end
	
	col = nil		
	CSV::Reader.parse response.body do |row|
		col ||= row
	end
	
	if col
		@server_response = response.code
		@result_code = col[0].data
		@avs_code = col[5].data
		@order_number = col[6].data
		@md5 = col[37].data
		@cvv2_response = col[38].data
		@cavv_response = col[39].data

		if @result_code == "1" # Approved/Pending/Test
			@is_success = true
			@authorization = col[4].data
		else
			@is_success = false
			@error_code = col[2].data
			@error_message = col[3].data
		end
	else
		@is_success = false
		@error_message = "Could not interpret the result. #{response.body}"
	end
	
	return @is_success
end