activemerchant 1.44.1 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -3
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG +48 -0
  5. data/CONTRIBUTORS +12 -0
  6. data/README.md +15 -5
  7. data/lib/active_merchant/billing.rb +2 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/gateway.rb +36 -4
  10. data/lib/active_merchant/billing/gateways/adyen.rb +6 -2
  11. data/lib/active_merchant/billing/gateways/authorize_net.rb +332 -255
  12. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  13. data/lib/active_merchant/billing/gateways/bogus.rb +9 -9
  14. data/lib/active_merchant/billing/gateways/borgun.rb +0 -1
  15. data/lib/active_merchant/billing/gateways/braintree_blue.rb +8 -0
  16. data/lib/active_merchant/billing/gateways/cashnet.rb +17 -10
  17. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  18. data/lib/active_merchant/billing/gateways/conekta.rb +1 -1
  19. data/lib/active_merchant/billing/gateways/cyber_source.rb +1 -1
  20. data/lib/active_merchant/billing/gateways/elavon.rb +3 -3
  21. data/lib/active_merchant/billing/gateways/eway_rapid.rb +114 -13
  22. data/lib/active_merchant/billing/gateways/finansbank.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  24. data/lib/active_merchant/billing/gateways/hps.rb +27 -20
  25. data/lib/active_merchant/billing/gateways/iats_payments.rb +68 -35
  26. data/lib/active_merchant/billing/gateways/litle.rb +36 -1
  27. data/lib/active_merchant/billing/gateways/merchant_one.rb +0 -1
  28. data/lib/active_merchant/billing/gateways/merchant_ware.rb +8 -4
  29. data/lib/active_merchant/billing/gateways/mercury.rb +17 -10
  30. data/lib/active_merchant/billing/gateways/moneris.rb +11 -6
  31. data/lib/active_merchant/billing/gateways/moneris_us.rb +126 -33
  32. data/lib/active_merchant/billing/gateways/money_movers.rb +0 -1
  33. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -1
  34. data/lib/active_merchant/billing/gateways/network_merchants.rb +5 -5
  35. data/lib/active_merchant/billing/gateways/nmi.rb +241 -5
  36. data/lib/active_merchant/billing/gateways/openpay.rb +1 -0
  37. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -1
  38. data/lib/active_merchant/billing/gateways/orbital.rb +6 -4
  39. data/lib/active_merchant/billing/gateways/pay_junction.rb +9 -5
  40. data/lib/active_merchant/billing/gateways/payex.rb +19 -9
  41. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -2
  42. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  43. data/lib/active_merchant/billing/gateways/payscout.rb +0 -2
  44. data/lib/active_merchant/billing/gateways/pin.rb +1 -1
  45. data/lib/active_merchant/billing/gateways/psigate.rb +1 -2
  46. data/lib/active_merchant/billing/gateways/redsys.rb +37 -40
  47. data/lib/active_merchant/billing/gateways/secure_pay.rb +181 -9
  48. data/lib/active_merchant/billing/gateways/stripe.rb +106 -31
  49. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  50. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +38 -10
  51. data/lib/active_merchant/billing/gateways/webpay.rb +14 -0
  52. data/lib/active_merchant/billing/payment_token.rb +21 -0
  53. data/lib/active_merchant/billing/response.rb +2 -1
  54. data/lib/active_merchant/country.rb +6 -1
  55. data/lib/active_merchant/version.rb +1 -1
  56. metadata +8 -3
  57. metadata.gz.sig +0 -0
  58. data/lib/active_merchant/billing/gateways/samurai.rb +0 -130
@@ -32,6 +32,19 @@ module ActiveMerchant #:nodoc:
32
32
  self.homepage_url = 'https://stripe.com/'
33
33
  self.display_name = 'Stripe'
34
34
 
35
+ STANDARD_ERROR_CODE_MAPPING = {
36
+ 'incorrect_number' => STANDARD_ERROR_CODE[:incorrect_number],
37
+ 'invalid_number' => STANDARD_ERROR_CODE[:invalid_number],
38
+ 'invalid_expiry_month' => STANDARD_ERROR_CODE[:invalid_expiry_date],
39
+ 'invalid_expiry_year' => STANDARD_ERROR_CODE[:invalid_expiry_date],
40
+ 'invalid_cvc' => STANDARD_ERROR_CODE[:invalid_cvc],
41
+ 'expired_card' => STANDARD_ERROR_CODE[:expired_card],
42
+ 'incorrect_cvc' => STANDARD_ERROR_CODE[:incorrect_cvc],
43
+ 'incorrect_zip' => STANDARD_ERROR_CODE[:incorrect_zip],
44
+ 'card_declined' => STANDARD_ERROR_CODE[:card_declined],
45
+ 'processing_error' => STANDARD_ERROR_CODE[:processing_error]
46
+ }
47
+
35
48
  def initialize(options = {})
