activemerchant 1.56.0 → 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +331 -0
  3. data/README.md +9 -9
  4. data/lib/active_merchant/billing/check.rb +3 -0
  5. data/lib/active_merchant/billing/credit_card.rb +8 -3
  6. data/lib/active_merchant/billing/credit_card_methods.rb +41 -1
  7. data/lib/active_merchant/billing/gateway.rb +14 -6
  8. data/lib/active_merchant/billing/gateways/adyen.rb +228 -0
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +157 -44
  10. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +7 -4
  11. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +283 -0
  12. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +68 -2
  13. data/lib/active_merchant/billing/gateways/blue_pay.rb +2 -2
  14. data/lib/active_merchant/billing/gateways/blue_snap.rb +348 -0
  15. data/lib/active_merchant/billing/gateways/bpoint.rb +1 -1
  16. data/lib/active_merchant/billing/gateways/braintree_blue.rb +58 -20
  17. data/lib/active_merchant/billing/gateways/bridge_pay.rb +37 -8
  18. data/lib/active_merchant/billing/gateways/card_stream.rb +161 -40
  19. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -0
  20. data/lib/active_merchant/billing/gateways/checkout_v2.rb +5 -2
  21. data/lib/active_merchant/billing/gateways/citrus_pay.rb +24 -0
  22. data/lib/active_merchant/billing/gateways/clearhaus.rb +24 -40
  23. data/lib/active_merchant/billing/gateways/conekta.rb +6 -1
  24. data/lib/active_merchant/billing/gateways/creditcall.rb +1 -1
  25. data/lib/active_merchant/billing/gateways/credorax.rb +310 -0
  26. data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
  27. data/lib/active_merchant/billing/gateways/cyber_source.rb +80 -64
  28. data/lib/active_merchant/billing/gateways/data_cash.rb +10 -304
  29. data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
  30. data/lib/active_merchant/billing/gateways/elavon.rb +40 -26
  31. data/lib/active_merchant/billing/gateways/element.rb +356 -0
  32. data/lib/active_merchant/billing/gateways/fat_zebra.rb +16 -2
  33. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -1
  34. data/lib/active_merchant/billing/gateways/forte.rb +10 -2
  35. data/lib/active_merchant/billing/gateways/global_collect.rb +311 -0
  36. data/lib/active_merchant/billing/gateways/global_transport.rb +1 -0
  37. data/lib/active_merchant/billing/gateways/iats_payments.rb +13 -0
  38. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  39. data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
  40. data/lib/active_merchant/billing/gateways/jetpay.rb +33 -19
  41. data/lib/active_merchant/billing/gateways/kushki.rb +217 -0
  42. data/lib/active_merchant/billing/gateways/latitude19.rb +416 -0
  43. data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -0
  44. data/lib/active_merchant/billing/gateways/litle.rb +29 -13
  45. data/lib/active_merchant/billing/gateways/mastercard.rb +268 -0
  46. data/lib/active_merchant/billing/gateways/maxipago.rb +145 -122
  47. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +15 -1
  48. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +10 -7
  49. data/lib/active_merchant/billing/gateways/mercury.rb +13 -5
  50. data/lib/active_merchant/billing/gateways/metrics_global.rb +1 -1
  51. data/lib/active_merchant/billing/gateways/migs.rb +23 -1
  52. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  53. data/lib/active_merchant/billing/gateways/moneris.rb +21 -1
  54. data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -0
  55. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +165 -0
  56. data/lib/active_merchant/billing/gateways/netbanx.rb +245 -0
  57. data/lib/active_merchant/billing/gateways/nmi.rb +30 -9
  58. data/lib/active_merchant/billing/gateways/omise.rb +9 -5
  59. data/lib/active_merchant/billing/gateways/openpay.rb +10 -1
  60. data/lib/active_merchant/billing/gateways/opp.rb +362 -0
  61. data/lib/active_merchant/billing/gateways/orbital.rb +28 -7
  62. data/lib/active_merchant/billing/gateways/pagarme.rb +248 -0
  63. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +190 -0
  64. data/lib/active_merchant/billing/gateways/payeezy.rb +61 -12
  65. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  66. data/lib/active_merchant/billing/gateways/payflow.rb +6 -0
  67. data/lib/active_merchant/billing/gateways/payment_express.rb +1 -1
  68. data/lib/active_merchant/billing/gateways/paymill.rb +29 -11
  69. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  70. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -6
  71. data/lib/active_merchant/billing/gateways/payu_in.rb +3 -2
  72. data/lib/active_merchant/billing/gateways/payu_latam.rb +402 -0
  73. data/lib/active_merchant/billing/gateways/pin.rb +6 -3
  74. data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
  75. data/lib/active_merchant/billing/gateways/psl_card.rb +3 -3
  76. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +1 -1
  77. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +0 -2
  78. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +1 -1
  79. data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
  80. data/lib/active_merchant/billing/gateways/qvalent.rb +44 -1
  81. data/lib/active_merchant/billing/gateways/redsys.rb +3 -0
  82. data/lib/active_merchant/billing/gateways/s5.rb +8 -5
  83. data/lib/active_merchant/billing/gateways/safe_charge.rb +220 -0
  84. data/lib/active_merchant/billing/gateways/sage.rb +397 -128
  85. data/lib/active_merchant/billing/gateways/sage_pay.rb +45 -20
  86. data/lib/active_merchant/billing/gateways/secure_net.rb +0 -5
  87. data/lib/active_merchant/billing/gateways/secure_pay.rb +1 -1
  88. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
  89. data/lib/active_merchant/billing/gateways/securion_pay.rb +46 -17
  90. data/lib/active_merchant/billing/gateways/stripe.rb +125 -29
  91. data/lib/active_merchant/billing/gateways/telr.rb +275 -0
  92. data/lib/active_merchant/billing/gateways/tns.rb +13 -222
  93. data/lib/active_merchant/billing/gateways/trans_first.rb +40 -16
  94. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +606 -0
  95. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +114 -9
  96. data/lib/active_merchant/billing/gateways/vanco.rb +14 -10
  97. data/lib/active_merchant/billing/gateways/visanet_peru.rb +209 -0
  98. data/lib/active_merchant/billing/gateways/wepay.rb +73 -38
  99. data/lib/active_merchant/billing/gateways/wirecard.rb +1 -0
  100. data/lib/active_merchant/billing/gateways/world_net.rb +344 -0
  101. data/lib/active_merchant/billing/gateways/worldpay.rb +48 -16
  102. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +15 -0
  103. data/lib/active_merchant/country.rb +6 -4
  104. data/lib/active_merchant/posts_data.rb +1 -1
  105. data/lib/active_merchant/version.rb +1 -1
  106. metadata +32 -13
  107. data/lib/active_merchant/billing/gateways/app55.rb +0 -176
  108. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
  109. data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -278
  110. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +0 -89
  111. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +0 -115
  112. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +0 -149
  113. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +0 -97
