activemerchant 1.95.0 → 1.96.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 +4 -4
- data/CHANGELOG +45 -0
- data/README.md +3 -0
- data/lib/active_merchant/billing/avs_result.rb +4 -5
- data/lib/active_merchant/billing/credit_card.rb +2 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +14 -0
- data/lib/active_merchant/billing/gateway.rb +10 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +19 -6
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +39 -10
- data/lib/active_merchant/billing/gateways/blue_snap.rb +4 -1
- data/lib/active_merchant/billing/gateways/bpoint.rb +4 -4
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +11 -1
- data/lib/active_merchant/billing/gateways/card_connect.rb +1 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +7 -7
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +24 -24
- data/lib/active_merchant/billing/gateways/credorax.rb +29 -3
- data/lib/active_merchant/billing/gateways/cyber_source.rb +2 -2
- data/lib/active_merchant/billing/gateways/decidir.rb +232 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +2 -6
- data/lib/active_merchant/billing/gateways/hps.rb +46 -1
- data/lib/active_merchant/billing/gateways/kushki.rb +1 -1
- data/lib/active_merchant/billing/gateways/migs.rb +8 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +1 -1
- data/lib/active_merchant/billing/gateways/nab_transact.rb +1 -1
- data/lib/active_merchant/billing/gateways/nmi.rb +39 -1
- data/lib/active_merchant/billing/gateways/opp.rb +20 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +40 -2
- data/lib/active_merchant/billing/gateways/paypal.rb +14 -1
- data/lib/active_merchant/billing/gateways/realex.rb +11 -5
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +43 -29
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +24 -5
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +8 -5
- data/lib/active_merchant/billing/gateways/worldpay.rb +157 -37
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +3 -2
@@ -33,9 +33,9 @@ module ActiveMerchant #:nodoc:
|
|
33
33
|
'10110' => STANDARD_ERROR_CODE[:incorrect_address],
|
34
34
|
'10111' => STANDARD_ERROR_CODE[:incorrect_address],
|
35
35
|
'10127' => STANDARD_ERROR_CODE[:card_declined],
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
36
|
+
'00043' => STANDARD_ERROR_CODE[:call_issuer],
|
37
|
+
'10205' => STANDARD_ERROR_CODE[:card_declined],
|
38
|
+
'10204' => STANDARD_ERROR_CODE[:pickup_card]
|
39
39
|
}
|
40
40
|
|
41
41
|
def initialize(options = {})
|
@@ -318,12 +318,15 @@ module ActiveMerchant #:nodoc:
|
|
318
318
|
def commit(action, parameters)
|
319
319
|
url = (test? ? self.test_url : self.live_url)
|
320
320
|
response = parse(ssl_post(url, post_data(action, parameters)))
|
321
|
-
|
321
|
+
approved = response[:status] == 'Approved'
|
322
|
+
error_code = nil
|
323
|
+
error_code = (STANDARD_ERROR_CODE_MAPPING[response[:error_code]] || STANDARD_ERROR_CODE[:processing_error]) unless approved
|
324
|
+
Response.new(approved, message_from(response), response,
|
322
325
|
:test => test?,
|
323
326
|
:authorization => response[:ref_num],
|
324
327
|
:cvv_result => response[:cvv2_result_code],
|
325
328
|
:avs_result => { :code => response[:avs_result_code] },
|
326
|
-
:error_code =>
|
329
|
+
:error_code => error_code
|
327
330
|
)
|
328
331
|
end
|
329
332
|
|
@@ -59,10 +59,12 @@ module ActiveMerchant #:nodoc:
|
|
59
59
|
|
60
60
|
def authorize(money, payment_method, options = {})
|
61
61
|
requires!(options, :order_id)
|
62
|
-
|
62
|
+
payment_details = payment_details_from(payment_method)
|
63
|
+
authorize_request(money, payment_method, payment_details.merge(options))
|
63
64
|
end
|
64
65
|
|
65
66
|
def capture(money, authorization, options = {})
|
67
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
66
68
|
MultiResponse.run do |r|
|
67
69
|
r.process { inquire_request(authorization, options, 'AUTHORISED') } unless options[:authorization_validated]
|
68
70
|
if r.params
|
@@ -74,6 +76,7 @@ module ActiveMerchant #:nodoc:
|
|
74
76
|
end
|
75
77
|
|
76
78
|
def void(authorization, options = {})
|
79
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
77
80
|
MultiResponse.run do |r|
|
78
81
|
r.process { inquire_request(authorization, options, 'AUTHORISED') } unless options[:authorization_validated]
|
79
82
|
r.process { cancel_request(authorization, options) }
|
@@ -81,6 +84,7 @@ module ActiveMerchant #:nodoc:
|
|
81
84
|
end
|
82
85
|
|
83
86
|
def refund(money, authorization, options = {})
|
87
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
84
88
|
response = MultiResponse.run do |r|
|
85
89
|
r.process { inquire_request(authorization, options, 'CAPTURED', 'SETTLED', 'SETTLED_BY_MERCHANT') }
|
86
90
|
r.process { refund_request(money, authorization, options) }
|
@@ -97,16 +101,22 @@ module ActiveMerchant #:nodoc:
|
|
97
101
|
# and other transactions should be performed on a normal eCom-flagged
|
98
102
|
# merchant ID.
|
99
103
|
def credit(money, payment_method, options = {})
|
100
|
-
|
104
|
+
payment_details = payment_details_from(payment_method)
|
105
|
+
credit_request(money, payment_method, payment_details.merge(:credit => true, **options))
|
101
106
|
end
|
102
107
|
|
103
|
-
def verify(
|
108
|
+
def verify(payment_method, options={})
|
104
109
|
MultiResponse.run(:use_first_response) do |r|
|
105
|
-
r.process { authorize(100,
|
110
|
+
r.process { authorize(100, payment_method, options) }
|
106
111
|
r.process(:ignore_result) { void(r.authorization, options.merge(:authorization_validated => true)) }
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
115
|
+
def store(credit_card, options={})
|
116
|
+
requires!(options, :customer)
|
117
|
+
store_request(credit_card, options)
|
118
|
+
end
|
119
|
+
|
110
120
|
def supports_scrubbing
|
111
121
|
true
|
112
122
|
end
|
@@ -144,6 +154,10 @@ module ActiveMerchant #:nodoc:
|
|
144
154
|
commit('credit', build_authorization_request(money, payment_method, options), :ok, 'SENT_FOR_REFUND', options)
|
145
155
|
end
|
146
156
|
|
157
|
+
def store_request(credit_card, options)
|
158
|
+
commit('store', build_store_request(credit_card, options), options)
|
159
|
+
end
|
160
|
+
|
147
161
|
def build_request
|
148
162
|
xml = Builder::XmlMarkup.new :indent => 2
|
149
163
|
xml.instruct! :xml, :encoding => 'UTF-8'
|
@@ -184,7 +198,7 @@ module ActiveMerchant #:nodoc:
|
|
184
198
|
end
|
185
199
|
end
|
186
200
|
add_payment_method(xml, money, payment_method, options)
|
187
|
-
|
201
|
+
add_shopper(xml, options)
|
188
202
|
if options[:hcg_additional_data]
|
189
203
|
add_hcg_additional_data(xml, options)
|
190
204
|
end
|
@@ -224,6 +238,22 @@ module ActiveMerchant #:nodoc:
|
|
224
238
|
end
|
225
239
|
end
|
226
240
|
|
241
|
+
def build_store_request(credit_card, options)
|
242
|
+
build_request do |xml|
|
243
|
+
xml.tag! 'submit' do
|
244
|
+
xml.tag! 'paymentTokenCreate' do
|
245
|
+
add_authenticated_shopper_id(xml, options)
|
246
|
+
xml.tag! 'createToken'
|
247
|
+
xml.tag! 'paymentInstrument' do
|
248
|
+
xml.tag! 'cardDetails' do
|
249
|
+
add_card(xml, credit_card, options)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
227
257
|
def add_amount(xml, money, options)
|
228
258
|
currency = options[:currency] || currency(money)
|
229
259
|
|
@@ -241,7 +271,7 @@ module ActiveMerchant #:nodoc:
|
|
241
271
|
end
|
242
272
|
|
243
273
|
def add_payment_method(xml, amount, payment_method, options)
|
244
|
-
if
|
274
|
+
if options[:payment_type] == :pay_as_order
|
245
275
|
if options[:merchant_code]
|
246
276
|
xml.tag! 'payAsOrder', 'orderCode' => payment_method, 'merchantCode' => options[:merchant_code] do
|
247
277
|
add_amount(xml, amount, options)
|
@@ -253,16 +283,14 @@ module ActiveMerchant #:nodoc:
|
|
253
283
|
end
|
254
284
|
else
|
255
285
|
xml.tag! 'paymentDetails', credit_fund_transfer_attribute(options) do
|
256
|
-
|
257
|
-
xml.tag! '
|
258
|
-
|
259
|
-
|
286
|
+
if options[:payment_type] == :token
|
287
|
+
xml.tag! 'TOKEN-SSL', 'tokenScope' => options[:token_scope] do
|
288
|
+
xml.tag! 'paymentTokenID', options[:token_id]
|
289
|
+
end
|
290
|
+
else
|
291
|
+
xml.tag! card_code_for(payment_method) do
|
292
|
+
add_card(xml, payment_method, options)
|
260
293
|
end
|
261
|
-
|
262
|
-
xml.tag! 'cardHolderName', options[:execute_threed] ? '3D' : payment_method.name
|
263
|
-
xml.tag! 'cvc', payment_method.verification_value
|
264
|
-
|
265
|
-
add_address(xml, (options[:billing_address] || options[:address]))
|
266
294
|
end
|
267
295
|
add_stored_credential_options(xml, options)
|
268
296
|
if options[:ip] && options[:session_id]
|
@@ -273,18 +301,37 @@ module ActiveMerchant #:nodoc:
|
|
273
301
|
end
|
274
302
|
|
275
303
|
if three_d_secure = options[:three_d_secure]
|
276
|
-
xml
|
277
|
-
xml.tag! 'threeDSVersion', three_d_secure[:version]
|
278
|
-
xid_tag = three_d_secure[:version] =~ /^2/ ? 'dsTransactionId' : 'xid'
|
279
|
-
xml.tag! xid_tag, three_d_secure[:xid]
|
280
|
-
xml.tag! 'cavv', three_d_secure[:cavv]
|
281
|
-
xml.tag! 'eci', three_d_secure[:eci]
|
282
|
-
end
|
304
|
+
add_three_d_secure(three_d_secure, xml)
|
283
305
|
end
|
284
306
|
end
|
285
307
|
end
|
286
308
|
end
|
287
309
|
|
310
|
+
def add_three_d_secure(three_d_secure, xml)
|
311
|
+
xml.tag! 'info3DSecure' do
|
312
|
+
xml.tag! 'threeDSVersion', three_d_secure[:version]
|
313
|
+
if three_d_secure[:version] =~ /^2/
|
314
|
+
xml.tag! 'dsTransactionId', three_d_secure[:ds_transaction_id]
|
315
|
+
else
|
316
|
+
xml.tag! 'xid', three_d_secure[:xid]
|
317
|
+
end
|
318
|
+
xml.tag! 'cavv', three_d_secure[:cavv]
|
319
|
+
xml.tag! 'eci', three_d_secure[:eci]
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def add_card(xml, payment_method, options)
|
324
|
+
xml.tag! 'cardNumber', payment_method.number
|
325
|
+
xml.tag! 'expiryDate' do
|
326
|
+
xml.tag! 'date', 'month' => format(payment_method.month, :two_digits), 'year' => format(payment_method.year, :four_digits)
|
327
|
+
end
|
328
|
+
|
329
|
+
xml.tag! 'cardHolderName', options[:execute_threed] ? '3D' : payment_method.name
|
330
|
+
xml.tag! 'cvc', payment_method.verification_value
|
331
|
+
|
332
|
+
add_address(xml, (options[:billing_address] || options[:address]))
|
333
|
+
end
|
334
|
+
|
288
335
|
def add_stored_credential_options(xml, options={})
|
289
336
|
if options[:stored_credential]
|
290
337
|
add_stored_credential_using_normalized_fields(xml, options)
|
@@ -321,10 +368,11 @@ module ActiveMerchant #:nodoc:
|
|
321
368
|
end
|
322
369
|
end
|
323
370
|
|
324
|
-
def
|
325
|
-
return unless options[:execute_threed] || options[:email]
|
371
|
+
def add_shopper(xml, options)
|
372
|
+
return unless options[:execute_threed] || options[:email] || options[:customer]
|
326
373
|
xml.tag! 'shopper' do
|
327
374
|
xml.tag! 'shopperEmailAddress', options[:email] if options[:email]
|
375
|
+
add_authenticated_shopper_id(xml, options)
|
328
376
|
xml.tag! 'browser' do
|
329
377
|
xml.tag! 'acceptHeader', options[:accept_header]
|
330
378
|
xml.tag! 'userAgentHeader', options[:user_agent]
|
@@ -332,6 +380,10 @@ module ActiveMerchant #:nodoc:
|
|
332
380
|
end
|
333
381
|
end
|
334
382
|
|
383
|
+
def add_authenticated_shopper_id(xml, options)
|
384
|
+
xml.tag!('authenticatedShopperID', options[:customer]) if options[:customer]
|
385
|
+
end
|
386
|
+
|
335
387
|
def add_address(xml, address)
|
336
388
|
return unless address
|
337
389
|
|
@@ -390,14 +442,17 @@ module ActiveMerchant #:nodoc:
|
|
390
442
|
end
|
391
443
|
|
392
444
|
def parse_element(raw, node)
|
445
|
+
node_name = node.name.underscore
|
393
446
|
node.attributes.each do |k, v|
|
394
|
-
raw["#{
|
447
|
+
raw["#{node_name}_#{k.underscore}".to_sym] = v
|
395
448
|
end
|
396
449
|
if node.has_elements?
|
397
|
-
raw[
|
450
|
+
raw[node_name.to_sym] = true unless node.name.blank?
|
398
451
|
node.elements.each { |e| parse_element(raw, e) }
|
452
|
+
elsif node.children.count > 1
|
453
|
+
raw[node_name.to_sym] = node.children.join(' ').strip
|
399
454
|
else
|
400
|
-
raw[
|
455
|
+
raw[node_name.to_sym] = node.text unless node.text.nil?
|
401
456
|
end
|
402
457
|
raw
|
403
458
|
end
|
@@ -420,13 +475,14 @@ module ActiveMerchant #:nodoc:
|
|
420
475
|
raw[:cookie] = @cookie
|
421
476
|
raw[:session_id] = options[:session_id]
|
422
477
|
end
|
423
|
-
success
|
478
|
+
success = success_from(action, raw, success_criteria)
|
479
|
+
message = message_from(success, raw, success_criteria)
|
424
480
|
|
425
481
|
Response.new(
|
426
482
|
success,
|
427
483
|
message,
|
428
484
|
raw,
|
429
|
-
:authorization => authorization_from(raw),
|
485
|
+
:authorization => authorization_from(action, raw, options),
|
430
486
|
:error_code => error_code_from(success, raw),
|
431
487
|
:test => test?,
|
432
488
|
:avs_result => AVSResult.new(code: AVS_CODE_MAP[raw[:avs_result_code_description]]),
|
@@ -456,19 +512,30 @@ module ActiveMerchant #:nodoc:
|
|
456
512
|
end
|
457
513
|
end
|
458
514
|
|
515
|
+
def success_from(action, raw, success_criteria)
|
516
|
+
success_criteria_success?(raw, success_criteria) || action_success?(action, raw)
|
517
|
+
end
|
518
|
+
|
519
|
+
def message_from(success, raw, success_criteria)
|
520
|
+
return 'SUCCESS' if success
|
521
|
+
raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_criteria)
|
522
|
+
end
|
523
|
+
|
459
524
|
# success_criteria can be:
|
460
525
|
# - a string or an array of strings (if one of many responses)
|
461
526
|
# - An array of strings if one of many responses could be considered a
|
462
527
|
# success.
|
463
|
-
def
|
464
|
-
|
465
|
-
|
466
|
-
|
528
|
+
def success_criteria_success?(raw, success_criteria)
|
529
|
+
success_criteria.include?(raw[:last_event]) || raw[:ok].present?
|
530
|
+
end
|
531
|
+
|
532
|
+
def action_success?(action, raw)
|
533
|
+
case action
|
534
|
+
when 'store'
|
535
|
+
raw[:token].present?
|
467
536
|
else
|
468
|
-
|
537
|
+
false
|
469
538
|
end
|
470
|
-
|
471
|
-
[ success, message ]
|
472
539
|
end
|
473
540
|
|
474
541
|
def error_code_from(success, raw)
|
@@ -483,11 +550,64 @@ module ActiveMerchant #:nodoc:
|
|
483
550
|
end
|
484
551
|
end
|
485
552
|
|
486
|
-
def authorization_from(raw)
|
553
|
+
def authorization_from(action, raw, options)
|
554
|
+
order_id = order_id_from(raw)
|
555
|
+
|
556
|
+
case action
|
557
|
+
when 'store'
|
558
|
+
authorization_from_token_details(
|
559
|
+
order_id: order_id,
|
560
|
+
token_id: raw[:payment_token_id],
|
561
|
+
token_scope: 'shopper',
|
562
|
+
customer: options[:customer]
|
563
|
+
)
|
564
|
+
else
|
565
|
+
order_id
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
def order_id_from(raw)
|
487
570
|
pair = raw.detect { |k, v| k.to_s =~ /_order_code$/ }
|
488
571
|
(pair ? pair.last : nil)
|
489
572
|
end
|
490
573
|
|
574
|
+
def authorization_from_token_details(options={})
|
575
|
+
[options[:order_id], options[:token_id], options[:token_scope], options[:customer]].join('|')
|
576
|
+
end
|
577
|
+
|
578
|
+
def order_id_from_authorization(authorization)
|
579
|
+
token_details_from_authorization(authorization)[:order_id]
|
580
|
+
end
|
581
|
+
|
582
|
+
def token_details_from_authorization(authorization)
|
583
|
+
order_id, token_id, token_scope, customer = authorization.split('|')
|
584
|
+
|
585
|
+
token_details = {}
|
586
|
+
token_details[:order_id] = order_id if order_id.present?
|
587
|
+
token_details[:token_id] = token_id if token_id.present?
|
588
|
+
token_details[:token_scope] = token_scope if token_scope.present?
|
589
|
+
token_details[:customer] = customer if customer.present?
|
590
|
+
|
591
|
+
token_details
|
592
|
+
end
|
593
|
+
|
594
|
+
def payment_details_from(payment_method)
|
595
|
+
payment_details = {}
|
596
|
+
if payment_method.respond_to?(:number)
|
597
|
+
payment_details[:payment_type] = :credit
|
598
|
+
else
|
599
|
+
token_details = token_details_from_authorization(payment_method)
|
600
|
+
payment_details.merge!(token_details)
|
601
|
+
if token_details.has_key?(:token_id)
|
602
|
+
payment_details[:payment_type] = :token
|
603
|
+
else
|
604
|
+
payment_details[:payment_type] = :pay_as_order
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
payment_details
|
609
|
+
end
|
610
|
+
|
491
611
|
def credit_fund_transfer_attribute(options)
|
492
612
|
return unless options[:credit]
|
493
613
|
{'action' => 'REFUND'}
|
@@ -183,6 +183,7 @@ module ActiveMerchant #:nodoc:
|
|
183
183
|
{ alpha2: 'KI', name: 'Kiribati', alpha3: 'KIR', numeric: '296' },
|
184
184
|
{ alpha2: 'KP', name: 'Korea, Democratic People\'s Republic of', alpha3: 'PRK', numeric: '408' },
|
185
185
|
{ alpha2: 'KR', name: 'Korea, Republic of', alpha3: 'KOR', numeric: '410' },
|
186
|
+
{ alpha2: 'XK', name: 'Kosovo', alpha3: 'XKX', numeric: '900' },
|
186
187
|
{ alpha2: 'KW', name: 'Kuwait', alpha3: 'KWT', numeric: '414' },
|
187
188
|
{ alpha2: 'KG', name: 'Kyrgyzstan', alpha3: 'KGZ', numeric: '417' },
|
188
189
|
{ alpha2: 'LA', name: 'Lao People\'s Democratic Republic', alpha3: 'LAO', numeric: '418' },
|
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.
|
4
|
+
version: 1.96.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: 2019-
|
11
|
+
date: 2019-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -204,6 +204,7 @@ files:
|
|
204
204
|
- lib/active_merchant/billing/gateways/cyber_source.rb
|
205
205
|
- lib/active_merchant/billing/gateways/d_local.rb
|
206
206
|
- lib/active_merchant/billing/gateways/data_cash.rb
|
207
|
+
- lib/active_merchant/billing/gateways/decidir.rb
|
207
208
|
- lib/active_merchant/billing/gateways/dibs.rb
|
208
209
|
- lib/active_merchant/billing/gateways/digitzs.rb
|
209
210
|
- lib/active_merchant/billing/gateways/ebanx.rb
|