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
@@ -94,6 +94,17 @@ module ActiveMerchant #:nodoc:
|
|
94
94
|
commit('V', nil, options.merge(post))
|
95
95
|
end
|
96
96
|
|
97
|
+
def supports_scrubbing?
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def scrub(transcript)
|
102
|
+
transcript.
|
103
|
+
gsub(%r((&?profile_key=)\w*(&?)), '\1[FILTERED]\2').
|
104
|
+
gsub(%r((&?card_number=)\d*(&?)), '\1[FILTERED]\2').
|
105
|
+
gsub(%r((&?cvv2=)\d*(&?)), '\1[FILTERED]\2')
|
106
|
+
end
|
107
|
+
|
97
108
|
private
|
98
109
|
|
99
110
|
def add_address(post, options)
|
@@ -68,6 +68,18 @@ module ActiveMerchant #:nodoc:
|
|
68
68
|
commit('addCard', post)
|
69
69
|
end
|
70
70
|
|
71
|
+
def supports_scrubbing?
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def scrub(transcript)
|
76
|
+
transcript.
|
77
|
+
gsub(%r((&?paymentCardNumber=)[^&]*)i, '\1[FILTERED]').
|
78
|
+
gsub(%r((CardNumber=)[^&]*)i, '\1[FILTERED]').
|
79
|
+
gsub(%r((&?paymentCardCSC=)[^&]*)i, '\1[FILTERED]').
|
80
|
+
gsub(%r((&?apiKey=)[^&]*)i, '\1[FILTERED]')
|
81
|
+
end
|
82
|
+
|
71
83
|
private
|
72
84
|
|
73
85
|
def add_transaction(post, identification)
|
@@ -0,0 +1,291 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MundipaggGateway < Gateway
|
4
|
+
self.live_url = 'https://api.mundipagg.com/core/v1'
|
5
|
+
|
6
|
+
self.supported_countries = ['US']
|
7
|
+
self.default_currency = 'USD'
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
9
|
+
|
10
|
+
self.homepage_url = 'https://www.mundipagg.com/'
|
11
|
+
self.display_name = 'Mundipagg'
|
12
|
+
|
13
|
+
STANDARD_ERROR_CODE_MAPPING = {
|
14
|
+
'400' => STANDARD_ERROR_CODE[:processing_error],
|
15
|
+
'401' => STANDARD_ERROR_CODE[:config_error],
|
16
|
+
'404' => STANDARD_ERROR_CODE[:processing_error],
|
17
|
+
'412' => STANDARD_ERROR_CODE[:processing_error],
|
18
|
+
'422' => STANDARD_ERROR_CODE[:processing_error],
|
19
|
+
'500' => STANDARD_ERROR_CODE[:processing_error]
|
20
|
+
}
|
21
|
+
|
22
|
+
STANDARD_ERROR_MESSAGE_MAPPING = {
|
23
|
+
'400' => 'Invalid request;',
|
24
|
+
'401' => 'Invalid API key;',
|
25
|
+
'404' => 'The requested resource does not exist;',
|
26
|
+
'412' => 'Valid parameters but request failed;',
|
27
|
+
'422' => 'Invalid parameters;',
|
28
|
+
'500' => 'An internal error occurred;'
|
29
|
+
}
|
30
|
+
|
31
|
+
def initialize(options={})
|
32
|
+
requires!(options, :api_key)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def purchase(money, payment, options={})
|
37
|
+
post = {}
|
38
|
+
add_invoice(post, money, options)
|
39
|
+
add_customer_data(post, options) unless payment.is_a?(String)
|
40
|
+
add_shipping_address(post, options)
|
41
|
+
add_payment(post, payment, options)
|
42
|
+
|
43
|
+
commit('sale', post)
|
44
|
+
end
|
45
|
+
|
46
|
+
def authorize(money, payment, options={})
|
47
|
+
post = {}
|
48
|
+
add_invoice(post, money, options)
|
49
|
+
add_customer_data(post, options) unless payment.is_a?(String)
|
50
|
+
add_shipping_address(post, options)
|
51
|
+
add_payment(post, payment, options)
|
52
|
+
add_capture_flag(post, payment)
|
53
|
+
commit('authonly', post)
|
54
|
+
end
|
55
|
+
|
56
|
+
def capture(money, authorization, options={})
|
57
|
+
post = {}
|
58
|
+
post[:code] = authorization
|
59
|
+
add_invoice(post, money, options)
|
60
|
+
commit('capture', post, authorization)
|
61
|
+
end
|
62
|
+
|
63
|
+
def refund(money, authorization, options={})
|
64
|
+
add_invoice(post={}, money, options)
|
65
|
+
commit('refund', post, authorization)
|
66
|
+
end
|
67
|
+
|
68
|
+
def void(authorization, options={})
|
69
|
+
commit('void', post=nil, authorization)
|
70
|
+
end
|
71
|
+
|
72
|
+
def store(payment, options={})
|
73
|
+
post = {}
|
74
|
+
options.update(name: payment.name)
|
75
|
+
options = add_customer(options) unless options[:customer_id]
|
76
|
+
add_payment(post, payment, options)
|
77
|
+
commit('store', post, options[:customer_id])
|
78
|
+
end
|
79
|
+
|
80
|
+
def verify(credit_card, options={})
|
81
|
+
MultiResponse.run(:use_first_response) do |r|
|
82
|
+
r.process { authorize(100, credit_card, options) }
|
83
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def supports_scrubbing?
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def scrub(transcript)
|
92
|
+
transcript
|
93
|
+
.gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]')
|
94
|
+
.gsub(%r(("cvv\\":\\")\d*), '\1[FILTERED]')
|
95
|
+
.gsub(%r((card\\":{\\"number\\":\\")\d*), '\1[FILTERED]')
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def add_customer(options)
|
101
|
+
post = {}
|
102
|
+
post[:name] = options[:name]
|
103
|
+
customer = commit('customer', post)
|
104
|
+
options.update(customer_id: customer.authorization)
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_customer_data(post, options)
|
108
|
+
post[:customer] = {}
|
109
|
+
post[:customer][:email] = options[:email]
|
110
|
+
end
|
111
|
+
|
112
|
+
def add_billing_address(post, type, options)
|
113
|
+
if address = (options[:billing_address] || options[:address])
|
114
|
+
billing = {}
|
115
|
+
address = options[:billing_address] || options[:address]
|
116
|
+
billing[:street] = address[:address1].match(/\D+/)[0].strip if address[:address1]
|
117
|
+
billing[:number] = address[:address1].match(/\d+/)[0] if address[:address1]
|
118
|
+
billing[:compliment] = address[:address2] if address[:address2]
|
119
|
+
billing[:city] = address[:city] if address[:city]
|
120
|
+
billing[:state] = address[:state] if address[:state]
|
121
|
+
billing[:country] = address[:country] if address[:country]
|
122
|
+
billing[:zip_code] = address[:zip] if address[:zip]
|
123
|
+
billing[:neighborhood] = address[:neighborhood]
|
124
|
+
post[:payment][type.to_sym][:card][:billing_address] = billing
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_shipping_address(post, options)
|
129
|
+
if address = options[:shipping_address]
|
130
|
+
post[:address] = {}
|
131
|
+
post[:address][:street] = address[:address1].match(/\D+/)[0].strip if address[:address1]
|
132
|
+
post[:address][:number] = address[:address1].match(/\d+/)[0] if address[:address1]
|
133
|
+
post[:address][:compliment] = address[:address2] if address[:address2]
|
134
|
+
post[:address][:city] = address[:city] if address[:city]
|
135
|
+
post[:address][:state] = address[:state] if address[:state]
|
136
|
+
post[:address][:country] = address[:country] if address[:country]
|
137
|
+
post[:address][:zip_code] = address[:zip] if address[:zip]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_invoice(post, money, options)
|
142
|
+
post[:amount] = money
|
143
|
+
post[:currency] = (options[:currency] || currency(money))
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_capture_flag(post, payment)
|
147
|
+
if voucher?(payment)
|
148
|
+
post[:payment][:voucher][:capture] = false
|
149
|
+
else
|
150
|
+
post[:payment][:credit_card][:capture] = false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def add_payment(post, payment, options)
|
155
|
+
post[:customer][:name] = payment.name if post[:customer]
|
156
|
+
post[:customer_id] = parse_auth(payment)[0] if payment.is_a?(String)
|
157
|
+
post[:payment] = {}
|
158
|
+
post[:payment][:gateway_affiliation_id] = @options[:gateway_id] if @options[:gateway_id]
|
159
|
+
post[:payment][:metadata] = { mundipagg_payment_method_code: '1' } if test?
|
160
|
+
if voucher?(payment)
|
161
|
+
add_voucher(post, payment, options)
|
162
|
+
else
|
163
|
+
add_credit_card(post, payment, options)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def add_credit_card(post, payment, options)
|
168
|
+
post[:payment][:payment_method] = 'credit_card'
|
169
|
+
post[:payment][:credit_card] = {}
|
170
|
+
if payment.is_a?(String)
|
171
|
+
post[:payment][:credit_card][:card_id] = parse_auth(payment)[1]
|
172
|
+
else
|
173
|
+
post[:payment][:credit_card][:card] = {}
|
174
|
+
post[:payment][:credit_card][:card][:number] = payment.number
|
175
|
+
post[:payment][:credit_card][:card][:holder_name] = payment.name
|
176
|
+
post[:payment][:credit_card][:card][:exp_month] = payment.month
|
177
|
+
post[:payment][:credit_card][:card][:exp_year] = payment.year
|
178
|
+
post[:payment][:credit_card][:card][:cvv] = payment.verification_value
|
179
|
+
add_billing_address(post,'credit_card', options)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def add_voucher(post, payment, options)
|
184
|
+
post[:currency] = 'BRL'
|
185
|
+
post[:payment][:payment_method] = 'voucher'
|
186
|
+
post[:payment][:voucher] = {}
|
187
|
+
post[:payment][:voucher][:card] = {}
|
188
|
+
post[:payment][:voucher][:card][:number] = payment.number
|
189
|
+
post[:payment][:voucher][:card][:holder_name] = payment.name
|
190
|
+
post[:payment][:voucher][:card][:holder_document] = options[:holder_document]
|
191
|
+
post[:payment][:voucher][:card][:exp_month] = payment.month
|
192
|
+
post[:payment][:voucher][:card][:exp_year] = payment.year
|
193
|
+
post[:payment][:voucher][:card][:cvv] = payment.verification_value
|
194
|
+
add_billing_address(post, 'voucher', options)
|
195
|
+
end
|
196
|
+
|
197
|
+
def voucher?(payment)
|
198
|
+
return false if payment.is_a?(String)
|
199
|
+
%w[sodexo vr].include? card_brand(payment)
|
200
|
+
end
|
201
|
+
|
202
|
+
def headers
|
203
|
+
{
|
204
|
+
'Authorization' => 'Basic ' + Base64.strict_encode64("#{@options[:api_key]}:"),
|
205
|
+
'Content-Type' => 'application/json',
|
206
|
+
'Accept' => 'application/json'
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
def parse(body)
|
211
|
+
JSON.parse(body)
|
212
|
+
end
|
213
|
+
|
214
|
+
def url_for(action, auth = nil)
|
215
|
+
url = live_url
|
216
|
+
case action
|
217
|
+
when 'store'
|
218
|
+
"#{url}/customers/#{auth}/cards/"
|
219
|
+
when 'customer'
|
220
|
+
"#{url}/customers/"
|
221
|
+
when 'refund', 'void'
|
222
|
+
"#{url}/charges/#{auth}/"
|
223
|
+
when 'capture'
|
224
|
+
"#{url}/charges/#{auth}/capture/"
|
225
|
+
else
|
226
|
+
"#{url}/charges/"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def commit(action, parameters, auth = nil)
|
231
|
+
url = url_for(action, auth)
|
232
|
+
parameters.merge!(parameters[:payment][:credit_card].delete(:card)).delete(:payment) if action == 'store'
|
233
|
+
response = if %w[refund void].include? action
|
234
|
+
parse(ssl_request(:delete, url, post_data(parameters), headers))
|
235
|
+
else
|
236
|
+
parse(ssl_post(url, post_data(parameters), headers))
|
237
|
+
end
|
238
|
+
|
239
|
+
Response.new(
|
240
|
+
success_from(response),
|
241
|
+
message_from(response),
|
242
|
+
response,
|
243
|
+
authorization: authorization_from(response, action),
|
244
|
+
avs_result: AVSResult.new(code: response['some_avs_response_key']),
|
245
|
+
cvv_result: CVVResult.new(response['some_cvv_response_key']),
|
246
|
+
test: test?,
|
247
|
+
error_code: error_code_from(response)
|
248
|
+
)
|
249
|
+
rescue ResponseError => e
|
250
|
+
message = get_error_message(e)
|
251
|
+
return Response.new(
|
252
|
+
false,
|
253
|
+
"#{STANDARD_ERROR_MESSAGE_MAPPING[e.response.code]} #{message}",
|
254
|
+
parse(e.response.body),
|
255
|
+
test: test?,
|
256
|
+
error_code: STANDARD_ERROR_CODE_MAPPING[e.response.code],
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
def success_from(response)
|
261
|
+
%w[pending paid processing canceled active].include? response['status']
|
262
|
+
end
|
263
|
+
|
264
|
+
def get_error_message(error)
|
265
|
+
JSON.parse(error.response.body)['message']
|
266
|
+
end
|
267
|
+
|
268
|
+
def message_from(response)
|
269
|
+
return response['message'] if response['message']
|
270
|
+
return response['last_transaction']['acquirer_message'] if response['last_transaction']
|
271
|
+
end
|
272
|
+
|
273
|
+
def authorization_from(response, action)
|
274
|
+
return "#{response['customer']['id']}|#{response['id']}" if action == 'store'
|
275
|
+
response['id']
|
276
|
+
end
|
277
|
+
|
278
|
+
def parse_auth(auth)
|
279
|
+
auth.split('|')
|
280
|
+
end
|
281
|
+
|
282
|
+
def post_data(parameters = {})
|
283
|
+
parameters.to_json
|
284
|
+
end
|
285
|
+
|
286
|
+
def error_code_from(response)
|
287
|
+
STANDARD_ERROR_CODE[:processing_error] unless success_from(response)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
|
11
11
|
class_attribute :test_periodic_url, :live_periodic_url
|
12
12
|
|
13
|
-
self.test_url = 'https://transact.nab.com.au/
|
13
|
+
self.test_url = 'https://demo.transact.nab.com.au/xmlapi/payment'
|
14
14
|
self.live_url = 'https://transact.nab.com.au/live/xmlapi/payment'
|
15
15
|
self.test_periodic_url = 'https://transact.nab.com.au/xmlapidemo/periodic'
|
16
16
|
self.live_periodic_url = 'https://transact.nab.com.au/xmlapi/periodic'
|
@@ -104,7 +104,7 @@ module ActiveMerchant #:nodoc:
|
|
104
104
|
|
105
105
|
def build_purchase_request(money, credit_card, options)
|
106
106
|
xml = Builder::XmlMarkup.new
|
107
|
-
xml.tag! 'amount',
|
107
|
+
xml.tag! 'amount', localized_amount(money, options[:currency] || currency(money))
|
108
108
|
xml.tag! 'currency', options[:currency] || currency(money)
|
109
109
|
xml.tag! 'purchaseOrderNo', options[:order_id].to_s.gsub(/[ ']/, '')
|
110
110
|
|
@@ -124,7 +124,7 @@ module ActiveMerchant #:nodoc:
|
|
124
124
|
|
125
125
|
transaction_id, order_id, preauth_id, original_amount = reference.split('*')
|
126
126
|
|
127
|
-
xml.tag! 'amount', (money ?
|
127
|
+
xml.tag! 'amount', (money ? localized_amount(money, options[:currency] || currency(money)) : original_amount)
|
128
128
|
xml.tag! 'currency', options[:currency] || currency(money)
|
129
129
|
xml.tag! 'txnID', transaction_id
|
130
130
|
xml.tag! 'purchaseOrderNo', order_id
|
@@ -205,7 +205,7 @@ module ActiveMerchant #:nodoc:
|
|
205
205
|
|
206
206
|
xml.tag! 'crn', identification
|
207
207
|
xml.tag! 'currency', options[:currency] || currency(money)
|
208
|
-
xml.tag! 'amount',
|
208
|
+
xml.tag! 'amount', localized_amount(money, options[:currency] || currency(money))
|
209
209
|
|
210
210
|
xml.target!
|
211
211
|
end
|
@@ -61,18 +61,10 @@ module ActiveMerchant #:nodoc:
|
|
61
61
|
post = {}
|
62
62
|
|
63
63
|
add_invoice(post, money, options)
|
64
|
+
add_payment(post, payment)
|
64
65
|
add_customer_data(post, options)
|
65
66
|
|
66
|
-
|
67
|
-
post[:card] = { token: payment }
|
68
|
-
commit_transaction('authorize', post)
|
69
|
-
else
|
70
|
-
MultiResponse.run do |r|
|
71
|
-
r.process { store(payment, options) }
|
72
|
-
post[:card] = { token: r.authorization }
|
73
|
-
r.process { commit_transaction('authorize', post) }
|
74
|
-
end
|
75
|
-
end
|
67
|
+
commit_transaction('authorize', post)
|
76
68
|
end
|
77
69
|
|
78
70
|
def capture(_money, authorization, _options = {})
|
@@ -150,6 +142,7 @@ module ActiveMerchant #:nodoc:
|
|
150
142
|
post[:order][:installments] = options[:installments] if options[:installments]
|
151
143
|
post[:order][:installments_type] = options[:installments_type] if options[:installments_type]
|
152
144
|
post[:order][:taxable_amount] = options[:taxable_amount] if options[:taxable_amount]
|
145
|
+
post[:order][:tax_percentage] = options[:tax_percentage] if options[:tax_percentage]
|
153
146
|
end
|
154
147
|
|
155
148
|
def add_payment(post, payment)
|
@@ -223,10 +216,10 @@ module ActiveMerchant #:nodoc:
|
|
223
216
|
end
|
224
217
|
|
225
218
|
def message_from(response)
|
226
|
-
if success_from(response)
|
227
|
-
response['transaction'] && response['transaction']['message']
|
228
|
-
else
|
219
|
+
if !success_from(response) && response['error']
|
229
220
|
response['error'] && response['error']['type']
|
221
|
+
else
|
222
|
+
response['transaction'] && response['transaction']['message']
|
230
223
|
end
|
231
224
|
end
|
232
225
|
|
@@ -38,18 +38,6 @@ module ActiveMerchant #:nodoc:
|
|
38
38
|
@express ||= PaypalExpressGateway.new(@options)
|
39
39
|
end
|
40
40
|
|
41
|
-
def supports_scrubbing?
|
42
|
-
true
|
43
|
-
end
|
44
|
-
|
45
|
-
def scrub(transcript)
|
46
|
-
transcript.
|
47
|
-
gsub(%r((<n1:Password>).+(</n1:Password>)), '\1[FILTERED]\2').
|
48
|
-
gsub(%r((<n1:Username>).+(</n1:Username>)), '\1[FILTERED]\2').
|
49
|
-
gsub(%r((<n2:CreditCardNumber>).+(</n2:CreditCardNumber)), '\1[FILTERED]\2').
|
50
|
-
gsub(%r((<n2:CVV2>)\d+(</n2:CVV2)), '\1[FILTERED]\2')
|
51
|
-
end
|
52
|
-
|
53
41
|
private
|
54
42
|
|
55
43
|
def define_transaction_type(transaction_arg)
|
@@ -269,7 +269,21 @@ module ActiveMerchant #:nodoc:
|
|
269
269
|
commit 'ManagePendingTransactionStatus', build_manage_pending_transaction_status(transaction_id, action)
|
270
270
|
end
|
271
271
|
|
272
|
+
def supports_scrubbing?
|
273
|
+
true
|
274
|
+
end
|
275
|
+
|
276
|
+
def scrub(transcript)
|
277
|
+
transcript.
|
278
|
+
gsub(%r((<n1:Password>).+(</n1:Password>)), '\1[FILTERED]\2').
|
279
|
+
gsub(%r((<n1:Username>).+(</n1:Username>)), '\1[FILTERED]\2').
|
280
|
+
gsub(%r((<n1:Signature>).+(</n1:Signature>)), '\1[FILTERED]\2').
|
281
|
+
gsub(%r((<n2:CreditCardNumber>).+(</n2:CreditCardNumber)), '\1[FILTERED]\2').
|
282
|
+
gsub(%r((<n2:CVV2>)\d+(</n2:CVV2)), '\1[FILTERED]\2')
|
283
|
+
end
|
284
|
+
|
272
285
|
private
|
286
|
+
|
273
287
|
def build_request_wrapper(action, options = {})
|
274
288
|
xml = Builder::XmlMarkup.new :indent => 2
|
275
289
|
xml.tag! action + 'Req', 'xmlns' => PAYPAL_NAMESPACE do
|