@@ -0,0 +1,344 @@
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # See https://helpdesk.worldnettps.com/support/solutions/articles/1000167298-integrator-guide
6
+ class WorldNetGateway < Gateway
7
+ self.test_url = 'https://testpayments.worldnettps.com/merchant/xmlpayment'
8
+ self.live_url = 'https://payments.worldnettps.com/merchant/xmlpayment'
9
+
10
+ self.homepage_url = 'http://worldnettps.com/'
11
+ self.display_name = 'WorldNet'
12
+
13
+ self.supported_countries = %w(IE GB US)
14
+ self.default_currency = 'EUR'
15
+
16
+ CARD_TYPES = {
17
+ visa: 'VISA',
18
+ master: 'MASTERCARD',
19
+ discover: 'DISCOVER',
20
+ american_express: 'AMEX',
21
+ maestro: 'MAESTRO',
22
+ diners_club: 'DINERS',
23
+ jcb: 'JCB',
24
+ secure_card: 'SECURECARD'
25
+ }.freeze
26
+ self.supported_cardtypes = CARD_TYPES.keys
27
+
28
+ def initialize(options = {})
29
+ requires!(options, :terminal_id, :secret)
30
+ options[:terminal_type] ||= 2 # eCommerce
31
+ super
32
+ end
33
+
34
+ def purchase(money, payment, options = {})
35
+ requires!(options, :order_id)
36
+
37
+ post = {}
38
+ add_invoice(post, money, options)
39
+ add_payment(post, payment)
40
+ add_address(post, payment, options)
41
+ add_customer_data(post, options)
42
+
43
+ commit('PAYMENT', post)
44
+ end
45
+
46
+ def authorize(money, payment, options = {})
47
+ requires!(options, :order_id)
48
+
49
+ post = {}
50
+ add_invoice(post, money, options)
51
+ add_payment(post, payment)
52
+ add_address(post, payment, options)
53
+ add_customer_data(post, options)
54
+
55
+ commit('PREAUTH', post)
56
+ end
57
+
58
+ def capture(money, authorization, options = {})
59
+ post = {}
60
+ add_invoice(post, money, options)
61
+ post[:uniqueref] = authorization
62
+
63
+ commit('PREAUTHCOMPLETION', post)
64
+ end
65
+
66
+ def refund(money, authorization, options = {})
67
+ requires!(options, :operator, :reason)
68
+
69
+ post = {}
70
+ post[:uniqueref] = authorization
71
+ add_invoice(post, money, options)
72
+ post[:operator] = options[:operator]
73
+ post[:reason] = options[:reason]
74
+
75
+ commit('REFUND', post)
76
+ end
77
+
78
+ def void(authorization, _options = {})
79
+ post = {}
80
+ post[:uniqueref] = authorization
81
+ commit('VOID', post)
82
+ end
83
+
84
+ def verify(credit_card, options = {})
85
+ MultiResponse.run(:use_first_response) do |r|
86
+ r.process { authorize(100, credit_card, options) }
87
+ r.process(:ignore_result) { void(r.authorization, options) }
88
+ end
89
+ end
90
+
91
+ def store(payment, options = {})
92
+ requires!(options, :order_id)
93
+
94
+ post = {}
95
+ post[:merchantref] = options[:order_id]
96
+ add_payment(post, payment)
97
+
98
+ commit('SECURECARDREGISTRATION', post)
99
+ end
100
+
101
+ def unstore(payment, options = {})
102
+ requires!(options, :order_id)
103
+
104
+ post = {}
105
+ post[:merchantref] = options[:order_id]
106
+ add_card_reference(post, payment)
107
+
108
+ commit('SECURECARDREMOVAL', post)
109
+ end
110
+
111
+ def supports_scrubbing?
112
+ true
113
+ end
114
+
115
+ def scrub(transcript)
116
+ transcript
117
+ .gsub(%r{(<CARDNUMBER>\d{6})\d+(\d{4}</CARDNUMBER>)}, '\1...\2')
118
+ .gsub(%r{(<CVV>)\d+(</CVV)}, '\1...\2')
119
+ end
120
+
121
+ private
122
+
123
+ def add_customer_data(post, options)
124
+ post[:email] = options[:email]
125
+ post[:ipaddress] = options[:ip]
126
+ end
127
+
128
+ def add_address(post, _creditcard, options)
129
+ address = options[:billing_address] || options[:address]
130
+ return unless address
131
+ post[:address1] = address[:address1]
132
+ post[:address2] = address[:address2]
133
+ post[:city] = address[:city]
134
+ post[:country] = address[:country] # ISO 3166-1-alpha-2 code.
135
+ post[:postcode] = address[:zip]
136
+ end
137
+
138
+ def add_invoice(post, money, options)
139
+ post[:orderid] = options[:order_id]
140
+ post[:amount] = amount(money)
141
+ post[:currency] = (options[:currency] || currency(money))
142
+ post[:description] = options[:description]
143
+ end
144
+
145
+ def add_payment(post, payment)
146
+ # a payment triggered with a secure_card (tokenised card) will not
147
+ # respond to `:number`
148
+ if payment.respond_to?(:number)
149
+ post[:cardholdername] = cardholdername(payment)
150
+ post[:cardtype] = CARD_TYPES[payment.brand.to_sym]
151
+ post[:cardnumber] = payment.number
152
+ post[:cvv] = payment.verification_value if payment.verification_value
153
+ post[:cardexpiry] = expdate(payment)
154
+ else
155
+ post[:cardtype] = CARD_TYPES[:secure_card]
156
+ post[:cardnumber] = payment
157
+ end
158
+ end
159
+
160
+ def add_card_reference(post, payment)
161
+ post[:cardreference] = payment
162
+ end
163
+
164
+ def cardholdername(payment)
165
+ [payment.first_name, payment.last_name].join(' ').slice(0, 60)
166
+ end
167
+
168
+ def parse(action, body)
169
+ results = {}
170
+ xml = Nokogiri::XML(body)
171
+ resp = xml.xpath("//#{action}RESPONSE | //ERROR")
172
+ resp.children.each do |element|
173
+ results[element.name.downcase.to_sym] = element.text
174
+ end
175
+ results
176
+ end
177
+
178
+ def commit(action, parameters)
179
+ url = (test? ? test_url : live_url)
180
+ response = parse(action, ssl_post(url, post_data(action, parameters)))
181
+
182
+ Response.new(
183
+ success_from(action, response),
184
+ message_from(response),
185
+ response,
186
+ authorization: authorization_from(action, response),
187
+ avs_result: AVSResult.new(code: response[:avs_response]),
188
+ cvv_result: CVVResult.new(response[:cvv_response]),
189
+ test: test?,
190
+ error_code: success_from(action, response) ? nil : message_to_standard_error_code_from(response)
191
+ )
192
+ end
193
+
194
+ def success_from(action, response)
195
+ case action
196
+ when 'SECURECARDREGISTRATION'
197
+ response[:cardreference].present?
198
+ when 'SECURECARDREMOVAL'
199
+ response[:datetime].present? && response[:hash].present?
200
+ else
201
+ response[:responsecode] == 'A'
202
+ end
203
+ end
204
+
205
+ def message_to_standard_error_code_from(response)
206
+ case message_from(response)
207
+ when /DECLINED/
208
+ STANDARD_ERROR_CODE[:card_declined]
209
+ when /CVV FAILURE/
210
+ STANDARD_ERROR_CODE[:incorrect_cvc]
211
+ when /Invalid CARDEXPIRY field/
212
+ STANDARD_ERROR_CODE[:invalid_expiry_date]
213
+ else
214
+ STANDARD_ERROR_CODE[:processing_error]
215
+ end
216
+ end
217
+
218
+ def message_from(response)
219
+ response[:responsetext] || response[:errorstring]
220
+ end
221
+
222
+ def authorization_from(action, response)
223
+ case action
224
+ when 'SECURECARDREGISTRATION'
225
+ response[:cardreference]
226
+ else
227
+ response[:uniqueref]
228
+ end
229
+ end
230
+
231
+ def post_data(action, parameters = {})
232
+ parameters[:terminalid] = @options[:terminal_id]
233
+ parameters[:terminaltype] = @options[:terminal_type]
234
+ parameters[:transactiontype] = 7 # eCommerce
235
+ parameters[:datetime] = create_time_stamp
236
+ parameters[:hash] = case action
237
+ when 'SECURECARDREGISTRATION'
238
+ build_store_signature(parameters)
239
+ when 'SECURECARDREMOVAL'
240
+ build_unstore_signature(parameters)
241
+ else
242
+ build_signature(parameters)
243
+ end
244
+ build_xml_request(action, fields(action), parameters)
245
+ end
246
+
247
+ def create_time_stamp
248
+ Time.now.gmtime.strftime('%d-%m-%Y:%H:%M:%S:%L')
249
+ end
250
+
251
+ def build_signature(parameters)
252
+ str = parameters[:terminalid]
253
+ str += (parameters[:uniqueref] || parameters[:orderid])
254
+ str += (parameters[:amount].to_s + parameters[:datetime])
255
+ Digest::MD5.hexdigest(str + @options[:secret])
256
+ end
257
+
258
+ def build_store_signature(parameters)
259
+ str = parameters[:terminalid]
260
+ str += parameters[:merchantref]
261
+ str += parameters[:datetime]
262
+ str += parameters[:cardnumber]
263
+ str += parameters[:cardexpiry]
264
+ str += parameters[:cardtype]
265
+ str += parameters[:cardholdername]
266
+ Digest::MD5.hexdigest(str + @options[:secret])
267
+ end
268
+
269
+ def build_unstore_signature(parameters)
270
+ str = parameters[:terminalid]
271
+ str += parameters[:merchantref]
272
+ str += parameters[:datetime]
273
+ str += parameters[:cardreference]
274
+ Digest::MD5.hexdigest(str + @options[:secret])
275
+ end
276
+
277
+ def fields(action)
278
+ # Gateway expects fields in fixed order below.
279
+ case action
280
+ when 'PAYMENT', 'PREAUTH'
281
+ [
282
+ :orderid,
283
+ :terminalid,
284
+ :amount,
285
+ :datetime,
286
+ :cardnumber, :cardtype, :cardexpiry, :cardholdername,
287
+ :hash,
288
+ :currency,
289
+ :terminaltype,
290
+ :transactiontype,
291
+ :email,
292
+ :cvv,
293
+ :address1, :address2,
294
+ :postcode,
295
+ :description,
296
+ :city, :country,
297
+ :ipaddress
298
+ ]
299
+ when 'PREAUTHCOMPLETION'
300
+ [:uniqueref, :terminalid, :amount, :datetime, :hash]
301
+ when 'REFUND'
302
+ [:uniqueref, :terminalid, :amount, :datetime, :hash,
303
+ :operator, :reason]
304
+ when 'VOID'
305
+ [:uniqueref]
306
+ when 'SECURECARDREGISTRATION'
307
+ [
308
+ :merchantref,
309
+ :terminalid,
310
+ :datetime,
311
+ :cardnumber, :cardexpiry, :cardtype, :cardholdername,
312
+ :hash,
313
+ :dontchecksecurity,
314
+ :cvv,
315
+ :issueno
316
+ ]
317
+ when 'SECURECARDREMOVAL'
318
+ [
319
+ :merchantref,
320
+ :cardreference,
321
+ :terminalid,
322
+ :datetime,
323
+ :hash
324
+ ]
325
+ end
326
+ end
327
+
328
+ def build_xml_request(action, fields, data)
329
+ xml = Builder::XmlMarkup.new indent: 2
330
+ xml.instruct!(:xml, version: '1.0', encoding: 'utf-8')
331
+ xml.tag!(action) do
332
+ fields.each do |field|
333
+ xml.tag!(field.to_s.upcase, data[field]) if data[field]
334
+ end
335
+ end
336
+ xml.target!
337
+ end
338
+
339
+ def expdate(credit_card)
340
+ sprintf('%02d%02d', credit_card.month, credit_card.year % 100)
341
+ end
342
+ end
343
+ end
344
+ end
@@ -8,6 +8,7 @@ module ActiveMerchant #:nodoc:
8
8
  self.money_format = :cents
