activemerchant 1.119.0 → 1.124.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 +216 -1
- data/README.md +4 -2
- data/lib/active_merchant/billing/check.rb +19 -12
- data/lib/active_merchant/billing/credit_card.rb +3 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +1 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +32 -14
- data/lib/active_merchant/billing/gateways/adyen.rb +94 -25
- data/lib/active_merchant/billing/gateways/authorize_net.rb +19 -11
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +29 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +52 -8
- data/lib/active_merchant/billing/gateways/card_stream.rb +17 -13
- data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +31 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +15 -9
- data/lib/active_merchant/billing/gateways/cyber_source.rb +53 -6
- data/lib/active_merchant/billing/gateways/d_local.rb +9 -2
- data/lib/active_merchant/billing/gateways/decidir.rb +7 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +70 -28
- data/lib/active_merchant/billing/gateways/element.rb +2 -0
- data/lib/active_merchant/billing/gateways/forte.rb +12 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +24 -10
- data/lib/active_merchant/billing/gateways/hps.rb +55 -1
- data/lib/active_merchant/billing/gateways/kushki.rb +23 -0
- data/lib/active_merchant/billing/gateways/litle.rb +1 -1
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +5 -4
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -0
- data/lib/active_merchant/billing/gateways/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/moka.rb +290 -0
- data/lib/active_merchant/billing/gateways/monei.rb +228 -144
- data/lib/active_merchant/billing/gateways/mundipagg.rb +14 -5
- data/lib/active_merchant/billing/gateways/netbanx.rb +26 -2
- data/lib/active_merchant/billing/gateways/nmi.rb +27 -9
- data/lib/active_merchant/billing/gateways/orbital.rb +99 -59
- data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
- data/lib/active_merchant/billing/gateways/pay_trace.rb +404 -0
- data/lib/active_merchant/billing/gateways/payeezy.rb +34 -6
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +21 -4
- data/lib/active_merchant/billing/gateways/payment_express.rb +5 -5
- data/lib/active_merchant/billing/gateways/paymentez.rb +5 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +376 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -3
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
- data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
- data/lib/active_merchant/billing/gateways/realex.rb +18 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +42 -24
- data/lib/active_merchant/billing/gateways/safe_charge.rb +25 -13
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +13 -4
- data/lib/active_merchant/billing/gateways/stripe.rb +18 -8
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +126 -48
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
- data/lib/active_merchant/billing/gateways/vpos.rb +220 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +78 -18
- data/lib/active_merchant/billing/response.rb +4 -0
- data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
- data/lib/active_merchant/billing.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/certs/cacert.pem +1582 -2431
- metadata +11 -3
@@ -16,8 +16,8 @@ module ActiveMerchant #:nodoc:
|
|
16
16
|
self.homepage_url = 'https://www.adyen.com/'
|
17
17
|
self.display_name = 'Adyen'
|
18
18
|
|
19
|
-
PAYMENT_API_VERSION = '
|
20
|
-
RECURRING_API_VERSION = '
|
19
|
+
PAYMENT_API_VERSION = 'v64'
|
20
|
+
RECURRING_API_VERSION = 'v49'
|
21
21
|
|
22
22
|
STANDARD_ERROR_CODE_MAPPING = {
|
23
23
|
'101' => STANDARD_ERROR_CODE[:incorrect_number],
|
@@ -59,6 +59,8 @@ module ActiveMerchant #:nodoc:
|
|
59
59
|
add_3ds_authenticated_data(post, options)
|
60
60
|
add_splits(post, options)
|
61
61
|
add_recurring_contract(post, options)
|
62
|
+
add_network_transaction_reference(post, options)
|
63
|
+
add_application_info(post, options)
|
62
64
|
commit('authorise', post, options)
|
63
65
|
end
|
64
66
|
|
@@ -67,21 +69,35 @@ module ActiveMerchant #:nodoc:
|
|
67
69
|
add_invoice_for_modification(post, money, options)
|
68
70
|
add_reference(post, authorization, options)
|
69
71
|
add_splits(post, options)
|
72
|
+
add_network_transaction_reference(post, options)
|
70
73
|
commit('capture', post, options)
|
71
74
|
end
|
72
75
|
|
73
76
|
def refund(money, authorization, options = {})
|
74
77
|
post = init_post(options)
|
75
78
|
add_invoice_for_modification(post, money, options)
|
76
|
-
|
79
|
+
add_reference(post, authorization, options)
|
77
80
|
add_splits(post, options)
|
81
|
+
add_network_transaction_reference(post, options)
|
78
82
|
commit('refund', post, options)
|
79
83
|
end
|
80
84
|
|
85
|
+
def credit(money, payment, options = {})
|
86
|
+
action = 'refundWithData'
|
87
|
+
post = init_post(options)
|
88
|
+
add_invoice(post, money, options)
|
89
|
+
add_payment(post, payment, options, action)
|
90
|
+
add_shopper_reference(post, options)
|
91
|
+
add_network_transaction_reference(post, options)
|
92
|
+
commit(action, post, options)
|
93
|
+
end
|
94
|
+
|
81
95
|
def void(authorization, options = {})
|
82
96
|
post = init_post(options)
|
97
|
+
endpoint = options[:cancel_or_refund] ? 'cancelOrRefund' : 'cancel'
|
83
98
|
add_reference(post, authorization, options)
|
84
|
-
|
99
|
+
add_network_transaction_reference(post, options)
|
100
|
+
commit(endpoint, post, options)
|
85
101
|
end
|
86
102
|
|
87
103
|
def adjust(money, authorization, options = {})
|
@@ -138,12 +154,19 @@ module ActiveMerchant #:nodoc:
|
|
138
154
|
true
|
139
155
|
end
|
140
156
|
|
157
|
+
def supports_network_tokenization?
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
141
161
|
def scrub(transcript)
|
142
162
|
transcript.
|
143
163
|
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
144
|
-
gsub(%r(("number\\?"
|
145
|
-
gsub(%r(("cvc\\?"
|
146
|
-
gsub(%r(("cavv\\?"
|
164
|
+
gsub(%r(("number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
165
|
+
gsub(%r(("cvc\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
166
|
+
gsub(%r(("cavv\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
167
|
+
gsub(%r(("bankLocationId\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
168
|
+
gsub(%r(("iban\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
169
|
+
gsub(%r(("bankAccountNumber\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]')
|
147
170
|
end
|
148
171
|
|
149
172
|
private
|
@@ -195,7 +218,7 @@ module ActiveMerchant #:nodoc:
|
|
195
218
|
}
|
196
219
|
|
197
220
|
def add_extra_data(post, payment, options)
|
198
|
-
post[:telephoneNumber] = options[:billing_address][:phone] if options.dig(:billing_address, :phone)
|
221
|
+
post[:telephoneNumber] = (options[:billing_address][:phone_number] if options.dig(:billing_address, :phone_number)) || (options[:billing_address][:phone] if options.dig(:billing_address, :phone)) || ''
|
199
222
|
post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset]
|
200
223
|
post[:selectedBrand] = options[:selected_brand] if options[:selected_brand]
|
201
224
|
post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard)
|
@@ -318,7 +341,7 @@ module ActiveMerchant #:nodoc:
|
|
318
341
|
post[:deliveryAddress][:stateOrProvince] = get_state(address)
|
319
342
|
post[:deliveryAddress][:country] = address[:country] if address[:country]
|
320
343
|
end
|
321
|
-
return unless post[:card]&.kind_of?(Hash)
|
344
|
+
return unless post[:bankAccount]&.kind_of?(Hash) || post[:card]&.kind_of?(Hash)
|
322
345
|
|
323
346
|
if (address = options[:billing_address] || options[:address]) && address[:country]
|
324
347
|
post[:billingAddress] = {}
|
@@ -341,6 +364,7 @@ module ActiveMerchant #:nodoc:
|
|
341
364
|
value: localized_amount(money, currency),
|
342
365
|
currency: currency
|
343
366
|
}
|
367
|
+
|
344
368
|
post[:amount] = amount
|
345
369
|
end
|
346
370
|
|
@@ -353,17 +377,32 @@ module ActiveMerchant #:nodoc:
|
|
353
377
|
post[:modificationAmount] = amount
|
354
378
|
end
|
355
379
|
|
356
|
-
def add_payment(post, payment, options)
|
380
|
+
def add_payment(post, payment, options, action = nil)
|
357
381
|
if payment.is_a?(String)
|
358
382
|
_, _, recurring_detail_reference = payment.split('#')
|
359
383
|
post[:selectedRecurringDetailReference] = recurring_detail_reference
|
360
384
|
options[:recurring_contract_type] ||= 'RECURRING'
|
385
|
+
elsif payment.is_a?(Check)
|
386
|
+
add_bank_account(post, payment, options, action)
|
361
387
|
else
|
362
388
|
add_mpi_data_for_network_tokenization_card(post, payment) if payment.is_a?(NetworkTokenizationCreditCard)
|
363
389
|
add_card(post, payment)
|
364
390
|
end
|
365
391
|
end
|
366
392
|
|
393
|
+
def add_bank_account(post, bank_account, options, action)
|
394
|
+
bank = {
|
395
|
+
bankAccountNumber: bank_account.account_number,
|
396
|
+
ownerName: bank_account.name,
|
397
|
+
countryCode: options[:billing_address][:country]
|
398
|
+
}
|
399
|
+
|
400
|
+
action == 'refundWithData' ? bank[:iban] = bank_account.routing_number : bank[:bankLocationId] = bank_account.routing_number
|
401
|
+
|
402
|
+
requires!(bank, :bankAccountNumber, :ownerName, :countryCode)
|
403
|
+
post[:bankAccount] = bank
|
404
|
+
end
|
405
|
+
|
367
406
|
def add_card(post, credit_card)
|
368
407
|
card = {
|
369
408
|
expiryMonth: credit_card.month,
|
@@ -374,7 +413,7 @@ module ActiveMerchant #:nodoc:
|
|
374
413
|
}
|
375
414
|
|
376
415
|
card.delete_if { |_k, v| v.blank? }
|
377
|
-
card[:holderName] ||= 'Not Provided'
|
416
|
+
card[:holderName] ||= 'Not Provided'
|
378
417
|
requires!(card, :expiryMonth, :expiryYear, :holderName, :number)
|
379
418
|
post[:card] = card
|
380
419
|
end
|
@@ -385,14 +424,16 @@ module ActiveMerchant #:nodoc:
|
|
385
424
|
options
|
386
425
|
end
|
387
426
|
|
388
|
-
def
|
389
|
-
|
390
|
-
|
427
|
+
def add_network_transaction_reference(post, options)
|
428
|
+
return unless ntid = options[:network_transaction_id] || options.dig(:stored_credential, :network_transaction_id)
|
429
|
+
|
430
|
+
post[:additionalData] = {} unless post[:additionalData]
|
431
|
+
post[:additionalData][:networkTxReference] = ntid
|
391
432
|
end
|
392
433
|
|
393
|
-
def
|
394
|
-
|
395
|
-
post[:originalReference] =
|
434
|
+
def add_reference(post, authorization, options = {})
|
435
|
+
original_reference = authorization.split('#').reject(&:empty?).first
|
436
|
+
post[:originalReference] = original_reference
|
396
437
|
end
|
397
438
|
|
398
439
|
def add_mpi_data_for_network_tokenization_card(post, payment)
|
@@ -403,10 +444,6 @@ module ActiveMerchant #:nodoc:
|
|
403
444
|
post[:mpiData][:eci] = payment.eci || '07'
|
404
445
|
end
|
405
446
|
|
406
|
-
def single_reference(authorization)
|
407
|
-
authorization if !authorization.include?('#')
|
408
|
-
end
|
409
|
-
|
410
447
|
def add_recurring_contract(post, options = {})
|
411
448
|
return unless options[:recurring_contract_type]
|
412
449
|
|
@@ -417,6 +454,31 @@ module ActiveMerchant #:nodoc:
|
|
417
454
|
post[:recurring] = recurring
|
418
455
|
end
|
419
456
|
|
457
|
+
def add_application_info(post, options)
|
458
|
+
post[:applicationInfo] ||= {}
|
459
|
+
add_external_platform(post, options)
|
460
|
+
add_merchant_application(post, options)
|
461
|
+
end
|
462
|
+
|
463
|
+
def add_external_platform(post, options)
|
464
|
+
return unless options[:externalPlatform]
|
465
|
+
|
466
|
+
post[:applicationInfo][:externalPlatform] = {
|
467
|
+
name: options[:externalPlatform][:name],
|
468
|
+
version: options[:externalPlatform][:version],
|
469
|
+
integrator: options[:externalPlatform][:integrator]
|
470
|
+
}
|
471
|
+
end
|
472
|
+
|
473
|
+
def add_merchant_application(post, options)
|
474
|
+
return unless options[:merchantApplication]
|
475
|
+
|
476
|
+
post[:applicationInfo][:merchantApplication] = {
|
477
|
+
name: options[:merchantApplication][:name],
|
478
|
+
version: options[:merchantApplication][:version]
|
479
|
+
}
|
480
|
+
end
|
481
|
+
|
420
482
|
def add_installments(post, options)
|
421
483
|
post[:installments] = {
|
422
484
|
value: options[:installments]
|
@@ -498,6 +560,7 @@ module ActiveMerchant #:nodoc:
|
|
498
560
|
raw_response = e.response.body
|
499
561
|
response = parse(raw_response)
|
500
562
|
end
|
563
|
+
|
501
564
|
success = success_from(action, response, options)
|
502
565
|
Response.new(
|
503
566
|
success,
|
@@ -506,6 +569,7 @@ module ActiveMerchant #:nodoc:
|
|
506
569
|
authorization: authorization_from(action, parameters, response),
|
507
570
|
test: test?,
|
508
571
|
error_code: success ? nil : error_code_from(response),
|
572
|
+
network_transaction_id: network_transaction_id_from(response),
|
509
573
|
avs_result: AVSResult.new(code: avs_code_from(response)),
|
510
574
|
cvv_result: CVVResult.new(cvv_result_from(response))
|
511
575
|
)
|
@@ -552,11 +616,10 @@ module ActiveMerchant #:nodoc:
|
|
552
616
|
response['refusalReason'] = 'Received unexpected 3DS authentication response. Use the execute_threed and/or threed_dynamic options to initiate a proper 3DS flow.'
|
553
617
|
return false
|
554
618
|
end
|
555
|
-
|
556
619
|
case action.to_s
|
557
620
|
when 'authorise', 'authorise3d'
|
558
621
|
%w[Authorised Received RedirectShopper].include?(response['resultCode'])
|
559
|
-
when 'capture', 'refund', 'cancel'
|
622
|
+
when 'capture', 'refund', 'cancel', 'cancelOrRefund'
|
560
623
|
response['response'] == "[#{action}-received]"
|
561
624
|
when 'adjustAuthorisation'
|
562
625
|
response['response'] == 'Authorised' || response['response'] == '[adjustAuthorisation-received]'
|
@@ -564,6 +627,8 @@ module ActiveMerchant #:nodoc:
|
|
564
627
|
response['result'] == 'Success'
|
565
628
|
when 'disable'
|
566
629
|
response['response'] == '[detail-successfully-disabled]'
|
630
|
+
when 'refundWithData'
|
631
|
+
response['resultCode'] == 'Received'
|
567
632
|
else
|
568
633
|
false
|
569
634
|
end
|
@@ -572,7 +637,7 @@ module ActiveMerchant #:nodoc:
|
|
572
637
|
def message_from(action, response)
|
573
638
|
return authorize_message_from(response) if %w(authorise authorise3d authorise3ds2).include?(action.to_s)
|
574
639
|
|
575
|
-
response['response'] || response['message'] || response['result']
|
640
|
+
response['response'] || response['message'] || response['result'] || response['resultCode']
|
576
641
|
end
|
577
642
|
|
578
643
|
def authorize_message_from(response)
|
@@ -595,7 +660,7 @@ module ActiveMerchant #:nodoc:
|
|
595
660
|
def init_post(options = {})
|
596
661
|
post = {}
|
597
662
|
add_merchant_account(post, options)
|
598
|
-
post[:reference] = options[:order_id] if options[:order_id]
|
663
|
+
post[:reference] = options[:order_id][0..79] if options[:order_id]
|
599
664
|
post
|
600
665
|
end
|
601
666
|
|
@@ -607,6 +672,10 @@ module ActiveMerchant #:nodoc:
|
|
607
672
|
STANDARD_ERROR_CODE_MAPPING[response['errorCode']]
|
608
673
|
end
|
609
674
|
|
675
|
+
def network_transaction_id_from(response)
|
676
|
+
response.dig('additionalData', 'networkTxReference')
|
677
|
+
end
|
678
|
+
|
610
679
|
def add_browser_info(browser_info, post)
|
611
680
|
return unless browser_info
|
612
681
|
|
@@ -567,14 +567,16 @@ module ActiveMerchant
|
|
567
567
|
|
568
568
|
xml.customerIP(options[:ip]) unless empty?(options[:ip])
|
569
569
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
570
|
+
if !empty?(options.fetch(:three_d_secure, {})) || options[:authentication_indicator] || options[:cardholder_authentication_value]
|
571
|
+
xml.cardholderAuthentication do
|
572
|
+
three_d_secure = options.fetch(:three_d_secure, {})
|
573
|
+
xml.authenticationIndicator(
|
574
|
+
options[:authentication_indicator] || three_d_secure[:eci]
|
575
|
+
)
|
576
|
+
xml.cardholderAuthenticationValue(
|
577
|
+
options[:cardholder_authentication_value] || three_d_secure[:cavv]
|
578
|
+
)
|
579
|
+
end
|
578
580
|
end
|
579
581
|
end
|
580
582
|
|
@@ -708,9 +710,10 @@ module ActiveMerchant
|
|
708
710
|
return unless options[:stored_credential]
|
709
711
|
|
710
712
|
xml.processingOptions do
|
711
|
-
if options[:stored_credential][:initial_transaction]
|
713
|
+
if options[:stored_credential][:initial_transaction] && options[:stored_credential][:reason_type] == 'recurring'
|
714
|
+
xml.isFirstRecurringPayment 'true'
|
715
|
+
elsif options[:stored_credential][:initial_transaction]
|
712
716
|
xml.isFirstSubsequentAuth 'true'
|
713
|
-
# xml.isFirstRecurringPayment 'true' if options[:stored_credential][:reason_type] == 'recurring'
|
714
717
|
elsif options[:stored_credential][:initiator] == 'cardholder'
|
715
718
|
xml.isStoredCredentials 'true'
|
716
719
|
else
|
@@ -720,7 +723,7 @@ module ActiveMerchant
|
|
720
723
|
end
|
721
724
|
|
722
725
|
def add_subsequent_auth_information(xml, options)
|
723
|
-
return unless options.dig(:stored_credential, :
|
726
|
+
return unless options.dig(:stored_credential, :initiator) == 'merchant'
|
724
727
|
|
725
728
|
xml.subsequentAuthInformation do
|
726
729
|
xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override]
|
@@ -934,6 +937,11 @@ module ActiveMerchant
|
|
934
937
|
empty?(element.content) ? nil : element.content
|
935
938
|
end
|
936
939
|
|
940
|
+
response[:network_trans_id] =
|
941
|
+
if element = doc.at_xpath('//networkTransId')
|
942
|
+
empty?(element.content) ? nil : element.content
|
943
|
+
end
|
944
|
+
|
937
945
|
response
|
938
946
|
end
|
939
947
|
|
@@ -563,6 +563,8 @@ module ActiveMerchant #:nodoc:
|
|
563
563
|
|
564
564
|
def build_get_customer_profile_request(xml, options)
|
565
565
|
xml.tag!('customerProfileId', options[:customer_profile_id])
|
566
|
+
xml.tag!('unmaskExpirationDate', options[:unmask_expiration_date]) if options[:unmask_expiration_date]
|
567
|
+
xml.tag!('includeIssuerInfo', options[:include_issuer_info]) if options[:include_issuer_info]
|
566
568
|
xml.target!
|
567
569
|
end
|
568
570
|
|
@@ -574,6 +576,7 @@ module ActiveMerchant #:nodoc:
|
|
574
576
|
xml.tag!('customerProfileId', options[:customer_profile_id])
|
575
577
|
xml.tag!('customerPaymentProfileId', options[:customer_payment_profile_id])
|
576
578
|
xml.tag!('unmaskExpirationDate', options[:unmask_expiration_date]) if options[:unmask_expiration_date]
|
579
|
+
xml.tag!('includeIssuerInfo', options[:include_issuer_info]) if options[:include_issuer_info]
|
577
580
|
xml.target!
|
578
581
|
end
|
579
582
|
|
@@ -84,6 +84,7 @@ module ActiveMerchant #:nodoc:
|
|
84
84
|
add_customer_data(post, options)
|
85
85
|
add_rebill(post, options) if options[:rebill]
|
86
86
|
add_duplicate_override(post, options)
|
87
|
+
add_stored_credential(post, options)
|
87
88
|
post[:TRANS_TYPE] = 'AUTH'
|
88
89
|
commit('AUTH_ONLY', money, post, options)
|
89
90
|
end
|
@@ -107,6 +108,7 @@ module ActiveMerchant #:nodoc:
|
|
107
108
|
add_customer_data(post, options)
|
108
109
|
add_rebill(post, options) if options[:rebill]
|
109
110
|
add_duplicate_override(post, options)
|
111
|
+
add_stored_credential(post, options)
|
110
112
|
post[:TRANS_TYPE] = 'SALE'
|
111
113
|
commit('AUTH_CAPTURE', money, post, options)
|
112
114
|
end
|
@@ -461,6 +463,33 @@ module ActiveMerchant #:nodoc:
|
|
461
463
|
post[:REB_CYCLES] = options[:rebill_cycles]
|
462
464
|
end
|
463
465
|
|
466
|
+
def add_stored_credential(post, options)
|
467
|
+
post[:cof] = initiator(options)
|
468
|
+
post[:cofscheduled] = scheduled(options)
|
469
|
+
end
|
470
|
+
|
471
|
+
def initiator(options)
|
472
|
+
return unless initiator = options.dig(:stored_credential, :initiator)
|
473
|
+
|
474
|
+
case initiator
|
475
|
+
when 'merchant'
|
476
|
+
'M'
|
477
|
+
when 'cardholder'
|
478
|
+
'C'
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def scheduled(options)
|
483
|
+
return unless reason_type = options.dig(:stored_credential, :reason_type)
|
484
|
+
|
485
|
+
case reason_type
|
486
|
+
when 'recurring' || 'installment'
|
487
|
+
'Y'
|
488
|
+
when 'unscheduled'
|
489
|
+
'N'
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
464
493
|
def post_data(action, parameters = {})
|
465
494
|
post = {}
|
466
495
|
post[:version] = '1'
|
@@ -386,7 +386,7 @@ module ActiveMerchant
|
|
386
386
|
|
387
387
|
def parse(response)
|
388
388
|
return bad_authentication_response if response.code.to_i == 401
|
389
|
-
return
|
389
|
+
return generic_error_response(response.body) if [403, 429].include?(response.code.to_i)
|
390
390
|
|
391
391
|
parsed = {}
|
392
392
|
doc = Nokogiri::XML(response.body)
|
@@ -564,7 +564,7 @@ module ActiveMerchant
|
|
564
564
|
{ 'description' => 'Unable to authenticate. Please check your credentials.' }
|
565
565
|
end
|
566
566
|
|
567
|
-
def
|
567
|
+
def generic_error_response(body)
|
568
568
|
{ 'description' => body }
|
569
569
|
end
|
570
570
|
end
|
@@ -7,7 +7,7 @@ rescue LoadError
|
|
7
7
|
raise 'Could not load the braintree gem. Use `gem install braintree` to install it.'
|
8
8
|
end
|
9
9
|
|
10
|
-
raise
|
10
|
+
raise 'Need braintree gem >= 2.0.0.' unless Braintree::Version::Major >= 2 && Braintree::Version::Minor >= 0
|
11
11
|
|
12
12
|
module ActiveMerchant #:nodoc:
|
13
13
|
module Billing #:nodoc:
|
@@ -115,10 +115,36 @@ module ActiveMerchant #:nodoc:
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
def verify(
|
119
|
-
|
120
|
-
|
121
|
-
|
118
|
+
def verify(creditcard, options = {})
|
119
|
+
if options[:allow_card_verification] == true
|
120
|
+
options.delete(:allow_card_verification)
|
121
|
+
exp_month = creditcard.month.to_s
|
122
|
+
exp_year = creditcard.year.to_s
|
123
|
+
expiration = "#{exp_month}/#{exp_year}"
|
124
|
+
payload = {
|
125
|
+
credit_card: {
|
126
|
+
number: creditcard.number,
|
127
|
+
expiration_date: expiration,
|
128
|
+
cvv: creditcard.verification_value,
|
129
|
+
billing_address: {
|
130
|
+
postal_code: options[:billing_address][:zip]
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
commit do
|
135
|
+
result = @braintree_gateway.verification.create(payload)
|
136
|
+
response = Response.new(result.success?, message_from_transaction_result(result), response_options(result))
|
137
|
+
response.cvv_result['message'] = ''
|
138
|
+
response.cvv_result['code'] = response.params['cvv_result'] if response.params['cvv_result']
|
139
|
+
response.avs_result['code'] = response.params['avs_result'][:code] if response.params.dig('avs_result', :code)
|
140
|
+
response
|
141
|
+
end
|
142
|
+
|
143
|
+
else
|
144
|
+
MultiResponse.run(:use_first_response) do |r|
|
145
|
+
r.process { authorize(100, creditcard, options) }
|
146
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
147
|
+
end
|
122
148
|
end
|
123
149
|
end
|
124
150
|
|
@@ -368,7 +394,11 @@ module ActiveMerchant #:nodoc:
|
|
368
394
|
|
369
395
|
def response_options(result)
|
370
396
|
options = {}
|
371
|
-
if result.
|
397
|
+
if result.credit_card_verification
|
398
|
+
options[:authorization] = result.credit_card_verification.id
|
399
|
+
options[:avs_result] = { code: avs_code_from(result.credit_card_verification) }
|
400
|
+
options[:cvv_result] = result.credit_card_verification.cvv_response_code
|
401
|
+
elsif result.transaction
|
372
402
|
options[:authorization] = result.transaction.id
|
373
403
|
options[:avs_result] = { code: avs_code_from(result.transaction) }
|
374
404
|
options[:cvv_result] = result.transaction.cvv_response_code
|
@@ -558,7 +588,8 @@ module ActiveMerchant #:nodoc:
|
|
558
588
|
'merchant_account_id' => transaction.merchant_account_id,
|
559
589
|
'risk_data' => risk_data,
|
560
590
|
'network_transaction_id' => transaction.network_transaction_id || nil,
|
561
|
-
'processor_response_code' => response_code_from_result(result)
|
591
|
+
'processor_response_code' => response_code_from_result(result),
|
592
|
+
'recurring' => transaction.recurring
|
562
593
|
}
|
563
594
|
end
|
564
595
|
|
@@ -592,6 +623,7 @@ module ActiveMerchant #:nodoc:
|
|
592
623
|
add_addresses(parameters, options)
|
593
624
|
|
594
625
|
add_descriptor(parameters, options)
|
626
|
+
add_risk_data(parameters, options)
|
595
627
|
add_travel_data(parameters, options) if options[:travel_data]
|
596
628
|
add_lodging_data(parameters, options) if options[:lodging_data]
|
597
629
|
add_channel(parameters, options)
|
@@ -652,6 +684,15 @@ module ActiveMerchant #:nodoc:
|
|
652
684
|
}
|
653
685
|
end
|
654
686
|
|
687
|
+
def add_risk_data(parameters, options)
|
688
|
+
return unless options[:risk_data]
|
689
|
+
|
690
|
+
parameters[:risk_data] = {
|
691
|
+
customer_browser: options[:risk_data][:customer_browser],
|
692
|
+
customer_ip: options[:risk_data][:customer_ip]
|
693
|
+
}
|
694
|
+
end
|
695
|
+
|
655
696
|
def add_level_2_data(parameters, options)
|
656
697
|
parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
|
657
698
|
parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
|
@@ -730,6 +771,8 @@ module ActiveMerchant #:nodoc:
|
|
730
771
|
else
|
731
772
|
parameters[:transaction_source] = stored_credential[:reason_type]
|
732
773
|
end
|
774
|
+
elsif %w(recurring_first moto).include?(stored_credential[:reason_type])
|
775
|
+
parameters[:transaction_source] = stored_credential[:reason_type]
|
733
776
|
else
|
734
777
|
parameters[:transaction_source] = ''
|
735
778
|
end
|
@@ -761,7 +804,8 @@ module ActiveMerchant #:nodoc:
|
|
761
804
|
eci_indicator: credit_card_or_vault_id.eci
|
762
805
|
}
|
763
806
|
elsif credit_card_or_vault_id.source == :android_pay || credit_card_or_vault_id.source == :google_pay
|
764
|
-
|
807
|
+
Braintree::Version::Major < 3 ? pay_card = :android_pay_card : pay_card = :google_pay_card
|
808
|
+
parameters[pay_card] = {
|
765
809
|
number: credit_card_or_vault_id.number,
|
766
810
|
cryptogram: credit_card_or_vault_id.payment_cryptogram,
|
767
811
|
expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'),
|
@@ -150,23 +150,13 @@ module ActiveMerchant #:nodoc:
|
|
150
150
|
|
151
151
|
def authorize(money, credit_card_or_reference, options = {})
|
152
152
|
post = {}
|
153
|
-
|
154
|
-
add_amount(post, money, options)
|
155
|
-
add_invoice(post, credit_card_or_reference, money, options)
|
156
|
-
add_credit_card_or_reference(post, credit_card_or_reference)
|
157
|
-
add_customer_data(post, options)
|
158
|
-
add_remote_address(post, options)
|
153
|
+
add_auth_purchase(post, -1, money, credit_card_or_reference, options)
|
159
154
|
commit('SALE', post)
|
160
155
|
end
|
161
156
|
|
162
157
|
def purchase(money, credit_card_or_reference, options = {})
|
163
158
|
post = {}
|
164
|
-
|
165
|
-
add_amount(post, money, options)
|
166
|
-
add_invoice(post, credit_card_or_reference, money, options)
|
167
|
-
add_credit_card_or_reference(post, credit_card_or_reference)
|
168
|
-
add_customer_data(post, options)
|
169
|
-
add_remote_address(post, options)
|
159
|
+
add_auth_purchase(post, 0, money, credit_card_or_reference, options)
|
170
160
|
commit('SALE', post)
|
171
161
|
end
|
172
162
|
|
@@ -184,6 +174,7 @@ module ActiveMerchant #:nodoc:
|
|
184
174
|
add_pair(post, :xref, authorization)
|
185
175
|
add_amount(post, money, options)
|
186
176
|
add_remote_address(post, options)
|
177
|
+
add_country_code(post, options)
|
187
178
|
response = commit('REFUND_SALE', post)
|
188
179
|
|
189
180
|
return response if response.success?
|
@@ -223,6 +214,16 @@ module ActiveMerchant #:nodoc:
|
|
223
214
|
|
224
215
|
private
|
225
216
|
|
217
|
+
def add_auth_purchase(post, pair_value, money, credit_card_or_reference, options)
|
218
|
+
add_pair(post, :captureDelay, pair_value)
|
219
|
+
add_amount(post, money, options)
|
220
|
+
add_invoice(post, credit_card_or_reference, money, options)
|
221
|
+
add_credit_card_or_reference(post, credit_card_or_reference)
|
222
|
+
add_customer_data(post, options)
|
223
|
+
add_remote_address(post, options)
|
224
|
+
add_country_code(post, options)
|
225
|
+
end
|
226
|
+
|
226
227
|
def add_amount(post, money, options)
|
227
228
|
currency = options[:currency] || currency(money)
|
228
229
|
add_pair(post, :amount, localized_amount(money, currency), required: true)
|
@@ -286,6 +287,10 @@ module ActiveMerchant #:nodoc:
|
|
286
287
|
add_pair(post, :remoteAddress, options[:ip] || '1.1.1.1')
|
287
288
|
end
|
288
289
|
|
290
|
+
def add_country_code(post, options)
|
291
|
+
post[:countryCode] = options[:country_code] || self.supported_countries[0]
|
292
|
+
end
|
293
|
+
|
289
294
|
def normalize_line_endings(str)
|
290
295
|
str.gsub(/%0D%0A|%0A%0D|%0D/, '%0A')
|
291
296
|
end
|
@@ -309,7 +314,6 @@ module ActiveMerchant #:nodoc:
|
|
309
314
|
end
|
310
315
|
|
311
316
|
def commit(action, parameters)
|
312
|
-
parameters.update(countryCode: self.supported_countries[0]) unless %w[CAPTURE CANCEL].include?(action)
|
313
317
|
parameters.update(
|
314
318
|
merchantID: @options[:login],
|
315
319
|
action: action
|
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
|
9
9
|
self.supported_countries = ['US']
|
10
10
|
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
11
|
-
self.homepage_url = '
|
11
|
+
self.homepage_url = 'https://transactcampus.com'
|
12
12
|
self.display_name = 'Cashnet'
|
13
13
|
self.money_format = :dollars
|
14
14
|
self.max_retries = 0
|
@@ -76,7 +76,7 @@ module ActiveMerchant #:nodoc:
|
|
76
76
|
|
77
77
|
return unparsable_response(raw_response) unless parsed_response
|
78
78
|
|
79
|
-
success = (parsed_response
|
79
|
+
success = success?(parsed_response)
|
80
80
|
Response.new(
|
81
81
|
success,
|
82
82
|
CASHNET_CODES[parsed_response[:result]],
|
@@ -86,6 +86,10 @@ module ActiveMerchant #:nodoc:
|
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
89
|
+
def success?(response)
|
90
|
+
response[:result] == '0'
|
91
|
+
end
|
92
|
+
|
89
93
|
def post_data(action, parameters = {})
|
90
94
|
post = {}
|
91
95
|
post[:command] = action
|
@@ -191,6 +195,7 @@ module ActiveMerchant #:nodoc:
|
|
191
195
|
'215' => 'Old PIN does not validate ',
|
192
196
|
'221' => 'Invalid credit card processor type specified in location or payment code',
|
193
197
|
'222' => 'Credit card processor error',
|
198
|
+
'230' => 'Host Error (USE VOID OR REVERSAL TO REFUND UNSETTLED TRANSACTIONS)',
|
194
199
|
'280' => 'SmartPay transaction not posted',
|
195
200
|
'301' => 'Original transaction not found for this customer',
|
196
201
|
'302' => 'Amount to refund exceeds original payment amount or is missing',
|