activemerchant 1.45.0 → 1.46.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
- checksums.yaml.gz.sig +3 -1
- data.tar.gz.sig +0 -0
- data/CHANGELOG +25 -0
- data/CONTRIBUTORS +9 -0
- data/README.md +6 -20
- data/lib/active_merchant.rb +9 -50
- data/lib/active_merchant/billing.rb +1 -0
- data/lib/active_merchant/billing/gateway.rb +10 -1
- data/lib/active_merchant/billing/gateways.rb +6 -11
- data/lib/active_merchant/billing/gateways/authorize_net.rb +58 -47
- data/lib/active_merchant/billing/gateways/beanstream.rb +1 -1
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +8 -8
- data/lib/active_merchant/billing/gateways/braintree.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +69 -22
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +2 -2
- data/lib/active_merchant/billing/gateways/checkout.rb +7 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +25 -9
- data/lib/active_merchant/billing/gateways/elavon.rb +1 -1
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +6 -3
- data/lib/active_merchant/billing/gateways/finansbank.rb +1 -1
- data/lib/active_merchant/billing/gateways/hps.rb +0 -1
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +1 -1
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +0 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +1 -1
- data/lib/active_merchant/billing/gateways/instapay.rb +0 -0
- data/lib/active_merchant/billing/gateways/ipp.rb +175 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +4 -11
- data/lib/active_merchant/billing/gateways/migs.rb +1 -1
- data/lib/active_merchant/billing/gateways/modern_payments.rb +1 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +2 -2
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +26 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +3 -3
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +16 -5
- data/lib/active_merchant/billing/gateways/payflow_express.rb +3 -3
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +2 -2
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +4 -4
- data/lib/active_merchant/billing/gateways/paypal.rb +15 -3
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +10 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +3 -3
- data/lib/active_merchant/billing/gateways/paypal_express.rb +4 -4
- data/lib/active_merchant/billing/gateways/pin.rb +10 -1
- data/lib/active_merchant/billing/gateways/quickbooks.rb +278 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +2 -2
- data/lib/active_merchant/billing/gateways/sage.rb +3 -3
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +1 -1
- data/lib/active_merchant/billing/gateways/secure_pay.rb +1 -1
- data/lib/active_merchant/billing/gateways/skip_jack.rb +0 -1
- data/lib/active_merchant/billing/gateways/stripe.rb +13 -2
- data/lib/active_merchant/billing/gateways/wirecard.rb +0 -1
- data/lib/active_merchant/billing/payment_token.rb +1 -1
- data/lib/active_merchant/connection.rb +169 -0
- data/lib/active_merchant/network_connection_retries.rb +78 -0
- data/lib/active_merchant/post_data.rb +24 -0
- data/lib/active_merchant/posts_data.rb +78 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/certs/cacert.pem +3866 -0
- metadata +22 -44
- metadata.gz.sig +0 -0
- data/lib/active_merchant/offsite_payments_shim.rb +0 -19
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'active_merchant/billing/gateways/beanstream/beanstream_core'
|
2
2
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
4
4
|
module Billing #:nodoc:
|
@@ -7,21 +7,21 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
params['pageContents']
|
8
8
|
end
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
class BeanstreamInteracGateway < Gateway
|
12
12
|
include BeanstreamCore
|
13
13
|
|
14
14
|
# Confirm a transaction posted back from the bank to Beanstream.
|
15
15
|
# Confirming a transaction does not require any credentials,
|
16
16
|
# and in an application with many merchants sharing a funded
|
17
|
-
# URL the application may not yet know which merchant the
|
17
|
+
# URL the application may not yet know which merchant the
|
18
18
|
# post back is for until the response of the confirmation is
|
19
19
|
# received, which contains the order number.
|
20
20
|
def self.confirm(transaction)
|
21
21
|
gateway = new(:login => '')
|
22
22
|
gateway.confirm(transaction)
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def purchase(money, options = {})
|
26
26
|
post = {}
|
27
27
|
add_amount(post, money)
|
@@ -31,20 +31,20 @@ module ActiveMerchant #:nodoc:
|
|
31
31
|
add_transaction_type(post, :purchase)
|
32
32
|
commit(post)
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
# Confirm a transaction posted back from the bank to Beanstream.
|
36
36
|
def confirm(transaction)
|
37
37
|
post(transaction)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
private
|
41
|
-
|
41
|
+
|
42
42
|
def add_interac_details(post, options)
|
43
43
|
address = options[:billing_address] || options[:address] || {}
|
44
44
|
post[:trnCardOwner] = address[:name]
|
45
45
|
post[:paymentMethod] = 'IO'
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def build_response(*args)
|
49
49
|
BeanstreamInteracResponse.new(*args)
|
50
50
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require 'active_merchant/billing/gateways/braintree/braintree_common'
|
2
2
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
4
4
|
module Billing #:nodoc:
|
5
5
|
class BraintreeGateway < Gateway
|
6
6
|
include BraintreeCommon
|
7
|
-
|
7
|
+
|
8
8
|
self.abstract_class = true
|
9
9
|
|
10
10
|
def self.new(options={})
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'active_merchant/billing/gateways/braintree/braintree_common'
|
2
2
|
|
3
3
|
begin
|
4
4
|
require "braintree"
|
@@ -310,17 +310,15 @@ module ActiveMerchant #:nodoc:
|
|
310
310
|
|
311
311
|
def response_from_result(result)
|
312
312
|
Response.new(result.success?, message_from_result(result),
|
313
|
-
{ braintree_transaction:
|
313
|
+
{ braintree_transaction: transaction_hash(result) },
|
314
314
|
{ authorization: (result.transaction.id if result.success?) }
|
315
315
|
)
|
316
316
|
end
|
317
317
|
|
318
318
|
def response_params(result)
|
319
319
|
params = {}
|
320
|
-
if result.success?
|
321
|
-
|
322
|
-
params[:customer_vault_id] = result.transaction.customer_details.id
|
323
|
-
end
|
320
|
+
params[:customer_vault_id] = result.transaction.customer_details.id if result.success?
|
321
|
+
params[:braintree_transaction] = transaction_hash(result)
|
324
322
|
params
|
325
323
|
end
|
326
324
|
|
@@ -330,16 +328,50 @@ module ActiveMerchant #:nodoc:
|
|
330
328
|
options[:authorization] = result.transaction.id
|
331
329
|
end
|
332
330
|
if result.transaction
|
333
|
-
options[:avs_result] = {
|
334
|
-
:code => nil, :message => nil,
|
335
|
-
:street_match => result.transaction.avs_street_address_response_code,
|
336
|
-
:postal_match => result.transaction.avs_postal_code_response_code
|
337
|
-
}
|
331
|
+
options[:avs_result] = { code: avs_code_from(result.transaction) }
|
338
332
|
options[:cvv_result] = result.transaction.cvv_response_code
|
339
333
|
end
|
340
334
|
options
|
341
335
|
end
|
342
336
|
|
337
|
+
def avs_code_from(transaction)
|
338
|
+
avs_mapping["street: #{transaction.avs_street_address_response_code}, zip: #{transaction.avs_postal_code_response_code}"]
|
339
|
+
end
|
340
|
+
|
341
|
+
def avs_mapping
|
342
|
+
{
|
343
|
+
"street: M, zip: M" => "M",
|
344
|
+
"street: M, zip: N" => "A",
|
345
|
+
"street: M, zip: U" => "B",
|
346
|
+
"street: M, zip: I" => "B",
|
347
|
+
"street: M, zip: A" => "B",
|
348
|
+
|
349
|
+
"street: N, zip: M" => "Z",
|
350
|
+
"street: N, zip: N" => "C",
|
351
|
+
"street: N, zip: U" => "C",
|
352
|
+
"street: N, zip: I" => "C",
|
353
|
+
"street: N, zip: A" => "C",
|
354
|
+
|
355
|
+
"street: U, zip: M" => "P",
|
356
|
+
"street: U, zip: N" => "N",
|
357
|
+
"street: U, zip: U" => "I",
|
358
|
+
"street: U, zip: I" => "I",
|
359
|
+
"street: U, zip: A" => "I",
|
360
|
+
|
361
|
+
"street: I, zip: M" => "P",
|
362
|
+
"street: I, zip: N" => "C",
|
363
|
+
"street: I, zip: U" => "I",
|
364
|
+
"street: I, zip: I" => "I",
|
365
|
+
"street: I, zip: A" => "I",
|
366
|
+
|
367
|
+
"street: A, zip: M" => "P",
|
368
|
+
"street: A, zip: N" => "C",
|
369
|
+
"street: A, zip: U" => "I",
|
370
|
+
"street: A, zip: I" => "I",
|
371
|
+
"street: A, zip: A" => "I"
|
372
|
+
}
|
373
|
+
end
|
374
|
+
|
343
375
|
def message_from_transaction_result(result)
|
344
376
|
if result.transaction && result.transaction.status == "gateway_rejected"
|
345
377
|
"Transaction declined - gateway rejected"
|
@@ -350,6 +382,16 @@ module ActiveMerchant #:nodoc:
|
|
350
382
|
end
|
351
383
|
end
|
352
384
|
|
385
|
+
def response_code_from_result(result)
|
386
|
+
if result.transaction
|
387
|
+
result.transaction.processor_response_code
|
388
|
+
elsif result.errors.size == 0 && result.credit_card_verification
|
389
|
+
result.credit_card_verification.processor_response_code
|
390
|
+
elsif result.errors.size > 0
|
391
|
+
result.errors.first.code
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
353
395
|
def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
|
354
396
|
transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
|
355
397
|
commit do
|
@@ -389,8 +431,7 @@ module ActiveMerchant #:nodoc:
|
|
389
431
|
"token" => cc.token,
|
390
432
|
"last_4" => cc.last_4,
|
391
433
|
"card_type" => cc.card_type,
|
392
|
-
"masked_number" => cc.masked_number
|
393
|
-
"token" => cc.token
|
434
|
+
"masked_number" => cc.masked_number
|
394
435
|
}
|
395
436
|
end
|
396
437
|
end
|
@@ -398,7 +439,12 @@ module ActiveMerchant #:nodoc:
|
|
398
439
|
hash
|
399
440
|
end
|
400
441
|
|
401
|
-
def transaction_hash(
|
442
|
+
def transaction_hash(result)
|
443
|
+
unless result.success?
|
444
|
+
return { "processor_response_code" => response_code_from_result(result) }
|
445
|
+
end
|
446
|
+
|
447
|
+
transaction = result.transaction
|
402
448
|
if transaction.vault_customer
|
403
449
|
vault_customer = {
|
404
450
|
}
|
@@ -444,14 +490,15 @@ module ActiveMerchant #:nodoc:
|
|
444
490
|
}
|
445
491
|
|
446
492
|
{
|
447
|
-
"order_id"
|
448
|
-
"status"
|
449
|
-
"credit_card_details"
|
450
|
-
"customer_details"
|
451
|
-
"billing_details"
|
452
|
-
"shipping_details"
|
453
|
-
"vault_customer"
|
454
|
-
"merchant_account_id"
|
493
|
+
"order_id" => transaction.order_id,
|
494
|
+
"status" => transaction.status,
|
495
|
+
"credit_card_details" => credit_card_details,
|
496
|
+
"customer_details" => customer_details,
|
497
|
+
"billing_details" => billing_details,
|
498
|
+
"shipping_details" => shipping_details,
|
499
|
+
"vault_customer" => vault_customer,
|
500
|
+
"merchant_account_id" => transaction.merchant_account_id,
|
501
|
+
"processor_response_code" => response_code_from_result(result)
|
455
502
|
}
|
456
503
|
end
|
457
504
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'active_merchant/billing/gateways/smart_ps.rb'
|
2
|
+
require 'active_merchant/billing/gateways/braintree/braintree_common'
|
3
3
|
|
4
4
|
module ActiveMerchant #:nodoc:
|
5
5
|
module Billing #:nodoc:
|
@@ -38,6 +38,7 @@ module ActiveMerchant #:nodoc:
|
|
38
38
|
commit('purchase', amount, options) do |xml|
|
39
39
|
add_credentials(xml, options)
|
40
40
|
add_invoice(xml, amount, options)
|
41
|
+
add_track_id(xml, options[:order_id])
|
41
42
|
add_payment_method(xml, payment_method)
|
42
43
|
add_billing_info(xml, options)
|
43
44
|
add_shipping_info(xml, options)
|
@@ -52,6 +53,7 @@ module ActiveMerchant #:nodoc:
|
|
52
53
|
commit('authorize', amount, options) do |xml|
|
53
54
|
add_credentials(xml, options)
|
54
55
|
add_invoice(xml, amount, options)
|
56
|
+
add_track_id(xml, options[:order_id])
|
55
57
|
add_payment_method(xml, payment_method)
|
56
58
|
add_billing_info(xml, options)
|
57
59
|
add_shipping_info(xml, options)
|
@@ -104,7 +106,6 @@ module ActiveMerchant #:nodoc:
|
|
104
106
|
def add_invoice(xml, amount, options)
|
105
107
|
xml.bill_amount_ amount(amount)
|
106
108
|
xml.bill_currencycode_ options[:currency] || currency(amount)
|
107
|
-
xml.trackid_ options[:order_id] if options[:order_id]
|
108
109
|
end
|
109
110
|
|
110
111
|
def add_payment_method(xml, payment_method)
|
@@ -157,7 +158,11 @@ module ActiveMerchant #:nodoc:
|
|
157
158
|
def add_reference(xml, authorization)
|
158
159
|
transid, trackid, _, _, _ = split_authorization(authorization)
|
159
160
|
xml.transid transid
|
160
|
-
xml
|
161
|
+
add_track_id(xml, trackid)
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_track_id(xml, trackid)
|
165
|
+
xml.trackid(trackid) if trackid
|
161
166
|
end
|
162
167
|
|
163
168
|
def commit(action, amount=nil, options={}, &builder)
|
@@ -150,6 +150,13 @@ module ActiveMerchant #:nodoc:
|
|
150
150
|
commit(build_refund_request(money, identification, options), options)
|
151
151
|
end
|
152
152
|
|
153
|
+
def verify(payment, options = {})
|
154
|
+
MultiResponse.run(:use_first_response) do |r|
|
155
|
+
r.process { authorize(100, payment, options) }
|
156
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
153
160
|
# Adds credit to a subscription (stand alone credit).
|
154
161
|
def credit(money, reference, options = {})
|
155
162
|
requires!(options, :order_id)
|
@@ -235,7 +242,7 @@ module ActiveMerchant #:nodoc:
|
|
235
242
|
xml = Builder::XmlMarkup.new :indent => 2
|
236
243
|
add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
|
237
244
|
add_auth_service(xml)
|
238
|
-
add_business_rules_data(xml)
|
245
|
+
add_business_rules_data(xml, options)
|
239
246
|
xml.target!
|
240
247
|
end
|
241
248
|
|
@@ -246,7 +253,7 @@ module ActiveMerchant #:nodoc:
|
|
246
253
|
add_line_item_data(xml, options)
|
247
254
|
add_purchase_data(xml, 0, false, options)
|
248
255
|
add_tax_service(xml)
|
249
|
-
add_business_rules_data(xml)
|
256
|
+
add_business_rules_data(xml, options)
|
250
257
|
xml.target!
|
251
258
|
end
|
252
259
|
|
@@ -257,7 +264,7 @@ module ActiveMerchant #:nodoc:
|
|
257
264
|
xml = Builder::XmlMarkup.new :indent => 2
|
258
265
|
add_purchase_data(xml, money, true, options)
|
259
266
|
add_capture_service(xml, request_id, request_token)
|
260
|
-
add_business_rules_data(xml)
|
267
|
+
add_business_rules_data(xml, options)
|
261
268
|
xml.target!
|
262
269
|
end
|
263
270
|
|
@@ -268,7 +275,7 @@ module ActiveMerchant #:nodoc:
|
|
268
275
|
add_check_service(xml)
|
269
276
|
else
|
270
277
|
add_purchase_service(xml, options)
|
271
|
-
add_business_rules_data(xml) unless options[:pinless_debit_card]
|
278
|
+
add_business_rules_data(xml, options) unless options[:pinless_debit_card]
|
272
279
|
end
|
273
280
|
xml.target!
|
274
281
|
end
|
@@ -337,7 +344,7 @@ module ActiveMerchant #:nodoc:
|
|
337
344
|
end
|
338
345
|
end
|
339
346
|
add_subscription_create_service(xml, options)
|
340
|
-
add_business_rules_data(xml)
|
347
|
+
add_business_rules_data(xml, options)
|
341
348
|
xml.target!
|
342
349
|
end
|
343
350
|
|
@@ -349,7 +356,7 @@ module ActiveMerchant #:nodoc:
|
|
349
356
|
add_creditcard_payment_method(xml) if creditcard
|
350
357
|
add_subscription(xml, options, reference)
|
351
358
|
add_subscription_update_service(xml, options)
|
352
|
-
add_business_rules_data(xml)
|
359
|
+
add_business_rules_data(xml, options)
|
353
360
|
xml.target!
|
354
361
|
end
|
355
362
|
|
@@ -374,11 +381,20 @@ module ActiveMerchant #:nodoc:
|
|
374
381
|
xml.target!
|
375
382
|
end
|
376
383
|
|
377
|
-
def add_business_rules_data(xml)
|
384
|
+
def add_business_rules_data(xml, options)
|
385
|
+
prioritized_options = [options, @options]
|
386
|
+
|
378
387
|
xml.tag! 'businessRules' do
|
379
|
-
xml.tag!('ignoreAVSResult', 'true') if
|
380
|
-
xml.tag!('ignoreCVResult', 'true') if
|
388
|
+
xml.tag!('ignoreAVSResult', 'true') if extract_option(prioritized_options, :ignore_avs)
|
389
|
+
xml.tag!('ignoreCVResult', 'true') if extract_option(prioritized_options, :ignore_cvv)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def extract_option prioritized_options, option_name
|
394
|
+
options_matching_key = prioritized_options.detect do |options|
|
395
|
+
options.has_key? option_name
|
381
396
|
end
|
397
|
+
options_matching_key[option_name] if options_matching_key
|
382
398
|
end
|
383
399
|
|
384
400
|
def add_line_item_data(xml, options)
|
@@ -7,8 +7,8 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
self.live_url = "https://api.ewaypayments.com/"
|
8
8
|
|
9
9
|
self.money_format = :cents
|
10
|
-
self.supported_countries = ['AU', 'NZ', 'GB']
|
11
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
10
|
+
self.supported_countries = ['AU', 'NZ', 'GB', 'SG']
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
|
12
12
|
self.homepage_url = "http://www.eway.com.au/"
|
13
13
|
self.display_name = "eWAY Rapid 3.1"
|
14
14
|
self.default_currency = "AUD"
|
@@ -187,6 +187,7 @@ module ActiveMerchant #:nodoc:
|
|
187
187
|
params[key] = {
|
188
188
|
'TotalAmount' => localized_amount(money, currency_code),
|
189
189
|
'InvoiceReference' => truncate(options[:order_id]),
|
190
|
+
'InvoiceNumber' => truncate(options[:order_id], 12),
|
190
191
|
'InvoiceDescription' => truncate(options[:description], 64),
|
191
192
|
'CurrencyCode' => currency_code,
|
192
193
|
}
|
@@ -352,7 +353,7 @@ module ActiveMerchant #:nodoc:
|
|
352
353
|
'D4403' => 'No Merchant Failed',
|
353
354
|
'D4404' => 'Pick Up Card Failed',
|
354
355
|
'D4405' => 'Do Not Honour Failed',
|
355
|
-
'D4406' => 'Error
|
356
|
+
'D4406' => 'Error Failed',
|
356
357
|
'D4407' => 'Pick Up Card, Special Failed',
|
357
358
|
'D4409' => 'Request In Progress Failed',
|
358
359
|
'D4412' => 'Invalid Transaction Failed',
|
@@ -406,6 +407,8 @@ module ActiveMerchant #:nodoc:
|
|
406
407
|
'D4498' => 'PayPal Create Transaction Error Failed',
|
407
408
|
'D4499' => 'Invalid Transaction for Auth/Void Failed',
|
408
409
|
'S5000' => 'System Error',
|
410
|
+
'S5011' => 'PayPal Connection Error',
|
411
|
+
'S5012' => 'PayPal Settings Error',
|
409
412
|
'S5085' => 'Started 3dSecure',
|
410
413
|
'S5086' => 'Routed 3dSecure',
|
411
414
|
'S5087' => 'Completed 3dSecure',
|
@@ -266,7 +266,6 @@ module ActiveMerchant #:nodoc:
|
|
266
266
|
"55" => "The 4-digit pin is invalid.",
|
267
267
|
"75" => "Maximum number of pin retries exceeded.",
|
268
268
|
"80" => "Card expiration date is invalid.",
|
269
|
-
"80" => "Card expiration date is invalid.",
|
270
269
|
"86" => "Can't verify card pin number."
|
271
270
|
}
|
272
271
|
def issuer_message(code)
|
File without changes
|
File without changes
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class IppGateway < Gateway
|
6
|
+
self.live_url = 'https://www.ippayments.com.au/interface/api/dts.asmx'
|
7
|
+
self.test_url = 'https://demo.ippayments.com.au/interface/api/dts.asmx'
|
8
|
+
|
9
|
+
self.supported_countries = ['AU']
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
|
11
|
+
|
12
|
+
self.homepage_url = 'http://www.ippayments.com.au/'
|
13
|
+
self.display_name = 'IPP'
|
14
|
+
|
15
|
+
self.money_format = :cents
|
16
|
+
|
17
|
+
STANDARD_ERROR_CODE_MAPPING = {
|
18
|
+
"05" => STANDARD_ERROR_CODE[:card_declined],
|
19
|
+
"06" => STANDARD_ERROR_CODE[:processing_error],
|
20
|
+
"14" => STANDARD_ERROR_CODE[:invalid_number],
|
21
|
+
"54" => STANDARD_ERROR_CODE[:expired_card],
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(options={})
|
25
|
+
requires!(options, :username, :password)
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def purchase(money, payment, options={})
|
30
|
+
commit("SubmitSinglePayment") do |xml|
|
31
|
+
xml.Transaction do
|
32
|
+
xml.CustRef options[:order_id]
|
33
|
+
add_amount(xml, money)
|
34
|
+
xml.TrnType "1"
|
35
|
+
add_credit_card(xml, payment)
|
36
|
+
add_credentials(xml)
|
37
|
+
xml.TrnSource options[:ip]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def authorize(money, payment, options={})
|
43
|
+
commit("SubmitSinglePayment") do |xml|
|
44
|
+
xml.Transaction do
|
45
|
+
xml.CustRef options[:order_id]
|
46
|
+
add_amount(xml, money)
|
47
|
+
xml.TrnType "2"
|
48
|
+
add_credit_card(xml, payment)
|
49
|
+
add_credentials(xml)
|
50
|
+
xml.TrnSource options[:ip]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def capture(money, authorization, options={})
|
56
|
+
commit("SubmitSingleCapture") do |xml|
|
57
|
+
xml.Capture do
|
58
|
+
xml.Receipt authorization
|
59
|
+
add_amount(xml, money)
|
60
|
+
add_credentials(xml)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def refund(money, authorization, options={})
|
66
|
+
commit("SubmitSingleRefund") do |xml|
|
67
|
+
xml.Refund do
|
68
|
+
xml.Receipt authorization
|
69
|
+
add_amount(xml, money)
|
70
|
+
add_credentials(xml)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def supports_scrubbing?
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def scrub(transcript)
|
80
|
+
transcript.
|
81
|
+
gsub(%r((<CardNumber>)[^<]+(<))i, '\1[FILTERED]\2').
|
82
|
+
gsub(%r((<CVN>)[^<]+(<))i, '\1[FILTERED]\2').
|
83
|
+
gsub(%r((<Password>)[^<]+(<))i, '\1[FILTERED]\2')
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def add_credentials(xml)
|
89
|
+
xml.Security do
|
90
|
+
xml.UserName @options[:username]
|
91
|
+
xml.Password @options[:password]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_amount(xml, money)
|
96
|
+
xml.Amount amount(money)
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_credit_card(xml, payment)
|
100
|
+
xml.CreditCard :Registered => "False" do
|
101
|
+
xml.CardNumber payment.number
|
102
|
+
xml.ExpM format(payment.month, :two_digits)
|
103
|
+
xml.ExpY format(payment.year, :four_digits)
|
104
|
+
xml.CVN payment.verification_value
|
105
|
+
xml.CardHolderName payment.name
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse(body)
|
110
|
+
element = Nokogiri::XML(body).root.first_element_child.first_element_child
|
111
|
+
|
112
|
+
response = {}
|
113
|
+
doc = Nokogiri::XML(element)
|
114
|
+
doc.root.elements.each do |e|
|
115
|
+
response[e.name.underscore.to_sym] = e.inner_text
|
116
|
+
end
|
117
|
+
response
|
118
|
+
end
|
119
|
+
|
120
|
+
def commit(action, &block)
|
121
|
+
headers = {
|
122
|
+
"Content-Type" => "text/xml; charset=utf-8",
|
123
|
+
"SOAPAction" => "http://www.ippayments.com.au/interface/api/dts/#{action}",
|
124
|
+
}
|
125
|
+
response = parse(ssl_post(commit_url, new_submit_xml(action, &block), headers))
|
126
|
+
|
127
|
+
Response.new(
|
128
|
+
success_from(response),
|
129
|
+
message_from(response),
|
130
|
+
response,
|
131
|
+
authorization: authorization_from(response),
|
132
|
+
error_code: error_code_from(response),
|
133
|
+
test: test?,
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
def new_submit_xml(action)
|
138
|
+
xml = Builder::XmlMarkup.new(indent: 2)
|
139
|
+
xml.instruct!
|
140
|
+
xml.soap :Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/" do
|
141
|
+
xml.soap :Body do
|
142
|
+
xml.__send__(action, "xmlns" => "http://www.ippayments.com.au/interface/api/dts") do
|
143
|
+
xml.trnXML do
|
144
|
+
inner_xml = Builder::XmlMarkup.new(indent: 2)
|
145
|
+
yield(inner_xml)
|
146
|
+
xml.cdata!(inner_xml.target!)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
xml.target!
|
152
|
+
end
|
153
|
+
|
154
|
+
def commit_url
|
155
|
+
(test? ? test_url : live_url)
|
156
|
+
end
|
157
|
+
|
158
|
+
def success_from(response)
|
159
|
+
(response[:response_code] == "0")
|
160
|
+
end
|
161
|
+
|
162
|
+
def error_code_from(response)
|
163
|
+
STANDARD_ERROR_CODE_MAPPING[response[:declined_code]]
|
164
|
+
end
|
165
|
+
|
166
|
+
def message_from(response)
|
167
|
+
response[:declined_message]
|
168
|
+
end
|
169
|
+
|
170
|
+
def authorization_from(response)
|
171
|
+
response[:receipt]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|