activemerchant 1.73.0 → 1.74.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82e5954024edb63baed3b663bb1dee80db73f320
4
- data.tar.gz: 8c6113aa891504bd482096bcd1f0de9f0d44209a
3
+ metadata.gz: 9058f19bf43858097b6bbd6a911b01a62aafa568
4
+ data.tar.gz: 5fc5302b4559796e838bc675a5b03ce61c42aa11
5
5
  SHA512:
6
- metadata.gz: b7bb0c7735d7e7f1d2b12952e13c22a770704a9c468f2d4c0f0c155f284b4d9565833276eb93fbeea4ff15539d41e5987f0dda381198787a13920c0857cd868a
7
- data.tar.gz: 6cb69f41e85f93e904ed140e54c0739eda87cbaf0b550506ac9dee21b1bc96b599ef4b417e06f23cffeff7a085a4e373283f70a346e713a62c882b8d21e1a7d3
6
+ metadata.gz: 792627ab57f85f7d6036a94ad5192e4fa0bc266154bde86f9a0f643ec35a8637c874749a758ff55c34b6069476829fc62b1df17ba59ae749a0e204545e88e503
7
+ data.tar.gz: 9c382d5af0c5c9794c1091b5706c264fd2317b84ea5a9cc6940f599b7981d45d012692f9af77ab5fc8e342035c8340acfbcd6f49cbc10ada944d2c4019bd7dd6
data/CHANGELOG CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+ == Version 1.74.0 (October 24, 2017)
6
+ * Adyen: Update list of supported countries [dtykocki] #2600
7
+ * Authorize.net CIM: Handle multiple error messages [amandapuff] #2537
8
+ * Barclaycard Smartpay: Pass street and house_number fields, in addition to standard address [deedeelavinder] #2603
9
+ * Barclaycard Smartpay: Use authorization pspReference for refunds [davidsantoso] #2599
10
+ * Beanstream: Pass email fields without address [curiousepic] #2615
11
+ * Beanstream: Support recurringPayment for auth, capture, and purchase transactions [dtykocki] #2617
12
+ * Borgun: Add support for USD transactions [dtykocki] #2602
13
+ * Borgun: Include currency code from split authorization for voids [dtykocki] #2605
14
+ * Checkout V2: Expose AVS and CVV results for purchases [dtykocki] #2619
15
+ * Credorax: Update response codes [curiousepic] #2595
16
+ * CyberSource: Support 3DSecure requests [curiousepic] #2624
17
+ * Ebanx: Pass person_type and name for stored cards [curiousepic] #2621
18
+ * Ebanx: Support Store and person_type option [curiousepic] #2604
19
+ * Elavon: Update endpoint URLs [curiousepic] #2608
20
+ * Netbanx: Fix basic auth by sending the account_number and api_key [anotherjosmith] #2616
21
+ * Payeezy: Adds support for store [deedeelavinder] #2591
22
+ * PayU Latam: Set payment_country gateway attribute [curiousepic] #2611
23
+ * Redsys: Support the DKK currency type [bpollack] #2618
24
+ * WePay: Only send ip and device for non-recurring transactions [dtykocki] #2597
25
+
5
26
  == Version 1.73.0 (September 28, 2017)
6
27
  * Adyen: Use original authorization pspReference on Refunds [lyverovski] #2589
7
28
  * Braintree Blue: Explicitly require braintree-ruby version 2.78 [anotherjosmith]
@@ -1777,7 +1798,7 @@ value [jduff]
1777
1798
  * Support default Return class for all Integrations that don't use returns [Soleone]
1778
1799
  * Add support for passing additional options when creating a Notification to all Integrations [Soleone]
1779
1800
  * Update BraintreeBlue#refund to have consistent method signature [Jonathan Rudenberg]
1780
- * Add rails/init.rb for gem campatability in Rails [Rūdolfs Ošiņš]
1801
+ * Add rails/init.rb for gem campatability in Rails [R?dolfs O?i??]
1781
1802
  * Fix Paypal Express response parser [Jonathan Rudenberg]
1782
1803
  * Braintree/Transax: Add tax field [wisq]
1783
1804
 
@@ -2093,7 +2114,7 @@ value [jduff]
2093
2114
  * Update Secure Pay Au to meet specs for MessageInfo elements [cody]
2094
2115
  * Add support for the Australian Secure Pay payment gateway [cody]
2095
2116
  * Allow LinkPoint cancellations for recurring billing. [yanagimoto.shin]
2096
- * Add support for Åland Islands to the country list [cody]
2117
+ * Add support for ?land Islands to the country list [cody]
2097
2118
 
2098
2119
  == Version 1.3.1 (January 28, 2008)
2099
2120
 
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
7
7
  self.test_url = 'https://pal-test.adyen.com/pal/servlet/Payment/v18'
8
8
  self.live_url = 'https://pal-live.adyen.com/pal/servlet/Payment/v18'
9
9
 
10
- self.supported_countries = ['AD','AE','AF','AG','AI','AL','AM','AO','AQ','AR','AS','AT','AU','AW','AX','AZ','BA','BB','BD','BE','BF','BG','BH','BI','BJ','BL','BM','BN','BO','BQ','BR','BS','BT','BV','BW','BY','BZ','CA','CC','CD','CF','CG','CH','CI','CK','CL','CM','CN','CO','CR','CU','CV','CW','CX','CY','CZ','DE','DJ','DK','DM','DO','DZ','EC','EE','EG','EH','ER','ES','ET','FI','FJ','FK','FM','FO','FR','GA','GB','GD','GE','GF','GG','GH','GI','GL','GM','GN','GP','GQ','GR','GS','GT','GU','GW','GY','HK','HM','HN','HR','HT','HU','ID','IE','IL','IM','IN','IO','IQ','IR','IS','IT','JE','JM','JO','JP','KE','KG','KH','KI','KM','KN','KP','KR','KW','KY','KZ','LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY','MA','MC','MD','ME','MF','MG','MH','MK','ML','MM','MN','MO','MP','MQ','MR','MS','MT','MU','MV','MW','MX','MY','MZ','NA','NC','NE','NF','NG','NI','NL','NO','NP','NR','NU','NZ','OM','PA','PE','PF','PG','PH','PK','PL','PM','PN','PR','PS','PT','PW','PY','QA','RE','RO','RS','RU','RW','SA','SB','SC','SD','SE','SG','SH','SI','SJ','SK','SL','SM','SN','SO','SR','SS','ST','SV','SX','SY','SZ','TC','TD','TF','TG','TH','TJ','TK','TL','TM','TN','TO','TR','TT','TV','TW','TZ','UA','UG','UM','US','UY','UZ','VA','VC','VE','VG','VI','VN','VU','WF','WS','YE','YT','ZA','ZM','ZW']
10
+ self.supported_countries = ['AT','AU','BE','BG','BR','CH','CY','CZ','DE','DK','EE','ES','FI','FR','GB','GI','GR','HK','HU','IE','IS','IT','LI','LT','LU','LV','MC','MT','MX','NL','NO','PL','PT','RO','SE','SG','SK','SI','US']
11
11
  self.default_currency = 'USD'
