activemerchant 1.106.0 → 1.108.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +79 -0
- data/README.md +2 -2
- data/lib/active_merchant/billing/gateways/adyen.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1 -1
- data/lib/active_merchant/billing/gateways/blue_pay.rb +2 -2
- data/lib/active_merchant/billing/gateways/borgun.rb +15 -4
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +11 -9
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +20 -9
- data/lib/active_merchant/billing/gateways/clearhaus.rb +1 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +74 -21
- data/lib/active_merchant/billing/gateways/d_local.rb +17 -5
- data/lib/active_merchant/billing/gateways/decidir.rb +29 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +13 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +58 -5
- data/lib/active_merchant/billing/gateways/element.rb +13 -5
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +2 -2
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +2 -2
- data/lib/active_merchant/billing/gateways/forte.rb +7 -6
- data/lib/active_merchant/billing/gateways/global_collect.rb +30 -24
- data/lib/active_merchant/billing/gateways/hps.rb +4 -2
- data/lib/active_merchant/billing/gateways/iats_payments.rb +31 -14
- data/lib/active_merchant/billing/gateways/iridium.rb +4 -2
- data/lib/active_merchant/billing/gateways/iveri.rb +4 -1
- data/lib/active_merchant/billing/gateways/ixopay.rb +1 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +34 -5
- data/lib/active_merchant/billing/gateways/litle.rb +6 -1
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +1 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +1 -1
- data/lib/active_merchant/billing/gateways/netbanx.rb +1 -1
- data/lib/active_merchant/billing/gateways/opp.rb +13 -7
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +4 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +44 -2
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/payu_latam.rb +1 -1
- data/lib/active_merchant/billing/gateways/pin.rb +1 -1
- data/lib/active_merchant/billing/gateways/quantum.rb +1 -1
- data/lib/active_merchant/billing/gateways/realex.rb +10 -3
- data/lib/active_merchant/billing/gateways/redsys.rb +1 -1
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +1 -1
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +1 -1
- data/lib/active_merchant/billing/gateways/stripe.rb +7 -2
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +40 -6
- data/lib/active_merchant/billing/gateways/transact_pro.rb +2 -2
- data/lib/active_merchant/billing/gateways/trexle.rb +1 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +8 -6
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/connection.rb +40 -42
- data/lib/active_merchant/network_connection_retries.rb +10 -12
- data/lib/active_merchant/version.rb +1 -1
- metadata +5 -4
@@ -21,6 +21,8 @@ module ActiveMerchant #:nodoc:
|
|
21
21
|
visa: 'Visa 3DSecure',
|
22
22
|
american_express: 'AMEX 3DSecure',
|
23
23
|
discover: 'Discover 3DSecure',
|
24
|
+
android_pay: 'GooglePayApp',
|
25
|
+
google_pay: 'GooglePayApp'
|
24
26
|
}
|
25
27
|
|
26
28
|
def initialize(options={})
|
@@ -199,9 +201,9 @@ module ActiveMerchant #:nodoc:
|
|
199
201
|
xml.hps :RoutingNumber, check.routing_number
|
200
202
|
xml.hps :AccountNumber, check.account_number
|
201
203
|
xml.hps :CheckNumber, check.number
|
202
|
-
xml.hps :AccountType, check.account_type
|
204
|
+
xml.hps :AccountType, check.account_type&.upcase
|
203
205
|
end
|
204
|
-
xml.hps :CheckType, check.account_holder_type
|
206
|
+
xml.hps :CheckType, check.account_holder_type&.upcase
|
205
207
|
end
|
206
208
|
|
207
209
|
def add_details(xml, options)
|
@@ -14,12 +14,13 @@ module ActiveMerchant #:nodoc:
|
|
14
14
|
self.display_name = 'iATS Payments'
|
15
15
|
|
16
16
|
ACTIONS = {
|
17
|
-
purchase: '
|
18
|
-
purchase_check: '
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
purchase: 'ProcessCreditCard',
|
18
|
+
purchase_check: 'ProcessACHEFT',
|
19
|
+
purchase_customer_code: 'ProcessCreditCardWithCustomerCode',
|
20
|
+
refund: 'ProcessCreditCardRefundWithTransactionId',
|
21
|
+
refund_check: 'ProcessACHEFTRefundWithTransactionId',
|
22
|
+
store: 'CreateCreditCardCustomerCode',
|
23
|
+
unstore: 'DeleteCustomerCode'
|
23
24
|
}
|
24
25
|
|
25
26
|
def initialize(options={})
|
@@ -42,7 +43,7 @@ module ActiveMerchant #:nodoc:
|
|
42
43
|
add_ip(post, options)
|
43
44
|
add_description(post, options)
|
44
45
|
|
45
|
-
commit((payment
|
46
|
+
commit(determine_purchase_type(payment), post)
|
46
47
|
end
|
47
48
|
|
48
49
|
def refund(money, authorization, options={})
|
@@ -90,6 +91,16 @@ module ActiveMerchant #:nodoc:
|
|
90
91
|
|
91
92
|
private
|
92
93
|
|
94
|
+
def determine_purchase_type(payment)
|
95
|
+
if payment.is_a?(String)
|
96
|
+
:purchase_customer_code
|
97
|
+
elsif payment.is_a?(Check)
|
98
|
+
:purchase_check
|
99
|
+
else
|
100
|
+
:purchase
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
93
104
|
def add_ip(post, options)
|
94
105
|
post[:customer_ip_address] = options[:ip] if options.has_key?(:ip)
|
95
106
|
end
|
@@ -101,6 +112,9 @@ module ActiveMerchant #:nodoc:
|
|
101
112
|
post[:city] = billing_address[:city]
|
102
113
|
post[:state] = billing_address[:state]
|
103
114
|
post[:zip_code] = billing_address[:zip]
|
115
|
+
post[:phone] = billing_address[:phone] if billing_address[:phone]
|
116
|
+
post[:email] = billing_address[:email] if billing_address[:email]
|
117
|
+
post[:country] = billing_address[:country] if billing_address[:country]
|
104
118
|
end
|
105
119
|
end
|
106
120
|
|
@@ -114,7 +128,9 @@ module ActiveMerchant #:nodoc:
|
|
114
128
|
end
|
115
129
|
|
116
130
|
def add_payment(post, payment)
|
117
|
-
if payment.is_a?(
|
131
|
+
if payment.is_a?(String)
|
132
|
+
post[:customer_code] = payment
|
133
|
+
elsif payment.is_a?(Check)
|
118
134
|
add_check(post, payment)
|
119
135
|
else
|
120
136
|
add_credit_card(post, payment)
|
@@ -178,12 +194,13 @@ module ActiveMerchant #:nodoc:
|
|
178
194
|
|
179
195
|
def endpoints
|
180
196
|
{
|
181
|
-
purchase: '
|
182
|
-
purchase_check: '
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
197
|
+
purchase: 'ProcessLinkv3.asmx',
|
198
|
+
purchase_check: 'ProcessLinkv3.asmx',
|
199
|
+
purchase_customer_code: 'ProcessLinkv3.asmx',
|
200
|
+
refund: 'ProcessLinkv3.asmx',
|
201
|
+
refund_check: 'ProcessLinkv3.asmx',
|
202
|
+
store: 'CustomerLinkv3.asmx',
|
203
|
+
unstore: 'CustomerLinkv3.asmx'
|
187
204
|
}
|
188
205
|
end
|
189
206
|
|
@@ -291,7 +291,8 @@ module ActiveMerchant #:nodoc:
|
|
291
291
|
order_id, cross_reference, _ = authorization.split(';')
|
292
292
|
build_request(options) do |xml|
|
293
293
|
if money
|
294
|
-
|
294
|
+
currency = options[:currency] || currency(money)
|
295
|
+
details = {'CurrencyCode' => currency_code(currency), 'Amount' => localized_amount(money, currency)}
|
295
296
|
else
|
296
297
|
details = {'CurrencyCode' => currency_code(default_currency), 'Amount' => '0'}
|
297
298
|
end
|
@@ -327,8 +328,9 @@ module ActiveMerchant #:nodoc:
|
|
327
328
|
end
|
328
329
|
|
329
330
|
def add_purchase_data(xml, type, money, options)
|
331
|
+
currency = options[:currency] || currency(money)
|
330
332
|
requires!(options, :order_id)
|
331
|
-
xml.tag! 'TransactionDetails', {'Amount' =>
|
333
|
+
xml.tag! 'TransactionDetails', {'Amount' => localized_amount(money, currency), 'CurrencyCode' => currency_code(currency)} do
|
332
334
|
xml.tag! 'MessageDetails', {'TransactionType' => type}
|
333
335
|
xml.tag! 'OrderID', options[:order_id]
|
334
336
|
xml.tag! 'TransactionControl' do
|
@@ -60,7 +60,10 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def verify(credit_card, options={})
|
63
|
-
|
63
|
+
MultiResponse.run(:use_first_response) do |r|
|
64
|
+
r.process { authorize(100, credit_card, options) }
|
65
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
66
|
+
end
|
64
67
|
end
|
65
68
|
|
66
69
|
def verify_credentials
|
@@ -8,6 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
|
9
9
|
self.supported_countries = %w(AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW)
|
10
10
|
self.default_currency = 'EUR'
|
11
|
+
self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LWD OMR TND)
|
11
12
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro]
|
12
13
|
|
13
14
|
self.homepage_url = 'https://www.ixopay.com'
|
@@ -4,8 +4,8 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.display_name = 'Kushki'
|
5
5
|
self.homepage_url = 'https://www.kushkipagos.com'
|
6
6
|
|
7
|
-
self.test_url = 'https://api-uat.kushkipagos.com/
|
8
|
-
self.live_url = 'https://api.kushkipagos.com/
|
7
|
+
self.test_url = 'https://api-uat.kushkipagos.com/'
|
8
|
+
self.live_url = 'https://api.kushkipagos.com/'
|
9
9
|
|
10
10
|
self.supported_countries = ['CL', 'CO', 'EC', 'MX', 'PE']
|
11
11
|
self.default_currency = 'USD'
|
@@ -24,6 +24,23 @@ module ActiveMerchant #:nodoc:
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def authorize(amount, payment_method, options={})
|
28
|
+
MultiResponse.run() do |r|
|
29
|
+
r.process { tokenize(amount, payment_method, options) }
|
30
|
+
r.process { preauthorize(amount, r.authorization, options) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def capture(amount, authorization, options={})
|
35
|
+
action = 'capture'
|
36
|
+
|
37
|
+
post = {}
|
38
|
+
post[:ticketNumber] = authorization
|
39
|
+
add_invoice(action, post, amount, options)
|
40
|
+
|
41
|
+
commit(action, post)
|
42
|
+
end
|
43
|
+
|
27
44
|
def refund(amount, authorization, options={})
|
28
45
|
action = 'refund'
|
29
46
|
|
@@ -75,6 +92,16 @@ module ActiveMerchant #:nodoc:
|
|
75
92
|
commit(action, post)
|
76
93
|
end
|
77
94
|
|
95
|
+
def preauthorize(amount, authorization, options)
|
96
|
+
action = 'preAuthorization'
|
97
|
+
|
98
|
+
post = {}
|
99
|
+
add_reference(post, authorization, options)
|
100
|
+
add_invoice(action, post, amount, options)
|
101
|
+
|
102
|
+
commit(action, post)
|
103
|
+
end
|
104
|
+
|
78
105
|
def add_invoice(action, post, money, options)
|
79
106
|
if action == 'tokenize'
|
80
107
|
post[:totalAmount] = amount(money).to_f
|
@@ -131,7 +158,9 @@ module ActiveMerchant #:nodoc:
|
|
131
158
|
'tokenize' => 'tokens',
|
132
159
|
'charge' => 'charges',
|
133
160
|
'void' => 'charges',
|
134
|
-
'refund' => 'refund'
|
161
|
+
'refund' => 'refund',
|
162
|
+
'preAuthorization' => 'preAuthorization',
|
163
|
+
'capture' => 'capture'
|
135
164
|
}
|
136
165
|
|
137
166
|
def commit(action, params)
|
@@ -178,9 +207,9 @@ module ActiveMerchant #:nodoc:
|
|
178
207
|
base_url = test? ? test_url : live_url
|
179
208
|
|
180
209
|
if ['void', 'refund'].include?(action)
|
181
|
-
base_url + ENDPOINT[action] + '/' + params[:ticketNumber].to_s
|
210
|
+
base_url + 'v1/' + ENDPOINT[action] + '/' + params[:ticketNumber].to_s
|
182
211
|
else
|
183
|
-
base_url + ENDPOINT[action]
|
212
|
+
base_url + 'card/v1/' + ENDPOINT[action]
|
184
213
|
end
|
185
214
|
end
|
186
215
|
|
@@ -263,6 +263,7 @@ module ActiveMerchant #:nodoc:
|
|
263
263
|
if payment_method.is_a?(String)
|
264
264
|
doc.token do
|
265
265
|
doc.litleToken(payment_method)
|
266
|
+
doc.expDate(format_exp_date(options[:basis_expiration_month], options[:basis_expiration_year])) if options[:basis_expiration_month] && options[:basis_expiration_year]
|
266
267
|
end
|
267
268
|
elsif payment_method.respond_to?(:track_data) && payment_method.track_data.present?
|
268
269
|
doc.card do
|
@@ -416,7 +417,11 @@ module ActiveMerchant #:nodoc:
|
|
416
417
|
end
|
417
418
|
|
418
419
|
def exp_date(payment_method)
|
419
|
-
|
420
|
+
format_exp_date(payment_method.month, payment_method.year)
|
421
|
+
end
|
422
|
+
|
423
|
+
def format_exp_date(month, year)
|
424
|
+
"#{format(month, :two_digits)}#{format(year, :two_digits)}"
|
420
425
|
end
|
421
426
|
|
422
427
|
def parse(kind, xml)
|
@@ -113,6 +113,7 @@ module ActiveMerchant #:nodoc:
|
|
113
113
|
|
114
114
|
post[:processing_mode] = options[:processing_mode]
|
115
115
|
post[:merchant_account_id] = options[:merchant_account_id] if options[:merchant_account_id]
|
116
|
+
post[:payment_method_option_id] = options[:payment_method_option_id] if options[:payment_method_option_id]
|
116
117
|
add_merchant_services(post, options)
|
117
118
|
end
|
118
119
|
|
@@ -123,7 +123,7 @@ module ActiveMerchant #:nodoc:
|
|
123
123
|
|
124
124
|
success = false
|
125
125
|
authorization = (raw['TransactionId'] || parameters[:transactionId])
|
126
|
-
if raw[:container]
|
126
|
+
if /Exception|Error/.match?(raw[:container])
|
127
127
|
message = (raw['Message'] || raw['Error']['Message'])
|
128
128
|
elsif raw['Error'] && !raw['Error'].empty?
|
129
129
|
message = (raw['Error']['ResponseText'] || raw['Error']['ResponseCode'])
|
@@ -222,7 +222,7 @@ module ActiveMerchant #:nodoc:
|
|
222
222
|
|
223
223
|
def get_url(uri)
|
224
224
|
url = (test? ? test_url : live_url)
|
225
|
-
if
|
225
|
+
if /^customervault/.match?(uri)
|
226
226
|
"#{url}#{uri}"
|
227
227
|
else
|
228
228
|
"#{url}cardpayments/v1/accounts/#{@options[:account_number]}/#{uri}"
|
@@ -13,8 +13,7 @@ module ActiveMerchant #:nodoc:
|
|
13
13
|
# == Usage
|
14
14
|
#
|
15
15
|
# gateway = ActiveMerchant::Billing::OppGateway.new(
|
16
|
-
#
|
17
|
-
# password: 'password',
|
16
|
+
# access_token: 'access_token',
|
18
17
|
# entity_id: 'entity id',
|
19
18
|
# )
|
20
19
|
#
|
@@ -119,7 +118,7 @@ module ActiveMerchant #:nodoc:
|
|
119
118
|
self.display_name = 'Open Payment Platform'
|
120
119
|
|
121
120
|
def initialize(options={})
|
122
|
-
requires!(options, :
|
121
|
+
requires!(options, :access_token, :entity_id)
|
123
122
|
super
|
124
123
|
end
|
125
124
|
|
@@ -167,7 +166,7 @@ module ActiveMerchant #:nodoc:
|
|
167
166
|
|
168
167
|
def scrub(transcript)
|
169
168
|
transcript.
|
170
|
-
gsub(%r((
|
169
|
+
gsub(%r((Authorization: Bearer )\w+)i, '\1[FILTERED]').
|
171
170
|
gsub(%r((card\.number=)\d+), '\1[FILTERED]').
|
172
171
|
gsub(%r((card\.cvv=)\d+), '\1[FILTERED]')
|
173
172
|
end
|
@@ -203,7 +202,7 @@ module ActiveMerchant #:nodoc:
|
|
203
202
|
end
|
204
203
|
|
205
204
|
def add_authentication(post)
|
206
|
-
post[:authentication] = { entityId: @options[:entity_id]
|
205
|
+
post[:authentication] = { entityId: @options[:entity_id] }
|
207
206
|
end
|
208
207
|
|
209
208
|
def add_customer_data(post, payment, options)
|
@@ -316,7 +315,7 @@ module ActiveMerchant #:nodoc:
|
|
316
315
|
ssl_post(
|
317
316
|
url,
|
318
317
|
post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&'),
|
319
|
-
|
318
|
+
headers
|
320
319
|
)
|
321
320
|
)
|
322
321
|
rescue ResponseError => e
|
@@ -335,6 +334,13 @@ module ActiveMerchant #:nodoc:
|
|
335
334
|
)
|
336
335
|
end
|
337
336
|
|
337
|
+
def headers
|
338
|
+
{
|
339
|
+
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
|
340
|
+
'Authorization' => "Bearer #{@options[:access_token]}"
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
338
344
|
def parse(body)
|
339
345
|
JSON.parse(body)
|
340
346
|
rescue JSON::ParserError
|
@@ -351,7 +357,7 @@ module ActiveMerchant #:nodoc:
|
|
351
357
|
|
352
358
|
success_regex = /^(000\.000\.|000\.100\.1|000\.[36])/
|
353
359
|
|
354
|
-
if success_regex
|
360
|
+
if success_regex.match?(response['result']['code'])
|
355
361
|
true
|
356
362
|
else
|
357
363
|
false
|
@@ -306,7 +306,8 @@ module ActiveMerchant #:nodoc:
|
|
306
306
|
gsub(%r((<OrbitalConnectionUsername>).+(</OrbitalConnectionUsername>)), '\1[FILTERED]\2').
|
307
307
|
gsub(%r((<OrbitalConnectionPassword>).+(</OrbitalConnectionPassword>)), '\1[FILTERED]\2').
|
308
308
|
gsub(%r((<AccountNum>).+(</AccountNum>)), '\1[FILTERED]\2').
|
309
|
-
|
309
|
+
# the response sometimes contains a new line that cuts off the end of the closing tag
|
310
|
+
gsub(%r((<CCAccountNum>).+(</CC)), '\1[FILTERED]\2').
|
310
311
|
gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
|
311
312
|
gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
|
312
313
|
gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2')
|
@@ -361,6 +362,15 @@ module ActiveMerchant #:nodoc:
|
|
361
362
|
end
|
362
363
|
end
|
363
364
|
|
365
|
+
def add_level_3_tax(xml, options={})
|
366
|
+
if (level_3 = options[:level_3_data])
|
367
|
+
xml.tag! :PC3VATtaxAmt, byte_limit(level_3[:vat_tax], 12) if level_3[:vat_tax]
|
368
|
+
xml.tag! :PC3AltTaxAmt, byte_limit(level_3[:alt_tax], 9) if level_3[:alt_tax]
|
369
|
+
xml.tag! :PC3VATtaxRate, byte_limit(level_3[:vat_rate], 4) if level_3[:vat_rate]
|
370
|
+
xml.tag! :PC3AltTaxInd, byte_limit(level_3[:alt_ind], 15) if level_3[:alt_ind]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
364
374
|
def add_level_2_advice_addendum(xml, options={})
|
365
375
|
if (level_2 = options[:level_2_data])
|
366
376
|
xml.tag! :AMEXTranAdvAddn1, byte_limit(level_2[:advice_addendum_1], 40) if level_2[:advice_addendum_1]
|
@@ -382,6 +392,35 @@ module ActiveMerchant #:nodoc:
|
|
382
392
|
end
|
383
393
|
end
|
384
394
|
|
395
|
+
def add_level_3_purchase(xml, options={})
|
396
|
+
if (level_3 = options[:level_3_data])
|
397
|
+
xml.tag! :PC3FreightAmt, byte_limit(level_3[:freight_amount], 12) if level_3[:freight_amount]
|
398
|
+
xml.tag! :PC3DutyAmt, byte_limit(level_3[:duty_amount], 12) if level_3[:duty_amount]
|
399
|
+
xml.tag! :PC3DestCountryCd, byte_limit(level_3[:dest_country], 3) if level_3[:dest_country]
|
400
|
+
xml.tag! :PC3ShipFromZip, byte_limit(level_3[:ship_from_zip], 10) if level_3[:ship_from_zip]
|
401
|
+
xml.tag! :PC3DiscAmt, byte_limit(level_3[:discount_amount], 12) if level_3[:discount_amount]
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
def add_line_items(xml, options={})
|
406
|
+
xml.tag! :PC3LineItemCount, byte_limit(options[:line_items].count, 2)
|
407
|
+
xml.tag! :PC3LineItemArray do
|
408
|
+
options[:line_items].each_with_index do |line_item, index|
|
409
|
+
xml.tag! :PC3LineItem do
|
410
|
+
xml.tag! :PC3DtlIndex, byte_limit(index + 1, 2)
|
411
|
+
line_item.each do |key, value|
|
412
|
+
if key == :line_tot
|
413
|
+
formatted_key = :PC3Dtllinetot
|
414
|
+
else
|
415
|
+
formatted_key = "PC3Dtl#{key.to_s.camelize}".to_sym
|
416
|
+
end
|
417
|
+
xml.tag! formatted_key, value
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
385
424
|
def add_address(xml, creditcard, options)
|
386
425
|
if (address = (options[:billing_address] || options[:address]))
|
387
426
|
avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
|
@@ -569,7 +608,7 @@ module ActiveMerchant #:nodoc:
|
|
569
608
|
|
570
609
|
initiator =
|
571
610
|
case parameters[:stored_credential][:initiator]
|
572
|
-
when 'customer' then 'C'
|
611
|
+
when 'cardholder', 'customer' then 'C'
|
573
612
|
when 'merchant' then 'M'
|
574
613
|
end
|
575
614
|
reason =
|
@@ -715,6 +754,9 @@ module ActiveMerchant #:nodoc:
|
|
715
754
|
end
|
716
755
|
|
717
756
|
add_level_2_purchase(xml, parameters)
|
757
|
+
add_level_3_purchase(xml, parameters)
|
758
|
+
add_level_3_tax(xml, parameters)
|
759
|
+
add_line_items(xml, parameters) if parameters[:line_items]
|
718
760
|
add_stored_credentials(xml, parameters)
|
719
761
|
add_pymt_brand_program_code(xml, creditcard, three_d_secure)
|
720
762
|
end
|
@@ -181,7 +181,7 @@ module ActiveMerchant #:nodoc:
|
|
181
181
|
node.xpath('.//*').each { |e| parse_element(payment_result_response, e) }
|
182
182
|
when node.xpath('.//*').to_a.any?
|
183
183
|
node.xpath('.//*').each { |e| parse_element(response, e) }
|
184
|
-
when node_name.to_s
|
184
|
+
when /amt$/.match?(node_name.to_s)
|
185
185
|
# *Amt elements don't put the value in the #text - instead they use a Currency attribute
|
186
186
|
response[node_name] = node.attributes['Currency'].to_s
|
187
187
|
when node_name == :ext_data
|
@@ -17,8 +17,8 @@ module ActiveMerchant #:nodoc:
|
|
17
17
|
|
18
18
|
self.supported_countries = %w[AU FJ GB HK IE MY NZ PG SG US]
|
19
19
|
|
20
|
-
self.homepage_url = '
|
21
|
-
self.display_name = 'PaymentExpress'
|
20
|
+
self.homepage_url = 'https://www.windcave.com/'
|
21
|
+
self.display_name = 'Windcave (formerly PaymentExpress)'
|
22
22
|
|
23
23
|
self.live_url = 'https://sec.paymentexpress.com/pxpost.aspx'
|
24
24
|
self.test_url = 'https://uat.paymentexpress.com/pxpost.aspx'
|