9
9
  self.supported_countries = %w(HK GB AU AD BE CH CY CZ DE DK ES FI FR GI GR HU IE IL IT LI LU MC MT NL NO NZ PL PT SE SG SI SM TR UM VA)
10
10
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :laser, :switch]
11
+ self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW)
11
12
  self.homepage_url = 'http://www.worldpay.com/'
12
13
  self.display_name = 'Worldpay Global'
13
14
 
@@ -59,9 +60,21 @@ module ActiveMerchant #:nodoc:
59
60
  end
60
61
 
61
62
  def refund(money, authorization, options = {})
62
- MultiResponse.run do |r|
63
- r.process{inquire_request(authorization, options, "CAPTURED", "SETTLED", "SETTLED_BY_MERCHANT")}
64
- r.process{refund_request(money, authorization, options)}
63
+ response = MultiResponse.run do |r|
64
+ r.process { inquire_request(authorization, options, "CAPTURED", "SETTLED", "SETTLED_BY_MERCHANT") }
65
+ r.process { refund_request(money, authorization, options) }
66
+ end
67
+
68
+ return response if response.success?
69
+ return response unless options[:force_full_refund_if_unsettled]
70
+
71
+ void(authorization, options ) if response.params["last_event"] == "AUTHORISED"
72
+ end
73
+
74
+ def verify(credit_card, options={})
75
+ MultiResponse.run(:use_first_response) do |r|
76
+ r.process { authorize(100, credit_card, options) }
77
+ r.process(:ignore_result) { void(r.authorization, options) }
65
78
  end