12
12
  self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover]
13
13
 
@@ -858,7 +858,9 @@ module ActiveMerchant #:nodoc:
858
858
 
859
859
  response_params = parse(action, xml)
860
860
 
861
- message = response_params['messages']['message']['text']
861
+ message_element= response_params["messages"]["message"]
862
+ first_error = message_element.is_a?(Array) ? message_element.first : message_element
863
+ message = first_error['text']
862
864
  test_mode = @options[:test_requests] || message =~ /Test Mode/
863
865
  success = response_params['messages']['result_code'] == 'Ok'
864
866
  response_params['direct_response'] = parse_direct_response(response_params['direct_response']) if response_params['direct_response']
@@ -867,7 +869,7 @@ module ActiveMerchant #:nodoc:
867
869
  response_options = {}
868
870
  response_options[:test] = test_mode
869
871
  response_options[:authorization] = transaction_id || response_params['customer_profile_id'] || (response_params['profile'] ? response_params['profile']['customer_profile_id'] : nil)
870
- response_options[:error_code] = response_params['messages']['message']['code'] unless success
872
+ response_options[:error_code] = first_error['code'] unless success
871
873
 
872
874
  Response.new(success, message, response_params, response_options)
873
875
  end
@@ -33,15 +33,8 @@ module ActiveMerchant #:nodoc:
33
33
  post = payment_request(money, options)
34
34
  post[:amount] = amount_hash(money, options[:currency])
35
35
  post[:card] = credit_card_hash(creditcard)
36
-
37
- if address = (options[:billing_address] || options[:address])
38
- post[:billingAddress] = address_hash(address)
39
- end
40
-
41
- if options[:shipping_address]
42
- post[:deliveryAddress] = address_hash(options[:shipping_address])
43
- end
44
-
36
+ post[:billingAddress] = billing_address_hash(options) if options[:billing_address]
37
+ post[:deliveryAddress] = shipping_address_hash(options) if options[:shipping_address]
45
38
  commit('authorise', post)
46
39
  end
47
40
 
@@ -139,7 +132,7 @@ module ActiveMerchant #:nodoc:
139
132
  response,
140
133
  test: test?,
141
134
  avs_result: AVSResult.new(:code => parse_avs_code(response)),
142
- authorization: response['recurringDetailReference'] || response['pspReference']
135
+ authorization: response['recurringDetailReference'] || authorization_from(post, response)
143
136
  )
144
137
 
145
138
  rescue ResponseError => e
@@ -158,6 +151,13 @@ module ActiveMerchant #:nodoc:
158
151
  raise
159
152
  end
160
153
 
154
+ def authorization_from(parameters, response)
155
+ authorization = [parameters[:originalReference], response['pspReference']].compact
156
+
157
+ return nil if authorization.empty?
158
+ return authorization.join("#")
159
+ end
160
+
161
161
  def parse_avs_code(response)
162
162
  AVS_MAPPING[response["avsResult"][0..1].strip] if response["avsResult"]
163
163
  end
@@ -223,17 +223,41 @@ module ActiveMerchant #:nodoc:
223
223
  end
224
224
  end
225
225
 
226
- def address_hash(address)
227
- full_address = "#{address[:address1]} #{address[:address2]}" if address
228
- street = address[:street] if address[:street]
229
- house = address[:houseNumberOrName] ? address[:houseNumberOrName] : full_address.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ')
226
+ def billing_address_hash(options)
227
+ address = options[:address] || options[:billing_address] if options[:address] || options[:billing_address]
228
+ street = options[:street] || parse_street(address)
229
+ house = options[:house_number] || parse_house_number(address)
230
+
231
+ create_address_hash(address, house, street)
232
+ end
233
+
234
+ def shipping_address_hash(options)
235
+ address = options[:shipping_address]
236
+ street = options[:shipping_street] || parse_street(address)
237
+ house = options[:shipping_house_number] || parse_house_number(address)
230
238
 
239
+ create_address_hash(address, house, street)
240
+ end
241
+
242
+ def parse_street(address)
243
+ address_to_parse = "#{address[:address1]} #{address[:address2]}"
244
+ street = address[:street] || address_to_parse.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
245
+ street.empty? ? "Not Provided" : street
246
+ end
247
+
248
+ def parse_house_number(address)
249
+ address_to_parse = "#{address[:address1]} #{address[:address2]}"
250
+ house = address[:houseNumberOrName] || address_to_parse.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ')
251
+ house.empty? ? "Not Provided" : house
252
+ end
253
+
254
+ def create_address_hash(address, house, street)
231
255
  hash = {}
256
+ hash[:houseNumberOrName] = house
257
+ hash[:street] = street
232
258
  hash[:city] = address[:city] if address[:city]
233
- hash[:street] = street || full_address.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
234
- hash[:houseNumberOrName] = house.empty? ? "Not Provided" : house
235
- hash[:postalCode] = address[:zip] if address[:zip]
236
259
  hash[:stateOrProvince] = address[:state] if address[:state]
260
+ hash[:postalCode] = address[:zip] if address[:zip]
237
261
  hash[:country] = address[:country] if address[:country]
238
262
  hash
239
263
  end
@@ -259,10 +283,14 @@ module ActiveMerchant #:nodoc:
259
283
  def modification_request(reference, options)
260
284
  hash = {}
261
285
  hash[:merchantAccount] = @options[:merchant]
262
- hash[:originalReference] = reference if reference
286
+ hash[:originalReference] = psp_reference_from(reference)
263
287
  hash.keep_if { |_, v| v }
264
288
  end
265
289
 
290
+ def psp_reference_from(authorization)
291
+ authorization.nil? ? nil : authorization.split("#").first
292
+ end
293
+
266
294
  def payment_request(money, options)
267
295
  hash = {}
268
296
  hash[:merchantAccount] = @options[:merchant]
@@ -75,6 +75,7 @@ module ActiveMerchant #:nodoc:
75
75
  add_address(post, options)
76
76
  add_transaction_type(post, :authorization)
77
77
  add_customer_ip(post, options)
78
+ add_recurring_payment(post, options)
78
79
  commit(post)
