activemerchant 1.73.0 → 1.74.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.
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.