66
79
  end
67
80
 
@@ -129,7 +142,7 @@ module ActiveMerchant #:nodoc:
129
142
  def build_authorization_request(money, payment_method, options)
130
143
  build_request do |xml|
131
144
  xml.tag! 'submit' do
132
- xml.tag! 'order', {'orderCode' => options[:order_id], 'installationId' => @options[:inst_id]}.reject{|_,v| !v} do
145
+ xml.tag! 'order', order_tag_attributes(options) do
133
146
  xml.description(options[:description].blank? ? "Purchase" : options[:description])
134
147
  add_amount(xml, money, options)
135
148
  if options[:order_content]
@@ -139,11 +152,18 @@ module ActiveMerchant #:nodoc:
139
152
  end
140
153
  add_payment_method(xml, money, payment_method, options)
141
154
  add_email(xml, options)
155
+ if options[:hcg_additional_data]
156
+ add_hcg_additional_data(xml, options)
157
+ end
142
158
  end
143
159
  end
144
160
  end
145
161
  end
146
162
 
163
+ def order_tag_attributes(options)
164
+ { 'orderCode' => options[:order_id], 'installationId' => options[:inst_id] || @options[:inst_id] }.reject{|_,v| !v}
165
+ end
166
+
147
167
  def build_capture_request(money, authorization, options)
