activemerchant 1.116.0 → 1.121.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +148 -1
- data/README.md +4 -2
- data/lib/active_merchant/billing/check.rb +10 -0
- data/lib/active_merchant/billing/credit_card.rb +3 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +80 -15
- data/lib/active_merchant/billing/gateways/adyen.rb +29 -8
- data/lib/active_merchant/billing/gateways/authorize_net.rb +37 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +54 -7
- data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -2
- data/lib/active_merchant/billing/gateways/credorax.rb +30 -14
- data/lib/active_merchant/billing/gateways/cyber_source.rb +51 -8
- data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
- data/lib/active_merchant/billing/gateways/decidir.rb +22 -2
- data/lib/active_merchant/billing/gateways/elavon.rb +54 -2
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +13 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +17 -6
- data/lib/active_merchant/billing/gateways/forte.rb +12 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +25 -6
- data/lib/active_merchant/billing/gateways/hps.rb +65 -2
- data/lib/active_merchant/billing/gateways/litle.rb +21 -5
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +2 -2
- data/lib/active_merchant/billing/gateways/netbanx.rb +37 -2
- data/lib/active_merchant/billing/gateways/orbital.rb +178 -45
- data/lib/active_merchant/billing/gateways/payeezy.rb +53 -11
- data/lib/active_merchant/billing/gateways/payment_express.rb +10 -5
- data/lib/active_merchant/billing/gateways/paymentez.rb +21 -1
- data/lib/active_merchant/billing/gateways/paypal.rb +10 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
- data/lib/active_merchant/billing/gateways/pin.rb +11 -0
- data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
- data/lib/active_merchant/billing/gateways/redsys.rb +101 -5
- data/lib/active_merchant/billing/gateways/safe_charge.rb +39 -6
- data/lib/active_merchant/billing/gateways/stripe.rb +9 -9
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +82 -25
- data/lib/active_merchant/billing/gateways/vpos.rb +177 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +31 -14
- data/lib/active_merchant/billing/response.rb +2 -1
- data/lib/active_merchant/version.rb +1 -1
- data/lib/certs/cacert.pem +1582 -2431
- metadata +5 -3
@@ -257,6 +257,8 @@ module ActiveMerchant
|
|
257
257
|
add_settings(xml, payment, options)
|
258
258
|
add_user_fields(xml, amount, options)
|
259
259
|
add_ship_from_address(xml, options)
|
260
|
+
add_processing_options(xml, options)
|
261
|
+
add_subsequent_auth_information(xml, options)
|
260
262
|
end
|
261
263
|
end
|
262
264
|
|
@@ -408,7 +410,7 @@ module ActiveMerchant
|
|
408
410
|
|
409
411
|
def add_settings(xml, source, options)
|
410
412
|
xml.transactionSettings do
|
411
|
-
if options[:recurring]
|
413
|
+
if options[:recurring] || subsequent_recurring_transaction?(options)
|
412
414
|
xml.setting do
|
413
415
|
xml.settingName('recurringBilling')
|
414
416
|
xml.settingValue('true')
|
@@ -702,6 +704,31 @@ module ActiveMerchant
|
|
702
704
|
xml.extraOptions("x_delim_char=#{options[:delimiter]}") if options[:delimiter]
|
703
705
|
end
|
704
706
|
|
707
|
+
def add_processing_options(xml, options)
|
708
|
+
return unless options[:stored_credential]
|
709
|
+
|
710
|
+
xml.processingOptions do
|
711
|
+
if options[:stored_credential][:initial_transaction] && options[:stored_credential][:reason_type] == 'recurring'
|
712
|
+
xml.isFirstRecurringPayment 'true'
|
713
|
+
elsif options[:stored_credential][:initial_transaction]
|
714
|
+
xml.isFirstSubsequentAuth 'true'
|
715
|
+
elsif options[:stored_credential][:initiator] == 'cardholder'
|
716
|
+
xml.isStoredCredentials 'true'
|
717
|
+
else
|
718
|
+
xml.isSubsequentAuth 'true'
|
719
|
+
end
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
def add_subsequent_auth_information(xml, options)
|
724
|
+
return unless options.dig(:stored_credential, :initiator) == 'merchant'
|
725
|
+
|
726
|
+
xml.subsequentAuthInformation do
|
727
|
+
xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override]
|
728
|
+
xml.originalNetworkTransId options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
|
729
|
+
end
|
730
|
+
end
|
731
|
+
|
705
732
|
def create_customer_payment_profile(credit_card, options)
|
706
733
|
commit(:cim_store_update, options) do |xml|
|
707
734
|
xml.customerProfileId options[:customer_profile_id]
|
@@ -764,6 +791,10 @@ module ActiveMerchant
|
|
764
791
|
end
|
765
792
|
end
|
766
793
|
|
794
|
+
def subsequent_recurring_transaction?(options)
|
795
|
+
options.dig(:stored_credential, :reason_type) == 'recurring' && !options.dig(:stored_credential, :initial_transaction)
|
796
|
+
end
|
797
|
+
|
767
798
|
def headers
|
768
799
|
{ 'Content-Type' => 'text/xml' }
|
769
800
|
end
|
@@ -904,6 +935,11 @@ module ActiveMerchant
|
|
904
935
|
empty?(element.content) ? nil : element.content
|
905
936
|
end
|
906
937
|
|
938
|
+
response[:network_trans_id] =
|
939
|
+
if element = doc.at_xpath('//networkTransId')
|
940
|
+
empty?(element.content) ? nil : element.content
|
941
|
+
end
|
942
|
+
|
907
943
|
response
|
908
944
|
end
|
909
945
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
|
2
3
|
module ActiveMerchant #:nodoc:
|
3
4
|
module Billing #:nodoc:
|
4
5
|
# ==== Customer Information Manager (CIM)
|
@@ -562,6 +563,8 @@ module ActiveMerchant #:nodoc:
|
|
562
563
|
|
563
564
|
def build_get_customer_profile_request(xml, options)
|
564
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]
|
565
568
|
xml.target!
|
566
569
|
end
|
567
570
|
|
@@ -573,6 +576,7 @@ module ActiveMerchant #:nodoc:
|
|
573
576
|
xml.tag!('customerProfileId', options[:customer_profile_id])
|
574
577
|
xml.tag!('customerPaymentProfileId', options[:customer_payment_profile_id])
|
575
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]
|
576
580
|
xml.target!
|
577
581
|
end
|
578
582
|
|
@@ -319,7 +319,9 @@ module ActiveMerchant
|
|
319
319
|
def add_fraud_info(doc, payment_method, options)
|
320
320
|
doc.send('transaction-fraud-info') do
|
321
321
|
doc.send('shopper-ip-address', options[:ip]) if options[:ip]
|
322
|
-
|
322
|
+
if fraud_info = options[:transaction_fraud_info]
|
323
|
+
doc.send('fraud-session-id', fraud_info[:fraud_session_id]) if fraud_info[:fraud_session_id]
|
324
|
+
end
|
323
325
|
unless payment_method.is_a? String
|
324
326
|
doc.send('shipping-contact-info') do
|
325
327
|
add_shipping_contact_info(doc, payment_method, options)
|
@@ -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']
|
139
|
+
response.avs_result['code'] = response.params['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
|
@@ -583,6 +613,7 @@ module ActiveMerchant #:nodoc:
|
|
583
613
|
parameters[:device_data] = options[:device_data] if options[:device_data]
|
584
614
|
parameters[:service_fee_amount] = options[:service_fee_amount] if options[:service_fee_amount]
|
585
615
|
|
616
|
+
add_account_type(parameters, options) if options[:account_type]
|
586
617
|
add_skip_options(parameters, options)
|
587
618
|
add_merchant_account_id(parameters, options)
|
588
619
|
|
@@ -591,6 +622,7 @@ module ActiveMerchant #:nodoc:
|
|
591
622
|
add_addresses(parameters, options)
|
592
623
|
|
593
624
|
add_descriptor(parameters, options)
|
625
|
+
add_risk_data(parameters, options)
|
594
626
|
add_travel_data(parameters, options) if options[:travel_data]
|
595
627
|
add_lodging_data(parameters, options) if options[:lodging_data]
|
596
628
|
add_channel(parameters, options)
|
@@ -609,6 +641,11 @@ module ActiveMerchant #:nodoc:
|
|
609
641
|
parameters
|
610
642
|
end
|
611
643
|
|
644
|
+
def add_account_type(parameters, options)
|
645
|
+
parameters[:options][:credit_card] = {}
|
646
|
+
parameters[:options][:credit_card][:account_type] = options[:account_type]
|
647
|
+
end
|
648
|
+
|
612
649
|
def add_skip_options(parameters, options)
|
613
650
|
parameters[:options][:skip_advanced_fraud_checking] = options[:skip_advanced_fraud_checking] if options[:skip_advanced_fraud_checking]
|
614
651
|
parameters[:options][:skip_avs] = options[:skip_avs] if options[:skip_avs]
|
@@ -646,6 +683,15 @@ module ActiveMerchant #:nodoc:
|
|
646
683
|
}
|
647
684
|
end
|
648
685
|
|
686
|
+
def add_risk_data(parameters, options)
|
687
|
+
return unless options[:risk_data]
|
688
|
+
|
689
|
+
parameters[:risk_data] = {
|
690
|
+
customer_browser: options[:risk_data][:customer_browser],
|
691
|
+
customer_ip: options[:risk_data][:customer_ip]
|
692
|
+
}
|
693
|
+
end
|
694
|
+
|
649
695
|
def add_level_2_data(parameters, options)
|
650
696
|
parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
|
651
697
|
parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
|
@@ -755,7 +801,8 @@ module ActiveMerchant #:nodoc:
|
|
755
801
|
eci_indicator: credit_card_or_vault_id.eci
|
756
802
|
}
|
757
803
|
elsif credit_card_or_vault_id.source == :android_pay || credit_card_or_vault_id.source == :google_pay
|
758
|
-
|
804
|
+
Braintree::Version::Major < 3 ? pay_card = :android_pay_card : pay_card = :google_pay_card
|
805
|
+
parameters[pay_card] = {
|
759
806
|
number: credit_card_or_vault_id.number,
|
760
807
|
cryptogram: credit_card_or_vault_id.payment_cryptogram,
|
761
808
|
expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'),
|
@@ -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',
|
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
self.supported_countries = %w[AD AE AR AT AU BE BG BH BR CH CL CN CO CY CZ DE DK EE EG ES FI FR GB GR HK HR HU IE IS IT JO JP KW LI LT LU LV MC MT MX MY NL NO NZ OM PE PL PT QA RO SA SE SG SI SK SM TR US]
|
10
10
|
self.default_currency = 'USD'
|
11
11
|
self.money_format = :cents
|
12
|
-
self.supported_cardtypes = %i[visa master american_express diners_club maestro discover]
|
12
|
+
self.supported_cardtypes = %i[visa master american_express diners_club maestro discover jcb]
|
13
13
|
self.currencies_without_fractions = %w(BIF DJF GNF ISK KMF XAF CLF XPF JPY PYG RWF KRW VUV VND XOF)
|
14
14
|
self.currencies_with_three_decimal_places = %w(BHD LYD JOD KWD OMR TND)
|
15
15
|
|
@@ -37,12 +37,15 @@ module ActiveMerchant #:nodoc:
|
|
37
37
|
post = {}
|
38
38
|
add_invoice(post, amount, options)
|
39
39
|
add_customer_data(post, options)
|
40
|
+
add_metadata(post, options)
|
40
41
|
|
41
42
|
commit(:capture, post, authorization)
|
42
43
|
end
|
43
44
|
|
44
45
|
def void(authorization, _options = {})
|
45
46
|
post = {}
|
47
|
+
add_metadata(post, options)
|
48
|
+
|
46
49
|
commit(:void, post, authorization)
|
47
50
|
end
|
48
51
|
|
@@ -50,6 +53,7 @@ module ActiveMerchant #:nodoc:
|
|
50
53
|
post = {}
|
51
54
|
add_invoice(post, amount, options)
|
52
55
|
add_customer_data(post, options)
|
56
|
+
add_metadata(post, options)
|
53
57
|
|
54
58
|
commit(:refund, post, authorization)
|
55
59
|
end
|
@@ -79,8 +83,10 @@ module ActiveMerchant #:nodoc:
|
|
79
83
|
add_invoice(post, amount, options)
|
80
84
|
add_payment_method(post, payment_method, options)
|
81
85
|
add_customer_data(post, options)
|
86
|
+
add_stored_credential_options(post, options)
|
82
87
|
add_transaction_data(post, options)
|
83
88
|
add_3ds(post, options)
|
89
|
+
add_metadata(post, options)
|
84
90
|
end
|
85
91
|
|
86
92
|
def add_invoice(post, money, options)
|
@@ -96,6 +102,11 @@ module ActiveMerchant #:nodoc:
|
|
96
102
|
post[:metadata][:udf5] = application_id || 'ActiveMerchant'
|
97
103
|
end
|
98
104
|
|
105
|
+
def add_metadata(post, options)
|
106
|
+
post[:metadata] = {} unless post[:metadata]
|
107
|
+
post[:metadata].merge!(options[:metadata]) if options[:metadata]
|
108
|
+
end
|
109
|
+
|
99
110
|
def add_payment_method(post, payment_method, options)
|
100
111
|
post[:source] = {}
|
101
112
|
if payment_method.is_a?(NetworkTokenizationCreditCard) && payment_method.source == :network_token
|
@@ -138,12 +149,33 @@ module ActiveMerchant #:nodoc:
|
|
138
149
|
post[:previous_payment_id] = options[:previous_charge_id] if options[:previous_charge_id]
|
139
150
|
end
|
140
151
|
|
152
|
+
def add_stored_credential_options(post, options = {})
|
153
|
+
return unless options[:stored_credential]
|
154
|
+
|
155
|
+
case options[:stored_credential][:initial_transaction]
|
156
|
+
when true
|
157
|
+
post[:merchant_initiated] = false
|
158
|
+
when false
|
159
|
+
post[:'source.stored'] = true
|
160
|
+
post[:previous_payment_id] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
|
161
|
+
post[:merchant_initiated] = true
|
162
|
+
end
|
163
|
+
|
164
|
+
case options[:stored_credential][:reason_type]
|
165
|
+
when 'recurring' || 'installment'
|
166
|
+
post[:payment_type] = 'Recurring'
|
167
|
+
when 'unscheduled'
|
168
|
+
return
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
141
172
|
def add_3ds(post, options)
|
142
173
|
if options[:three_d_secure] || options[:execute_threed]
|
143
174
|
post[:'3ds'] = {}
|
144
175
|
post[:'3ds'][:enabled] = true
|
145
176
|
post[:success_url] = options[:callback_url] if options[:callback_url]
|
146
177
|
post[:failure_url] = options[:callback_url] if options[:callback_url]
|
178
|
+
post[:'3ds'][:attempt_n3d] = options[:attempt_n3d] if options[:attempt_n3d]
|
147
179
|
end
|
148
180
|
|
149
181
|
if options[:three_d_secure]
|
@@ -151,7 +183,6 @@ module ActiveMerchant #:nodoc:
|
|
151
183
|
post[:'3ds'][:cryptogram] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
152
184
|
post[:'3ds'][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
|
153
185
|
post[:'3ds'][:xid] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid]
|
154
|
-
post[:'3ds'][:attempt_n3d] = options[:attempt_n3d] if options[:attempt_n3d]
|
155
186
|
end
|
156
187
|
end
|
157
188
|
|
@@ -25,7 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LYD OMR TND)
|
26
26
|
|
27
27
|
self.money_format = :cents
|
28
|
-
self.supported_cardtypes = %i[visa master maestro]
|
28
|
+
self.supported_cardtypes = %i[visa master maestro american_express]
|
29
29
|
|
30
30
|
RESPONSE_MESSAGES = {
|
31
31
|
'00' => 'Approved or completed successfully',
|
@@ -117,7 +117,8 @@ module ActiveMerchant #:nodoc:
|
|
117
117
|
'96' => 'System malfunction',
|
118
118
|
'R0' => 'Stop Payment Order',
|
119
119
|
'R1' => 'Revocation of Authorisation Order',
|
120
|
-
'R3' => 'Revocation of all Authorisations Order'
|
120
|
+
'R3' => 'Revocation of all Authorisations Order',
|
121
|
+
'1A' => 'Strong Customer Authentication required'
|
121
122
|
}
|
122
123
|
|
123
124
|
def initialize(options = {})
|
@@ -324,14 +325,16 @@ module ActiveMerchant #:nodoc:
|
|
324
325
|
end
|
325
326
|
|
326
327
|
def add_3d_secure(post, options)
|
327
|
-
if options[:eci] && options[:xid]
|
328
|
+
if (options[:eci] && options[:xid]) || (options[:three_d_secure] && options[:three_d_secure][:version]&.start_with?('1'))
|
328
329
|
add_3d_secure_1_data(post, options)
|
329
330
|
elsif options[:execute_threed] && options[:three_ds_2]
|
330
331
|
three_ds_2_options = options[:three_ds_2]
|
331
332
|
browser_info = three_ds_2_options[:browser_info]
|
332
333
|
post[:'3ds_initiate'] = options[:three_ds_initiate] || '01'
|
334
|
+
post[:f23] = options[:f23] if options[:f23]
|
333
335
|
post[:'3ds_purchasedate'] = Time.now.utc.strftime('%Y%m%d%I%M%S')
|
334
336
|
options.dig(:stored_credential, :initiator) == 'merchant' ? post[:'3ds_channel'] = '03' : post[:'3ds_channel'] = '02'
|
337
|
+
post[:'3ds_reqchallengeind'] = options[:three_ds_reqchallengeind] if options[:three_ds_reqchallengeind]
|
335
338
|
post[:'3ds_redirect_url'] = three_ds_2_options[:notification_url]
|
336
339
|
post[:'3ds_challengewindowsize'] = options[:three_ds_challenge_window_size] || '03'
|
337
340
|
post[:d5] = browser_info[:user_agent]
|
@@ -343,22 +346,35 @@ module ActiveMerchant #:nodoc:
|
|
343
346
|
post[:d6] = browser_info[:language]
|
344
347
|
post[:'3ds_browserjavaenabled'] = browser_info[:java]
|
345
348
|
post[:'3ds_browseracceptheader'] = browser_info[:accept_header]
|
346
|
-
|
347
|
-
post[:'3ds_shipaddrstate'] = shipping_address[:state]
|
348
|
-
post[:'3ds_shipaddrpostcode'] = shipping_address[:zip]
|
349
|
-
post[:'3ds_shipaddrline2'] = shipping_address[:address2]
|
350
|
-
post[:'3ds_shipaddrline1'] = shipping_address[:address1]
|
351
|
-
post[:'3ds_shipaddrcountry'] = shipping_address[:country]
|
352
|
-
post[:'3ds_shipaddrcity'] = shipping_address[:city]
|
353
|
-
end
|
349
|
+
add_complete_shipping_address(post, options[:shipping_address]) if options[:shipping_address]
|
354
350
|
elsif options[:three_d_secure]
|
355
351
|
add_normalized_3d_secure_2_data(post, options)
|
356
352
|
end
|
357
353
|
end
|
358
354
|
|
359
355
|
def add_3d_secure_1_data(post, options)
|
360
|
-
|
361
|
-
|
356
|
+
if three_d_secure_options = options[:three_d_secure]
|
357
|
+
post[:i8] = build_i8(
|
358
|
+
three_d_secure_options[:eci],
|
359
|
+
three_d_secure_options[:cavv],
|
360
|
+
three_d_secure_options[:xid]
|
361
|
+
)
|
362
|
+
post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('1') ? '1.0' : three_d_secure_options[:version]
|
363
|
+
else
|
364
|
+
post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid])
|
365
|
+
post[:'3ds_version'] = options[:three_ds_version].nil? || options[:three_ds_version]&.start_with?('1') ? '1.0' : options[:three_ds_version]
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def add_complete_shipping_address(post, shipping_address)
|
370
|
+
return if shipping_address.values.any?(&:blank?)
|
371
|
+
|
372
|
+
post[:'3ds_shipaddrstate'] = shipping_address[:state]
|
373
|
+
post[:'3ds_shipaddrpostcode'] = shipping_address[:zip]
|
374
|
+
post[:'3ds_shipaddrline2'] = shipping_address[:address2]
|
375
|
+
post[:'3ds_shipaddrline1'] = shipping_address[:address1]
|
376
|
+
post[:'3ds_shipaddrcountry'] = shipping_address[:country]
|
377
|
+
post[:'3ds_shipaddrcity'] = shipping_address[:city]
|
362
378
|
end
|
363
379
|
|
364
380
|
def add_normalized_3d_secure_2_data(post, options)
|
@@ -368,7 +384,7 @@ module ActiveMerchant #:nodoc:
|
|
368
384
|
three_d_secure_options[:eci],
|
369
385
|
three_d_secure_options[:cavv]
|
370
386
|
)
|
371
|
-
post[:'3ds_version'] = three_d_secure_options[:version]
|
387
|
+
post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('2') ? '2.0' : three_d_secure_options[:version]
|
372
388
|
post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id]
|
373
389
|
end
|
374
390
|
|
@@ -25,8 +25,8 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
self.live_url = 'https://ics2wsa.ic3.com/commerce/1.x/transactionProcessor'
|
26
26
|
|
27
27
|
# Schema files can be found here: https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/
|
28
|
-
TEST_XSD_VERSION = '1.
|
29
|
-
PRODUCTION_XSD_VERSION = '1.
|
28
|
+
TEST_XSD_VERSION = '1.181'
|
29
|
+
PRODUCTION_XSD_VERSION = '1.181'
|
30
30
|
ECI_BRAND_MAPPING = {
|
31
31
|
visa: 'vbv',
|
32
32
|
master: 'spa',
|
@@ -256,8 +256,9 @@ module ActiveMerchant #:nodoc:
|
|
256
256
|
|
257
257
|
private
|
258
258
|
|
259
|
-
# Create all address hash key value pairs
|
260
|
-
#
|
259
|
+
# Create all required address hash key value pairs
|
260
|
+
# If a value of nil is received, that value will be passed on to the gateway and will not be replaced with a default value
|
261
|
+
# Billing address fields received without an override value or with an empty string value will be replaced with the default_address values
|
261
262
|
def setup_address_hash(options)
|
262
263
|
default_address = {
|
263
264
|
address1: 'Unspecified',
|
@@ -268,10 +269,20 @@ module ActiveMerchant #:nodoc:
|
|
268
269
|
}
|
269
270
|
|
270
271
|
submitted_address = options[:billing_address] || options[:address] || default_address
|
271
|
-
options[:billing_address] = default_address.merge(submitted_address.symbolize_keys) { |_k, default, submitted|
|
272
|
+
options[:billing_address] = default_address.merge(submitted_address.symbolize_keys) { |_k, default, submitted| check_billing_field_value(default, submitted) }
|
272
273
|
options[:shipping_address] = options[:shipping_address] || {}
|
273
274
|
end
|
274
275
|
|
276
|
+
def check_billing_field_value(default, submitted)
|
277
|
+
if submitted.nil?
|
278
|
+
nil
|
279
|
+
elsif submitted.blank?
|
280
|
+
default
|
281
|
+
else
|
282
|
+
submitted
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
275
286
|
def build_auth_request(money, creditcard_or_reference, options)
|
276
287
|
xml = Builder::XmlMarkup.new indent: 2
|
277
288
|
add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
|
@@ -287,6 +298,8 @@ module ActiveMerchant #:nodoc:
|
|
287
298
|
add_partner_solution_id(xml)
|
288
299
|
add_stored_credential_options(xml, options)
|
289
300
|
add_merchant_description(xml, options)
|
301
|
+
add_sales_slip_number(xml, options)
|
302
|
+
add_airline_data(xml, options)
|
290
303
|
|
291
304
|
xml.target!
|
292
305
|
end
|
@@ -325,6 +338,8 @@ module ActiveMerchant #:nodoc:
|
|
325
338
|
add_threeds_2_ucaf_data(xml, payment_method_or_reference, options)
|
326
339
|
add_decision_manager_fields(xml, options)
|
327
340
|
add_mdd_fields(xml, options)
|
341
|
+
add_sales_slip_number(xml, options)
|
342
|
+
add_airline_data(xml, options)
|
328
343
|
if !payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) == 'check'
|
329
344
|
add_check_service(xml)
|
330
345
|
add_issuer_additional_data(xml, options)
|
@@ -512,6 +527,18 @@ module ActiveMerchant #:nodoc:
|
|
512
527
|
end
|
513
528
|
end
|
514
529
|
|
530
|
+
def add_sales_slip_number(xml, options)
|
531
|
+
xml.tag! 'salesSlipNumber', options[:sales_slip_number] if options[:sales_slip_number]
|
532
|
+
end
|
533
|
+
|
534
|
+
def add_airline_data(xml, options)
|
535
|
+
return unless options[:airline_agent_code]
|
536
|
+
|
537
|
+
xml.tag! 'airlineData' do
|
538
|
+
xml.tag! 'agentCode', options[:airline_agent_code]
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
515
542
|
def add_purchase_data(xml, money = 0, include_grand_total = false, options = {})
|
516
543
|
xml.tag! 'purchaseTotals' do
|
517
544
|
xml.tag! 'currency', options[:currency] || currency(money)
|
@@ -520,9 +547,12 @@ module ActiveMerchant #:nodoc:
|
|
520
547
|
end
|
521
548
|
|
522
549
|
def add_address(xml, payment_method, address, options, shipTo = false)
|
550
|
+
first_name, last_name = address_names(address[:name], payment_method)
|
551
|
+
bill_to_merchant_tax_id = options[:merchant_tax_id] unless shipTo
|
552
|
+
|
523
553
|
xml.tag! shipTo ? 'shipTo' : 'billTo' do
|
524
|
-
xml.tag! 'firstName',
|
525
|
-
xml.tag! 'lastName',
|
554
|
+
xml.tag! 'firstName', first_name if first_name
|
555
|
+
xml.tag! 'lastName', last_name if last_name
|
526
556
|
xml.tag! 'street1', address[:address1]
|
527
557
|
xml.tag! 'street2', address[:address2] unless address[:address2].blank?
|
528
558
|
xml.tag! 'city', address[:city]
|
@@ -536,9 +566,20 @@ module ActiveMerchant #:nodoc:
|
|
536
566
|
xml.tag! 'ipAddress', options[:ip] unless options[:ip].blank? || shipTo
|
537
567
|
xml.tag! 'driversLicenseNumber', options[:drivers_license_number] unless options[:drivers_license_number].blank?
|
538
568
|
xml.tag! 'driversLicenseState', options[:drivers_license_state] unless options[:drivers_license_state].blank?
|
569
|
+
xml.tag! 'merchantTaxID', bill_to_merchant_tax_id unless bill_to_merchant_tax_id.blank?
|
539
570
|
end
|
540
571
|
end
|
541
572
|
|
573
|
+
def address_names(address_name, payment_method)
|
574
|
+
names = split_names(address_name)
|
575
|
+
return names if names.any?(&:present?)
|
576
|
+
|
577
|
+
[
|
578
|
+
payment_method&.first_name,
|
579
|
+
payment_method&.last_name
|
580
|
+
]
|
581
|
+
end
|
582
|
+
|
542
583
|
def add_creditcard(xml, creditcard)
|
543
584
|
xml.tag! 'card' do
|
544
585
|
xml.tag! 'accountNumber', creditcard.number
|
@@ -581,7 +622,7 @@ module ActiveMerchant #:nodoc:
|
|
581
622
|
xml.tag! 'merchantDefinedData' do
|
582
623
|
(1..100).each do |each|
|
583
624
|
key = "mdd_field_#{each}".to_sym
|
584
|
-
xml.tag!(
|
625
|
+
xml.tag!('mddField', options[key], 'id' => each) if options[key]
|
585
626
|
end
|
586
627
|
end
|
587
628
|
end
|
@@ -830,6 +871,8 @@ module ActiveMerchant #:nodoc:
|
|
830
871
|
|
831
872
|
xml.tag! 'installment' do
|
832
873
|
xml.tag! 'totalCount', options[:installment_total_count]
|
874
|
+
xml.tag!('planType', options[:installment_plan_type]) if options[:installment_plan_type]
|
875
|
+
xml.tag!('firstInstallmentDate', options[:first_installment_date]) if options[:first_installment_date]
|
833
876
|
end
|
834
877
|
end
|
835
878
|
|