activemerchant 1.62.0 → 1.79.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +420 -2
- data/README.md +1 -2
- data/lib/active_merchant/billing/credit_card.rb +13 -14
- data/lib/active_merchant/billing/credit_card_methods.rb +3 -1
- data/lib/active_merchant/billing/gateway.rb +25 -9
- data/lib/active_merchant/billing/gateways/adyen.rb +299 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +168 -56
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -2
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +65 -22
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +87 -7
- data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -8
- data/lib/active_merchant/billing/gateways/borgun.rb +10 -10
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +1 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +49 -15
- data/lib/active_merchant/billing/gateways/card_connect.rb +286 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +97 -2
- data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +14 -2
- data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
- data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +44 -14
- data/lib/active_merchant/billing/gateways/citrus_pay.rb +0 -1
- data/lib/active_merchant/billing/gateways/clearhaus.rb +0 -2
- data/lib/active_merchant/billing/gateways/conekta.rb +4 -4
- data/lib/active_merchant/billing/gateways/creditcall.rb +71 -9
- data/lib/active_merchant/billing/gateways/credorax.rb +117 -5
- data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +54 -15
- data/lib/active_merchant/billing/gateways/data_cash.rb +12 -0
- data/lib/active_merchant/billing/gateways/dibs.rb +0 -1
- data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +37 -95
- data/lib/active_merchant/billing/gateways/element.rb +11 -1
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +3 -29
- data/lib/active_merchant/billing/gateways/first_pay.rb +12 -10
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +37 -20
- data/lib/active_merchant/billing/gateways/forte.rb +0 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +55 -16
- data/lib/active_merchant/billing/gateways/global_transport.rb +16 -2
- data/lib/active_merchant/billing/gateways/hps.rb +12 -1
- data/lib/active_merchant/billing/gateways/iats_payments.rb +2 -2
- data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +12 -9
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +227 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -2
- data/lib/active_merchant/billing/gateways/litle.rb +107 -30
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +262 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +11 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +16 -4
- data/lib/active_merchant/billing/gateways/mercury.rb +14 -1
- data/lib/active_merchant/billing/gateways/migs.rb +28 -6
- data/lib/active_merchant/billing/gateways/moneris.rb +20 -12
- data/lib/active_merchant/billing/gateways/moneris_us.rb +11 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +292 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +4 -4
- data/lib/active_merchant/billing/gateways/netbanx.rb +60 -16
- data/lib/active_merchant/billing/gateways/netbilling.rb +0 -1
- data/lib/active_merchant/billing/gateways/nmi.rb +12 -1
- data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
- data/lib/active_merchant/billing/gateways/omise.rb +9 -5
- data/lib/active_merchant/billing/gateways/openpay.rb +13 -0
- data/lib/active_merchant/billing/gateways/opp.rb +124 -114
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +14 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +83 -14
- data/lib/active_merchant/billing/gateways/pay_hub.rb +2 -2
- data/lib/active_merchant/billing/gateways/payeezy.rb +152 -46
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -2
- data/lib/active_merchant/billing/gateways/payflow.rb +24 -2
- data/lib/active_merchant/billing/gateways/payment_express.rb +3 -2
- data/lib/active_merchant/billing/gateways/paymentez.rb +276 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +18 -10
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +14 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +0 -12
- data/lib/active_merchant/billing/gateways/paystation.rb +14 -1
- data/lib/active_merchant/billing/gateways/payu_latam.rb +102 -62
- data/lib/active_merchant/billing/gateways/pin.rb +5 -0
- data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +12 -1
- data/lib/active_merchant/billing/gateways/qbms.rb +11 -0
- data/lib/active_merchant/billing/gateways/quickbooks.rb +10 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +21 -17
- data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
- data/lib/active_merchant/billing/gateways/qvalent.rb +60 -3
- data/lib/active_merchant/billing/gateways/realex.rb +16 -6
- data/lib/active_merchant/billing/gateways/redsys.rb +8 -2
- data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
- data/lib/active_merchant/billing/gateways/sage.rb +8 -3
- data/lib/active_merchant/billing/gateways/sage_pay.rb +29 -13
- data/lib/active_merchant/billing/gateways/secure_net.rb +11 -1
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +53 -7
- data/lib/active_merchant/billing/gateways/stripe.rb +84 -26
- data/lib/active_merchant/billing/gateways/tns.rb +0 -1
- data/lib/active_merchant/billing/gateways/trans_first.rb +3 -2
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +61 -26
- data/lib/active_merchant/billing/gateways/trexle.rb +217 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +114 -9
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +45 -22
- data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
- data/lib/active_merchant/billing/gateways/wepay.rb +79 -46
- data/lib/active_merchant/billing/gateways/wirecard.rb +5 -4
- data/lib/active_merchant/billing/gateways/worldpay.rb +85 -20
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +27 -8
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/connection.rb +48 -12
- data/lib/active_merchant/net_http_ssl_connection.rb +9 -0
- data/lib/active_merchant/network_connection_retries.rb +6 -4
- data/lib/active_merchant/posts_data.rb +11 -1
- data/lib/active_merchant/version.rb +1 -1
- data/lib/active_merchant.rb +2 -5
- data/lib/certs/cacert.pem +85 -0
- data/lib/support/ssl_version.rb +87 -0
- metadata +25 -9
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
@@ -36,24 +36,25 @@ module ActiveMerchant
|
|
36
36
|
}
|
37
37
|
|
38
38
|
STANDARD_ERROR_CODE_MAPPING = {
|
39
|
-
'36' => STANDARD_ERROR_CODE[:incorrect_number],
|
40
|
-
'237' => STANDARD_ERROR_CODE[:invalid_number],
|
41
|
-
'2315' => STANDARD_ERROR_CODE[:invalid_number],
|
42
|
-
'37' => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
43
|
-
'2316' => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
44
|
-
'378' => STANDARD_ERROR_CODE[:invalid_cvc],
|
45
|
-
'38' => STANDARD_ERROR_CODE[:expired_card],
|
46
|
-
'2317' => STANDARD_ERROR_CODE[:expired_card],
|
47
|
-
'244' => STANDARD_ERROR_CODE[:incorrect_cvc],
|
48
|
-
'227' => STANDARD_ERROR_CODE[:incorrect_address],
|
49
39
|
'2127' => STANDARD_ERROR_CODE[:incorrect_address],
|
50
40
|
'22' => STANDARD_ERROR_CODE[:card_declined],
|
41
|
+
'227' => STANDARD_ERROR_CODE[:incorrect_address],
|
51
42
|
'23' => STANDARD_ERROR_CODE[:card_declined],
|
52
|
-
'
|
43
|
+
'2315' => STANDARD_ERROR_CODE[:invalid_number],
|
44
|
+
'2316' => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
45
|
+
'2317' => STANDARD_ERROR_CODE[:expired_card],
|
53
46
|
'235' => STANDARD_ERROR_CODE[:processing_error],
|
47
|
+
'237' => STANDARD_ERROR_CODE[:invalid_number],
|
54
48
|
'24' => STANDARD_ERROR_CODE[:pickup_card],
|
49
|
+
'244' => STANDARD_ERROR_CODE[:incorrect_cvc],
|
55
50
|
'300' => STANDARD_ERROR_CODE[:config_error],
|
56
|
-
'
|
51
|
+
'3153' => STANDARD_ERROR_CODE[:processing_error],
|
52
|
+
'3155' => STANDARD_ERROR_CODE[:unsupported_feature],
|
53
|
+
'36' => STANDARD_ERROR_CODE[:incorrect_number],
|
54
|
+
'37' => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
55
|
+
'378' => STANDARD_ERROR_CODE[:invalid_cvc],
|
56
|
+
'38' => STANDARD_ERROR_CODE[:expired_card],
|
57
|
+
'384' => STANDARD_ERROR_CODE[:config_error],
|
57
58
|
}
|
58
59
|
|
59
60
|
MARKET_TYPE = {
|
@@ -91,6 +92,7 @@ module ActiveMerchant
|
|
91
92
|
APPLE_PAY_DATA_DESCRIPTOR = "COMMON.APPLE.INAPP.PAYMENT"
|
92
93
|
|
93
94
|
PAYMENT_METHOD_NOT_SUPPORTED_ERROR = "155"
|
95
|
+
INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = "54"
|
94
96
|
|
95
97
|
def initialize(options={})
|
96
98
|
requires!(options, :login, :password)
|
@@ -130,11 +132,20 @@ module ActiveMerchant
|
|
130
132
|
end
|
131
133
|
|
132
134
|
def refund(amount, authorization, options={})
|
133
|
-
if auth_was_for_cim?(authorization)
|
135
|
+
response = if auth_was_for_cim?(authorization)
|
134
136
|
cim_refund(amount, authorization, options)
|
135
137
|
else
|
136
138
|
normal_refund(amount, authorization, options)
|
137
139
|
end
|
140
|
+
|
141
|
+
return response if response.success?
|
142
|
+
return response unless options[:force_full_refund_if_unsettled]
|
143
|
+
|
144
|
+
if response.params["response_reason_code"] == INELIGIBLE_FOR_ISSUING_CREDIT_ERROR
|
145
|
+
void(authorization, options)
|
146
|
+
else
|
147
|
+
response
|
148
|
+
end
|
138
149
|
end
|
139
150
|
|
140
151
|
def void(authorization, options={})
|
@@ -156,10 +167,10 @@ module ActiveMerchant
|
|
156
167
|
xml.transactionType('refundTransaction')
|
157
168
|
xml.amount(amount(amount))
|
158
169
|
|
159
|
-
add_payment_source(xml, payment)
|
160
|
-
|
170
|
+
add_payment_source(xml, payment, options, :credit)
|
171
|
+
xml.refTransId(transaction_id_from(options[:transaction_id])) if options[:transaction_id]
|
172
|
+
add_invoice(xml, 'refundTransaction', options)
|
161
173
|
add_customer_data(xml, payment, options)
|
162
|
-
add_line_items(xml, options)
|
163
174
|
add_settings(xml, payment, options)
|
164
175
|
add_user_fields(xml, amount, options)
|
165
176
|
end
|
@@ -181,6 +192,12 @@ module ActiveMerchant
|
|
181
192
|
end
|
182
193
|
end
|
183
194
|
|
195
|
+
def unstore(authorization)
|
196
|
+
customer_profile_id, _, _ = split_authorization(authorization)
|
197
|
+
|
198
|
+
delete_customer_profile(customer_profile_id)
|
199
|
+
end
|
200
|
+
|
184
201
|
def verify_credentials
|
185
202
|
response = commit(:verify_credentials) { }
|
186
203
|
response.success?
|
@@ -229,11 +246,15 @@ module ActiveMerchant
|
|
229
246
|
xml.transactionRequest do
|
230
247
|
xml.transactionType(transaction_type)
|
231
248
|
xml.amount(amount(amount))
|
232
|
-
add_payment_source(xml, payment)
|
233
|
-
add_invoice(xml, options)
|
249
|
+
add_payment_source(xml, payment, options)
|
250
|
+
add_invoice(xml, transaction_type, options)
|
251
|
+
add_tax_fields(xml, options)
|
252
|
+
add_duty_fields(xml, options)
|
253
|
+
add_shipping_fields(xml, options)
|
254
|
+
add_tax_exempt_status(xml, options)
|
255
|
+
add_po_number(xml, options)
|
234
256
|
add_customer_data(xml, payment, options)
|
235
257
|
add_market_type_device_type(xml, payment, options)
|
236
|
-
add_line_items(xml, options)
|
237
258
|
add_settings(xml, payment, options)
|
238
259
|
add_user_fields(xml, amount, options)
|
239
260
|
end
|
@@ -244,8 +265,12 @@ module ActiveMerchant
|
|
244
265
|
xml.transaction do
|
245
266
|
xml.send(transaction_type) do
|
246
267
|
xml.amount(amount(amount))
|
247
|
-
|
248
|
-
|
268
|
+
add_tax_fields(xml, options)
|
269
|
+
add_shipping_fields(xml, options)
|
270
|
+
add_duty_fields(xml, options)
|
271
|
+
add_payment_source(xml, payment, options)
|
272
|
+
add_invoice(xml, transaction_type, options)
|
273
|
+
add_tax_exempt_status(xml, options)
|
249
274
|
end
|
250
275
|
end
|
251
276
|
end
|
@@ -256,6 +281,9 @@ module ActiveMerchant
|
|
256
281
|
xml.transaction do
|
257
282
|
xml.profileTransPriorAuthCapture do
|
258
283
|
xml.amount(amount(amount))
|
284
|
+
add_tax_fields(xml, options)
|
285
|
+
add_shipping_fields(xml, options)
|
286
|
+
add_duty_fields(xml, options)
|
259
287
|
xml.transId(transaction_id_from(authorization))
|
260
288
|
end
|
261
289
|
end
|
@@ -268,8 +296,13 @@ module ActiveMerchant
|
|
268
296
|
xml.transactionRequest do
|
269
297
|
xml.transactionType('priorAuthCaptureTransaction')
|
270
298
|
xml.amount(amount(amount))
|
299
|
+
add_tax_fields(xml, options)
|
300
|
+
add_duty_fields(xml, options)
|
301
|
+
add_shipping_fields(xml, options)
|
302
|
+
add_tax_exempt_status(xml, options)
|
303
|
+
add_po_number(xml, options)
|
271
304
|
xml.refTransId(transaction_id_from(authorization))
|
272
|
-
add_invoice(xml, options)
|
305
|
+
add_invoice(xml, "capture", options)
|
273
306
|
add_user_fields(xml, amount, options)
|
274
307
|
end
|
275
308
|
end
|
@@ -283,8 +316,11 @@ module ActiveMerchant
|
|
283
316
|
xml.transaction do
|
284
317
|
xml.profileTransRefund do
|
285
318
|
xml.amount(amount(amount))
|
319
|
+
add_tax_fields(xml, options)
|
320
|
+
add_shipping_fields(xml, options)
|
321
|
+
add_duty_fields(xml, options)
|
286
322
|
xml.creditCardNumberMasked(card_number)
|
287
|
-
add_invoice(xml, options)
|
323
|
+
add_invoice(xml, "profileTransRefund", options)
|
288
324
|
xml.transId(transaction_id)
|
289
325
|
end
|
290
326
|
end
|
@@ -306,7 +342,12 @@ module ActiveMerchant
|
|
306
342
|
end
|
307
343
|
xml.refTransId(transaction_id)
|
308
344
|
|
309
|
-
add_invoice(xml, options)
|
345
|
+
add_invoice(xml, 'refundTransaction', options)
|
346
|
+
add_tax_fields(xml, options)
|
347
|
+
add_duty_fields(xml, options)
|
348
|
+
add_shipping_fields(xml, options)
|
349
|
+
add_tax_exempt_status(xml, options)
|
350
|
+
add_po_number(xml, options)
|
310
351
|
add_customer_data(xml, nil, options)
|
311
352
|
add_user_fields(xml, amount, options)
|
312
353
|
end
|
@@ -334,29 +375,16 @@ module ActiveMerchant
|
|
334
375
|
end
|
335
376
|
end
|
336
377
|
|
337
|
-
def add_payment_source(xml, source)
|
378
|
+
def add_payment_source(xml, source, options, action = nil)
|
338
379
|
return unless source
|
339
380
|
if source.is_a?(String)
|
340
|
-
add_token_payment_method(xml, source)
|
381
|
+
add_token_payment_method(xml, source, options)
|
341
382
|
elsif card_brand(source) == 'check'
|
342
383
|
add_check(xml, source)
|
343
384
|
elsif card_brand(source) == 'apple_pay'
|
344
385
|
add_apple_pay_payment_token(xml, source)
|
345
386
|
else
|
346
|
-
add_credit_card(xml, source)
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
def add_line_items(xml, options)
|
351
|
-
return unless options[:line_items]
|
352
|
-
xml.lineItems do
|
353
|
-
options[:line_items].each do |line_item|
|
354
|
-
xml.lineItem do
|
355
|
-
line_item.each do |key, value|
|
356
|
-
xml.send(camel_case_lower(key), value)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|
387
|
+
add_credit_card(xml, source, action)
|
360
388
|
end
|
361
389
|
end
|
362
390
|
|
@@ -384,10 +412,10 @@ module ActiveMerchant
|
|
384
412
|
ActiveMerchant.deprecated "Using the duplicate_window class_attribute is deprecated. Use the transaction options hash instead."
|
385
413
|
set_duplicate_window(xml, self.class.duplicate_window)
|
386
414
|
end
|
387
|
-
if options
|
415
|
+
if options.key?(:email_customer)
|
388
416
|
xml.setting do
|
389
417
|
xml.settingName("emailCustomer")
|
390
|
-
xml.settingValue("true")
|
418
|
+
xml.settingValue(options[:email_customer] ? "true" : "false")
|
391
419
|
end
|
392
420
|
end
|
393
421
|
if options[:header_email_receipt]
|
@@ -396,6 +424,12 @@ module ActiveMerchant
|
|
396
424
|
xml.settingValue(options[:header_email_receipt])
|
397
425
|
end
|
398
426
|
end
|
427
|
+
if options[:test_request]
|
428
|
+
xml.setting do
|
429
|
+
xml.settingName("testRequest")
|
430
|
+
xml.settingValue("1")
|
431
|
+
end
|
432
|
+
end
|
399
433
|
end
|
400
434
|
end
|
401
435
|
|
@@ -423,7 +457,7 @@ module ActiveMerchant
|
|
423
457
|
end
|
424
458
|
end
|
425
459
|
|
426
|
-
def add_credit_card(xml, credit_card)
|
460
|
+
def add_credit_card(xml, credit_card, action)
|
427
461
|
if credit_card.track_data
|
428
462
|
add_swipe_data(xml, credit_card)
|
429
463
|
else
|
@@ -434,7 +468,7 @@ module ActiveMerchant
|
|
434
468
|
if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand)
|
435
469
|
xml.cardCode(credit_card.verification_value)
|
436
470
|
end
|
437
|
-
if credit_card.is_a?(NetworkTokenizationCreditCard)
|
471
|
+
if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit
|
438
472
|
xml.cryptogram(credit_card.payment_cryptogram)
|
439
473
|
end
|
440
474
|
end
|
@@ -455,8 +489,10 @@ module ActiveMerchant
|
|
455
489
|
end
|
456
490
|
end
|
457
491
|
|
458
|
-
def add_token_payment_method(xml, token)
|
492
|
+
def add_token_payment_method(xml, token, options)
|
459
493
|
customer_profile_id, customer_payment_profile_id, _ = split_authorization(token)
|
494
|
+
customer_profile_id = options[:customer_profile_id] if options[:customer_profile_id]
|
495
|
+
customer_payment_profile_id = options[:customer_payment_profile_id] if options[:customer_payment_profile_id]
|
460
496
|
xml.customerProfileId(customer_profile_id)
|
461
497
|
xml.customerPaymentProfileId(customer_payment_profile_id)
|
462
498
|
end
|
@@ -508,7 +544,7 @@ module ActiveMerchant
|
|
508
544
|
|
509
545
|
def add_customer_data(xml, payment_source, options)
|
510
546
|
xml.customer do
|
511
|
-
xml.id(options[:customer]) unless empty?(options[:customer]) || options[:customer] !~ /^\
|
547
|
+
xml.id(options[:customer]) unless empty?(options[:customer]) || options[:customer] !~ /^\w+$/
|
512
548
|
xml.email(options[:email]) unless empty?(options[:email])
|
513
549
|
end
|
514
550
|
|
@@ -518,8 +554,11 @@ module ActiveMerchant
|
|
518
554
|
xml.customerIP(options[:ip]) unless empty?(options[:ip])
|
519
555
|
|
520
556
|
xml.cardholderAuthentication do
|
521
|
-
|
522
|
-
xml.
|
557
|
+
three_d_secure = options.fetch(:three_d_secure, {})
|
558
|
+
xml.authenticationIndicator(
|
559
|
+
options[:authentication_indicator] || three_d_secure[:eci])
|
560
|
+
xml.cardholderAuthenticationValue(
|
561
|
+
options[:cardholder_authentication_value] || three_d_secure[:cavv])
|
523
562
|
end
|
524
563
|
end
|
525
564
|
|
@@ -528,13 +567,15 @@ module ActiveMerchant
|
|
528
567
|
|
529
568
|
xml.billTo do
|
530
569
|
first_name, last_name = names_from(payment_source, address, options)
|
570
|
+
state = state_from(address, options)
|
571
|
+
full_address = "#{address[:address1]} #{address[:address2]}".strip
|
572
|
+
|
531
573
|
xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
|
532
574
|
xml.lastName(truncate(last_name, 50)) unless empty?(last_name)
|
533
|
-
|
534
575
|
xml.company(truncate(address[:company], 50)) unless empty?(address[:company])
|
535
|
-
xml.address(truncate(
|
576
|
+
xml.address(truncate(full_address, 60))
|
536
577
|
xml.city(truncate(address[:city], 40))
|
537
|
-
xml.state(
|
578
|
+
xml.state(truncate(state, 40))
|
538
579
|
xml.zip(truncate((address[:zip] || options[:zip]), 20))
|
539
580
|
xml.country(truncate(address[:country], 60))
|
540
581
|
xml.phoneNumber(truncate(address[:phone], 25)) unless empty?(address[:phone])
|
@@ -552,12 +593,12 @@ module ActiveMerchant
|
|
552
593
|
else
|
553
594
|
[address[:first_name], address[:last_name]]
|
554
595
|
end
|
596
|
+
full_address = "#{address[:address1]} #{address[:address2]}".strip
|
555
597
|
|
556
598
|
xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
|
557
599
|
xml.lastName(truncate(last_name, 50)) unless empty?(last_name)
|
558
|
-
|
559
600
|
xml.company(truncate(address[:company], 50)) unless empty?(address[:company])
|
560
|
-
xml.address(truncate(
|
601
|
+
xml.address(truncate(full_address, 60))
|
561
602
|
xml.city(truncate(address[:city], 40))
|
562
603
|
xml.state(truncate(address[:state], 40))
|
563
604
|
xml.zip(truncate(address[:zip], 20))
|
@@ -570,13 +611,68 @@ module ActiveMerchant
|
|
570
611
|
xml.refId(truncate(options[:order_id], 20))
|
571
612
|
end
|
572
613
|
|
573
|
-
def add_invoice(xml, options)
|
614
|
+
def add_invoice(xml, transaction_type, options)
|
574
615
|
xml.order do
|
575
616
|
xml.invoiceNumber(truncate(options[:order_id], 20))
|
576
617
|
xml.description(truncate(options[:description], 255))
|
618
|
+
xml.purchaseOrderNumber(options[:po_number]) if options[:po_number] && transaction_type.start_with?("profileTrans")
|
619
|
+
end
|
620
|
+
|
621
|
+
# Authorize.net API requires lineItems to be placed directly after order tag
|
622
|
+
if options[:line_items]
|
623
|
+
xml.lineItems do
|
624
|
+
options[:line_items].each do |line_item|
|
625
|
+
xml.lineItem do
|
626
|
+
line_item.each do |key, value|
|
627
|
+
xml.send(camel_case_lower(key), value)
|
628
|
+
end
|
629
|
+
end
|
630
|
+
end
|
631
|
+
end
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
def add_tax_fields(xml, options)
|
636
|
+
tax = options[:tax]
|
637
|
+
if tax.is_a?(Hash)
|
638
|
+
xml.tax do
|
639
|
+
xml.amount(amount(tax[:amount].to_i))
|
640
|
+
xml.name(tax[:name])
|
641
|
+
xml.description(tax[:description])
|
642
|
+
end
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
def add_duty_fields(xml, options)
|
647
|
+
duty = options[:duty]
|
648
|
+
if duty.is_a?(Hash)
|
649
|
+
xml.duty do
|
650
|
+
xml.amount(amount(duty[:amount].to_i))
|
651
|
+
xml.name(duty[:name])
|
652
|
+
xml.description(duty[:description])
|
653
|
+
end
|
577
654
|
end
|
578
655
|
end
|
579
656
|
|
657
|
+
def add_shipping_fields(xml, options)
|
658
|
+
shipping = options[:shipping]
|
659
|
+
if shipping.is_a?(Hash)
|
660
|
+
xml.shipping do
|
661
|
+
xml.amount(amount(shipping[:amount].to_i))
|
662
|
+
xml.name(shipping[:name])
|
663
|
+
xml.description(shipping[:description])
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
def add_tax_exempt_status(xml, options)
|
669
|
+
xml.taxExempt(options[:tax_exempt]) if options[:tax_exempt]
|
670
|
+
end
|
671
|
+
|
672
|
+
def add_po_number(xml, options)
|
673
|
+
xml.poNumber(options[:po_number]) if options[:po_number]
|
674
|
+
end
|
675
|
+
|
580
676
|
def create_customer_payment_profile(credit_card, options)
|
581
677
|
commit(:cim_store_update) do |xml|
|
582
678
|
xml.customerProfileId options[:customer_profile_id]
|
@@ -616,6 +712,12 @@ module ActiveMerchant
|
|
616
712
|
end
|
617
713
|
end
|
618
714
|
|
715
|
+
def delete_customer_profile(customer_profile_id)
|
716
|
+
commit(:cim_store_delete_customer) do |xml|
|
717
|
+
xml.customerProfileId(customer_profile_id)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
619
721
|
def names_from(payment_source, address, options)
|
620
722
|
if payment_source && !payment_source.is_a?(PaymentToken) && !payment_source.is_a?(String)
|
621
723
|
first_name, last_name = split_names(address[:name])
|
@@ -625,6 +727,14 @@ module ActiveMerchant
|
|
625
727
|
end
|
626
728
|
end
|
627
729
|
|
730
|
+
def state_from(address, options)
|
731
|
+
if ["US", "CA"].include?(address[:country])
|
732
|
+
address[:state] || 'NC'
|
733
|
+
else
|
734
|
+
address[:state] || 'n/a'
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
628
738
|
def headers
|
629
739
|
{ 'Content-Type' => 'text/xml' }
|
630
740
|
end
|
@@ -683,6 +793,8 @@ module ActiveMerchant
|
|
683
793
|
"createCustomerProfileRequest"
|
684
794
|
elsif action == :cim_store_update
|
685
795
|
"createCustomerPaymentProfileRequest"
|
796
|
+
elsif action == :cim_store_delete_customer
|
797
|
+
"deleteCustomerProfileRequest"
|
686
798
|
elsif action == :verify_credentials
|
687
799
|
"authenticateTestRequest"
|
688
800
|
elsif is_cim_action?(action)
|
@@ -798,7 +910,7 @@ module ActiveMerchant
|
|
798
910
|
if cim?(action) || (action == :verify_credentials)
|
799
911
|
response[:result_code] == "Ok"
|
800
912
|
else
|
801
|
-
response[:response_code]
|
913
|
+
[APPROVED, FRAUD_REVIEW].include?(response[:response_code]) && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
|
802
914
|
end
|
803
915
|
end
|
804
916
|
|
@@ -827,7 +939,7 @@ module ActiveMerchant
|
|
827
939
|
end
|
828
940
|
|
829
941
|
def cim?(action)
|
830
|
-
(action == :cim_store) || (action == :cim_store_update)
|
942
|
+
(action == :cim_store) || (action == :cim_store_update) || (action == :cim_store_delete_customer)
|
831
943
|
end
|
832
944
|
|
833
945
|
def transaction_id_from(authorization)
|
@@ -858,7 +858,9 @@ module ActiveMerchant #:nodoc:
|
|
858
858
|
|
859
859
|
response_params = parse(action, xml)
|
860
860
|
|
861
|
-
|
861
|
+
message_element= response_params["messages"]["message"]
|
862
|
+
first_error = message_element.is_a?(Array) ? message_element.first : message_element
|
863
|
+
message = first_error['text']
|
862
864
|
test_mode = @options[:test_requests] || message =~ /Test Mode/
|
863
865
|
success = response_params['messages']['result_code'] == 'Ok'
|
864
866
|
response_params['direct_response'] = parse_direct_response(response_params['direct_response']) if response_params['direct_response']
|
@@ -867,7 +869,7 @@ module ActiveMerchant #:nodoc:
|
|
867
869
|
response_options = {}
|
868
870
|
response_options[:test] = test_mode
|
869
871
|
response_options[:authorization] = transaction_id || response_params['customer_profile_id'] || (response_params['profile'] ? response_params['profile']['customer_profile_id'] : nil)
|
870
|
-
response_options[:error_code] =
|
872
|
+
response_options[:error_code] = first_error['code'] unless success
|
871
873
|
|
872
874
|
Response.new(success, message, response_params, response_options)
|
873
875
|
end
|
@@ -4,8 +4,9 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.test_url = 'https://pal-test.barclaycardsmartpay.com/pal/servlet'
|
5
5
|
self.live_url = 'https://pal-live.barclaycardsmartpay.com/pal/servlet'
|
6
6
|
|
7
|
-
self.supported_countries = ['AL', 'AD', 'AM', 'AT', 'AZ', 'BY', 'BE', 'BA', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', '
|
7
|
+
self.supported_countries = ['AL', 'AD', 'AM', 'AT', 'AZ', 'BY', 'BE', 'BA', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IS', 'IE', 'IT', 'KZ', 'LV', 'LI', 'LT', 'LU', 'MK', 'MT', 'MD', 'MC', 'ME', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'SM', 'RS', 'SK', 'SI', 'ES', 'SE', 'CH', 'TR', 'UA', 'GB', 'VA']
|
8
8
|
self.default_currency = 'EUR'
|
9
|
+
self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND)
|
9
10
|
self.money_format = :cents
|
10
11
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro]
|
11
12
|
|
@@ -32,15 +33,9 @@ module ActiveMerchant #:nodoc:
|
|
32
33
|
post = payment_request(money, options)
|
33
34
|
post[:amount] = amount_hash(money, options[:currency])
|
34
35
|
post[:card] = credit_card_hash(creditcard)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
if options[:shipping_address]
|
41
|
-
post[:deliveryAddress] = address_hash(options[:shipping_address])
|
42
|
-
end
|
43
|
-
|
36
|
+
post[:billingAddress] = billing_address_hash(options) if options[:billing_address]
|
37
|
+
post[:deliveryAddress] = shipping_address_hash(options) if options[:shipping_address]
|
38
|
+
add_3ds(post, options) if options[:execute_threed]
|
44
39
|
commit('authorise', post)
|
45
40
|
end
|
46
41
|
|
@@ -66,6 +61,10 @@ module ActiveMerchant #:nodoc:
|
|
66
61
|
post = payment_request(money, options)
|
67
62
|
post[:amount] = amount_hash(money, options[:currency])
|
68
63
|
post[:card] = credit_card_hash(creditcard)
|
64
|
+
post[:dateOfBirth] = options[:date_of_birth] if options[:date_of_birth]
|
65
|
+
post[:entityType] = options[:entity_type] if options[:entity_type]
|
66
|
+
post[:nationality] = options[:nationality] if options[:nationality]
|
67
|
+
post[:shopperName] = options[:shopper_name] if options[:shopper_name]
|
69
68
|
|
70
69
|
commit('refundWithData', post)
|
71
70
|
end
|
@@ -138,7 +137,7 @@ module ActiveMerchant #:nodoc:
|
|
138
137
|
response,
|
139
138
|
test: test?,
|
140
139
|
avs_result: AVSResult.new(:code => parse_avs_code(response)),
|
141
|
-
authorization: response['recurringDetailReference'] || response
|
140
|
+
authorization: response['recurringDetailReference'] || authorization_from(post, response)
|
142
141
|
)
|
143
142
|
|
144
143
|
rescue ResponseError => e
|
@@ -157,6 +156,13 @@ module ActiveMerchant #:nodoc:
|
|
157
156
|
raise
|
158
157
|
end
|
159
158
|
|
159
|
+
def authorization_from(parameters, response)
|
160
|
+
authorization = [parameters[:originalReference], response['pspReference']].compact
|
161
|
+
|
162
|
+
return nil if authorization.empty?
|
163
|
+
return authorization.join("#")
|
164
|
+
end
|
165
|
+
|
160
166
|
def parse_avs_code(response)
|
161
167
|
AVS_MAPPING[response["avsResult"][0..1].strip] if response["avsResult"]
|
162
168
|
end
|
@@ -206,8 +212,8 @@ module ActiveMerchant #:nodoc:
|
|
206
212
|
end
|
207
213
|
|
208
214
|
def success_from(response)
|
209
|
-
return true if response.has_key?('authCode')
|
210
215
|
return true if response['result'] == 'Success'
|
216
|
+
return true if response['resultCode'] == 'Authorised'
|
211
217
|
return true if response['resultCode'] == 'Received'
|
212
218
|
successful_responses = %w([capture-received] [cancel-received] [refund-received])
|
213
219
|
successful_responses.include?(response['response'])
|
@@ -217,30 +223,57 @@ module ActiveMerchant #:nodoc:
|
|
217
223
|
case action
|
218
224
|
when 'store'
|
219
225
|
"#{test? ? self.test_url : self.live_url}/Recurring/v12/storeToken"
|
226
|
+
when 'finalize3ds'
|
227
|
+
"#{test? ? self.test_url : self.live_url}/Payment/v12/authorise3d"
|
220
228
|
else
|
221
229
|
"#{test? ? self.test_url : self.live_url}/Payment/v12/#{action}"
|
222
230
|
end
|
223
231
|
end
|
224
232
|
|
225
|
-
def
|
226
|
-
|
227
|
-
street =
|
228
|
-
house =
|
233
|
+
def billing_address_hash(options)
|
234
|
+
address = options[:address] || options[:billing_address] if options[:address] || options[:billing_address]
|
235
|
+
street = options[:street] || parse_street(address)
|
236
|
+
house = options[:house_number] || parse_house_number(address)
|
237
|
+
|
238
|
+
create_address_hash(address, house, street)
|
239
|
+
end
|
240
|
+
|
241
|
+
def shipping_address_hash(options)
|
242
|
+
address = options[:shipping_address]
|
243
|
+
street = options[:shipping_street] || parse_street(address)
|
244
|
+
house = options[:shipping_house_number] || parse_house_number(address)
|
229
245
|
|
246
|
+
create_address_hash(address, house, street)
|
247
|
+
end
|
248
|
+
|
249
|
+
def parse_street(address)
|
250
|
+
address_to_parse = "#{address[:address1]} #{address[:address2]}"
|
251
|
+
street = address[:street] || address_to_parse.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
|
252
|
+
street.empty? ? "Not Provided" : street
|
253
|
+
end
|
254
|
+
|
255
|
+
def parse_house_number(address)
|
256
|
+
address_to_parse = "#{address[:address1]} #{address[:address2]}"
|
257
|
+
house = address[:houseNumberOrName] || address_to_parse.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ')
|
258
|
+
house.empty? ? "Not Provided" : house
|
259
|
+
end
|
260
|
+
|
261
|
+
def create_address_hash(address, house, street)
|
230
262
|
hash = {}
|
263
|
+
hash[:houseNumberOrName] = house
|
264
|
+
hash[:street] = street
|
231
265
|
hash[:city] = address[:city] if address[:city]
|
232
|
-
hash[:street] = street || full_address.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
|
233
|
-
hash[:houseNumberOrName] = house || full_address.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ')
|
234
|
-
hash[:postalCode] = address[:zip] if address[:zip]
|
235
266
|
hash[:stateOrProvince] = address[:state] if address[:state]
|
267
|
+
hash[:postalCode] = address[:zip] if address[:zip]
|
236
268
|
hash[:country] = address[:country] if address[:country]
|
237
269
|
hash
|
238
270
|
end
|
239
271
|
|
240
272
|
def amount_hash(money, currency)
|
273
|
+
currency = currency || currency(money)
|
241
274
|
hash = {}
|
242
|
-
hash[:currency] = currency
|
243
|
-
hash[:value] =
|
275
|
+
hash[:currency] = currency
|
276
|
+
hash[:value] = localized_amount(money, currency) if money
|
244
277
|
hash
|
245
278
|
end
|
246
279
|
|
@@ -257,10 +290,14 @@ module ActiveMerchant #:nodoc:
|
|
257
290
|
def modification_request(reference, options)
|
258
291
|
hash = {}
|
259
292
|
hash[:merchantAccount] = @options[:merchant]
|
260
|
-
hash[:originalReference] = reference
|
293
|
+
hash[:originalReference] = psp_reference_from(reference)
|
261
294
|
hash.keep_if { |_, v| v }
|
262
295
|
end
|
263
296
|
|
297
|
+
def psp_reference_from(authorization)
|
298
|
+
authorization.nil? ? nil : authorization.split("#").first
|
299
|
+
end
|
300
|
+
|
264
301
|
def payment_request(money, options)
|
265
302
|
hash = {}
|
266
303
|
hash[:merchantAccount] = @options[:merchant]
|
@@ -268,6 +305,7 @@ module ActiveMerchant #:nodoc:
|
|
268
305
|
hash[:shopperEmail] = options[:email] if options[:email]
|
269
306
|
hash[:shopperIP] = options[:ip] if options[:ip]
|
270
307
|
hash[:shopperReference] = options[:customer] if options[:customer]
|
308
|
+
hash[:shopperInteraction] = options[:shopper_interaction] if options[:shopper_interaction]
|
271
309
|
hash.keep_if { |_, v| v }
|
272
310
|
end
|
273
311
|
|
@@ -278,6 +316,11 @@ module ActiveMerchant #:nodoc:
|
|
278
316
|
hash[:shopperReference] = options[:customer] if options[:customer]
|
279
317
|
hash.keep_if { |_, v| v }
|
280
318
|
end
|
319
|
+
|
320
|
+
def add_3ds(post, options)
|
321
|
+
post[:additionalData] = { executeThreeD: 'true' }
|
322
|
+
post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] }
|
323
|
+
end
|
281
324
|
end
|
282
325
|
end
|
283
326
|
end
|