148
168
  build_order_modify_request(authorization) do |xml|
149
169
  xml.tag! 'capture' do
@@ -170,12 +190,11 @@ module ActiveMerchant #:nodoc:
170
190
 
171
191
  def add_amount(xml, money, options)
172
192
  currency = options[:currency] || currency(money)
173
- amount = localized_amount(money, currency)
174
193
 
175
194
  amount_hash = {
176
- :value => amount,
195
+ :value => localized_amount(money, currency),
177
196
  'currencyCode' => currency,
178
- 'exponent' => 2
197
+ 'exponent' => non_fractional_currency?(currency) ? 0 : 2
179
198
  }
180
199
 
181
200
  if options[:debit_credit_indicator]
@@ -209,8 +228,11 @@ module ActiveMerchant #:nodoc:
209
228
 
210
229
  add_address(xml, (options[:billing_address] || options[:address]))
211
230
  end
212
- if options[:ip]
213
- xml.tag! 'session', 'shopperIPAddress' => options[:ip]
231
+ if options[:ip] && options[:session_id]
232
+ xml.tag! 'session', 'shopperIPAddress' => options[:ip], 'id' => options[:session_id]
233
+ else
234
+ xml.tag! 'session', 'shopperIPAddress' => options[:ip] if options[:ip]
235
+ xml.tag! 'session', 'id' => options[:session_id] if options[:session_id]
214
236
  end