79
80
  end
80
81
 
@@ -86,6 +87,7 @@ module ActiveMerchant #:nodoc:
86
87
  add_address(post, options)
87
88
  add_transaction_type(post, purchase_action(source))
88
89
  add_customer_ip(post, options)
90
+ add_recurring_payment(post, options)
89
91
  commit(post)
90
92
  end
91
93
 
@@ -138,7 +138,7 @@ module ActiveMerchant #:nodoc:
138
138
 
139
139
  # The homepage URL of the gateway
140
140
  base.homepage_url = 'http://www.beanstream.com/'
141
- base.live_url = 'https://www.beanstream.com/scripts/process_transaction.asp'
141
+ base.live_url = 'https://api.na.bambora.com/scripts/process_transaction.asp'
142
142
 
143
143
  # The name of the gateway
144
144
  base.display_name = 'Beanstream.com'
@@ -161,6 +161,7 @@ module ActiveMerchant #:nodoc:
161
161
  add_amount(post, money)
162
162
  add_reference(post, reference)
163
163
  add_transaction_type(post, :capture)
164
+ add_recurring_payment(post, options)
164
165
  commit(post)
165
166
  end
166
167
 
@@ -221,11 +222,13 @@ module ActiveMerchant #:nodoc:
221
222
  end
222
223
 
223
224
  def add_address(post, options)
225
+ post[:ordEmailAddress] = options[:email] if options[:email]
226
+ post[:shipEmailAddress] = options[:shipping_email] || options[:email] if options[:email]
227
+
224
228
  prepare_address_for_non_american_countries(options)
225
229
 
226
230
  if billing_address = options[:billing_address] || options[:address]
227
231
  post[:ordName] = billing_address[:name]
228
- post[:ordEmailAddress] = options[:email]
229
232
  post[:ordPhoneNumber] = billing_address[:phone]
230
233
  post[:ordAddress1] = billing_address[:address1]
231
234
  post[:ordAddress2] = billing_address[:address2]
@@ -234,9 +237,9 @@ module ActiveMerchant #:nodoc:
234
237
  post[:ordPostalCode] = billing_address[:zip]
235
238
  post[:ordCountry] = billing_address[:country]
236
239
  end
240
+
237
241
  if shipping_address = options[:shipping_address]
238
242
  post[:shipName] = shipping_address[:name]
239
- post[:shipEmailAddress] = options[:email]
240
243
  post[:shipPhoneNumber] = shipping_address[:phone]
241
244
  post[:shipAddress1] = shipping_address[:address1]
242
245
  post[:shipAddress2] = shipping_address[:address2]
@@ -263,6 +266,10 @@ module ActiveMerchant #:nodoc:
263
266
  end
264
267
  end
265
268
 
269
+ def add_recurring_payment(post, options)
270
+ post[:recurringPayment] = true if options[:recurring].to_s == 'true'
271
+ end
272
+
266
273
  def add_invoice(post, options)
267
274
  post[:trnOrderNumber] = options[:order_id]
268
275
  post[:trnComments] = options[:description]
@@ -465,4 +472,3 @@ module ActiveMerchant #:nodoc:
465
472
  end
466
473
  end
467
474
  end
468
-
@@ -26,7 +26,6 @@ module ActiveMerchant #:nodoc:
26
26
  post[:TransType] = '1'
27
27
  add_invoice(post, money, options)
28
28
  add_payment_method(post, payment)
29
-
30
29
  commit('sale', post)
31
30
  end
32
31
 
@@ -35,7 +34,6 @@ module ActiveMerchant #:nodoc:
35
34
  post[:TransType] = '5'
36
35
  add_invoice(post, money, options)
37
36
  add_payment_method(post, payment)
38
-
39
37
  commit('authonly', post)
40
38
  end
41
39
 
@@ -57,9 +55,10 @@ module ActiveMerchant #:nodoc:
57
55
 
58
56
  def void(authorization, options={})
59
57
  post = {}
60
- # TransType and TrAmount must match original values from auth or purchase.
61
- _, _, _, _, _, transtype, tramount = split_authorization(authorization)
58
+ # TransType, TrAmount, and currency must match original values from auth or purchase.
59
+ _, _, _, _, _, transtype, tramount, currency = split_authorization(authorization)
62
60
  post[:TransType] = transtype
61
+ options[:currency] = options[:currency] || CURRENCY_CODES.key(currency)
63
62
  add_invoice(post, tramount.to_i, options)
64
63
  add_reference(post, authorization)
65
64
  commit('void', post)
@@ -80,6 +79,7 @@ module ActiveMerchant #:nodoc:
80
79
  CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
81
80
  CURRENCY_CODES["ISK"] = "352"
82
81
  CURRENCY_CODES["EUR"] = "978"
82
+ CURRENCY_CODES["USD"] = "840"
83
83
 
84
84
  def add_invoice(post, money, options)
85
85
  post[:TrAmount] = amount(money)
@@ -95,7 +95,7 @@ module ActiveMerchant #:nodoc:
95
95
  end
96
96
 
97
97
  def add_reference(post, authorization)
98
- dateandtime, batch, transaction, rrn, authcode, _, _ = split_authorization(authorization)
98
+ dateandtime, batch, transaction, rrn, authcode, _, _, _ = split_authorization(authorization)
99
99
  post[:DateAndTime] = dateandtime
100
100
  post[:Batch] = batch
101
101
  post[:Transaction] = transaction
@@ -166,13 +166,14 @@ module ActiveMerchant #:nodoc:
166
166
  response[:rrn],
167
167
  response[:authcode],
168
168
  response[:transtype],
169
- response[:tramount]
169
+ response[:tramount],
170
+ response[:trcurrency]
170
171
  ].join("|")
171
172
  end
172
173
 
173
174
  def split_authorization(authorization)
174
- dateandtime, batch, transaction, rrn, authcode, transtype, tramount = authorization.split("|")
175
- [dateandtime, batch, transaction, rrn, authcode, transtype, tramount]
175
+ dateandtime, batch, transaction, rrn, authcode, transtype, tramount, currency = authorization.split("|")
176
+ [dateandtime, batch, transaction, rrn, authcode, transtype, tramount, currency]
176
177
  end
177
178
 
178
179
  def headers
@@ -17,10 +17,24 @@ module ActiveMerchant #:nodoc:
17
17
  end
18
18
 
19
19
  def purchase(amount, payment_method, options={})
20
- MultiResponse.run do |r|
20
+ multi = MultiResponse.run do |r|
21
21
  r.process { authorize(amount, payment_method, options) }
22
22
  r.process { capture(amount, r.authorization, options) }