36
49
  requires!(options, :login)
37
50
  @api_key = options[:login]
@@ -41,11 +54,18 @@ module ActiveMerchant #:nodoc:
41
54
  super
42
55
  end
43
56
 
44
- def authorize(money, creditcard, options = {})
45
- post = create_post_for_auth_or_purchase(money, creditcard, options)
46
- post[:capture] = "false"
47
-
48
- commit(:post, 'charges', post, options)
57
+ def authorize(money, payment, options = {})
58
+ MultiResponse.run do |r|
59
+ if payment.is_a?(ApplePayPaymentToken)
60
+ r.process { tokenize_apple_pay_token(payment) }
61
+ payment = StripePaymentToken.new(r.params["token"]) if r.success?
62
+ end
63
+ r.process do |r|
64
+ post = create_post_for_auth_or_purchase(money, payment, options)
65
+ post[:capture] = "false"
66
+ commit(:post, 'charges', post, options)
67
+ end
68
+ end.responses.last
49
69
  end
50
70
 
51
71
  # To create a charge on a card or a token, call
@@ -55,10 +75,17 @@ module ActiveMerchant #:nodoc:
55
75
  # To create a charge on a customer, call
56
76
  #
57
77
  # purchase(money, nil, { :customer => id, ... })
58
- def purchase(money, creditcard, options = {})
59
- post = create_post_for_auth_or_purchase(money, creditcard, options)
60
-
61
- commit(:post, 'charges', post, options)
78
+ def purchase(money, payment, options = {})
79
+ MultiResponse.run do |r|
80
+ if payment.is_a?(ApplePayPaymentToken)
81
+ r.process { tokenize_apple_pay_token(payment) }
82
+ payment = StripePaymentToken.new(r.params["token"]) if r.success?
83
+ end
84
+ r.process do |r|
85
+ post = create_post_for_auth_or_purchase(money, payment, options)
86
+ commit(:post, 'charges', post, options)
87
+ end
88
+ end.responses.last
62
89
  end
63
90
 
64
91
  def capture(money, authorization, options = {})
@@ -88,9 +115,9 @@ module ActiveMerchant #:nodoc:
88
115
  end
89
116
  end
90
117
 
91
- def verify(creditcard, options = {})
118
+ def verify(payment, options = {})
92
119
  MultiResponse.run(:use_first_response) do |r|
93
- r.process { authorize(50, creditcard, options) }
120
+ r.process { authorize(50, payment, options) }
94
121
  r.process(:ignore_result) { void(r.authorization, options) }
95
122
  end
96
123
  end
@@ -113,10 +140,17 @@ module ActiveMerchant #:nodoc:
113
140
  end
114
141
 
115
142
  # Note: creating a new credit card will not change the customer's existing default credit card (use :set_default => true)
116
- def store(creditcard, options = {})
117
- post = {}
143
+ def store(payment, options = {})
118
144
  card_params = {}
119
- add_creditcard(card_params, creditcard, options)
145
+ post = {}
146
+
147
+ if payment.is_a?(ApplePayPaymentToken)
148
+ token_exchange_response = tokenize_apple_pay_token(payment)
149
+ card_params = { card: token_exchange_response.params["token"]["id"] } if token_exchange_response.success?
150
+ else
151
+ add_creditcard(card_params, payment, options)
152
+ end
153
+
120
154
  post[:description] = options[:description] if options[:description]
121
155
  post[:email] = options[:email] if options[:email]
122
156
 
@@ -146,24 +180,56 @@ module ActiveMerchant #:nodoc:
146
180
  commit(:post, "customers/#{CGI.escape(customer_id)}", options, options)
147
181
  end
148
182
 