215
237
  end
216
238
  end
@@ -224,6 +246,8 @@ module ActiveMerchant #:nodoc:
224
246
  end
225
247
 
226
248
  def add_address(xml, address)
249
+ return unless address
250
+
227
251
  address = address_with_defaults(address)
228
252
 
229
253
  xml.tag! 'cardAddress' do
@@ -243,6 +267,14 @@ module ActiveMerchant #:nodoc:
243
267
  end
244
268
  end
245
269
 
270
+ def add_hcg_additional_data(xml, options)
271
+ xml.tag! 'hcgAdditionalData' do
272
+ options[:hcg_additional_data].each do |k, v|
273
+ xml.tag! "param", {name: k.to_s}, v
274
+ end
275
+ end
276
+ end
277
+
246
278
  def address_with_defaults(address)
247
279
  address ||= {}
248
280
  address.delete_if { |_, v| v.blank? }
@@ -286,6 +318,7 @@ module ActiveMerchant #:nodoc:
286
318
  message,
287
319
  raw,
288
320
  :authorization => authorization_from(raw),
321
+ :error_code => error_code_from(success, raw),
289
322
  :test => test?)
290
323
 
291
324
  rescue ActiveMerchant::ResponseError => e
@@ -315,6 +348,12 @@ module ActiveMerchant #:nodoc:
315
348
  [ success, message ]
316
349
  end
317
350
 
351
+ def error_code_from(success, raw)
352
+ unless success == "SUCCESS"
353
+ raw[:iso8583_return_code_code] || raw[:error_code] || nil
354
+ end
355
+ end
356
+
318
357
  def required_status_message(raw, success_criteria)
319
358
  if(!success_criteria.include?(raw[:last_event]))