23
23
  end
24
+
25
+ merged_params = multi.responses.map { |r| r.params }.reduce({}, :merge)
26
+ succeeded = success_from(merged_params)
27
+
28
+ Response.new(
29
+ succeeded,
30
+ message_from(succeeded, merged_params),
31
+ merged_params,
32
+ authorization: authorization_from(merged_params),
33
+ avs_result: avs_result(:purchase, succeeded, merged_params),
34
+ cvv_result: cvv_result(:purchase, succeeded, merged_params),
35
+ error_code: error_code_from(succeeded, merged_params),
36
+ test: test?
37
+ )
24
38
  end
25
39
 
26
40
  def authorize(amount, payment_method, options={})
@@ -98,8 +112,8 @@ module ActiveMerchant #:nodoc:
98
112
  address = options[:billing_address]
99
113
  if(address && post[:card])
100
114
  post[:card][:billingDetails] = {}
101
- post[:card][:billingDetails][:address1] = address[:address1]
102
- post[:card][:billingDetails][:address2] = address[:address2]
115
+ post[:card][:billingDetails][:addressLine1] = address[:address1]
116
+ post[:card][:billingDetails][:addressLine2] = address[:address2]
103
117
  post[:card][:billingDetails][:city] = address[:city]
104
118
  post[:card][:billingDetails][:state] = address[:state]
105
119
  post[:card][:billingDetails][:country] = address[:country]
@@ -125,8 +139,8 @@ module ActiveMerchant #:nodoc:
125
139
  authorization: authorization_from(response),
126
140
  error_code: error_code_from(succeeded, response),
127
141
  test: test?,
128
- avs_result: avs_result(action, response),
129
- cvv_result: cvv_result(action, response))
142
+ avs_result: avs_result(action, succeeded, response),
143
+ cvv_result: cvv_result(action, succeeded, response))
130
144
  end
131
145
 
132
146
  def headers
@@ -148,12 +162,20 @@ module ActiveMerchant #:nodoc:
148
162
  test? ? test_url : live_url
149
163
  end
150
164
 
151
- def avs_result(action, response)
152
- action == :purchase ? AVSResult.new(code: response["card"]["avsCheck"]) : nil
165
+ def avs_result(action, succeeded, response)
166
+ if succeeded
167
+ action == :purchase ? AVSResult.new(code: response["card"]["avsCheck"]) : nil
168
+ else
169
+ nil
170
+ end
153
171
  end
154
172
 
155
- def cvv_result(action, response)
156
- action == :purchase ? CVVResult.new(response["card"]["cvvCheck"]) : nil
173
+ def cvv_result(action, succeeded, response)
174
+ if succeeded
175
+ action == :purchase ? CVVResult.new(response["card"]["cvvCheck"]) : nil
176
+ else
177
+ nil
178
+ end
157
179
  end
158
180
 
159
181
  def parse(body)
@@ -30,71 +30,87 @@ module ActiveMerchant #:nodoc:
30
30
  "03" => "Invalid merchant",
31
31
  "04" => "Pick up card",
32
32
  "05" => "Do not Honour",
33
- "06" => "Invalid Transaction for Terminal",
33
+ "06" => "Error",
34
34
  "07" => "Pick up card special condition",
35
- "08" => "Time-Out",
36
- "09" => "No Original",
35
+ "08" => "Honour with identification",
36
+ "09" => "Request in progress",
37
37
  "10" => "Approved for partial amount",
38
- "11" => "Partial Approval",
39
- "12" => "Invalid transaction card / issuer / acquirer",
38
+ "11" => "Approved (VIP)",
39
+ "12" => "Invalid transaction",
40
40
  "13" => "Invalid amount",
41
41
  "14" => "Invalid card number",
42
- "17" => "Invalid Capture date (terminal business date)",
43
- "19" => "System Error; Re-enter transaction",
44
- "20" => "No From Account",
45
- "21" => "No To Account",
46
- "22" => "No Checking Account",
47
- "23" => "No Saving Account",
48
- "24" => "No Credit Account",
42
+ "15" => "No such issuer",
43
+ "16" => "Approved, update track 3",
44
+ "17" => "Customer cancellation",
45
+ "18" => "Customer dispute",
46
+ "19" => "Re-enter transaction",
47
+ "20" => "Invalid response",
48
+ "21" => "No action taken",
49
+ "22" => "Suspected malfunction",
50
+ "23" => "Unacceptable transaction fee",
51
+ "24" => "File update not supported by receiver",
52
+ "25" => "No such record",
53
+ "26" => "Duplicate record update, old record replaced",
54
+ "27" => "File update field edit error",
55
+ "28" => "File locked out while update",
56
+ "29" => "File update error, contact acquirer",
49
57
  "30" => "Format error",
50
- "34" => "Implausible card data",
58
+ "31" => "Issuer signed-off",
59
+ "32" => "Completed partially",
60
+ "33" => "Pick-up, expired card",
61
+ "34" => "Suspect Fraud",
62
+ "35" => "Pick-up, card acceptor contact acquirer",
63
+ "36" => "Pick up, card restricted",
64
+ "37" => "Pick up, call acquirer security",
65
+ "38" => "Pick up, Allowable PIN tries exceeded",
51
66
  "39" => "Transaction Not Allowed",
67
+ "40" => "Requested function not supported",
52
68
  "41" => "Lost Card, Pickup",
53
- "42" => "Special Pickup",
54
- "43" => "Hot Card, Pickup (if possible)",
55
- "44" => "Pickup Card",
69
+ "42" => "No universal account",
70
+ "43" => "Pick up, stolen card",
71
+ "44" => "No investment account",
72
+ "50" => "Do not renew",
56
73
  "51" => "Not sufficient funds",
57
74
  "52" => "No checking Account",
58
75
  "53" => "No savings account",
59
76
  "54" => "Expired card",
60
77
  "55" => "Pin incorrect",
78
+ "56" => "No card record",
61
79
  "57" => "Transaction not allowed for cardholder",
62
80
  "58" => "Transaction not allowed for merchant",
63
81
  "59" => "Suspected Fraud",
82
+ "60" => "Card acceptor contact acquirer",
64
83
  "61" => "Exceeds withdrawal amount limit",
65
84
  "62" => "Restricted card",
66
- "63" => "MAC Key Error",
85
+ "63" => "Security violation",
86
+ "64" => "Wrong original amount",
67
87
  "65" => "Activity count limit exceeded",