149
- def unstore(customer_id, card_id = nil, options = {})
150
- if card_id.nil?
183
+ def unstore(customer_id, options = {}, deprecated_options = {})
184
+ if options.kind_of?(String)
185
+ ActiveMerchant.deprecated "Passing the card_id as the 2nd parameter is deprecated. Put it in the options hash instead."
186
+ options = deprecated_options.merge(card_id: options)
187
+ end
188
+
189
+ if options[:card_id]
190
+ commit(:delete, "customers/#{CGI.escape(customer_id)}/cards/#{CGI.escape(options[:card_id])}", nil, options)
191
+ else
151
192
  commit(:delete, "customers/#{CGI.escape(customer_id)}", nil, options)
193
+ end
194
+ end
195
+
196
+ def tokenize_apple_pay_token(apple_pay_payment_token, options = {})
197
+ token_response = api_request(:post, "tokens?pk_token=#{CGI.escape(apple_pay_payment_token.payment_data.to_json)}")
198
+ success = !token_response.key?("error")
199
+
200
+ if success && token_response.key?("id")
201
+ Response.new(success, nil, token: token_response)
152
202
  else
153
- commit(:delete, "customers/#{CGI.escape(customer_id)}/cards/#{CGI.escape(card_id)}", nil, options)
203
+ Response.new(success, token_response["error"]["message"])
154
204
  end
155
205
  end
156
206
 
157
207
  private
158
208
 
159
- def create_post_for_auth_or_purchase(money, creditcard, options)
209
+ class StripePaymentToken < PaymentToken
210
+ def type
211
+ 'stripe'
212
+ end
213
+ end
214
+
215
+ def create_post_for_auth_or_purchase(money, payment, options)
160
216
  post = {}
161
217
  add_amount(post, money, options, true)
162
- add_creditcard(post, creditcard, options)
163
- add_customer(post, creditcard, options)
164
- add_customer_data(post,options)
218
+ if payment.is_a?(StripePaymentToken)
219
+ add_payment_token(post, payment, options)
220
+ else
221
+ add_creditcard(post, payment, options)
222
+ end
223
+ add_customer(post, payment, options)
224
+ add_customer_data(post, options)
165
225
  post[:description] = options[:description]
166
- post[:metadata] = { email: options[:email] } if options[:email]
226
+ post[:statement_description] = options[:statement_description]
227
+
228
+ post[:metadata] = {}
229
+ post[:metadata][:email] = options[:email] if options[:email]
230
+ post[:metadata][:order_id] = options[:order_id] if options[:order_id]
231
+ post.delete(:metadata) if post[:metadata].empty?
232
+
167
233
  add_flags(post, options)
168
234
  add_application_fee(post, options)
169
235
  post
@@ -228,8 +294,12 @@ module ActiveMerchant #:nodoc:
228
294
  end
229
295
  end
230
296
 
231
- def add_customer(post, creditcard, options)
232
- post[:customer] = options[:customer] if options[:customer] && !creditcard.respond_to?(:number)
297
+ def add_payment_token(post, token, options = {})
298
+ post[:card] = token.payment_data["id"]
299
+ end
300
+
301
+ def add_customer(post, payment, options)
302
+ post[:customer] = options[:customer] if options[:customer] && !payment.respond_to?(:number)
233
303
  end
234
304
 
235
305
  def add_flags(post, options)
@@ -280,21 +350,25 @@ module ActiveMerchant #:nodoc:
280
350
  headers
281
351
  end
282
352
 
283
- def commit(method, url, parameters=nil, options = {})
284
- add_expand_parameters(parameters, options) if parameters
285
-
353
+ def api_request(method, endpoint, parameters = nil, options = {})
286
354
  raw_response = response = nil
287
- success = false
288
355
  begin
289
- raw_response = ssl_request(method, self.live_url + url, post_data(parameters), headers(options))
356
+ raw_response = ssl_request(method, self.live_url + endpoint, post_data(parameters), headers(options))
290
357
  response = parse(raw_response)
291
- success = !response.key?("error")
292
358
  rescue ResponseError => e
293
359
  raw_response = e.response.body
294
360
  response = response_error(raw_response)
295
361
  rescue JSON::ParserError
296
362
  response = json_error(raw_response)
297
363
  end
364
+ response
365
+ end
366
+
367
+ def commit(method, url, parameters = nil, options = {})
368
+ add_expand_parameters(parameters, options) if parameters
369
+
370
+ response = api_request(method, url, parameters, options)
371
+ success = !response.key?("error")
298
372
 
299
373
  card = response["card"] || response["active_card"] || {}