320
359
  "A transaction status of #{success_criteria.collect{|c| "'#{c}'"}.join(" or ")} is required."
@@ -330,13 +369,6 @@ module ActiveMerchant #:nodoc:
330
369
  credentials = "#{@options[:login]}:#{@options[:password]}"
331
370
  "Basic #{[credentials].pack('m').strip}"
332
371
  end
333
-
334
- def localized_amount(money, currency)
335
- amount = amount(money)
336
- return amount unless CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s)
337
-
338
- amount.to_i / 100 * 100
339
- end
340
372
  end
341
373
  end
342
374
  end
@@ -15,6 +15,21 @@ module ActiveMerchant #:nodoc:
15
15
  self.require_name = false
16
16
 
17
17
  attr_accessor :payment_cryptogram, :eci, :transaction_id
18
+ attr_writer :source
19
+
20
+ SOURCES = [:apple_pay, :android_pay]
21
+
22
+ def source
23
+ if defined?(@source) && SOURCES.include?(@source)
24
+ @source
25
+ else
26
+ :apple_pay
27
+ end
28
+ end
29
+
30
+ def credit_card?
31
+ true
32
+ end
18
33
 
19
34
  def type
20
35
  "network_tokenization"
@@ -72,6 +72,7 @@ module ActiveMerchant #:nodoc:
72
72
  { alpha2: 'AD', name: 'Andorra', alpha3: 'AND', numeric: '020' },
73
73
  { alpha2: 'AO', name: 'Angola', alpha3: 'AGO', numeric: '024' },
74
74
  { alpha2: 'AI', name: 'Anguilla', alpha3: 'AIA', numeric: '660' },
75
+ { alpha2: 'AQ', name: 'Antarctica', alpha3: 'ATA', numeric: '010' },
75
76
  { alpha2: 'AG', name: 'Antigua and Barbuda', alpha3: 'ATG', numeric: '028' },
76
77
  { alpha2: 'AR', name: 'Argentina', alpha3: 'ARG', numeric: '032' },
77
78
  { alpha2: 'AM', name: 'Armenia', alpha3: 'ARM', numeric: '051' },
@@ -90,6 +91,7 @@ module ActiveMerchant #:nodoc:
90
91
  { alpha2: 'BM', name: 'Bermuda', alpha3: 'BMU', numeric: '060' },
91
92
  { alpha2: 'BT', name: 'Bhutan', alpha3: 'BTN', numeric: '064' },
92
93
  { alpha2: 'BO', name: 'Bolivia', alpha3: 'BOL', numeric: '068' },
94
+ { alpha2: 'BQ', name: 'Bonaire, Sint Eustatius and Saba', alpha3: 'BES', numeric: '535' },
93
95
  { alpha2: 'BA', name: 'Bosnia and Herzegovina', alpha3: 'BIH', numeric: '070' },
94
96
  { alpha2: 'BW', name: 'Botswana', alpha3: 'BWA', numeric: '072' },
95
97
  { alpha2: 'BV', name: 'Bouvet Island', alpha3: 'BVD', numeric: '074' },
@@ -181,7 +183,6 @@ module ActiveMerchant #:nodoc:
181
183
  { alpha2: 'KI', name: 'Kiribati', alpha3: 'KIR', numeric: '296' },
182
184
  { alpha2: 'KP', name: 'Korea, Democratic People\'s Republic of', alpha3: 'PRK', numeric: '408' },
183
185
  { alpha2: 'KR', name: 'Korea, Republic of', alpha3: 'KOR', numeric: '410' },
184
- { alpha2: 'KV', name: 'Kosovo', alpha3: 'KSV', numeric: '377' },
185
186
  { alpha2: 'KW', name: 'Kuwait', alpha3: 'KWT', numeric: '414' },
186
187
  { alpha2: 'KG', name: 'Kyrgyzstan', alpha3: 'KGZ', numeric: '417' },
187
188
  { alpha2: 'LA', name: 'Lao People\'s Democratic Republic', alpha3: 'LAO', numeric: '418' },
@@ -220,7 +221,6 @@ module ActiveMerchant #:nodoc:
220
221
  { alpha2: 'NR', name: 'Nauru', alpha3: 'NRU', numeric: '520' },
