activemerchant 1.26.0 → 1.27.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +17 -0
- data/CONTRIBUTORS +20 -0
- data/README.md +5 -0
- data/lib/active_merchant/billing/base.rb +2 -2
- data/lib/active_merchant/billing/gateway.rb +6 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +0 -3
- data/lib/active_merchant/billing/gateways/balanced.rb +462 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +3 -3
- data/lib/active_merchant/billing/gateways/beanstream.rb +1 -1
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +3 -2
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +1 -1
- data/lib/active_merchant/billing/gateways/braintree.rb +2 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +11 -1
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +2 -4
- data/lib/active_merchant/billing/gateways/card_stream.rb +2 -2
- data/lib/active_merchant/billing/gateways/certo_direct.rb +2 -3
- data/lib/active_merchant/billing/gateways/cyber_source.rb +3 -3
- data/lib/active_merchant/billing/gateways/data_cash.rb +3 -3
- data/lib/active_merchant/billing/gateways/efsnet.rb +3 -3
- data/lib/active_merchant/billing/gateways/epay.rb +3 -3
- data/lib/active_merchant/billing/gateways/eway.rb +8 -7
- data/lib/active_merchant/billing/gateways/eway_managed.rb +3 -3
- data/lib/active_merchant/billing/gateways/exact.rb +2 -2
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +4 -4
- data/lib/active_merchant/billing/gateways/federated_canada.rb +2 -2
- data/lib/active_merchant/billing/gateways/first_pay.rb +3 -3
- data/lib/active_merchant/billing/gateways/garanti.rb +2 -2
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +3 -1
- data/lib/active_merchant/billing/gateways/inspire.rb +2 -2
- data/lib/active_merchant/billing/gateways/instapay.rb +2 -2
- data/lib/active_merchant/billing/gateways/iridium.rb +4 -5
- data/lib/active_merchant/billing/gateways/itransact.rb +2 -2
- data/lib/active_merchant/billing/gateways/jetpay.rb +3 -3
- data/lib/active_merchant/billing/gateways/linkpoint.rb +3 -6
- data/lib/active_merchant/billing/gateways/litle.rb +50 -34
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +3 -3
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +2 -2
- data/lib/active_merchant/billing/gateways/migs.rb +8 -4
- data/lib/active_merchant/billing/gateways/modern_payments.rb +2 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +4 -4
- data/lib/active_merchant/billing/gateways/moneris.rb +3 -3
- data/lib/active_merchant/billing/gateways/moneris_us.rb +3 -3
- data/lib/active_merchant/billing/gateways/nab_transact.rb +8 -6
- data/lib/active_merchant/billing/gateways/net_registry.rb +2 -2
- data/lib/active_merchant/billing/gateways/netaxept.rb +4 -4
- data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
- data/lib/active_merchant/billing/gateways/ogone.rb +10 -5
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +3 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +4 -4
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +2 -2
- data/lib/active_merchant/billing/gateways/pay_secure.rb +2 -2
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +7 -5
- data/lib/active_merchant/billing/gateways/payflow.rb +39 -37
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +4 -3
- data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +98 -85
- data/lib/active_merchant/billing/gateways/paystation.rb +2 -2
- data/lib/active_merchant/billing/gateways/payway.rb +3 -2
- data/lib/active_merchant/billing/gateways/plugnpay.rb +63 -66
- data/lib/active_merchant/billing/gateways/psigate.rb +3 -3
- data/lib/active_merchant/billing/gateways/psl_card.rb +3 -3
- data/lib/active_merchant/billing/gateways/quantum.rb +2 -2
- data/lib/active_merchant/billing/gateways/quickpay.rb +2 -2
- data/lib/active_merchant/billing/gateways/realex.rb +7 -7
- data/lib/active_merchant/billing/gateways/sage.rb +2 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +2 -3
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage_pay.rb +8 -6
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +2 -2
- data/lib/active_merchant/billing/gateways/secure_net.rb +4 -4
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +9 -6
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +2 -2
- data/lib/active_merchant/billing/gateways/skip_jack.rb +3 -3
- data/lib/active_merchant/billing/gateways/smart_ps.rb +3 -1
- data/lib/active_merchant/billing/gateways/stripe.rb +2 -2
- data/lib/active_merchant/billing/gateways/trans_first.rb +2 -2
- data/lib/active_merchant/billing/gateways/transax.rb +1 -3
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +3 -3
- data/lib/active_merchant/billing/gateways/usa_epay.rb +2 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +3 -2
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -6
- data/lib/active_merchant/billing/gateways/verifi.rb +2 -2
- data/lib/active_merchant/billing/gateways/wirecard.rb +4 -4
- data/lib/active_merchant/billing/gateways/worldpay.rb +37 -18
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +6 -5
- data/lib/active_merchant/billing/integrations/first_data.rb +38 -0
- data/lib/active_merchant/billing/integrations/first_data/helper.rb +63 -0
- data/lib/active_merchant/billing/integrations/first_data/notification.rb +56 -0
- data/lib/active_merchant/billing/integrations/helper.rb +4 -0
- data/lib/active_merchant/billing/integrations/maksuturva.rb +86 -0
- data/lib/active_merchant/billing/integrations/maksuturva/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/maksuturva/notification.rb +48 -0
- data/lib/active_merchant/billing/integrations/paxum.rb +44 -0
- data/lib/active_merchant/billing/integrations/paxum/common.rb +24 -0
- data/lib/active_merchant/billing/integrations/paxum/helper.rb +42 -0
- data/lib/active_merchant/billing/integrations/paxum/notification.rb +33 -0
- data/lib/active_merchant/billing/integrations/pxpay.rb +31 -0
- data/lib/active_merchant/billing/integrations/pxpay/helper.rb +110 -0
- data/lib/active_merchant/billing/integrations/pxpay/notification.rb +157 -0
- data/lib/active_merchant/billing/integrations/pxpay/return.rb +25 -0
- data/lib/active_merchant/billing/integrations/web_pay.rb +45 -0
- data/lib/active_merchant/billing/integrations/web_pay/common.rb +50 -0
- data/lib/active_merchant/billing/integrations/web_pay/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/web_pay/notification.rb +51 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/support/gateway_support.rb +9 -2
- data/lib/support/ssl_verify.rb +93 -0
- metadata +45 -71
- data.tar.gz.sig +0 -3
- metadata.gz.sig +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class NetbillingGateway < Gateway
|
4
|
-
|
4
|
+
self.live_url = self.test_url = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
|
5
5
|
|
6
6
|
TRANSACTIONS = {
|
7
7
|
:authorization => 'A',
|
@@ -143,7 +143,7 @@ module ActiveMerchant #:nodoc:
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def commit(action, parameters)
|
146
|
-
response = parse(ssl_post(
|
146
|
+
response = parse(ssl_post(self.live_url, post_data(action, parameters)))
|
147
147
|
|
148
148
|
Response.new(success?(response), message_from(response), response,
|
149
149
|
:test => test_response?(response),
|
@@ -36,7 +36,7 @@ module ActiveMerchant #:nodoc:
|
|
36
36
|
# :user => "my_ogone_user_id",
|
37
37
|
# :password => "my_ogone_pswd",
|
38
38
|
# :signature => "my_ogone_sha_signature", # Only if you configured your Ogone environment so.
|
39
|
-
# :signature_encryptor => "sha512", # Can be "
|
39
|
+
# :signature_encryptor => "sha512", # Can be "none" (default), "sha1", "sha256" or "sha512".
|
40
40
|
# # Must be the same as the one configured in your Ogone account.
|
41
41
|
# )
|
42
42
|
#
|
@@ -122,10 +122,12 @@ module ActiveMerchant #:nodoc:
|
|
122
122
|
:pop_ix => 'POPIX' } # display the identification page in a pop-up window
|
123
123
|
# and remain in the pop-up window.
|
124
124
|
|
125
|
-
OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = "Signature usage will be
|
126
|
-
OGONE_LOW_ENCRYPTION_DEPRECATION_MESSAGE = "SHA512 signature encryptor will be required from a future release of ActiveMerchant's Ogone Gateway. Please update your Ogone account to use it."
|
125
|
+
OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = "Signature usage will be the default for a future release of ActiveMerchant. You should either begin using it, or update your configuration to explicitly disable it (signature_encryptor: none)"
|
127
126
|
OGONE_STORE_OPTION_DEPRECATION_MESSAGE = "The 'store' option has been renamed to 'billing_id', and its usage is deprecated."
|
128
127
|
|
128
|
+
self.test_url = URLS[:order] % "test"
|
129
|
+
self.live_url = URLS[:order] % "prod"
|
130
|
+
|
129
131
|
self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
|
130
132
|
# also supports Airplus and UATP
|
131
133
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
|
@@ -370,12 +372,15 @@ module ActiveMerchant #:nodoc:
|
|
370
372
|
|
371
373
|
def post_data(action, parameters = {})
|
372
374
|
add_pair parameters, 'Operation', action
|
373
|
-
|
375
|
+
add_signature(parameters)
|
374
376
|
parameters.to_query
|
375
377
|
end
|
376
378
|
|
377
379
|
def add_signature(parameters)
|
378
|
-
|
380
|
+
if @options[:signature].blank?
|
381
|
+
deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE) unless(@options[:signature_encryptor] == "none")
|
382
|
+
return
|
383
|
+
end
|
379
384
|
|
380
385
|
sha_encryptor = case @options[:signature_encryptor]
|
381
386
|
when 'sha256'
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class OptimalPaymentGateway < Gateway
|
4
|
-
|
5
|
-
|
4
|
+
self.test_url = 'https://webservices.test.optimalpayments.com/creditcardWS/CreditCardServlet/v1'
|
5
|
+
self.live_url = 'https://webservices.optimalpayments.com/creditcardWS/CreditCardServlet/v1'
|
6
6
|
|
7
7
|
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
8
8
|
self.supported_countries = ['CA', 'US', 'GB']
|
@@ -91,7 +91,7 @@ module ActiveMerchant #:nodoc:
|
|
91
91
|
raise 'Unknown Action'
|
92
92
|
end
|
93
93
|
txnRequest = URI.encode(xml)
|
94
|
-
response = parse(ssl_post(test? ?
|
94
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, "txnMode=#{action}&txnRequest=#{txnRequest}"))
|
95
95
|
|
96
96
|
Response.new(successful?(response), message_from(response), hash_from_xml(response),
|
97
97
|
:test => test?,
|
@@ -41,12 +41,12 @@ module ActiveMerchant #:nodoc:
|
|
41
41
|
|
42
42
|
SUCCESS, APPROVED = '0', '00'
|
43
43
|
|
44
|
-
class_attribute :
|
44
|
+
class_attribute :secondary_test_url, :secondary_live_url
|
45
45
|
|
46
|
-
self.
|
46
|
+
self.test_url = "https://orbitalvar1.paymentech.net/authorize"
|
47
47
|
self.secondary_test_url = "https://orbitalvar2.paymentech.net/authorize"
|
48
48
|
|
49
|
-
self.
|
49
|
+
self.live_url = "https://orbital1.paymentech.net/authorize"
|
50
50
|
self.secondary_live_url = "https://orbital2.paymentech.net/authorize"
|
51
51
|
|
52
52
|
self.supported_countries = ["US", "CA"]
|
@@ -223,7 +223,7 @@ module ActiveMerchant #:nodoc:
|
|
223
223
|
|
224
224
|
def remote_url
|
225
225
|
unless $!.class == ActiveMerchant::ConnectionError
|
226
|
-
self.test? ? self.
|
226
|
+
self.test? ? self.test_url : self.live_url
|
227
227
|
else
|
228
228
|
self.test? ? self.secondary_test_url : self.secondary_live_url
|
229
229
|
end
|
@@ -73,7 +73,7 @@ module ActiveMerchant #:nodoc:
|
|
73
73
|
# threed - must remain blank unless you are using your own 3D Secure server
|
74
74
|
#
|
75
75
|
class PayGateXmlGateway < Gateway
|
76
|
-
|
76
|
+
self.live_url = 'https://www.paygate.co.za/payxml/process.trans'
|
77
77
|
|
78
78
|
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
79
79
|
self.supported_countries = ['US', 'ZA']
|
@@ -250,7 +250,7 @@ module ActiveMerchant #:nodoc:
|
|
250
250
|
end
|
251
251
|
|
252
252
|
def commit(action, request)
|
253
|
-
response = parse(action, ssl_post(
|
253
|
+
response = parse(action, ssl_post(self.live_url, request))
|
254
254
|
Response.new(successful?(response), message_from(response), response,
|
255
255
|
:test => test?,
|
256
256
|
:authorization => response[:tid]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class PaySecureGateway < Gateway
|
4
|
-
|
4
|
+
self.live_url = self.test_url = 'https://clearance.commsecure.com.au/cgi-bin/PSDirect'
|
5
5
|
|
6
6
|
self.money_format = :cents
|
7
7
|
|
@@ -73,7 +73,7 @@ module ActiveMerchant #:nodoc:
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def commit(action, money, parameters)
|
76
|
-
response = parse( ssl_post(
|
76
|
+
response = parse( ssl_post(self.live_url, post_data(action, parameters)) )
|
77
77
|
|
78
78
|
Response.new(successful?(response), message_from(response), response,
|
79
79
|
:test => test_response?(response),
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class PayboxDirectGateway < Gateway
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class_attribute :live_url_backup
|
5
|
+
|
6
|
+
self.test_url = 'https://preprod-ppps.paybox.com/PPPS.php'
|
7
|
+
self.live_url = 'https://ppps.paybox.com/PPPS.php'
|
8
|
+
self.live_url_backup = 'https://ppps1.paybox.com/PPPS.php'
|
7
9
|
|
8
10
|
# Payment API Version
|
9
11
|
API_VERSION = '00103'
|
@@ -141,8 +143,8 @@ module ActiveMerchant #:nodoc:
|
|
141
143
|
parameters[:montant] = ('0000000000' + (money ? amount(money) : ''))[-10..-1]
|
142
144
|
parameters[:devise] = CURRENCY_CODES[options[:currency] || currency(money)]
|
143
145
|
request_data = post_data(action,parameters)
|
144
|
-
response = parse(ssl_post(test? ?
|
145
|
-
response = parse(ssl_post(
|
146
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, request_data))
|
147
|
+
response = parse(ssl_post(self.live_url_backup, request_data)) if service_unavailable?(response) && !test?
|
146
148
|
Response.new(success?(response), message_from(response), response.merge(
|
147
149
|
:timestamp => parameters[:dateq]),
|
148
150
|
:test => test?,
|
@@ -6,25 +6,25 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
module Billing #:nodoc:
|
7
7
|
class PayflowGateway < Gateway
|
8
8
|
include PayflowCommonAPI
|
9
|
-
|
9
|
+
|
10
10
|
RECURRING_ACTIONS = Set.new([:add, :modify, :cancel, :inquiry, :reactivate, :payment])
|
11
|
-
|
11
|
+
|
12
12
|
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover, :diners_club]
|
13
13
|
self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_payflow-pro-overview-outside'
|
14
14
|
self.display_name = 'PayPal Payflow Pro'
|
15
|
-
|
15
|
+
|
16
16
|
def authorize(money, credit_card_or_reference, options = {})
|
17
17
|
request = build_sale_or_authorization_request(:authorization, money, credit_card_or_reference, options)
|
18
|
-
|
18
|
+
|
19
19
|
commit(request, options)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def purchase(money, credit_card_or_reference, options = {})
|
23
23
|
request = build_sale_or_authorization_request(:purchase, money, credit_card_or_reference, options)
|
24
24
|
|
25
25
|
commit(request, options)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def credit(money, identification_or_credit_card, options = {})
|
29
29
|
if identification_or_credit_card.is_a?(String)
|
30
30
|
deprecated CREDIT_DEPRECATION_MESSAGE
|
@@ -36,13 +36,14 @@ module ActiveMerchant #:nodoc:
|
|
36
36
|
commit(request, options)
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def refund(money, reference, options = {})
|
41
41
|
commit(build_reference_request(:credit, money, reference, options), options)
|
42
42
|
end
|
43
|
+
|
43
44
|
# Adds or modifies a recurring Payflow profile. See the Payflow Pro Recurring Billing Guide for more details:
|
44
45
|
# https://www.paypal.com/en_US/pdf/PayflowPro_RecurringBilling_Guide.pdf
|
45
|
-
#
|
46
|
+
#
|
46
47
|
# Several options are available to customize the recurring profile:
|
47
48
|
#
|
48
49
|
# * <tt>profile_id</tt> - is only required for editing a recurring profile
|
@@ -51,7 +52,7 @@ module ActiveMerchant #:nodoc:
|
|
51
52
|
# * <tt>periodicity</tt> - The frequency that the recurring payments will occur at. Can be one of
|
52
53
|
# :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily, :semimonthly, :quadweekly, :quarterly, :semiyearly
|
53
54
|
# * <tt>payments</tt> - The term, or number of payments that will be made
|
54
|
-
# * <tt>comment</tt> - A comment associated with the profile
|
55
|
+
# * <tt>comment</tt> - A comment associated with the profile
|
55
56
|
def recurring(money, credit_card, options = {})
|
56
57
|
options[:name] = credit_card.name if options[:name].blank? && credit_card
|
57
58
|
request = build_recurring_request(options[:profile_id] ? :modify : :add, money, options) do |xml|
|
@@ -59,30 +60,30 @@ module ActiveMerchant #:nodoc:
|
|
59
60
|
end
|
60
61
|
commit(request, options.merge(:request_type => :recurring))
|
61
62
|
end
|
62
|
-
|
63
|
+
|
63
64
|
def cancel_recurring(profile_id)
|
64
65
|
request = build_recurring_request(:cancel, 0, :profile_id => profile_id)
|
65
66
|
commit(request, options.merge(:request_type => :recurring))
|
66
67
|
end
|
67
|
-
|
68
|
+
|
68
69
|
def recurring_inquiry(profile_id, options = {})
|
69
70
|
request = build_recurring_request(:inquiry, nil, options.update( :profile_id => profile_id ))
|
70
71
|
commit(request, options.merge(:request_type => :recurring))
|
71
|
-
end
|
72
|
-
|
72
|
+
end
|
73
|
+
|
73
74
|
def express
|
74
75
|
@express ||= PayflowExpressGateway.new(@options)
|
75
76
|
end
|
76
|
-
|
77
|
+
|
77
78
|
private
|
78
79
|
def build_sale_or_authorization_request(action, money, credit_card_or_reference, options)
|
79
80
|
if credit_card_or_reference.is_a?(String)
|
80
81
|
build_reference_sale_or_authorization_request(action, money, credit_card_or_reference, options)
|
81
|
-
else
|
82
|
+
else
|
82
83
|
build_credit_card_request(action, money, credit_card_or_reference, options)
|
83
|
-
end
|
84
|
+
end
|
84
85
|
end
|
85
|
-
|
86
|
+
|
86
87
|
def build_reference_sale_or_authorization_request(action, money, reference, options)
|
87
88
|
xml = Builder::XmlMarkup.new
|
88
89
|
xml.tag! TRANSACTIONS[action] do
|
@@ -114,9 +115,9 @@ module ActiveMerchant #:nodoc:
|
|
114
115
|
end
|
115
116
|
xml.target!
|
116
117
|
end
|
117
|
-
|
118
|
+
|
118
119
|
def build_credit_card_request(action, money, credit_card, options)
|
119
|
-
xml = Builder::XmlMarkup.new
|
120
|
+
xml = Builder::XmlMarkup.new
|
120
121
|
xml.tag! TRANSACTIONS[action] do
|
121
122
|
xml.tag! 'PayData' do
|
122
123
|
xml.tag! 'Invoice' do
|
@@ -134,18 +135,18 @@ module ActiveMerchant #:nodoc:
|
|
134
135
|
billing_address = options[:billing_address] || options[:address]
|
135
136
|
add_address(xml, 'BillTo', billing_address, options) if billing_address
|
136
137
|
add_address(xml, 'ShipTo', options[:shipping_address], options) if options[:shipping_address]
|
137
|
-
|
138
|
+
|
138
139
|
xml.tag! 'TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money)
|
139
140
|
end
|
140
|
-
|
141
|
+
|
141
142
|
xml.tag! 'Tender' do
|
142
143
|
add_credit_card(xml, credit_card)
|
143
144
|
end
|
144
|
-
end
|
145
|
+
end
|
145
146
|
end
|
146
147
|
xml.target!
|
147
148
|
end
|
148
|
-
|
149
|
+
|
149
150
|
def add_credit_card(xml, credit_card)
|
150
151
|
xml.tag! 'Card' do
|
151
152
|
xml.tag! 'CardType', credit_card_type(credit_card)
|
@@ -153,7 +154,7 @@ module ActiveMerchant #:nodoc:
|
|
153
154
|
xml.tag! 'ExpDate', expdate(credit_card)
|
154
155
|
xml.tag! 'NameOnCard', credit_card.first_name
|
155
156
|
xml.tag! 'CVNum', credit_card.verification_value if credit_card.verification_value?
|
156
|
-
|
157
|
+
|
157
158
|
if requires_start_date_or_issue_number?(credit_card)
|
158
159
|
xml.tag!('ExtData', 'Name' => 'CardStart', 'Value' => startdate(credit_card)) unless credit_card.start_month.blank? || credit_card.start_year.blank?
|
159
160
|
xml.tag!('ExtData', 'Name' => 'CardIssue', 'Value' => format(credit_card.issue_number, :two_digits)) unless credit_card.issue_number.blank?
|
@@ -161,33 +162,33 @@ module ActiveMerchant #:nodoc:
|
|
161
162
|
xml.tag! 'ExtData', 'Name' => 'LASTNAME', 'Value' => credit_card.last_name
|
162
163
|
end
|
163
164
|
end
|
164
|
-
|
165
|
+
|
165
166
|
def credit_card_type(credit_card)
|
166
167
|
return '' if card_brand(credit_card).blank?
|
167
|
-
|
168
|
+
|
168
169
|
CARD_MAPPING[card_brand(credit_card).to_sym]
|
169
170
|
end
|
170
|
-
|
171
|
+
|
171
172
|
def expdate(creditcard)
|
172
173
|
year = sprintf("%.4i", creditcard.year.to_s.sub(/^0+/, ''))
|
173
174
|
month = sprintf("%.2i", creditcard.month.to_s.sub(/^0+/, ''))
|
174
175
|
|
175
176
|
"#{year}#{month}"
|
176
177
|
end
|
177
|
-
|
178
|
+
|
178
179
|
def startdate(creditcard)
|
179
180
|
year = format(creditcard.start_year, :two_digits)
|
180
181
|
month = format(creditcard.start_month, :two_digits)
|
181
182
|
|
182
183
|
"#{month}#{year}"
|
183
184
|
end
|
184
|
-
|
185
|
+
|
185
186
|
def build_recurring_request(action, money, options)
|
186
187
|
unless RECURRING_ACTIONS.include?(action)
|
187
188
|
raise StandardError, "Invalid Recurring Profile Action: #{action}"
|
188
189
|
end
|
189
190
|
|
190
|
-
xml = Builder::XmlMarkup.new
|
191
|
+
xml = Builder::XmlMarkup.new
|
191
192
|
xml.tag! 'RecurringProfiles' do
|
192
193
|
xml.tag! 'RecurringProfile' do
|
193
194
|
xml.tag! action.to_s.capitalize do
|
@@ -199,23 +200,24 @@ module ActiveMerchant #:nodoc:
|
|
199
200
|
xml.tag! 'Term', options[:payments] unless options[:payments].nil?
|
200
201
|
xml.tag! 'Comment', options[:comment] unless options[:comment].nil?
|
201
202
|
xml.tag! 'RetryNumDays', options[:retry_num_days] unless options[:retry_num_days].nil?
|
202
|
-
|
203
|
+
xml.tag! 'MaxFailPayments', options[:max_fail_payments] unless options[:max_fail_payments].nil?
|
204
|
+
|
203
205
|
if initial_tx = options[:initial_transaction]
|
204
206
|
requires!(initial_tx, [:type, :authorization, :purchase])
|
205
207
|
requires!(initial_tx, :amount) if initial_tx[:type] == :purchase
|
206
|
-
|
208
|
+
|
207
209
|
xml.tag! 'OptionalTrans', TRANSACTIONS[initial_tx[:type]]
|
208
210
|
xml.tag! 'OptionalTransAmt', amount(initial_tx[:amount]) unless initial_tx[:amount].blank?
|
209
211
|
end
|
210
|
-
|
212
|
+
|
211
213
|
if action == :add
|
212
214
|
xml.tag! 'Start', format_rp_date(options[:starting_at] || Date.today + 1 )
|
213
215
|
else
|
214
216
|
xml.tag! 'Start', format_rp_date(options[:starting_at]) unless options[:starting_at].nil?
|
215
217
|
end
|
216
|
-
|
218
|
+
|
217
219
|
xml.tag! 'EMail', options[:email] unless options[:email].nil?
|
218
|
-
|
220
|
+
|
219
221
|
billing_address = options[:billing_address] || options[:address]
|
220
222
|
add_address(xml, 'BillTo', billing_address, options) if billing_address
|
221
223
|
add_address(xml, 'ShipTo', options[:shipping_address], options) if options[:shipping_address]
|
@@ -256,8 +258,8 @@ module ActiveMerchant #:nodoc:
|
|
256
258
|
time.to_s
|
257
259
|
end
|
258
260
|
end
|
259
|
-
|
260
|
-
def build_response(success, message, response, options = {})
|
261
|
+
|
262
|
+
def build_response(success, message, response, options = {})
|
261
263
|
PayflowResponse.new(success, message, response, options)
|
262
264
|
end
|
263
265
|
end
|
@@ -13,6 +13,9 @@ module ActiveMerchant #:nodoc:
|
|
13
13
|
|
14
14
|
base.class_attribute :timeout
|
15
15
|
base.timeout = 60
|
16
|
+
|
17
|
+
base.test_url = 'https://pilot-payflowpro.paypal.com'
|
18
|
+
base.live_url = 'https://payflowpro.paypal.com'
|
16
19
|
|
17
20
|
# Enable safe retry of failed connections
|
18
21
|
# Payflow is safe to retry because retried transactions use the same
|
@@ -24,8 +27,6 @@ module ActiveMerchant #:nodoc:
|
|
24
27
|
end
|
25
28
|
|
26
29
|
XMLNS = 'http://www.paypal.com/XMLPay'
|
27
|
-
TEST_URL = 'https://pilot-payflowpro.paypal.com'
|
28
|
-
LIVE_URL = 'https://payflowpro.paypal.com'
|
29
30
|
|
30
31
|
CARD_MAPPING = {
|
31
32
|
:visa => 'Visa',
|
@@ -197,7 +198,7 @@ module ActiveMerchant #:nodoc:
|
|
197
198
|
request = build_request(request_body, options)
|
198
199
|
headers = build_headers(request.size)
|
199
200
|
|
200
|
-
response = parse(ssl_post(test? ?
|
201
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers))
|
201
202
|
|
202
203
|
build_response(response[:result] == "0", response[:message], response,
|
203
204
|
:test => test?,
|
@@ -21,7 +21,7 @@ module ActiveMerchant #:nodoc:
|
|
21
21
|
self.homepage_url = 'http://www.paymentexpress.com/'
|
22
22
|
self.display_name = 'PaymentExpress'
|
23
23
|
|
24
|
-
|
24
|
+
self.live_url = self.test_url = 'https://sec.paymentexpress.com/pxpost.aspx'
|
25
25
|
|
26
26
|
APPROVED = '1'
|
27
27
|
|
@@ -236,7 +236,7 @@ module ActiveMerchant #:nodoc:
|
|
236
236
|
add_transaction_type(request, action)
|
237
237
|
|
238
238
|
# Parse the XML response
|
239
|
-
response = parse( ssl_post(
|
239
|
+
response = parse( ssl_post(self.live_url, request.to_s) )
|
240
240
|
|
241
241
|
# Return a response
|
242
242
|
PaymentExpressResponse.new(response[:success] == APPROVED, response[:card_holder_help_text], response,
|
@@ -2,24 +2,18 @@ module ActiveMerchant #:nodoc:
|
|
2
2
|
module Billing #:nodoc:
|
3
3
|
# This module is included in both PaypalGateway and PaypalExpressGateway
|
4
4
|
module PaypalCommonAPI
|
5
|
-
def self.included(base)
|
6
|
-
base.default_currency = 'USD'
|
7
|
-
base.cattr_accessor :pem_file
|
8
|
-
base.cattr_accessor :signature
|
9
|
-
end
|
10
|
-
|
11
5
|
API_VERSION = '72'
|
12
|
-
|
6
|
+
|
13
7
|
URLS = {
|
14
8
|
:test => { :certificate => 'https://api.sandbox.paypal.com/2.0/',
|
15
9
|
:signature => 'https://api-3t.sandbox.paypal.com/2.0/' },
|
16
10
|
:live => { :certificate => 'https://api-aa.paypal.com/2.0/',
|
17
11
|
:signature => 'https://api-3t.paypal.com/2.0/' }
|
18
12
|
}
|
19
|
-
|
13
|
+
|
20
14
|
PAYPAL_NAMESPACE = 'urn:ebay:api:PayPalAPI'
|
21
15
|
EBAY_NAMESPACE = 'urn:ebay:apis:eBLBaseComponents'
|
22
|
-
|
16
|
+
|
23
17
|
ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
24
18
|
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
25
19
|
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
@@ -28,7 +22,7 @@ module ActiveMerchant #:nodoc:
|
|
28
22
|
'xmlns:n1' => EBAY_NAMESPACE,
|
29
23
|
'env:mustUnderstand' => '0'
|
30
24
|
}
|
31
|
-
|
25
|
+
|
32
26
|
AUSTRALIAN_STATES = {
|
33
27
|
'ACT' => 'Australian Capital Territory',
|
34
28
|
'NSW' => 'New South Wales',
|
@@ -39,11 +33,19 @@ module ActiveMerchant #:nodoc:
|
|
39
33
|
'VIC' => 'Victoria',
|
40
34
|
'WA' => 'Western Australia'
|
41
35
|
}
|
42
|
-
|
36
|
+
|
43
37
|
SUCCESS_CODES = [ 'Success', 'SuccessWithWarning' ]
|
44
|
-
|
38
|
+
|
45
39
|
FRAUD_REVIEW_CODE = "11610"
|
46
|
-
|
40
|
+
|
41
|
+
def self.included(base)
|
42
|
+
base.default_currency = 'USD'
|
43
|
+
base.cattr_accessor :pem_file
|
44
|
+
base.cattr_accessor :signature
|
45
|
+
base.live_url = URLS[:live][:signature]
|
46
|
+
base.test_url = URLS[:test][:signature]
|
47
|
+
end
|
48
|
+
|
47
49
|
# The gateway must be configured with either your PayPal PEM file
|
48
50
|
# or your PayPal API Signature. Only one is required.
|
49
51
|
#
|
@@ -54,15 +56,14 @@ module ActiveMerchant #:nodoc:
|
|
54
56
|
# globally and then you won't need to
|
55
57
|
# include this option
|
56
58
|
#
|
57
|
-
# <tt>:signature</tt> The text of your PayPal signature.
|
59
|
+
# <tt>:signature</tt> The text of your PayPal signature.
|
58
60
|
# If you are only using one API Signature
|
59
61
|
# on your site you can declare it
|
60
62
|
# globally and then you won't need to
|
61
63
|
# include this option
|
62
|
-
|
63
64
|
def initialize(options = {})
|
64
65
|
requires!(options, :login, :password)
|
65
|
-
|
66
|
+
|
66
67
|
headers = {'X-PP-AUTHORIZATION' => options.delete(:auth_signature), 'X-PAYPAL-MESSAGE-PROTOCOL' => 'SOAP11'} if options[:auth_signature]
|
67
68
|
@options = {
|
68
69
|
:pem => pem_file,
|
@@ -70,14 +71,14 @@ module ActiveMerchant #:nodoc:
|
|
70
71
|
:headers => headers || {}
|
71
72
|
}.update(options)
|
72
73
|
|
73
|
-
|
74
|
+
|
74
75
|
if @options[:pem].blank? && @options[:signature].blank?
|
75
|
-
raise ArgumentError, "An API Certificate or API Signature is required to make requests to PayPal"
|
76
|
+
raise ArgumentError, "An API Certificate or API Signature is required to make requests to PayPal"
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
super
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
def test?
|
82
83
|
@options[:test] || Base.gateway_mode == :test
|
83
84
|
end
|
@@ -85,11 +86,11 @@ module ActiveMerchant #:nodoc:
|
|
85
86
|
def reauthorize(money, authorization, options = {})
|
86
87
|
commit 'DoReauthorization', build_reauthorize_request(money, authorization, options)
|
87
88
|
end
|
88
|
-
|
89
|
+
|
89
90
|
def capture(money, authorization, options = {})
|
90
91
|
commit 'DoCapture', build_capture_request(money, authorization, options)
|
91
92
|
end
|
92
|
-
|
93
|
+
|
93
94
|
# Transfer money to one or more recipients.
|
94
95
|
#
|
95
96
|
# gateway.transfer 1000, 'bob@example.com',
|
@@ -107,7 +108,19 @@ module ActiveMerchant #:nodoc:
|
|
107
108
|
def void(authorization, options = {})
|
108
109
|
commit 'DoVoid', build_void_request(authorization, options)
|
109
110
|
end
|
110
|
-
|
111
|
+
|
112
|
+
# Refunds a transaction.
|
113
|
+
#
|
114
|
+
# For a full refund pass nil for the amount:
|
115
|
+
#
|
116
|
+
# gateway.refund nil, 'G39883289DH238'
|
117
|
+
#
|
118
|
+
# This will automatically make the :refund_type be "Full".
|
119
|
+
#
|
120
|
+
# For a partial refund just pass the amount as usual:
|
121
|
+
#
|
122
|
+
# gateway.refund 100, 'UBU83983N920'
|
123
|
+
#
|
111
124
|
def refund(money, identification, options = {})
|
112
125
|
commit 'RefundTransaction', build_refund_request(money, identification, options)
|
113
126
|
end
|
@@ -135,7 +148,7 @@ module ActiveMerchant #:nodoc:
|
|
135
148
|
#
|
136
149
|
# 0 – You do not require that the buyer’s shipping address be a confirmed address.
|
137
150
|
# 1 – You require that the buyer’s shipping address be a confirmed address.
|
138
|
-
#
|
151
|
+
#
|
139
152
|
# * <tt>:merchant_session_id</tt> -- (Optional) Your buyer session identification token.
|
140
153
|
# * <tt>:return_fmf_details</tt> -- (Optional) Flag to indicate whether you want the results returned by Fraud Management Filters. By default, you do not receive this information. It is one of the following values:
|
141
154
|
#
|
@@ -146,13 +159,13 @@ module ActiveMerchant #:nodoc:
|
|
146
159
|
#
|
147
160
|
# <PP * | PAYPAL *><Merchant descriptor as set in the Payment Receiving Preferences><1 space><soft descriptor>
|
148
161
|
# The soft descriptor can contain only the following characters:
|
149
|
-
#
|
162
|
+
#
|
150
163
|
# Alphanumeric characters
|
151
164
|
# - (dash)
|
152
165
|
# * (asterisk)
|
153
166
|
# . (period)
|
154
167
|
# {space}
|
155
|
-
#
|
168
|
+
#
|
156
169
|
def reference_transaction(money, options = {})
|
157
170
|
requires!(options, :reference_id)
|
158
171
|
commit 'DoReferenceTransaction', build_reference_transaction_request(money, options)
|
@@ -191,7 +204,7 @@ module ActiveMerchant #:nodoc:
|
|
191
204
|
# Shipping – Only transactions involving UPS shipping fees
|
192
205
|
# BalanceAffecting – Only transactions that affect the account balance
|
193
206
|
# ECheck – Only transactions involving eCheck
|
194
|
-
#
|
207
|
+
#
|
195
208
|
# * <tt>:currency_code </tt> -- (Optional) Search by currency code.
|
196
209
|
# * <tt>:status</tt> -- (Optional) Search by transaction status. It is one of the following values:
|
197
210
|
# One of:
|
@@ -200,7 +213,7 @@ module ActiveMerchant #:nodoc:
|
|
200
213
|
# Success – The payment has been completed and the funds have been added successfully to your account balance.
|
201
214
|
# Denied – You denied the payment. This happens only if the payment was previously pending.
|
202
215
|
# Reversed – A payment was reversed due to a chargeback or other type of reversal. The funds have been removed from your account balance and returned to the buyer.
|
203
|
-
#
|
216
|
+
#
|
204
217
|
def transaction_search(options)
|
205
218
|
requires!(options, :start_date)
|
206
219
|
commit 'TransactionSearch', build_transaction_search(options)
|
@@ -222,24 +235,24 @@ module ActiveMerchant #:nodoc:
|
|
222
235
|
|
223
236
|
# DoAuthorization takes the transaction_id returned when you call
|
224
237
|
# DoExpressCheckoutPayment with a PaymentAction of 'Order'.
|
225
|
-
# When you did that, you created an order authorization subject to settlement
|
238
|
+
# When you did that, you created an order authorization subject to settlement
|
226
239
|
# with PayPal DoAuthorization and DoCapture
|
227
|
-
#
|
240
|
+
#
|
228
241
|
# ==== Parameters:
|
229
242
|
# * <tt>:transaction_id</tt> -- The ID returned by DoExpressCheckoutPayment with a PaymentAction of 'Order'.
|
230
243
|
# * <tt>:money</tt> -- The amount of money to be authorized for this purchase.
|
231
|
-
#
|
244
|
+
#
|
232
245
|
def authorize_transaction(transaction_id, money, options = {})
|
233
246
|
commit 'DoAuthorization', build_do_authorize(transaction_id, money, options)
|
234
247
|
end
|
235
248
|
|
236
|
-
# The ManagePendingTransactionStatus API operation accepts or denys a
|
249
|
+
# The ManagePendingTransactionStatus API operation accepts or denys a
|
237
250
|
# pending transaction held by Fraud Management Filters.
|
238
251
|
#
|
239
252
|
# ==== Parameters:
|
240
253
|
# * <tt>:transaction_id</tt> -- The ID of the transaction held by Fraud Management Filters.
|
241
254
|
# * <tt>:action</tt> -- Either 'Accept' or 'Deny'
|
242
|
-
#
|
255
|
+
#
|
243
256
|
def manage_pending_transaction(transaction_id, action)
|
244
257
|
commit 'ManagePendingTransactionStatus', build_manage_pending_transaction_status(transaction_id, action)
|
245
258
|
end
|
@@ -271,7 +284,7 @@ module ActiveMerchant #:nodoc:
|
|
271
284
|
|
272
285
|
def build_reauthorize_request(money, authorization, options)
|
273
286
|
xml = Builder::XmlMarkup.new
|
274
|
-
|
287
|
+
|
275
288
|
xml.tag! 'DoReauthorizationReq', 'xmlns' => PAYPAL_NAMESPACE do
|
276
289
|
xml.tag! 'DoReauthorizationRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
277
290
|
xml.tag! 'n2:Version', API_VERSION
|
@@ -280,12 +293,12 @@ module ActiveMerchant #:nodoc:
|
|
280
293
|
end
|
281
294
|
end
|
282
295
|
|
283
|
-
xml.target!
|
296
|
+
xml.target!
|
284
297
|
end
|
285
|
-
|
286
|
-
def build_capture_request(money, authorization, options)
|
298
|
+
|
299
|
+
def build_capture_request(money, authorization, options)
|
287
300
|
xml = Builder::XmlMarkup.new
|
288
|
-
|
301
|
+
|
289
302
|
xml.tag! 'DoCaptureReq', 'xmlns' => PAYPAL_NAMESPACE do
|
290
303
|
xml.tag! 'DoCaptureRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
291
304
|
xml.tag! 'n2:Version', API_VERSION
|
@@ -297,28 +310,28 @@ module ActiveMerchant #:nodoc:
|
|
297
310
|
end
|
298
311
|
end
|
299
312
|
|
300
|
-
xml.target!
|
313
|
+
xml.target!
|
301
314
|
end
|
302
|
-
|
315
|
+
|
303
316
|
def build_refund_request(money, identification, options)
|
304
317
|
xml = Builder::XmlMarkup.new
|
305
|
-
|
318
|
+
|
306
319
|
xml.tag! 'RefundTransactionReq', 'xmlns' => PAYPAL_NAMESPACE do
|
307
320
|
xml.tag! 'RefundTransactionRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
308
321
|
xml.tag! 'n2:Version', API_VERSION
|
309
322
|
xml.tag! 'TransactionID', identification
|
310
|
-
xml.tag! 'Amount', amount(money), 'currencyID' => options[:currency] || currency(money)
|
311
|
-
xml.tag! 'RefundType', 'Partial'
|
323
|
+
xml.tag! 'Amount', amount(money), 'currencyID' => (options[:currency] || currency(money)) if money.present?
|
324
|
+
xml.tag! 'RefundType', (options[:refund_type] || (money.present? ? 'Partial' : 'Full'))
|
312
325
|
xml.tag! 'Memo', options[:note] unless options[:note].blank?
|
313
326
|
end
|
314
327
|
end
|
315
|
-
|
316
|
-
xml.target!
|
328
|
+
|
329
|
+
xml.target!
|
317
330
|
end
|
318
|
-
|
331
|
+
|
319
332
|
def build_void_request(authorization, options)
|
320
333
|
xml = Builder::XmlMarkup.new
|
321
|
-
|
334
|
+
|
322
335
|
xml.tag! 'DoVoidReq', 'xmlns' => PAYPAL_NAMESPACE do
|
323
336
|
xml.tag! 'DoVoidRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
324
337
|
xml.tag! 'n2:Version', API_VERSION
|
@@ -327,15 +340,15 @@ module ActiveMerchant #:nodoc:
|
|
327
340
|
end
|
328
341
|
end
|
329
342
|
|
330
|
-
xml.target!
|
343
|
+
xml.target!
|
331
344
|
end
|
332
|
-
|
333
|
-
def build_mass_pay_request(*args)
|
345
|
+
|
346
|
+
def build_mass_pay_request(*args)
|
334
347
|
default_options = args.last.is_a?(Hash) ? args.pop : {}
|
335
348
|
recipients = args.first.is_a?(Array) ? args : [args]
|
336
|
-
|
349
|
+
|
337
350
|
xml = Builder::XmlMarkup.new
|
338
|
-
|
351
|
+
|
339
352
|
xml.tag! 'MassPayReq', 'xmlns' => PAYPAL_NAMESPACE do
|
340
353
|
xml.tag! 'MassPayRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
341
354
|
xml.tag! 'n2:Version', API_VERSION
|
@@ -351,7 +364,7 @@ module ActiveMerchant #:nodoc:
|
|
351
364
|
end
|
352
365
|
end
|
353
366
|
end
|
354
|
-
|
367
|
+
|
355
368
|
xml.target!
|
356
369
|
end
|
357
370
|
|
@@ -361,12 +374,12 @@ module ActiveMerchant #:nodoc:
|
|
361
374
|
xml.tag! 'Action', action
|
362
375
|
end
|
363
376
|
end
|
364
|
-
|
377
|
+
|
365
378
|
def build_reference_transaction_request(money, options)
|
366
379
|
opts = options.dup
|
367
380
|
opts[:ip_address] ||= opts[:ip]
|
368
381
|
currency_code = opts[:currency] || currency(money)
|
369
|
-
reference_transaction_optional_fields = %w{ n2:ReferenceID n2:PaymentAction
|
382
|
+
reference_transaction_optional_fields = %w{ n2:ReferenceID n2:PaymentAction
|
370
383
|
n2:PaymentType n2:IPAddress
|
371
384
|
n2:ReqConfirmShipping n2:MerchantSessionId
|
372
385
|
n2:ReturnFMFDetails n2:SoftDescriptor }
|
@@ -426,18 +439,18 @@ module ActiveMerchant #:nodoc:
|
|
426
439
|
|
427
440
|
def legacy_parse(action, xml)
|
428
441
|
response = {}
|
429
|
-
|
442
|
+
|
430
443
|
error_messages = []
|
431
444
|
error_codes = []
|
432
|
-
|
445
|
+
|
433
446
|
xml = REXML::Document.new(xml)
|
434
447
|
if root = REXML::XPath.first(xml, "//#{action}Response")
|
435
|
-
root.elements.each do |node|
|
448
|
+
root.elements.each do |node|
|
436
449
|
case node.name
|
437
450
|
when 'Errors'
|
438
451
|
short_message = nil
|
439
452
|
long_message = nil
|
440
|
-
|
453
|
+
|
441
454
|
node.elements.each do |child|
|
442
455
|
case child.name
|
443
456
|
when "LongMessage"
|
@@ -479,20 +492,20 @@ module ActiveMerchant #:nodoc:
|
|
479
492
|
|
480
493
|
def build_request(body)
|
481
494
|
xml = Builder::XmlMarkup.new
|
482
|
-
|
495
|
+
|
483
496
|
xml.instruct!
|
484
497
|
xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
|
485
498
|
xml.tag! 'env:Header' do
|
486
499
|
add_credentials(xml) unless @options[:headers] && @options[:headers]['X-PP-AUTHORIZATION']
|
487
500
|
end
|
488
|
-
|
501
|
+
|
489
502
|
xml.tag! 'env:Body' do
|
490
503
|
xml << body
|
491
504
|
end
|
492
505
|
end
|
493
506
|
xml.target!
|
494
507
|
end
|
495
|
-
|
508
|
+
|
496
509
|
def add_credentials(xml)
|
497
510
|
xml.tag! 'RequesterCredentials', CREDENTIALS_NAMESPACES do
|
498
511
|
xml.tag! 'n1:Credentials' do
|
@@ -503,7 +516,7 @@ module ActiveMerchant #:nodoc:
|
|
503
516
|
end
|
504
517
|
end
|
505
518
|
end
|
506
|
-
|
519
|
+
|
507
520
|
def add_address(xml, element, address)
|
508
521
|
return if address.nil?
|
509
522
|
xml.tag! element do
|
@@ -517,7 +530,7 @@ module ActiveMerchant #:nodoc:
|
|
517
530
|
xml.tag! 'n2:PostalCode', address[:zip]
|
518
531
|
end
|
519
532
|
end
|
520
|
-
|
533
|
+
|
521
534
|
def add_payment_details_items_xml(xml, options, currency_code)
|
522
535
|
options[:items].each do |item|
|
523
536
|
xml.tag! 'n2:PaymentDetailsItem' do
|
@@ -533,11 +546,11 @@ module ActiveMerchant #:nodoc:
|
|
533
546
|
end
|
534
547
|
end
|
535
548
|
end
|
536
|
-
|
549
|
+
|
537
550
|
def add_payment_details(xml, money, currency_code, options = {})
|
538
551
|
xml.tag! 'n2:PaymentDetails' do
|
539
552
|
xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
|
540
|
-
|
553
|
+
|
541
554
|
# All of the values must be included together and add up to the order total
|
542
555
|
if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
|
543
556
|
xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
|
@@ -551,36 +564,36 @@ module ActiveMerchant #:nodoc:
|
|
551
564
|
xml.tag! 'n2:InsuranceOptionOffered', options[:insurance_option_offered] if options.has_key?(:insurance_option_offered)
|
552
565
|
|
553
566
|
xml.tag! 'n2:OrderDescription', options[:description] unless options[:description].blank?
|
554
|
-
|
567
|
+
|
555
568
|
# Custom field Character length and limitations: 256 single-byte alphanumeric characters
|
556
|
-
xml.tag! 'n2:Custom', options[:custom] unless options[:custom].blank?
|
569
|
+
xml.tag! 'n2:Custom', options[:custom] unless options[:custom].blank?
|
557
570
|
|
558
571
|
xml.tag! 'n2:InvoiceID', (options[:order_id] || options[:invoice_id]) unless (options[:order_id] || options[:invoice_id]).blank?
|
559
|
-
xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
|
572
|
+
xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
|
560
573
|
|
561
|
-
# The notify URL applies only to DoExpressCheckoutPayment.
|
574
|
+
# The notify URL applies only to DoExpressCheckoutPayment.
|
562
575
|
# This value is ignored when set in SetExpressCheckout or GetExpressCheckoutDetails
|
563
|
-
xml.tag! 'n2:NotifyURL', options[:notify_url] unless options[:notify_url].blank?
|
564
|
-
|
576
|
+
xml.tag! 'n2:NotifyURL', options[:notify_url] unless options[:notify_url].blank?
|
577
|
+
|
565
578
|
add_address(xml, 'n2:ShipToAddress', options[:shipping_address]) unless options[:shipping_address].blank?
|
566
|
-
|
579
|
+
|
567
580
|
add_payment_details_items_xml(xml, options, currency_code) unless options[:items].blank?
|
568
581
|
|
569
582
|
add_express_only_payment_details(xml, options) if options[:express_request]
|
570
583
|
|
571
584
|
# Any value other than Y – This is not a recurring transaction
|
572
|
-
# To pass Y in this field, you must have established a billing agreement with
|
585
|
+
# To pass Y in this field, you must have established a billing agreement with
|
573
586
|
# the buyer specifying the amount, frequency, and duration of the recurring payment.
|
574
587
|
# requires version 80.0 of the API
|
575
|
-
xml.tag! 'n2:Recurring', options[:recurring] unless options[:recurring].blank?
|
588
|
+
xml.tag! 'n2:Recurring', options[:recurring] unless options[:recurring].blank?
|
576
589
|
end
|
577
590
|
end
|
578
591
|
|
579
592
|
def add_express_only_payment_details(xml, options = {})
|
580
|
-
add_optional_fields(xml,
|
581
|
-
%w{n2:NoteText n2:SoftDescriptor
|
582
|
-
n2:TransactionId n2:AllowedPaymentMethodType
|
583
|
-
n2:PaymentRequestID n2:PaymentAction},
|
593
|
+
add_optional_fields(xml,
|
594
|
+
%w{n2:NoteText n2:SoftDescriptor
|
595
|
+
n2:TransactionId n2:AllowedPaymentMethodType
|
596
|
+
n2:PaymentRequestID n2:PaymentAction},
|
584
597
|
options)
|
585
598
|
end
|
586
599
|
|
@@ -599,14 +612,14 @@ module ActiveMerchant #:nodoc:
|
|
599
612
|
end
|
600
613
|
xml
|
601
614
|
end
|
602
|
-
|
615
|
+
|
603
616
|
def endpoint_url
|
604
617
|
URLS[test? ? :test : :live][@options[:signature].blank? ? :certificate : :signature]
|
605
618
|
end
|
606
619
|
|
607
620
|
def commit(action, request)
|
608
621
|
response = parse(action, ssl_post(endpoint_url, build_request(request), @options[:headers]))
|
609
|
-
|
622
|
+
|
610
623
|
build_response(successful?(response), message_from(response), response,
|
611
624
|
:test => test?,
|
612
625
|
:authorization => authorization_from(response),
|
@@ -615,19 +628,19 @@ module ActiveMerchant #:nodoc:
|
|
615
628
|
:cvv_result => response[:cvv2_code]
|
616
629
|
)
|
617
630
|
end
|
618
|
-
|
631
|
+
|
619
632
|
def fraud_review?(response)
|
620
633
|
response[:error_codes] == FRAUD_REVIEW_CODE
|
621
634
|
end
|
622
|
-
|
635
|
+
|
623
636
|
def authorization_from(response)
|
624
637
|
response[:transaction_id] || response[:authorization_id] || response[:refund_transaction_id] # middle one is from reauthorization
|
625
638
|
end
|
626
|
-
|
639
|
+
|
627
640
|
def successful?(response)
|
628
641
|
SUCCESS_CODES.include?(response[:ack])
|
629
642
|
end
|
630
|
-
|
643
|
+
|
631
644
|
def message_from(response)
|
632
645
|
response[:message] || response[:ack]
|
633
646
|
end
|