300
374
  avs_code = AVS_CODE_TRANSLATOR["line1: #{card["address_line1_check"]}, zip: #{card["address_zip_check"]}"]
@@ -306,7 +380,8 @@ module ActiveMerchant #:nodoc:
306
380
  :test => response.has_key?("livemode") ? !response["livemode"] : false,
307
381
  :authorization => success ? response["id"] : response["error"]["charge"],
308
382
  :avs_result => { :code => avs_code },
309
- :cvv_result => cvc_code
383
+ :cvv_result => cvc_code,
384
+ :error_code => success ? nil : STANDARD_ERROR_CODE_MAPPING[response["error"]["code"]]
310
385
  )
311
386
  end
312
387
 
@@ -0,0 +1,227 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class TnsGateway < Gateway
4
+ self.display_name = 'TNS'
5
+ self.homepage_url = 'http://www.tnsi.com/'
6
+
7
+ # Testing is partitioned by account.
8
+ self.live_url = 'https://secure.na.tnspayments.com/api/rest/version/22/'
9
+
10
+ self.supported_countries = %w(AR AU BR FR DE HK MX NZ SG GB US)
11
+
12
+ self.default_currency = 'USD'
13
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro, :laser]
14
+
15
+ def initialize(options={})
16
+ requires!(options, :userid, :password)
17
+ super
18
+ end
19
+
20
+ def purchase(amount, payment_method, options={})
21
+ MultiResponse.run do |r|
22
+ r.process { authorize(amount, payment_method, options) }
23
+ r.process { capture(amount, r.authorization, options) }
24
+ end
25
+ end
26
+
27
+ def authorize(amount, payment_method, options={})
28
+ post = new_post
29
+ add_invoice(post, amount, options)
30
+ add_reference(post, *new_authorization)
31
+ add_payment_method(post, payment_method)
32
+ add_customer_data(post, options)
33
+
34
+ commit('authorize', post)
35
+ end
36
+
37
+ def capture(amount, authorization, options={})
38
+ post = new_post
39
+ add_invoice(post, amount, options, :transaction)
40
+ add_reference(post, *next_authorization(authorization))
41
+ add_customer_data(post, options)
42
+
43
+ commit('capture', post)
44
+ end
45
+
46
+ def refund(amount, authorization, options={})
47
+ post = new_post
48
+ add_invoice(post, amount, options, :transaction)
49
+ add_reference(post, *next_authorization(authorization))
50
+ add_customer_data(post, options)
51
+
52
+ commit('refund', post)
53
+ end
54
+
55
+ def void(authorization, options={})
56
+ post = new_post
57
+ add_reference(post, *next_authorization(authorization), :targetTransactionId)
58
+
59
+ commit('void', post)
60
+ end
61
+
62
+ def verify(credit_card, options={})
63
+ MultiResponse.run(:use_first_response) do |r|
64
+ r.process { authorize(100, credit_card, options) }
65
+ r.process(:ignore_result) { void(r.authorization, options) }
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def new_post
72
+ {
73
+ order: {},
74
+ sourceOfFunds: {
75
+ provided: {
76
+ card: {
77
+ }
78
+ }
79
+ },
80
+ customer: {},
81
+ billing: {},
82
+ shipping: {},
83
+ transaction: {},
84
+ }
85
+ end
86
+
87
+ def add_invoice(post, amount, options, node=:order)
88
+ post[node][:amount] = amount(amount)
89
+ post[node][:currency] = (options[:currency] || currency(amount))
90
+ end
91
+
92
+ def add_reference(post, orderid, transactionid, transaction_reference, reference_key=:reference)
93
+ post[:orderid] = orderid
94
+ post[:transactionid] = transactionid
95
+ post[:transaction][reference_key] = transaction_reference if transaction_reference
96
+ end
97
+
98
+ def add_payment_method(post, payment_method)
99
+ card = {}
100
+ card[:expiry] = {}
101
+ card[:number] = payment_method.number
102
+ card[:securityCode] = payment_method.verification_value
103
+ card[:expiry][:year] = format(payment_method.year, :two_digits)
104
+ card[:expiry][:month] = format(payment_method.month, :two_digits)
105
+
106
+ post[:sourceOfFunds][:type] = 'CARD'
107
+ post[:sourceOfFunds][:provided][:card].merge!(card)
108
+ end
109
+
110
+ def add_customer_data(post, options)
111
+ billing = {}
112
+ shipping = {}
113
+ customer = {}
114
+ if(billing_address = (options[:billing_address] || options[:address]))
115
+ billing[:address] = {}
116
+ billing[:address][:street] = billing_address[:address1]
117
+ billing[:address][:street2] = billing_address[:address2]
118
+ billing[:address][:city] = billing_address[:city]
119
+ billing[:address][:stateProvince] = billing_address[:state]
120
+ billing[:address][:postcodeZip] = billing_address[:zip]
121
+ billing[:address][:country] = billing_address[:country]
122
+ billing[:phone] = billing_address[:phone]
123
+
124
+ customer[:email] = options[:email] if options[:email]
125
+ customer[:ipaddress] = options[:ip] if options[:ip]
126
+ end
127
+
128
+ if(shipping_address = options[:shipping_address])
129
+ shipping[:address] = {}
130
+ shipping[:address][:street] = shipping_address[:address1]
131
+ shipping[:address][:street2] = shipping_address[:address2]
132
+ shipping[:address][:city] = shipping_address[:city]
133
+ shipping[:address][:stateProvince] = shipping_address[:state]
134
+ shipping[:address][:postcodeZip] = shipping_address[:zip]
135
+ shipping[:address][:shipcountry] = shipping_address[:country]
136
+
137
+ last_name, first_middle_names = split_name(shipping_address[:name])
138
+ shipping[:firstName] = first_middle_names if first_middle_names
139
+ shipping[:lastName] = last_name if last_name
140
+ end
141
+ post[:billing].merge!(billing)
142
+ post[:shipping].merge!(shipping)
143
+ post[:customer].merge!(customer)
144
+ end
145
+
146
+ def commit(action, post)
147
+ url = build_url(post.delete(:orderid), post.delete(:transactionid))
148
+ headers = {
149
+ 'Authorization' => 'Basic ' + Base64.encode64("merchant.#{@options[:userid]}:#{@options[:password]}").strip.delete("\r\n"),
150
+ 'Content-Type' => 'application/json',
151
+ }
152
+ post[:apiOperation] = action.upcase
153
+ raw = parse(ssl_request(:put, url, build_request(post), headers))
154
+
155
+ succeeded = success_from(raw['result'])
156
+ Response.new(
157
+ succeeded,
158
+ message_from(succeeded, raw),
159
+ raw,
160
+ :authorization => authorization_from(post, raw),
161
+ :test => test?
162
+ )
163
+ end
164
+
165
+ def build_url(orderid, transactionid)
166
+ "#{live_url}merchant/#{@options[:userid]}/order/#{orderid}/transaction/#{transactionid}"
167
+ end
168
+
169
+ def build_request(post = {})
170
+ post.to_json
171
+ end
172
+
173
+ def parse(body)
174
+ JSON.parse(body)
175
+ end
176
+
177
+ def success_from(response)
178
+ response == 'SUCCESS'
179
+ end
180
+
181
+ def message_from(succeeded, response)
182
+ if succeeded
183
+ 'Succeeded'
184
+ else
185
+ [
186
+ response['result'],
187
+ response['response'] && response['response']['gatewayCode'],
188
+ response['error'] && response['error']['cause'],
189
+ response['error'] && response['error']['explanation']
190
+ ].compact.join(' - ')
191
+ end
192
+ end
193
+
194
+ def authorization_from(request, response)
195
+ [response['order']['id'], response['transaction']['id']].join('|') if response['order']
196
+ end
197
+
198
+ def split_authorization(authorization)
199
+ authorization.split('|')
200
+ end
201
+
202
+ def new_authorization
203
+ # Must be unique within a merchant id.
204
+ orderid = SecureRandom.uuid
205
+
206
+ # Must be unique within an order id.
207
+ transactionid = '1'
208
+
209
+ # New transactions have no previous reference.
210
+ transaction_reference = nil
211
+ [orderid, transactionid, transaction_reference]
212
+ end
213
+
214
+ def next_authorization(authorization)
215
+ orderid, prev_transactionid = split_authorization(authorization)
216
+ next_transactionid = SecureRandom.uuid
217
+ [orderid, next_transactionid, prev_transactionid]
218
+ end
219
+
220
+ def split_name(full_name)
221
+ return nil unless full_name
222
+ names = full_name.split
223
+ [names.pop, names.join(' ')]
224
+ end
225
+ end
226
+ end
227
+ end
@@ -18,6 +18,25 @@ module ActiveMerchant #:nodoc:
18
18
  :void => 'cc:void'