68
- "66" => "Exceeds Acquirer Limit",
69
- "67" => "Retain Card; no reason specified",
70
- "68" => "Response received too late",
88
+ "66" => "Call acquirers security department",
89
+ "67" => "Card to be picked up at ATM",
90
+ "68" => "Response received too late.",
91
+ "70" => "Invalid transaction; contact card issuer",
92
+ "71" => "Decline PIN not changed",
71
93
  "75" => "Pin tries exceeded",
72
- "76" => "Invalid Account",
73
- "77" => "Issuer Does Not Participate In The Service",
74
- "78" => "Function Not Available",
75
- "79" => "Key Validation Error",
76
- "80" => "Approval for Purchase Amount Only",
77
- "81" => "Unable to Verify PIN",
94
+ "76" => "Wrong PIN, number of PIN tries exceeded",
95
+ "77" => "Wrong Reference No.",
96
+ "78" => "Record Not Found",
97
+ "79" => "Already reversed",
98
+ "80" => "Network error",
99
+ "81" => "Foreign network error / PIN cryptographic error",
78
100
  "82" => "Time out at issuer system",
79
- "83" => "Not declined (Valid for all zero amount transactions)",
80
- "84" => "Invalid Life Cycle of transaction",
81
- "85" => "Not declined",
101
+ "83" => "Transaction failed",
102
+ "84" => "Pre-authorization timed out",
103
+ "85" => "No reason to decline",
82
104
  "86" => "Cannot verify pin",
83
105
  "87" => "Purchase amount only, no cashback allowed",
84
106
  "88" => "MAC sync Error",
85
- "89" => "Security Violation",
107
+ "89" => "Authentication failure",
86
108
  "91" => "Issuer not available",
87
109
  "92" => "Unable to route at acquirer Module",
88
- "93" => "Transaction cannot be completed",
89
- "94" => "Duplicate transaction",
90
- "95" => "Contact Acquirer",
110
+ "93" => "Cannot be completed, violation of law",
111
+ "94" => "Duplicate Transmission",
112
+ "95" => "Reconcile error / Auth Not found",
91
113
  "96" => "System malfunction",
92
- "97" => "No Funds Transfer",
93
- "98" => "Duplicate Reversal",
94
- "99" => "Duplicate Transaction",
95
- "N3" => "Cash Service Not Available",
96
- "N4" => "Cash Back Request Exceeds Issuer Limit",
97
- "N7" => "N7 (visa), Decline CVV2 failure",
98
114
  "R0" => "Stop Payment Order",
99
115
  "R1" => "Revocation of Authorisation Order",
100
116
  "R3" => "Revocation of all Authorisations Order"
@@ -258,6 +258,7 @@ module ActiveMerchant #:nodoc:
258
258
  add_decision_manager_fields(xml, options)
259
259
  add_mdd_fields(xml, options)
260
260
  add_auth_service(xml, creditcard_or_reference, options)
261
+ xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service]
261
262
  add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference)
262
263
  add_business_rules_data(xml, creditcard_or_reference, options)
263
264
  xml.target!
@@ -294,6 +295,7 @@ module ActiveMerchant #:nodoc:
294
295
  add_check_service(xml)
295
296
  else
296
297
  add_purchase_service(xml, payment_method_or_reference, options)
298
+ xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service]
297
299
  add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference)
298
300
  add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card]
299
301
  end
@@ -24,7 +24,8 @@ module ActiveMerchant #:nodoc:
24
24
  authorize: "direct",
25
25
  capture: "capture",
26
26
  refund: "refund",
27
- void: "cancel"
27
+ void: "cancel",
28
+ store: "token"
28
29
  }
29
30
 
30
31
  HTTP_METHOD = {
@@ -32,7 +33,8 @@ module ActiveMerchant #:nodoc:
32
33
  authorize: :post,
33
34
  capture: :get,
34
35
  refund: :post,
35
- void: :get
36
+ void: :get,
37
+ store: :post
36
38
  }
37
39
 
38
40
  def initialize(options={})
@@ -46,9 +48,10 @@ module ActiveMerchant #:nodoc:
46
48
  add_operation(post)
47
49
  add_invoice(post, money, options)
48
50
  add_customer_data(post, payment, options)
49
- add_payment(post, payment)
51
+ add_card_or_token(post, payment)
50
52
  add_address(post, options)
51
- add_customer_responsible_person(post, payment, options) if post[:payment][:country] == 'BR'
53
+ add_customer_responsible_person(post, payment, options)
54
+
52
55
  commit(:purchase, post)
53
56
  end
54
57
 
@@ -58,9 +61,9 @@ module ActiveMerchant #:nodoc:
58
61
  add_operation(post)
59
62
  add_invoice(post, money, options)
60
63
  add_customer_data(post, payment, options)
61
- add_payment(post, payment)
64
+ add_card_or_token(post, payment)
62
65
  add_address(post, options)
63
- add_customer_responsible_person(post, payment, options) if post[:payment][:country] == 'BR'
66
+ add_customer_responsible_person(post, payment, options)
64
67
  post[:payment][:creditcard][:auto_capture] = false
65
68
 
66
69
  commit(:authorize, post)
@@ -94,6 +97,15 @@ module ActiveMerchant #:nodoc:
94
97
  commit(:void, post)
95
98
  end
96
99
 
100
+ def store(credit_card, options={})
101
+ post = {}
102
+ add_integration_key(post)
103
+ add_payment_details(post, credit_card)
104
+ post[:country] = customer_country(options)
105
+
106
+ commit(:store, post)
107
+ end
108
+
97
109
  def verify(credit_card, options={})
98
110
  MultiResponse.run(:use_first_response) do |r|
99
111
  r.process { authorize(100, credit_card, options) }
@@ -127,17 +139,20 @@ module ActiveMerchant #:nodoc:
127
139
  end
128
140
 
129
141
  def add_customer_data(post, payment, options)
130
- post[:payment][:name] = payment.name
142
+ post[:payment][:name] = customer_name(payment, options)
131
143
  post[:payment][:email] = options[:email] || "unspecified@example.com"
132
144
  post[:payment][:document] = options[:document]
133
145
  post[:payment][:birth_date] = options[:birth_date] if options[:birth_date]
134
146
  end
135
147
 
136
- def add_customer_responsible_person(post, payment, options)
137
- post[:payment][:responsible] = {}
138
- post[:payment][:responsible][:name] = payment.name
139
- post[:payment][:responsible][:document] = options[:document]
140
- post[:payment][:responsible][:birth_date] = options[:birth_date] if options[:birth_date]
148
+ def add_customer_responsible_person(post, payment, options)
149
+ post[:payment][:person_type] = options[:person_type] if options[:person_type]
150
+ if options[:person_type] && options[:person_type].downcase == 'business'
151
+ post[:payment][:responsible] = {}
152
+ post[:payment][:responsible][:name] = customer_name(payment, options)
153
+ post[:payment][:responsible][:document] = options[:document] if options[:document]
154
+ post[:payment][:responsible][:birth_date] = options[:birth_date] if options[:birth_date]
155
+ end
141
156
  end
