activemerchant 1.78.0 → 1.79.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 +49 -0
- data/lib/active_merchant.rb +2 -5
- data/lib/active_merchant/billing/credit_card_methods.rb +3 -1
- data/lib/active_merchant/billing/gateways/adyen.rb +17 -2
- data/lib/active_merchant/billing/gateways/authorize_net.rb +16 -11
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +1 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +0 -1
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +1 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +17 -4
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +7 -0
- data/lib/active_merchant/billing/gateways/clearhaus.rb +0 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +11 -2
- data/lib/active_merchant/billing/gateways/ebanx.rb +3 -3
- data/lib/active_merchant/billing/gateways/elavon.rb +1 -1
- data/lib/active_merchant/billing/gateways/first_pay.rb +10 -9
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +11 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +12 -0
- data/lib/active_merchant/billing/gateways/migs.rb +0 -2
- data/lib/active_merchant/billing/gateways/mundipagg.rb +291 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +4 -4
- data/lib/active_merchant/billing/gateways/paymentez.rb +6 -13
- data/lib/active_merchant/billing/gateways/paypal.rb +0 -12
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +14 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +10 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +11 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +11 -0
- data/lib/active_merchant/billing/gateways/realex.rb +14 -1
- data/lib/active_merchant/billing/gateways/redsys.rb +1 -1
- data/lib/active_merchant/billing/gateways/safe_charge.rb +8 -4
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +41 -6
- data/lib/active_merchant/billing/gateways/stripe.rb +14 -4
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +45 -14
- data/lib/active_merchant/connection.rb +38 -9
- data/lib/active_merchant/net_http_ssl_connection.rb +9 -0
- data/lib/active_merchant/network_connection_retries.rb +2 -0
- data/lib/active_merchant/posts_data.rb +10 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/support/ssl_version.rb +87 -0
- metadata +7 -4
@@ -88,6 +88,16 @@ module ActiveMerchant #:nodoc:
|
|
88
88
|
authorize(0, credit_card, options)
|
89
89
|
end
|
90
90
|
|
91
|
+
def supports_scrubbing?
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
def scrub(transcript)
|
96
|
+
transcript.
|
97
|
+
gsub(%r((pstn_cn=)\d*), '\1[FILTERED]').
|
98
|
+
gsub(%r((pstn_cc=)\d*), '\1[FILTERED]')
|
99
|
+
end
|
100
|
+
|
91
101
|
private
|
92
102
|
|
93
103
|
def new_request
|
@@ -86,6 +86,17 @@ module ActiveMerchant #:nodoc:
|
|
86
86
|
commit(nil, nil, options)
|
87
87
|
end
|
88
88
|
|
89
|
+
def supports_scrubbing?
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
93
|
+
def scrub(transcript)
|
94
|
+
transcript.
|
95
|
+
gsub(%r((<Passphrase>)[^<]*(</Passphrase>))i, '\1[FILTERED]\2').
|
96
|
+
gsub(%r((<CardNumber>)[^<]*(</CardNumber>))i, '\1[FILTERED]\2').
|
97
|
+
gsub(%r((<CardIDNumber>)[^<]*(</CardIDNumber>))i, '\1[FILTERED]\2')
|
98
|
+
end
|
99
|
+
|
89
100
|
private
|
90
101
|
|
91
102
|
def commit(money, creditcard, options = {})
|
@@ -113,6 +113,17 @@ module ActiveMerchant #:nodoc:
|
|
113
113
|
commit(:query, nil, {})
|
114
114
|
end
|
115
115
|
|
116
|
+
def supports_scrubbing?
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
def scrub(transcript)
|
121
|
+
transcript.
|
122
|
+
gsub(%r((<ConnectionTicket>)[^<]*(</ConnectionTicket>))i, '\1[FILTERED]\2').
|
123
|
+
gsub(%r((<CreditCardNumber>)[^<]*(</CreditCardNumber>))i, '\1[FILTERED]\2').
|
124
|
+
gsub(%r((<CardSecurityCode>)[^<]*(</CardSecurityCode>))i, '\1[FILTERED]\2')
|
125
|
+
end
|
126
|
+
|
116
127
|
private
|
117
128
|
|
118
129
|
def hosted?
|
@@ -35,7 +35,7 @@ module ActiveMerchant
|
|
35
35
|
self.money_format = :cents
|
36
36
|
self.default_currency = 'EUR'
|
37
37
|
self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :switch, :solo, :laser ]
|
38
|
-
self.supported_countries = %w(IE GB FR BE NL LU IT)
|
38
|
+
self.supported_countries = %w(IE GB FR BE NL LU IT US CA ES)
|
39
39
|
self.homepage_url = 'http://www.realexpayments.com/'
|
40
40
|
self.display_name = 'Realex'
|
41
41
|
|
@@ -140,6 +140,7 @@ module ActiveMerchant
|
|
140
140
|
add_card(xml, credit_card)
|
141
141
|
xml.tag! 'autosettle', 'flag' => auto_settle_flag(action)
|
142
142
|
add_signed_digest(xml, timestamp, @options[:login], sanitize_order_id(options[:order_id]), amount(money), (options[:currency] || currency(money)), credit_card.number)
|
143
|
+
add_network_tokenization_card(xml, credit_card) if credit_card.is_a?(NetworkTokenizationCreditCard)
|
143
144
|
add_comments(xml, options)
|
144
145
|
add_address_and_customer_info(xml, options)
|
145
146
|
end
|
@@ -251,6 +252,18 @@ module ActiveMerchant
|
|
251
252
|
end
|
252
253
|
end
|
253
254
|
|
255
|
+
def add_network_tokenization_card(xml, payment)
|
256
|
+
xml.tag! 'mpi' do
|
257
|
+
xml.tag! 'cavv', payment.payment_cryptogram
|
258
|
+
xml.tag! 'eci', payment.eci
|
259
|
+
end
|
260
|
+
xml.tag! 'supplementarydata' do
|
261
|
+
xml.tag! 'item', 'type' => 'mobile' do
|
262
|
+
xml.tag! 'field01', payment.source.to_s.gsub('_','-')
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
254
267
|
def format_address_code(address)
|
255
268
|
code = [address[:zip].to_s, address[:address1].to_s + address[:address2].to_s]
|
256
269
|
code.collect{|e| e.gsub(/\D/, "")}.reject{|e| e.empty?}.join("|")
|
@@ -25,7 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
post[:sg_APIType] = 1 if options[:three_d_secure]
|
26
26
|
trans_type = options[:three_d_secure] ? "Sale3D" : "Sale"
|
27
27
|
add_transaction_data(trans_type, post, money, options)
|
28
|
-
add_payment(post, payment)
|
28
|
+
add_payment(post, payment, options)
|
29
29
|
add_customer_details(post, payment, options)
|
30
30
|
|
31
31
|
commit(post)
|
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
|
|
34
34
|
def authorize(money, payment, options={})
|
35
35
|
post = {}
|
36
36
|
add_transaction_data("Auth", post, money, options)
|
37
|
-
add_payment(post, payment)
|
37
|
+
add_payment(post, payment, options)
|
38
38
|
add_customer_details(post, payment, options)
|
39
39
|
|
40
40
|
commit(post)
|
@@ -69,7 +69,7 @@ module ActiveMerchant #:nodoc:
|
|
69
69
|
|
70
70
|
def credit(money, payment, options={})
|
71
71
|
post = {}
|
72
|
-
add_payment(post, payment)
|
72
|
+
add_payment(post, payment, options)
|
73
73
|
add_transaction_data("Credit", post, money, options)
|
74
74
|
post[:sg_CreditType] = 1
|
75
75
|
|
@@ -125,14 +125,18 @@ module ActiveMerchant #:nodoc:
|
|
125
125
|
post[:sg_WebsiteID] = options[:website_id] if options[:website_id]
|
126
126
|
post[:sg_IPAddress] = options[:ip] if options[:ip]
|
127
127
|
post[:sg_VendorID] = options[:vendor_id] if options[:vendor_id]
|
128
|
+
post[:sg_Descriptor] = options[:merchant_descriptor] if options[:merchant_descriptor]
|
129
|
+
post[:sg_MerchantPhoneNumber] = options[:merchant_phone_number] if options[:merchant_phone_number]
|
130
|
+
post[:sg_MerchantName] = options[:merchant_name] if options[:merchant_name]
|
128
131
|
end
|
129
132
|
|
130
|
-
def add_payment(post, payment)
|
133
|
+
def add_payment(post, payment, options={})
|
131
134
|
post[:sg_NameOnCard] = payment.name
|
132
135
|
post[:sg_CardNumber] = payment.number
|
133
136
|
post[:sg_ExpMonth] = format(payment.month, :two_digits)
|
134
137
|
post[:sg_ExpYear] = format(payment.year, :two_digits)
|
135
138
|
post[:sg_CVV2] = payment.verification_value
|
139
|
+
post[:sg_StoredCredentialMode] = (options[:stored_credential_mode] == true ? 1 : 0)
|
136
140
|
end
|
137
141
|
|
138
142
|
def add_customer_details(post, payment, options)
|
@@ -229,7 +229,7 @@ module ActiveMerchant #:nodoc:
|
|
229
229
|
end
|
230
230
|
|
231
231
|
def commit(action, money, parameters)
|
232
|
-
parameters[:amount] =
|
232
|
+
parameters[:amount] = localized_amount(money, parameters[:currency] || default_currency) if money
|
233
233
|
response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
|
234
234
|
Response.new(response["response"] == "1", message_from(response), response,
|
235
235
|
:authorization => (response["transactionid"] || response["customer_vault_id"]),
|
@@ -44,7 +44,7 @@ module ActiveMerchant #:nodoc:
|
|
44
44
|
purchase_with_token(money, payment_method, options)
|
45
45
|
else
|
46
46
|
MultiResponse.run do |r|
|
47
|
-
r.process { save_card(
|
47
|
+
r.process { save_card(options[:store], payment_method, options) }
|
48
48
|
r.process { purchase_with_token(money, r.authorization, options) }
|
49
49
|
end
|
50
50
|
end
|
@@ -62,7 +62,7 @@ module ActiveMerchant #:nodoc:
|
|
62
62
|
authorize_with_token(money, payment_method, options)
|
63
63
|
else
|
64
64
|
MultiResponse.run do |r|
|
65
|
-
r.process { save_card(
|
65
|
+
r.process { save_card(options[:store], payment_method, options) }
|
66
66
|
r.process { authorize_with_token(money, r.authorization, options) }
|
67
67
|
end
|
68
68
|
end
|
@@ -88,6 +88,24 @@ module ActiveMerchant #:nodoc:
|
|
88
88
|
commit("transactions/#{authorization}/void.xml", '')
|
89
89
|
end
|
90
90
|
|
91
|
+
|
92
|
+
# Public: Determine whether a credit card is chargeable card and available for purchases.
|
93
|
+
#
|
94
|
+
# payment_method - The CreditCard or the Spreedly payment method token.
|
95
|
+
# options - A hash of options:
|
96
|
+
# :store - Retain the payment method if the verify
|
97
|
+
# succeeds. Defaults to false. (optional)
|
98
|
+
def verify(payment_method, options = {})
|
99
|
+
if payment_method.is_a?(String)
|
100
|
+
verify_with_token(payment_method, options)
|
101
|
+
else
|
102
|
+
MultiResponse.run do |r|
|
103
|
+
r.process { save_card(options[:store], payment_method, options) }
|
104
|
+
r.process { verify_with_token(r.authorization, options) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
91
109
|
# Public: Store a credit card in the Spreedly vault and retain it.
|
92
110
|
#
|
93
111
|
# credit_card - The CreditCard to store
|
@@ -106,6 +124,13 @@ module ActiveMerchant #:nodoc:
|
|
106
124
|
commit("payment_methods/#{authorization}/redact.xml", '', :put)
|
107
125
|
end
|
108
126
|
|
127
|
+
# Public: Get the transaction with the given token.
|
128
|
+
def find(transaction_token)
|
129
|
+
commit("transactions/#{transaction_token}.xml", nil, :get)
|
130
|
+
end
|
131
|
+
|
132
|
+
alias_method :status, :find
|
133
|
+
|
109
134
|
def supports_scrubbing?
|
110
135
|
true
|
111
136
|
end
|
@@ -140,10 +165,20 @@ module ActiveMerchant #:nodoc:
|
|
140
165
|
commit("gateways/#{@options[:gateway_token]}/authorize.xml", request)
|
141
166
|
end
|
142
167
|
|
168
|
+
def verify_with_token(payment_method_token, options)
|
169
|
+
request = build_xml_request('transaction') do |doc|
|
170
|
+
add_invoice(doc, nil, options)
|
171
|
+
doc.payment_method_token(payment_method_token)
|
172
|
+
doc.retain_on_success(true) if options[:store]
|
173
|
+
add_extra_options(:gateway_specific_fields, doc, options)
|
174
|
+
end
|
175
|
+
|
176
|
+
commit("gateways/#{@options[:gateway_token]}/verify.xml", request)
|
177
|
+
end
|
178
|
+
|
143
179
|
def auth_purchase_request(money, payment_method_token, options)
|
144
180
|
build_xml_request('transaction') do |doc|
|
145
181
|
add_invoice(doc, money, options)
|
146
|
-
doc.ip(options[:ip])
|
147
182
|
add_extra_options(:gateway_specific_fields, doc, options)
|
148
183
|
doc.payment_method_token(payment_method_token)
|
149
184
|
doc.retain_on_success(true) if options[:store]
|
@@ -151,11 +186,11 @@ module ActiveMerchant #:nodoc:
|
|
151
186
|
end
|
152
187
|
|
153
188
|
def add_invoice(doc, money, options)
|
154
|
-
doc.amount amount(money)
|
189
|
+
doc.amount amount(money) unless money.nil?
|
155
190
|
doc.currency_code(options[:currency] || currency(money) || default_currency)
|
156
191
|
doc.order_id(options[:order_id])
|
157
|
-
doc.ip(options[:ip])
|
158
|
-
doc.description(options[:description])
|
192
|
+
doc.ip(options[:ip]) if options[:ip]
|
193
|
+
doc.description(options[:description]) if options[:description]
|
159
194
|
end
|
160
195
|
|
161
196
|
def add_credit_card(doc, credit_card, options)
|
@@ -25,7 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
self.default_currency = 'USD'
|
26
26
|
self.money_format = :cents
|
27
27
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro]
|
28
|
-
self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF)
|
28
|
+
self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF UGX)
|
29
29
|
|
30
30
|
self.homepage_url = 'https://stripe.com/'
|
31
31
|
self.display_name = 'Stripe'
|
@@ -549,14 +549,14 @@ module ActiveMerchant #:nodoc:
|
|
549
549
|
add_expand_parameters(parameters, options) if parameters
|
550
550
|
response = api_request(method, url, parameters, options)
|
551
551
|
|
552
|
-
success =
|
552
|
+
success = success_from(response)
|
553
553
|
|
554
554
|
card = card_from_response(response)
|
555
555
|
avs_code = AVS_CODE_TRANSLATOR["line1: #{card["address_line1_check"]}, zip: #{card["address_zip_check"]}"]
|
556
556
|
cvc_code = CVC_CODE_TRANSLATOR[card["cvc_check"]]
|
557
557
|
|
558
558
|
Response.new(success,
|
559
|
-
success
|
559
|
+
message_from(success, response),
|
560
560
|
response,
|
561
561
|
:test => response_is_test?(response),
|
562
562
|
:authorization => authorization_from(success, url, method, response),
|
@@ -568,7 +568,7 @@ module ActiveMerchant #:nodoc:
|
|
568
568
|
end
|
569
569
|
|
570
570
|
def authorization_from(success, url, method, response)
|
571
|
-
return response
|
571
|
+
return response.fetch("error", {})["charge"] unless success
|
572
572
|
|
573
573
|
if url == "customers"
|
574
574
|
[response["id"], response["sources"]["data"].first["id"]].join("|")
|
@@ -579,6 +579,14 @@ module ActiveMerchant #:nodoc:
|
|
579
579
|
end
|
580
580
|
end
|
581
581
|
|
582
|
+
def message_from(success, response)
|
583
|
+
success ? "Transaction approved" : response.fetch("error", {"message" => "No error details"})["message"]
|
584
|
+
end
|
585
|
+
|
586
|
+
def success_from(response)
|
587
|
+
!response.key?("error") && response["status"] != "failed"
|
588
|
+
end
|
589
|
+
|
582
590
|
def response_error(raw_response)
|
583
591
|
begin
|
584
592
|
parse(raw_response)
|
@@ -626,6 +634,8 @@ module ActiveMerchant #:nodoc:
|
|
626
634
|
end
|
627
635
|
|
628
636
|
def error_code_from(response)
|
637
|
+
return STANDARD_ERROR_CODE_MAPPING['processing_error'] unless response['error']
|
638
|
+
|
629
639
|
code = response['error']['code']
|
630
640
|
decline_code = response['error']['decline_code'] if code == 'card_declined'
|
631
641
|
|
@@ -140,7 +140,12 @@ module ActiveMerchant #:nodoc:
|
|
140
140
|
|
141
141
|
if options.has_key? :email
|
142
142
|
post[:custemail] = options[:email]
|
143
|
-
|
143
|
+
if options[:cust_receipt]
|
144
|
+
post[:custreceipt] = options[:cust_receipt]
|
145
|
+
post[:custreceiptname] = options[:cust_receipt_name] if options[:cust_receipt_name]
|
146
|
+
else
|
147
|
+
post[:custreceipt] = 'No'
|
148
|
+
end
|
144
149
|
end
|
145
150
|
|
146
151
|
if options.has_key? :customer
|
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
|
7
7
|
self.default_currency = 'GBP'
|
8
8
|
self.money_format = :cents
|
9
|
-
self.supported_countries = %w(HK GB AU AD BE CH CY CZ DE DK ES FI FR GI GR HU IE IT LI LU MC MT NL NO NZ PL PT SE SG SI SM TR UM VA)
|
9
|
+
self.supported_countries = %w(HK GB AU AD AR BE BR CA CH CN CO CR CY CZ DE DK ES FI FR GI GR HU IE IN IT JP LI LU MC MT MY MX NL NO NZ PA PE PL PT SE SG SI SM TR UM VA)
|
10
10
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :laser, :switch]
|
11
11
|
self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW)
|
12
12
|
self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND)
|
@@ -55,7 +55,7 @@ module ActiveMerchant #:nodoc:
|
|
55
55
|
|
56
56
|
def void(authorization, options = {})
|
57
57
|
MultiResponse.run do |r|
|
58
|
-
r.process{inquire_request(authorization, options, "AUTHORISED")}
|
58
|
+
r.process{inquire_request(authorization, options, "AUTHORISED")} unless options[:authorization_validated]
|
59
59
|
r.process{cancel_request(authorization, options)}
|
60
60
|
end
|
61
61
|
end
|
@@ -83,7 +83,7 @@ module ActiveMerchant #:nodoc:
|
|
83
83
|
def verify(credit_card, options={})
|
84
84
|
MultiResponse.run(:use_first_response) do |r|
|
85
85
|
r.process { authorize(100, credit_card, options) }
|
86
|
-
r.process(:ignore_result) { void(r.authorization, options) }
|
86
|
+
r.process(:ignore_result) { void(r.authorization, options.merge(:authorization_validated => true)) }
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -101,27 +101,27 @@ module ActiveMerchant #:nodoc:
|
|
101
101
|
private
|
102
102
|
|
103
103
|
def authorize_request(money, payment_method, options)
|
104
|
-
commit('authorize', build_authorization_request(money, payment_method, options), "AUTHORISED")
|
104
|
+
commit('authorize', build_authorization_request(money, payment_method, options), "AUTHORISED", options)
|
105
105
|
end
|
106
106
|
|
107
107
|
def capture_request(money, authorization, options)
|
108
|
-
commit('capture', build_capture_request(money, authorization, options), :ok)
|
108
|
+
commit('capture', build_capture_request(money, authorization, options), :ok, options)
|
109
109
|
end
|
110
110
|
|
111
111
|
def cancel_request(authorization, options)
|
112
|
-
commit('cancel', build_void_request(authorization, options), :ok)
|
112
|
+
commit('cancel', build_void_request(authorization, options), :ok, options)
|
113
113
|
end
|
114
114
|
|
115
115
|
def inquire_request(authorization, options, *success_criteria)
|
116
|
-
commit('inquiry', build_order_inquiry_request(authorization, options), *success_criteria)
|
116
|
+
commit('inquiry', build_order_inquiry_request(authorization, options), *success_criteria, options)
|
117
117
|
end
|
118
118
|
|
119
119
|
def refund_request(money, authorization, options)
|
120
|
-
commit('refund', build_refund_request(money, authorization, options), :ok)
|
120
|
+
commit('refund', build_refund_request(money, authorization, options), :ok, options)
|
121
121
|
end
|
122
122
|
|
123
123
|
def credit_request(money, payment_method, options)
|
124
|
-
commit('credit', build_authorization_request(money, payment_method, options), :ok)
|
124
|
+
commit('credit', build_authorization_request(money, payment_method, options), :ok, options)
|
125
125
|
end
|
126
126
|
|
127
127
|
def build_request
|
@@ -252,9 +252,13 @@ module ActiveMerchant #:nodoc:
|
|
252
252
|
end
|
253
253
|
|
254
254
|
def add_email(xml, options)
|
255
|
-
return unless options[:email]
|
255
|
+
return unless options[:execute_threed] || options[:email]
|
256
256
|
xml.tag! 'shopper' do
|
257
|
-
xml.tag! 'shopperEmailAddress', options[:email]
|
257
|
+
xml.tag! 'shopperEmailAddress', options[:email] if options[:email]
|
258
|
+
xml.tag! 'browser' do
|
259
|
+
xml.tag! 'acceptHeader', options[:accept_header]
|
260
|
+
xml.tag! 'userAgentHeader', options[:user_agent]
|
261
|
+
end
|
258
262
|
end
|
259
263
|
end
|
260
264
|
|
@@ -321,9 +325,24 @@ module ActiveMerchant #:nodoc:
|
|
321
325
|
raw
|
322
326
|
end
|
323
327
|
|
324
|
-
def
|
325
|
-
|
326
|
-
|
328
|
+
def headers(options)
|
329
|
+
headers = {
|
330
|
+
'Content-Type' => 'text/xml',
|
331
|
+
'Authorization' => encoded_credentials
|
332
|
+
}
|
333
|
+
if options[:cookie]
|
334
|
+
headers.merge!('Set-Cookie' => options[:cookie]) if options[:cookie]
|
335
|
+
end
|
336
|
+
headers
|
337
|
+
end
|
338
|
+
|
339
|
+
def commit(action, request, *success_criteria, options)
|
340
|
+
xml = ssl_post(url, request, headers(options))
|
341
|
+
raw = parse(action, xml)
|
342
|
+
if options[:execute_threed]
|
343
|
+
raw[:cookie] = @cookie
|
344
|
+
raw[:session_id] = options[:session_id]
|
345
|
+
end
|
327
346
|
success, message = success_and_message_from(raw, success_criteria)
|
328
347
|
|
329
348
|
Response.new(
|
@@ -346,6 +365,18 @@ module ActiveMerchant #:nodoc:
|
|
346
365
|
test? ? self.test_url : self.live_url
|
347
366
|
end
|
348
367
|
|
368
|
+
# Override the regular handle response so we can access the headers
|
369
|
+
# Set-Cookie value is needed for 3DS transactions
|
370
|
+
def handle_response(response)
|
371
|
+
case response.code.to_i
|
372
|
+
when 200...300
|
373
|
+
@cookie = response.response['Set-Cookie']
|
374
|
+
response.body
|
375
|
+
else
|
376
|
+
raise ResponseError.new(response)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
349
380
|
# success_criteria can be:
|
350
381
|
# - a string or an array of strings (if one of many responses)
|
351
382
|
# - An array of strings if one of many responses could be considered a
|
@@ -5,6 +5,7 @@ require 'benchmark'
|
|
5
5
|
|
6
6
|
module ActiveMerchant
|
7
7
|
class Connection
|
8
|
+
using NetHttpSslConnection
|
8
9
|
include NetworkConnectionRetries
|
9
10
|
|
10
11
|
MAX_RETRIES = 3
|
@@ -21,6 +22,11 @@ module ActiveMerchant
|
|
21
22
|
attr_accessor :read_timeout
|
22
23
|
attr_accessor :verify_peer
|
23
24
|
attr_accessor :ssl_version
|
25
|
+
if Net::HTTP.instance_methods.include?(:min_version=)
|
26
|
+
attr_accessor :min_version
|
27
|
+
attr_accessor :max_version
|
28
|
+
end
|
29
|
+
attr_reader :ssl_connection
|
24
30
|
attr_accessor :ca_file
|
25
31
|
attr_accessor :ca_path
|
26
32
|
attr_accessor :pem
|
@@ -44,7 +50,12 @@ module ActiveMerchant
|
|
44
50
|
@max_retries = MAX_RETRIES
|
45
51
|
@ignore_http_status = false
|
46
52
|
@ssl_version = nil
|
47
|
-
|
53
|
+
if Net::HTTP.instance_methods.include?(:min_version=)
|
54
|
+
@min_version = nil
|
55
|
+
@max_version = nil
|
56
|
+
end
|
57
|
+
@ssl_connection = {}
|
58
|
+
@proxy_address = :ENV
|
48
59
|
@proxy_port = nil
|
49
60
|
end
|
50
61
|
|
@@ -63,6 +74,10 @@ module ActiveMerchant
|
|
63
74
|
result = nil
|
64
75
|
|
65
76
|
realtime = Benchmark.realtime do
|
77
|
+
http.start unless http.started?
|
78
|
+
@ssl_connection = http.ssl_connection
|
79
|
+
info "connection_ssl_version=#{ssl_connection[:version]} connection_ssl_cipher=#{ssl_connection[:cipher]}", tag
|
80
|
+
|
66
81
|
result = case method
|
67
82
|
when :get
|
68
83
|
raise ArgumentError, "GET requests do not support a request body" if body
|
@@ -80,8 +95,14 @@ module ActiveMerchant
|
|
80
95
|
# It's kind of ambiguous whether the RFC allows bodies
|
81
96
|
# for DELETE requests. But Net::HTTP's delete method
|
82
97
|
# very unambiguously does not.
|
83
|
-
|
84
|
-
|
98
|
+
if body
|
99
|
+
debug body
|
100
|
+
req = Net::HTTP::Delete.new(endpoint.request_uri, headers)
|
101
|
+
req.body = body
|
102
|
+
http.request(req)
|
103
|
+
else
|
104
|
+
http.delete(endpoint.request_uri, headers)
|
105
|
+
end
|
85
106
|
else
|
86
107
|
raise ArgumentError, "Unsupported request method #{method.to_s.upcase}"
|
87
108
|
end
|
@@ -95,16 +116,20 @@ module ActiveMerchant
|
|
95
116
|
|
96
117
|
ensure
|
97
118
|
info "connection_request_total_time=%.4fs" % [Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start], tag
|
119
|
+
http.finish if http.started?
|
98
120
|
end
|
99
121
|
|
100
122
|
private
|
123
|
+
|
101
124
|
def http
|
102
|
-
http
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
125
|
+
@http ||= begin
|
126
|
+
http = Net::HTTP.new(endpoint.host, endpoint.port, proxy_address, proxy_port)
|
127
|
+
configure_debugging(http)
|
128
|
+
configure_timeouts(http)
|
129
|
+
configure_ssl(http)
|
130
|
+
configure_cert(http)
|
131
|
+
http
|
132
|
+
end
|
108
133
|
end
|
109
134
|
|
110
135
|
def configure_debugging(http)
|
@@ -121,6 +146,10 @@ module ActiveMerchant
|
|
121
146
|
|
122
147
|
http.use_ssl = true
|
123
148
|
http.ssl_version = ssl_version if ssl_version
|
149
|
+
if http.respond_to?(:min_version=)
|
150
|
+
http.min_version = min_version if min_version
|
151
|
+
http.max_version = max_version if max_version
|
152
|
+
end
|
124
153
|
|
125
154
|
if verify_peer
|
126
155
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|