19
19
  }
20
20
 
21
+ STANDARD_ERROR_CODE_MAPPING = {
22
+ '00011' => STANDARD_ERROR_CODE[:incorrect_number],
23
+ '00012' => STANDARD_ERROR_CODE[:incorrect_number],
24
+ '00013' => STANDARD_ERROR_CODE[:incorrect_number],
25
+ '00014' => STANDARD_ERROR_CODE[:invalid_number],
26
+ '00015' => STANDARD_ERROR_CODE[:invalid_expiry_date],
27
+ '00016' => STANDARD_ERROR_CODE[:invalid_expiry_date],
28
+ '00017' => STANDARD_ERROR_CODE[:expired_card],
29
+ '10116' => STANDARD_ERROR_CODE[:incorrect_cvc],
30
+ '10107' => STANDARD_ERROR_CODE[:incorrect_zip],
31
+ '10109' => STANDARD_ERROR_CODE[:incorrect_address],
32
+ '10110' => STANDARD_ERROR_CODE[:incorrect_address],
33
+ '10111' => STANDARD_ERROR_CODE[:incorrect_address],
34
+ '10127' => STANDARD_ERROR_CODE[:card_declined],
35
+ '10128' => STANDARD_ERROR_CODE[:processing_error],
36
+ '10132' => STANDARD_ERROR_CODE[:processing_error],
37
+ '00043' => STANDARD_ERROR_CODE[:call_issuer]
38
+ }
39
+
21
40
  def initialize(options = {})