142
157
 
143
158
  def add_address(post, options)
@@ -147,7 +162,7 @@ module ActiveMerchant #:nodoc:
147
162
  post[:payment][:city] = address[:city]
148
163
  post[:payment][:state] = address[:state]
149
164
  post[:payment][:zipcode] = address[:zip]
150
- post[:payment][:country] = address[:country]
165
+ post[:payment][:country] = address[:country].downcase
151
166
  post[:payment][:phone_number] = address[:phone]
152
167
  end
153
168
  end
@@ -159,14 +174,30 @@ module ActiveMerchant #:nodoc:
159
174
  post[:payment][:instalments] = options[:instalments] || 1
160
175
  end
161
176
 
162
- def add_payment(post, payment)
163
- post[:payment][:payment_type_code] = CARD_BRAND[payment.brand.to_sym]
164
- post[:payment][:creditcard] = {
165
- card_number: payment.number,
166
- card_name: payment.name,
167
- card_due_date: "#{payment.month}/#{payment.year}",
168
- card_cvv: payment.verification_value
169
- }
177
+ def add_card_or_token(post, payment)
178
+ if payment.is_a?(String)
179
+ payment, brand = payment.split("|")
180
+ end
181
+ post[:payment][:payment_type_code] = payment.is_a?(String) ? brand : CARD_BRAND[payment.brand.to_sym]
182
+ post[:payment][:creditcard] = payment_details(payment)
183
+ end
184
+
185
+ def add_payment_details(post, payment)
186
+ post[:payment_type_code] = CARD_BRAND[payment.brand.to_sym]
187
+ post[:creditcard] = payment_details(payment)
188
+ end
189
+
190
+ def payment_details(payment)
191
+ if payment.is_a?(String)
192
+ { token: payment }
193
+ else
194
+ {
195
+ card_number: payment.number,
196
+ card_name: payment.name,
197
+ card_due_date: "#{payment.month}/#{payment.year}",
198
+ card_cvv: payment.verification_value
199
+ }
200
+ end
170
201
  end
171
202
 
172
203
  def parse(body)
@@ -183,7 +214,7 @@ module ActiveMerchant #:nodoc:
183
214
  success,
184
215
  message_from(response),
185
216
  response,
186
- authorization: authorization_from(response),
217
+ authorization: authorization_from(action, parameters, response),
187
218
  test: test?,
188
219
  error_code: error_code_from(response, success)
189
220
  )
@@ -196,6 +227,8 @@ module ActiveMerchant #:nodoc:
196
227
  response.try(:[], "payment").try(:[], "status") == "PE"
197
228
  elsif action == :void
198
229
  response.try(:[], "payment").try(:[], "status") == "CA"
230
+ elsif action == :store
231
+ response.try(:[], "status") == "SUCCESS"
199
232
  else
200
233
  false
201
234
  end
@@ -206,8 +239,12 @@ module ActiveMerchant #:nodoc:
206
239
  response.try(:[], "payment").try(:[], "transaction_status").try(:[], "description")
207
240
  end
208
241
 
209
- def authorization_from(response)
210
- response.try(:[], "payment").try(:[], "hash")
242
+ def authorization_from(action, parameters, response)
243
+ if action == :store
244
+ response.try(:[], "token") + "|" + CARD_BRAND[parameters[:payment_type_code].to_sym]
245
+ else
246
+ response.try(:[], "payment").try(:[], "hash")
247
+ end
211
248
  end
212
249
 
213
250
  def post_data(action, parameters = {})
@@ -239,6 +276,21 @@ module ActiveMerchant #:nodoc:
239
276
  response.try(:[], "payment").try(:[], "transaction_status").try(:[], "code")
240
277
  end
241
278
  end
279
+
280
+ def customer_country(options)
281
+ if country = options[:country] || (options[:billing_address][:country] if options[:billing_address])
282
+ country.downcase
283
+ end
284
+ end
285
+
286
+ def customer_name(payment, options)
287
+ address_name = options[:billing_address][:name] if options[:billing_address] && options[:billing_address][:name]
288
+ if payment.is_a?(String)
289
+ address_name || "Not Provided"
290
+ else
291
+ payment.name
292
+ end
293
+ end
242
294
  end
243
295
  end
244
296
  end
@@ -7,8 +7,8 @@ module ActiveMerchant #:nodoc:
7
7
 
8
8
  class_attribute :test_url, :live_url, :delimiter, :actions
9
9
 
10
- self.test_url = 'https://demo.myvirtualmerchant.com/VirtualMerchantDemo/process.do'
11
- self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
10
+ self.test_url = 'https://api.demo.convergepay.com/VirtualMerchantDemo/process.do'
11
+ self.live_url = 'https://api.convergepay.com/VirtualMerchant/process.do'
12
12
 
13
13
  self.display_name = 'Elavon MyVirtualMerchant'
14
14
  self.supported_countries = %w(US CA PR DE IE NO PL LU BE NL)
@@ -241,11 +241,15 @@ module ActiveMerchant #:nodoc:
241
241
  {
242
242
  'Accept' => 'application/json',
243
243
  'Content-type' => 'application/json',
244
- 'Authorization' => "Basic #{Base64.strict_encode64(@options[:api_key].to_s).strip}",
244
+ 'Authorization' => "Basic #{basic_auth}",
245
245
  'User-Agent' => "Netbanx-Paysafe v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
246
246
  }
247
247
  end
248
248
 
249
+ def basic_auth
250
+ Base64.strict_encode64("#{@options[:account_number]}:#{@options[:api_key]}")
251
+ end
252
+
249
253
  def error_code_from(response)
250
254
  unless success_from(response)
251
255
  case response['errorCode']
@@ -3,9 +3,9 @@ module ActiveMerchant
3
3
  class PayeezyGateway < Gateway
4
4
  class_attribute :integration_url
5
5
 
6
- self.test_url = 'https://api-cert.payeezy.com/v1/transactions'
7
- self.integration_url = 'https://api-cat.payeezy.com/v1/transactions'
8
- self.live_url = 'https://api.payeezy.com/v1/transactions'
6
+ self.test_url = 'https://api-cert.payeezy.com/v1'
7
+ self.integration_url = 'https://api-cat.payeezy.com/v1'
8
+ self.live_url = 'https://api.payeezy.com/v1'
9
9
 
