activemerchant 1.116.0 → 1.121.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 +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
|
|