221
222
  { alpha2: 'NP', name: 'Nepal', alpha3: 'NPL', numeric: '524' },
222
223
  { alpha2: 'NL', name: 'Netherlands', alpha3: 'NLD', numeric: '528' },
223
- { alpha2: 'AN', name: 'Netherlands Antilles', alpha3: 'ANT', numeric: '530' },
224
224
  { alpha2: 'NC', name: 'New Caledonia', alpha3: 'NCL', numeric: '540' },
225
225
  { alpha2: 'NZ', name: 'New Zealand', alpha3: 'NZL', numeric: '554' },
226
226
  { alpha2: 'NI', name: 'Nicaragua', alpha3: 'NIC', numeric: '558' },
@@ -264,15 +264,17 @@ module ActiveMerchant #:nodoc:
264
264
  { alpha2: 'SC', name: 'Seychelles', alpha3: 'SYC', numeric: '690' },
265
265
  { alpha2: 'SL', name: 'Sierra Leone', alpha3: 'SLE', numeric: '694' },
266
266
  { alpha2: 'SG', name: 'Singapore', alpha3: 'SGP', numeric: '702' },
267
+ { alpha2: 'SX', name: 'Sint Maarten', alpha3: 'SXM', numeric: '534' },
267
268
  { alpha2: 'SK', name: 'Slovakia', alpha3: 'SVK', numeric: '703' },
268
269
  { alpha2: 'SI', name: 'Slovenia', alpha3: 'SVN', numeric: '705' },
269
270
  { alpha2: 'SB', name: 'Solomon Islands', alpha3: 'SLB', numeric: '090' },
270
271
  { alpha2: 'SO', name: 'Somalia', alpha3: 'SOM', numeric: '706' },
271
272
  { alpha2: 'ZA', name: 'South Africa', alpha3: 'ZAF', numeric: '710' },
272
273
  { alpha2: 'GS', name: 'South Georgia and the South Sandwich Islands', alpha3: 'SGS', numeric: '239' },
274
+ { alpha2: 'SS', name: 'South Sudan', alpha3: 'SSD', numeric: '728' },
273
275
  { alpha2: 'ES', name: 'Spain', alpha3: 'ESP', numeric: '724' },
274
276
  { alpha2: 'LK', name: 'Sri Lanka', alpha3: 'LKA', numeric: '144' },
275
- { alpha2: 'SD', name: 'Sudan', alpha3: 'SDN', numeric: '736' },
277
+ { alpha2: 'SD', name: 'Sudan', alpha3: 'SDN', numeric: '729' },
276
278
  { alpha2: 'SR', name: 'Suriname', alpha3: 'SUR', numeric: '740' },
277
279
  { alpha2: 'SJ', name: 'Svalbard and Jan Mayen', alpha3: 'SJM', numeric: '744' },
278
280
  { alpha2: 'SZ', name: 'Swaziland', alpha3: 'SWZ', numeric: '748' },
@@ -323,7 +325,7 @@ module ActiveMerchant #:nodoc:
323
325
  country_code = CountryCode.new(name)
324
326
  country = COUNTRIES.detect{|c| c[country_code.format] == upcase_name }
325
327
  else
326
- country = COUNTRIES.detect{|c| c[:name] == name }
328
+ country = COUNTRIES.detect{|c| c[:name].upcase == name.upcase }
327
329
  end
328
330
  raise InvalidCountryCodeError, "No country could be found for the country #{name}" if country.nil?
329
331
  Country.new(country.dup)
@@ -41,7 +41,7 @@ module ActiveMerchant #:nodoc:
41
41
 
42
42
  def raw_ssl_request(method, endpoint, data, headers = {})
43
43
  logger.warn "#{self.class} using ssl_strict=false, which is insecure" if logger unless ssl_strict
44
- logger.warn "#{self.class} posting to plaintext endpoint, which is insecure" if logger unless endpoint =~ /^https:/
44
+ logger.warn "#{self.class} posting to plaintext endpoint, which is insecure" if logger unless endpoint.to_s =~ /^https:/
45
45
 
46
46
  connection = new_connection(endpoint)
47
47
  connection.open_timeout = open_timeout
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = "1.56.0"
2
+ VERSION = "1.66.0"
3
3
  end