activemerchant 1.52.0 → 1.53.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 +56 -0
- data/README.md +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +4 -1
- data/lib/active_merchant/billing/gateways/banwire.rb +11 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +12 -1
- data/lib/active_merchant/billing/gateways/blue_pay.rb +519 -506
- data/lib/active_merchant/billing/gateways/borgun.rb +10 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +13 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +0 -1
- data/lib/active_merchant/billing/gateways/card_stream.rb +14 -19
- data/lib/active_merchant/billing/gateways/cecabank.rb +11 -1
- data/lib/active_merchant/billing/gateways/cenpos.rb +62 -2
- data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +3 -3
- data/lib/active_merchant/billing/gateways/conekta.rb +11 -1
- data/lib/active_merchant/billing/gateways/creditcall.rb +208 -0
- data/lib/active_merchant/billing/gateways/epay.rb +12 -0
- data/lib/active_merchant/billing/gateways/eway.rb +11 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +11 -0
- data/lib/active_merchant/billing/gateways/forte.rb +238 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +11 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +10 -1
- data/lib/active_merchant/billing/gateways/linkpoint.rb +11 -0
- data/lib/active_merchant/billing/gateways/litle.rb +8 -1
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +1 -1
- data/lib/active_merchant/billing/gateways/micropayment.rb +167 -0
- data/lib/active_merchant/billing/gateways/migs.rb +13 -4
- data/lib/active_merchant/billing/gateways/monei.rb +1 -1
- data/lib/active_merchant/billing/gateways/netbilling.rb +11 -1
- data/lib/active_merchant/billing/gateways/nmi.rb +164 -178
- data/lib/active_merchant/billing/gateways/ogone.rb +50 -15
- data/lib/active_merchant/billing/gateways/openpay.rb +10 -1
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +5 -5
- data/lib/active_merchant/billing/gateways/payment_express.rb +11 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +11 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paystation.rb +3 -4
- data/lib/active_merchant/billing/gateways/pin.rb +10 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +106 -57
- data/lib/active_merchant/billing/gateways/realex.rb +10 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +20 -0
- data/lib/active_merchant/billing/gateways/s5.rb +1 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +11 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +1 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +10 -4
- data/lib/active_merchant/billing/gateways/tns.rb +15 -4
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +11 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +12 -2
- data/lib/active_merchant/billing/gateways/wirecard.rb +11 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +11 -0
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +1 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +5 -2
@@ -65,6 +65,16 @@ module ActiveMerchant #:nodoc:
|
|
65
65
|
commit('void', post)
|
66
66
|
end
|
67
67
|
|
68
|
+
def supports_scrubbing
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def scrub(transcript)
|
73
|
+
transcript.gsub(%r((<PAN>)[^&]*(</PAN>))i, '\1[FILTERED]\2').
|
74
|
+
gsub(%r((<CVC2>)[^&]*(</CVC2>))i, '\1[FILTERED]\2').
|
75
|
+
gsub(%r(((?:\r\n)?Authorization: Basic )[^\r\n]+(\r\n)?), '\1[FILTERED]\2')
|
76
|
+
end
|
77
|
+
|
68
78
|
private
|
69
79
|
|
70
80
|
CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
|
@@ -1,9 +1,21 @@
|
|
1
1
|
module BraintreeCommon
|
2
2
|
def self.included(base)
|
3
|
-
base.supported_countries = %w(US CA
|
3
|
+
base.supported_countries = %w(US CA AD AT BE BG HR CY CZ DK EE FI FR GI DE GR GG HU IS IM IE IT JE LV LI LT LU MT MC NL NO PL PT RO SM SK SI ES SE CH TR GB SG HK MY AU NZ)
|
4
4
|
base.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
|
5
5
|
base.homepage_url = 'http://www.braintreepaymentsolutions.com'
|
6
6
|
base.display_name = 'Braintree'
|
7
7
|
base.default_currency = 'USD'
|
8
8
|
end
|
9
|
+
|
10
|
+
def supports_scrubbing
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def scrub(transcript)
|
15
|
+
return "Not currently supported." if transcript.blank?
|
16
|
+
transcript.
|
17
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
18
|
+
gsub(%r((&?ccnumber=)\d*(&?)), '\1[FILTERED]\2').
|
19
|
+
gsub(%r((&?cvv=)\d*(&?)), '\1[FILTERED]\2')
|
20
|
+
end
|
9
21
|
end
|
@@ -46,7 +46,7 @@ module ActiveMerchant #:nodoc:
|
|
46
46
|
|
47
47
|
super
|
48
48
|
|
49
|
-
if wiredump_device
|
49
|
+
if wiredump_device.present?
|
50
50
|
logger = ((Logger === wiredump_device) ? wiredump_device : Logger.new(wiredump_device))
|
51
51
|
logger.level = Logger::DEBUG
|
52
52
|
else
|
@@ -60,7 +60,7 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
:private_key => options[:private_key],
|
61
61
|
:environment => (options[:environment] || (test? ? :sandbox : :production)).to_sym,
|
62
62
|
:custom_user_agent => "ActiveMerchant #{ActiveMerchant::VERSION}",
|
63
|
-
:logger => logger,
|
63
|
+
:logger => options[:logger] || logger,
|
64
64
|
)
|
65
65
|
|
66
66
|
@braintree_gateway = Braintree::Gateway.new( @configuration )
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class CardStreamGateway < Gateway
|
4
|
+
|
5
|
+
THREEDSECURE_REQUIRED_DEPRECATION_MESSAGE = "Specifying the :threeDSRequired initialization option is deprecated. Please use the `:threeds_required => true` *transaction* option instead."
|
6
|
+
|
4
7
|
self.test_url = self.live_url = 'https://gateway.cardstream.com/direct/'
|
5
8
|
self.money_format = :cents
|
6
9
|
self.default_currency = 'GBP'
|
@@ -61,10 +64,10 @@ module ActiveMerchant #:nodoc:
|
|
61
64
|
|
62
65
|
def initialize(options = {})
|
63
66
|
requires!(options, :login, :shared_secret)
|
67
|
+
@threeds_required = false
|
64
68
|
if (options[:threeDSRequired])
|
65
|
-
|
66
|
-
|
67
|
-
@threeDSRequired = 'N'
|
69
|
+
ActiveMerchant.deprecated(THREEDSECURE_REQUIRED_DEPRECATION_MESSAGE)
|
70
|
+
@threeds_required = options[:threeDSRequired]
|
68
71
|
end
|
69
72
|
super
|
70
73
|
end
|
@@ -74,7 +77,6 @@ module ActiveMerchant #:nodoc:
|
|
74
77
|
add_amount(post, money, options)
|
75
78
|
add_invoice(post, creditcard, money, options)
|
76
79
|
add_creditcard(post, creditcard)
|
77
|
-
add_address(post, creditcard, options)
|
78
80
|
add_customer_data(post, options)
|
79
81
|
commit('PREAUTH', post)
|
80
82
|
end
|
@@ -84,7 +86,6 @@ module ActiveMerchant #:nodoc:
|
|
84
86
|
add_amount(post, money, options)
|
85
87
|
add_invoice(post, creditcard, money, options)
|
86
88
|
add_creditcard(post, creditcard)
|
87
|
-
add_address(post, creditcard, options)
|
88
89
|
add_customer_data(post, options)
|
89
90
|
commit('SALE', post)
|
90
91
|
end
|
@@ -135,19 +136,12 @@ module ActiveMerchant #:nodoc:
|
|
135
136
|
end
|
136
137
|
|
137
138
|
def add_customer_data(post, options)
|
138
|
-
address = options[:billing_address] || options[:address]
|
139
|
-
add_pair(post, :customerPostCode, address[:zip])
|
140
139
|
add_pair(post, :customerEmail, options[:email])
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
return if address.nil?
|
148
|
-
|
149
|
-
add_pair(post, :customerAddress, address[:address1] + " " + (address[:address2].nil? ? "" : address[:address2]))
|
150
|
-
add_pair(post, :customerPostCode, address[:zip])
|
140
|
+
if (address = options[:billing_address] || options[:address])
|
141
|
+
add_pair(post, :customerAddress, "#{address[:address1]} #{address[:address2]}".strip)
|
142
|
+
add_pair(post, :customerPostCode, address[:zip])
|
143
|
+
add_pair(post, :customerPhone, options[:phone])
|
144
|
+
end
|
151
145
|
end
|
152
146
|
|
153
147
|
def add_invoice(post, credit_card, money, options)
|
@@ -158,6 +152,9 @@ module ActiveMerchant #:nodoc:
|
|
158
152
|
add_pair(post, :item1Description, (options[:description] || options[:order_id]).slice(0, 15))
|
159
153
|
add_pair(post, :item1GrossValue, amount(money))
|
160
154
|
end
|
155
|
+
|
156
|
+
add_pair(post, :threeDSRequired, (options[:threeds_required] || @threeds_required) ? 'Y' : 'N')
|
157
|
+
add_pair(post, :type, options[:type] || '1')
|
161
158
|
end
|
162
159
|
|
163
160
|
def add_creditcard(post, credit_card)
|
@@ -200,9 +197,7 @@ module ActiveMerchant #:nodoc:
|
|
200
197
|
parameters.update(
|
201
198
|
:merchantID => @options[:login],
|
202
199
|
:action => action,
|
203
|
-
:type => '1', #Ecommerce
|
204
200
|
:countryCode => self.supported_countries[0],
|
205
|
-
:threeDSRequired => @threeDSRequired #Disable 3d secure by default
|
206
201
|
)
|
207
202
|
# adds a signature to the post hash/array
|
208
203
|
add_hmac(parameters)
|
@@ -94,6 +94,17 @@ module ActiveMerchant #:nodoc:
|
|
94
94
|
commit(CECA_ACTION_REFUND, post)
|
95
95
|
end
|
96
96
|
|
97
|
+
def supports_scrubbing
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def scrub(transcript)
|
102
|
+
transcript.
|
103
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
104
|
+
gsub(%r((&?pan=)[^&]*)i, '\1[FILTERED]').
|
105
|
+
gsub(%r((&?cvv2=)[^&]*)i, '\1[FILTERED]')
|
106
|
+
end
|
107
|
+
|
97
108
|
private
|
98
109
|
|
99
110
|
def add_creditcard(post, creditcard)
|
@@ -226,4 +237,3 @@ module ActiveMerchant #:nodoc:
|
|
226
237
|
end
|
227
238
|
end
|
228
239
|
end
|
229
|
-
|
@@ -148,7 +148,8 @@ module ActiveMerchant #:nodoc:
|
|
148
148
|
|
149
149
|
data = build_request(post)
|
150
150
|
begin
|
151
|
-
|
151
|
+
xml = ssl_post(self.live_url, data, headers)
|
152
|
+
raw = parse(xml)
|
152
153
|
rescue ActiveMerchant::ResponseError => e
|
153
154
|
if(e.response.code == "500" && e.response.body.start_with?("<s:Envelope"))
|
154
155
|
raw = {
|
@@ -166,7 +167,9 @@ module ActiveMerchant #:nodoc:
|
|
166
167
|
raw,
|
167
168
|
authorization: authorization_from(post, raw),
|
168
169
|
error_code: error_code_from(succeeded, raw),
|
169
|
-
test: test
|
170
|
+
test: test?,
|
171
|
+
cvv_result: cvv_result_from_xml(xml),
|
172
|
+
avs_result: avs_result_from_xml(xml)
|
170
173
|
)
|
171
174
|
end
|
172
175
|
|
@@ -257,6 +260,63 @@ module ActiveMerchant #:nodoc:
|
|
257
260
|
def error_code_from(succeeded, response)
|
258
261
|
succeeded ? nil : STANDARD_ERROR_CODE_MAPPING[response[:result]]
|
259
262
|
end
|
263
|
+
|
264
|
+
def cvv_result_from_xml(xml)
|
265
|
+
ActiveMerchant::Billing::CVVResult.new(cvv_result_code(xml))
|
266
|
+
end
|
267
|
+
|
268
|
+
def avs_result_from_xml(xml)
|
269
|
+
ActiveMerchant::Billing::AVSResult.new(code: avs_result_code(xml))
|
270
|
+
end
|
271
|
+
|
272
|
+
def cvv_result_code(xml)
|
273
|
+
cvv = validation_result_element(xml, "CVV")
|
274
|
+
return nil unless cvv
|
275
|
+
validation_result_matches?(*validation_result_element_text(cvv.parent)) ? 'M' : 'N'
|
276
|
+
end
|
277
|
+
|
278
|
+
def avs_result_code(xml)
|
279
|
+
billing_address_elem = validation_result_element(xml, "Billing Address")
|
280
|
+
zip_code_elem = validation_result_element(xml, "Zip Code")
|
281
|
+
|
282
|
+
return nil unless billing_address_elem && zip_code_elem
|
283
|
+
|
284
|
+
billing_matches = avs_result_matches(billing_address_elem)
|
285
|
+
zip_matches = avs_result_matches(zip_code_elem)
|
286
|
+
|
287
|
+
if billing_matches && zip_matches
|
288
|
+
'D'
|
289
|
+
elsif !billing_matches && zip_matches
|
290
|
+
'P'
|
291
|
+
elsif billing_matches && !zip_matches
|
292
|
+
'B'
|
293
|
+
else
|
294
|
+
'C'
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def avs_result_matches(elem)
|
299
|
+
validation_result_matches?(*validation_result_element_text(elem.parent))
|
300
|
+
end
|
301
|
+
|
302
|
+
def validation_result_element(xml, name)
|
303
|
+
doc = Nokogiri::XML(xml)
|
304
|
+
doc.remove_namespaces!
|
305
|
+
doc.at_xpath("//ParameterValidationResultList//ParameterValidationResult//Name[text() = '#{name}']")
|
306
|
+
end
|
307
|
+
|
308
|
+
def validation_result_element_text(element)
|
309
|
+
result_text = element.elements.detect { |elem|
|
310
|
+
elem.name == "Result"
|
311
|
+
}.children.detect { |elem| elem.text }.text
|
312
|
+
|
313
|
+
result_text.split(";").collect(&:strip)
|
314
|
+
end
|
315
|
+
|
316
|
+
def validation_result_matches?(present, match)
|
317
|
+
present.downcase.start_with?('present') &&
|
318
|
+
match.downcase.start_with?('match')
|
319
|
+
end
|
260
320
|
end
|
261
321
|
end
|
262
322
|
end
|
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
self.default_currency = 'USD'
|
8
8
|
self.money_format = :decimals
|
9
9
|
|
10
|
-
self.supported_countries = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', '
|
10
|
+
self.supported_countries = ['AD', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
11
11
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
12
12
|
|
13
13
|
self.homepage_url = 'https://www.checkout.com/'
|
@@ -3,10 +3,10 @@ module ActiveMerchant #:nodoc:
|
|
3
3
|
class CheckoutV2Gateway < Gateway
|
4
4
|
self.display_name = "Checkout.com V2 Gateway"
|
5
5
|
self.homepage_url = "https://www.checkout.com/"
|
6
|
-
self.
|
7
|
-
self.
|
6
|
+
self.live_url = "https://api2.checkout.com/v2"
|
7
|
+
self.test_url = "http://sandbox.checkout.com/api2/v2"
|
8
8
|
|
9
|
-
self.supported_countries = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', '
|
9
|
+
self.supported_countries = ['AD', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
10
10
|
self.default_currency = "USD"
|
11
11
|
self.money_format = :cents
|
12
12
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
@@ -55,6 +55,17 @@ module ActiveMerchant #:nodoc:
|
|
55
55
|
commit(:post, "charges/#{identifier}/refund", post)
|
56
56
|
end
|
57
57
|
|
58
|
+
def supports_scrubbing
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def scrub(transcript)
|
63
|
+
transcript.
|
64
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
65
|
+
gsub(%r((&?card%5Bnumber%5D=)[^&]*)i, '\1[FILTERED]').
|
66
|
+
gsub(%r((&?card%5Bcvc%5D=)[^&]*)i, '\1[FILTERED]')
|
67
|
+
end
|
68
|
+
|
58
69
|
private
|
59
70
|
|
60
71
|
def add_order(post, money, options)
|
@@ -207,4 +218,3 @@ module ActiveMerchant #:nodoc:
|
|
207
218
|
end
|
208
219
|
end
|
209
220
|
end
|
210
|
-
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class CreditcallGateway < Gateway
|
6
|
+
self.test_url = 'https://test.cardeasexml.com/generic.cex'
|
7
|
+
self.live_url = 'https://live.cardeasexml.com/'
|
8
|
+
|
9
|
+
self.supported_countries = ['US']
|
10
|
+
self.default_currency = 'USD'
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
12
|
+
|
13
|
+
self.homepage_url = 'https://www.creditcall.com'
|
14
|
+
self.display_name = 'Creditcall'
|
15
|
+
|
16
|
+
def initialize(options={})
|
17
|
+
requires!(options, :terminal_id, :transaction_key)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def purchase(money, payment_method, options={})
|
22
|
+
multi_response = MultiResponse.run do |r|
|
23
|
+
r.process { authorize(money, payment_method, options) }
|
24
|
+
r.process { capture(money, r.authorization, options) }
|
25
|
+
end
|
26
|
+
|
27
|
+
Response.new(
|
28
|
+
multi_response.primary_response.success?,
|
29
|
+
multi_response.primary_response.message,
|
30
|
+
multi_response.primary_response.params,
|
31
|
+
authorization: multi_response.responses.first.authorization,
|
32
|
+
test: test?
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def authorize(money, payment_method, options={})
|
37
|
+
request = build_xml_request do |xml|
|
38
|
+
add_transaction_details(xml, money, nil, "Auth", options)
|
39
|
+
add_terminal_details(xml, options)
|
40
|
+
add_card_details(xml, payment_method, options)
|
41
|
+
end
|
42
|
+
|
43
|
+
commit(request)
|
44
|
+
end
|
45
|
+
|
46
|
+
def capture(money, authorization, options={})
|
47
|
+
request = build_xml_request do |xml|
|
48
|
+
add_transaction_details(xml, money, authorization, "Conf", options)
|
49
|
+
add_terminal_details(xml, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
commit(request)
|
53
|
+
end
|
54
|
+
|
55
|
+
def refund(money, authorization, options={})
|
56
|
+
request = build_xml_request do |xml|
|
57
|
+
add_transaction_details(xml, money, authorization, "Refund", options)
|
58
|
+
add_terminal_details(xml, options)
|
59
|
+
end
|
60
|
+
|
61
|
+
commit(request)
|
62
|
+
end
|
63
|
+
|
64
|
+
def void(authorization, options={})
|
65
|
+
request = build_xml_request do |xml|
|
66
|
+
add_transaction_details(xml, nil, authorization, "Void", options)
|
67
|
+
add_terminal_details(xml, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
commit(request)
|
71
|
+
end
|
72
|
+
|
73
|
+
def verify(credit_card, options={})
|
74
|
+
MultiResponse.run(:use_first_response) do |r|
|
75
|
+
r.process { authorize(100, credit_card, options) }
|
76
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def supports_scrubbing?
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
def scrub(transcript)
|
85
|
+
transcript.
|
86
|
+
gsub(%r((<TransactionKey>).+?(</TransactionKey>))i, '\1[FILTERED]\2').
|
87
|
+
gsub(%r((<PAN>).+?(</PAN>))i, '\1[FILTERED]\2').
|
88
|
+
gsub(%r((<CSC>).+?(</CSC>))i, '\1[FILTERED]\2')
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def build_xml_request
|
94
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
95
|
+
xml.Request(type: "CardEaseXML", version: "1.0.0") do
|
96
|
+
yield(xml)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
builder.to_xml
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_transaction_details(xml, amount, authorization, type, options={})
|
103
|
+
xml.TransactionDetails do
|
104
|
+
xml.MessageType type
|
105
|
+
xml.Amount(unit: "Minor"){ xml.text(amount) } if amount
|
106
|
+
xml.CardEaseReference authorization if authorization
|
107
|
+
xml.VoidReason "01" if type == "Void"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_terminal_details(xml, options={})
|
112
|
+
xml.TerminalDetails do
|
113
|
+
xml.TerminalID @options[:terminal_id]
|
114
|
+
xml.TransactionKey @options[:transaction_key]
|
115
|
+
xml.Software(version: "SoftwareVersion"){ xml.text("SoftwareName") }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_card_details(xml, payment_method, options={})
|
120
|
+
xml.CardDetails do
|
121
|
+
xml.Manual(type: "cnp") do
|
122
|
+
xml.PAN payment_method.number
|
123
|
+
xml.ExpiryDate exp_date(payment_method)
|
124
|
+
xml.CSC payment_method.verification_value
|
125
|
+
end
|
126
|
+
|
127
|
+
if address = options[:billing_address]
|
128
|
+
xml.AdditionalVerification do
|
129
|
+
xml.Address address[:address1]
|
130
|
+
xml.Zip address[:zip]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def exp_date(payment_method)
|
137
|
+
"#{format(payment_method.year, :two_digits)}#{format(payment_method.month, :two_digits)}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def parse(body)
|
141
|
+
response = {}
|
142
|
+
xml = Nokogiri::XML(body)
|
143
|
+
|
144
|
+
node = xml.xpath("//Response/TransactionDetails")
|
145
|
+
node.children.each do |childnode|
|
146
|
+
response[childnode.name] = childnode.text
|
147
|
+
end
|
148
|
+
|
149
|
+
node = xml.xpath("//Response/Result")
|
150
|
+
node.children.each do |childnode|
|
151
|
+
if childnode.elements.empty?
|
152
|
+
response[childnode.name] = childnode.text
|
153
|
+
else
|
154
|
+
childnode_to_response(response, childnode)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
response
|
159
|
+
end
|
160
|
+
|
161
|
+
def childnode_to_response(response, childnode)
|
162
|
+
childnode.elements.each do |element|
|
163
|
+
if element.name == "Error"
|
164
|
+
response["ErrorCode"] = element.attr("code")
|
165
|
+
response["ErrorMessage"] = element.text
|
166
|
+
else
|
167
|
+
response[element.name] = element.text
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def commit(parameters)
|
173
|
+
response = parse(ssl_post(url, parameters))
|
174
|
+
|
175
|
+
Response.new(
|
176
|
+
success_from(response),
|
177
|
+
message_from(response),
|
178
|
+
response,
|
179
|
+
authorization: authorization_from(response),
|
180
|
+
avs_result: AVSResult.new(code: response["some_avs_response_key"]),
|
181
|
+
cvv_result: CVVResult.new(response["some_cvv_response_key"]),
|
182
|
+
test: test?
|
183
|
+
)
|
184
|
+
end
|
185
|
+
|
186
|
+
def url
|
187
|
+
test? ? test_url : live_url
|
188
|
+
end
|
189
|
+
|
190
|
+
def success_from(response)
|
191
|
+
response["LocalResult"] == "0" || response["LocalResult"] == "00"
|
192
|
+
end
|
193
|
+
|
194
|
+
def message_from(response)
|
195
|
+
if success_from(response)
|
196
|
+
"Succeeded"
|
197
|
+
else
|
198
|
+
response["ErrorMessage"]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def authorization_from(response)
|
203
|
+
response["CardEaseReference"]
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|