10
10
  self.default_currency = 'USD'
11
11
  self.money_format = :cents
@@ -31,7 +31,7 @@ module ActiveMerchant
31
31
  end
32
32
 
33
33
  def purchase(amount, payment_method, options = {})
34
- params = {transaction_type: 'purchase'}
34
+ params = payment_method.is_a?(String) ? { transaction_type: 'recurring' } : { transaction_type: 'purchase' }
35
35
 
36
36
  add_invoice(params, options)
37
37
  add_payment_method(params, payment_method, options)
@@ -73,6 +73,14 @@ module ActiveMerchant
73
73
  commit(params, options)
74
74
  end
75
75
 
76
+ def store(payment_method, options = {})
77
+ params = {}
78
+
79
+ add_creditcard_for_tokenization(params, payment_method, options)
80
+
81
+ commit(params, options)
82
+ end
83
+
76
84
  def void(authorization, options = {})
77
85
  params = {transaction_type: 'void'}
78
86
 
@@ -119,27 +127,34 @@ module ActiveMerchant
119
127
  params[:method] = method
120
128
  end
121
129
 
130
+ def add_creditcard_for_tokenization(params, payment_method, options)
131
+ params[:apikey] = @options[:apikey]
132
+ params[:js_security_key] = options[:js_security_key]
133
+ params[:ta_token] = options[:ta_token]
134
+ params[:callback] = 'Payeezy.callback'
135
+ params[:type] = 'FDToken'
136
+ card = add_card_data(payment_method)
137
+ params['credit_card.type'] = card[:type]
138
+ params['credit_card.cardholder_name'] = card[:cardholder_name]
139
+ params['credit_card.card_number'] = card[:card_number]
140
+ params['credit_card.exp_date'] = card[:exp_date]
141
+ params['credit_card.cvv'] = card[:cvv]
142
+ end
143
+
144
+ def is_store_action?(params)
145
+ params[:ta_token].present?
146
+ end
147
+
122
148
  def add_payment_method(params, payment_method, options)
123
149
  if payment_method.is_a? Check
124
150
  add_echeck(params, payment_method, options)
151
+ elsif payment_method.is_a? String
152
+ add_token(params, payment_method, options)
125
153
  else
126
154
  add_creditcard(params, payment_method)
127
155
  end
128
156
  end
129
157
 
130
- def add_creditcard(params, creditcard)
131
- credit_card = {}
132
-
133
- credit_card[:type] = CREDIT_CARD_BRAND[creditcard.brand]
134
- credit_card[:cardholder_name] = creditcard.name
135
- credit_card[:card_number] = creditcard.number
136
- credit_card[:exp_date] = "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :two_digits)}"
137
- credit_card[:cvv] = creditcard.verification_value if creditcard.verification_value?
138
-
139
- params[:method] = 'credit_card'
140
- params[:credit_card] = credit_card
141
- end
142
-
143
158
  def add_echeck(params, echeck, options)
144
159
  tele_check = {}
145
160
 
@@ -156,6 +171,44 @@ module ActiveMerchant
156
171
  params[:tele_check] = tele_check
157
172
  end
158
173
 
174
+ def add_token(params, payment_method, options)
175
+ token = {}
176
+ token[:token_type] = 'FDToken'
177
+
178
+ type, cardholder_name, exp_date, card_number = payment_method.split('|')
179
+
180
+ token[:token_data] = {}
181
+ token[:token_data][:type] = type
182
+ token[:token_data][:cardholder_name] = cardholder_name
183
+ token[:token_data][:value] = card_number
184
+ token[:token_data][:exp_date] = exp_date
185
+ token[:token_data][:cvv] = options[:cvv] if options[:cvv]
186
+
187
+ params[:method] = 'token'
188
+ params[:token] = token
189
+ end
190
+
191
+ def add_creditcard(params, creditcard)
192
+ credit_card = add_card_data(creditcard)
193
+
194
+ params[:method] = 'credit_card'
195
+ params[:credit_card] = credit_card
196
+ end
197
+
198
+ def add_card_data(payment_method)
199
+ card = {}
200
+ card[:type] = CREDIT_CARD_BRAND[payment_method.brand]
201
+ card[:cardholder_name] = payment_method.name
202
+ card[:card_number] = payment_method.number
203
+ card[:exp_date] = format_exp_date(payment_method.month, payment_method.year)
204
+ card[:cvv] = payment_method.verification_value if payment_method.verification_value?
205
+ card
206
+ end
207
+
208
+ def format_exp_date(month, year)
209
+ "#{format(month, :two_digits)}#{format(year, :two_digits)}"
210
+ end
211
+
159
212
  def add_address(params, options)
160
213
  address = options[:billing_address]
161
214
  return unless address
@@ -180,25 +233,18 @@ module ActiveMerchant
180
233
  end
181
234
 
182
235
  def commit(params, options)
183
- url = if options[:integration]
184
- integration_url
185
- elsif test?
186
- test_url
187
- else
188
- live_url
189
- end
236
+ url = base_url(options) + endpoint(params)
190
237
 
191
238
  if transaction_id = params.delete(:transaction_id)
192
239
  url = "#{url}/#{transaction_id}"
193
240
  end
194
241
 
195
242
  begin
196
- body = params.to_json
197
- response = parse(ssl_post(url, body, headers(body)))
243
+ response = api_request(url, params)
198
244
  rescue ResponseError => e
199
245
  response = response_error(e.response.body)
200
246
  rescue JSON::ParserError
201
- response = json_error(raw_response)
247
+ response = json_error(e.response.body)
202
248
  end
203
249
 
204
250
  Response.new(
@@ -213,17 +259,34 @@ module ActiveMerchant
213
259
  )
214
260
  end
215
261
 
216
- def success_from(response)
217
- response['transaction_status'] == 'approved'
262
+ def base_url(options)
263
+ if options[:integration]
264
+ integration_url
265
+ elsif test?
266
+ test_url
267
+ else
268
+ live_url
269
+ end
218
270
  end
219
271
 