22
41
  requires!(options, :login)
23
42
  super
@@ -29,8 +48,10 @@ module ActiveMerchant #:nodoc:
29
48
  add_amount(post, money)
30
49
  add_invoice(post, options)
31
50
  add_credit_card(post, credit_card)
32
- add_address(post, credit_card, options)
33
- add_customer_data(post, options)
51
+ unless credit_card.track_data.present?
52
+ add_address(post, credit_card, options)
53
+ add_customer_data(post, options)
54
+ end
34
55
  add_split_payments(post, options)
35
56
 
36
57
  commit(:authorization, post)
@@ -42,8 +63,10 @@ module ActiveMerchant #:nodoc:
42
63
  add_amount(post, money)
43
64
  add_invoice(post, options)
44
65
  add_credit_card(post, credit_card)
45
- add_address(post, credit_card, options)
46
- add_customer_data(post, options)
66
+ unless credit_card.track_data.present?
67
+ add_address(post, credit_card, options)
68
+ add_customer_data(post, options)
69
+ end
47
70
  add_split_payments(post, options)
48
71
 
49
72
  commit(:purchase, post)
@@ -146,10 +169,15 @@ module ActiveMerchant #:nodoc:
146
169
  end
147
170
 
148
171
  def add_credit_card(post, credit_card)
149
- post[:card] = credit_card.number
150
- post[:cvv2] = credit_card.verification_value if credit_card.verification_value?
151
- post[:expir] = expdate(credit_card)
152
- post[:name] = credit_card.name
172
+ if credit_card.track_data.present?
173
+ post[:magstripe] = credit_card.track_data
174
+ post[:cardpresent] = true
175
+ else
176
+ post[:card] = credit_card.number
177
+ post[:cvv2] = credit_card.verification_value if credit_card.verification_value?
178
+ post[:expir] = expdate(credit_card)
179
+ post[:name] = credit_card.name
180
+ end
153
181
  end
154
182
 
155
183
  # see: http://wiki.usaepay.com/developer/transactionapi#split_payments
@@ -194,12 +222,12 @@ module ActiveMerchant #:nodoc:
194
222
  def commit(action, parameters)
195
223
  url = (test? ? self.test_url : self.live_url)
196
224
  response = parse(ssl_post(url, post_data(action, parameters)))
197
-
198
225
  Response.new(response[:status] == 'Approved', message_from(response), response,
199
226
  :test => test?,
200
227
  :authorization => response[:ref_num],
201
228
  :cvv_result => response[:cvv2_result_code],
202
- :avs_result => { :code => response[:avs_result_code] }
229
+ :avs_result => { :code => response[:avs_result_code] },
230
+ :error_code => STANDARD_ERROR_CODE_MAPPING[response[:error_code]]
203
231
  )
204
232
  end
205
233