220
- def authorization_from(params, response)
221
- [
222
- response['transaction_id'],
223
- response['transaction_tag'],
224
- params[:method],
225
- (response['amount'] && response['amount'].to_i)
226
- ].join('|')
272
+ def endpoint(params)
273
+ is_store_action?(params) ? '/securitytokens' : '/transactions'
274
+ end
275
+
276
+ def api_request(url, params)
277
+ if is_store_action?(params)
278
+ callback = ssl_request(:get, "#{url}?#{post_data(params)}", nil, {})
279
+ payload = callback[/{(?:\n|.)*}/]
280
+ parse(payload)
281
+ else
282
+ body = params.to_json
283
+ parse(ssl_post(url, body, headers(body)))
284
+ end
285
+ end
286
+
287
+ def post_data(params)
288
+ return nil unless params
289
+ params.reject { |k, v| v.blank? }.collect { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
227
290
  end
228
291
 
229
292
  def generate_hmac(nonce, current_timestamp, payload)
@@ -256,19 +319,55 @@ module ActiveMerchant
256
319
  response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ')
257
320
  end
258
321
 
322
+ def success_from(response)
323
+ if response['transaction_status']
324
+ response['transaction_status'] == 'approved'
325
+ elsif response['results']
326
+ response['results']['status'] == 'success'
327
+ else
328
+ false
329
+ end
330
+ end
331
+
259
332
  def handle_message(response, success)
260
- if success
333
+ if success && response['status'].present?
334
+ 'Token successfully created.'
335
+ elsif success
261
336
  "#{response['gateway_message']} - #{response['bank_message']}"
262
337
  elsif %w(401 403).include?(response['code'])
263
338
  response['message']
264
339
  elsif response.key?('Error')
265
340
  response['Error']['messages'].first['description']
341
+ elsif response.key?('results')
342
+ response['results']['Error']['messages'].first['description']
266
343
  elsif response.key?('error')
267
344
  response['error']
268
345
  elsif response.key?('fault')
269
346
  response['fault'].to_h['faultstring']
270
347
  else
271
- response['bank_message']
348
+ response['bank_message'] || 'Failure to successfully create token.'
349
+ end
350
+ end
351
+
352
+ def authorization_from(params, response)
353
+ if is_store_action?(params)
354
+ if success_from(response)
355
+ [
356
+ response['results']['token']['type'],
357
+ response['results']['token']['cardholder_name'],
358
+ response['results']['token']['exp_date'],
359
+ response['results']['token']['value']
360
+ ].join('|')
361
+ else
362
+ nil
363
+ end
364
+ else
365
+ [
366
+ response['transaction_id'],
367
+ response['transaction_tag'],
368
+ params[:method],
369
+ (response['amount'] && response['amount'].to_i)
370
+ ].join('|')
272
371
  end
273
372
  end
274
373
 
@@ -31,6 +31,7 @@ module ActiveMerchant #:nodoc:
31
31
  def initialize(options={})
32
32
  requires!(options, :merchant_id, :account_id, :api_login, :api_key)
33
33
  super
34
+ @options[:payment_country] ||= options[:payment_country] if options[:payment_country]
34
35
  end
35
36
 
36
37
  def purchase(amount, payment_method, options={})
@@ -138,7 +139,7 @@ module ActiveMerchant #:nodoc:
138
139
 
139
140
  def add_transaction_elements(post, type, options)
140
141
  transaction = {}
141
- transaction[:paymentCountry] = options[:payment_country] || (options[:billing_address][:country] if options[:billing_address])
142
+ transaction[:paymentCountry] = @options[:payment_country] || (options[:billing_address][:country] if options[:billing_address])
142
143
  transaction[:type] = type
143
144
  transaction[:ipAddress] = options[:ip] if options[:ip]
144
145
  transaction[:userAgent] = options[:user_agent] if options[:user_agent]
@@ -59,6 +59,7 @@ module ActiveMerchant #:nodoc:
59
59
  "COP" => '170',
60
60
  "CRC" => '188',
61
61
  "CZK" => '203',
62
+ "DKK" => '208',
62
63
  "DOP" => '214',
63
64
  "EUR" => '978',
64
65
  "GBP" => '826',
@@ -84,8 +84,6 @@ module ActiveMerchant #:nodoc:
84
84
  post[:cvv] = creditcard.verification_value unless options[:recurring]
85
85
  post[:expiration_month] = creditcard.month
86
86
  post[:expiration_year] = creditcard.year
87
- post[:original_ip] = options[:ip] if options[:ip]
88
- post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
89
87
 
90
88
  if(billing_address = (options[:billing_address] || options[:address]))
91
89
  post[:address] = {}
@@ -100,6 +98,8 @@ module ActiveMerchant #:nodoc:
100
98
  post[:client_secret] = @options[:client_secret]
101
99
  commit('/credit_card/transfer', post, options)
102
100
  else
101
+ post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
102
+ post[:original_ip] = options[:ip] if options[:ip]
103
103
  commit('/credit_card/create', post, options)
104
104
  end
105
105
  end
@@ -49,7 +49,7 @@ module ActiveMerchant
49
49
  end
50
50
 
51
51
  def request(method, body, headers = {})
52
- request_start = Time.now.to_f
52
+ request_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
53
53
 
54
54
  retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do
55
55
  begin
@@ -89,7 +89,7 @@ module ActiveMerchant
89
89
  end
90
90
 
91
91
  ensure
92
- info "connection_request_total_time=%.4fs" % [Time.now.to_f - request_start], tag
92
+ info "connection_request_total_time=%.4fs" % [Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start], tag
93
93
  end
94
94
 
95
95
  private
@@ -42,19 +42,19 @@ module ActiveMerchant
42
42
  request_start = nil
43
43
 
44
44
  begin
45
- request_start = Time.now.to_f
45
+ request_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
46
46
  result = yield
47
- log_with_retry_details(options[:logger], initial_retries-retries + 1, Time.now.to_f - request_start, "success", options[:tag])
47
+ log_with_retry_details(options[:logger], initial_retries-retries + 1, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, "success", options[:tag])
48
48
  result
49
49
  rescue ActiveMerchant::RetriableConnectionError => e
50
50
  retries -= 1
51
51
 
52
- log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
52
+ log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag])
53
53
  retry unless retries.zero?
54
54
  raise ActiveMerchant::ConnectionError.new(e.message, e)
55
55
  rescue ActiveMerchant::ConnectionError, ActiveMerchant::InvalidResponseError => e
56
56
  retries -= 1
57
- log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
57
+ log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag])
58
58
  retry if (options[:retry_safe] || retry_safe) && !retries.zero?
59
59
  raise
60
60
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = "1.73.0"
2
+ VERSION = "1.74.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemerchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.73.0
4
+ version: 1.74.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-29 00:00:00.000000000 Z
11
+ date: 2017-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -413,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
413
413
  version: '0'
414
414
  requirements: []
415
415
  rubyforge_project: activemerchant
416
- rubygems_version: 2.5.2
416
+ rubygems_version: 2.5.2.1
417
417
  signing_key:
418
418
  specification_version: 4
419
419
  summary: Framework and tools for dealing with credit card transactions.