activemerchant 1.26.0 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/CHANGELOG +17 -0
  2. data/CONTRIBUTORS +20 -0
  3. data/README.md +5 -0
  4. data/lib/active_merchant/billing/base.rb +2 -2
  5. data/lib/active_merchant/billing/gateway.rb +6 -0
  6. data/lib/active_merchant/billing/gateways/authorize_net.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +0 -3
  8. data/lib/active_merchant/billing/gateways/balanced.rb +462 -0
  9. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +3 -3
  10. data/lib/active_merchant/billing/gateways/beanstream.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +3 -2
  12. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +1 -1
  13. data/lib/active_merchant/billing/gateways/braintree.rb +2 -0
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +11 -1
  15. data/lib/active_merchant/billing/gateways/braintree_orange.rb +2 -4
  16. data/lib/active_merchant/billing/gateways/card_stream.rb +2 -2
  17. data/lib/active_merchant/billing/gateways/certo_direct.rb +2 -3
  18. data/lib/active_merchant/billing/gateways/cyber_source.rb +3 -3
  19. data/lib/active_merchant/billing/gateways/data_cash.rb +3 -3
  20. data/lib/active_merchant/billing/gateways/efsnet.rb +3 -3
  21. data/lib/active_merchant/billing/gateways/epay.rb +3 -3
  22. data/lib/active_merchant/billing/gateways/eway.rb +8 -7
  23. data/lib/active_merchant/billing/gateways/eway_managed.rb +3 -3
  24. data/lib/active_merchant/billing/gateways/exact.rb +2 -2
  25. data/lib/active_merchant/billing/gateways/fat_zebra.rb +4 -4
  26. data/lib/active_merchant/billing/gateways/federated_canada.rb +2 -2
  27. data/lib/active_merchant/billing/gateways/first_pay.rb +3 -3
  28. data/lib/active_merchant/billing/gateways/garanti.rb +2 -2
  29. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +3 -1
  30. data/lib/active_merchant/billing/gateways/inspire.rb +2 -2
  31. data/lib/active_merchant/billing/gateways/instapay.rb +2 -2
  32. data/lib/active_merchant/billing/gateways/iridium.rb +4 -5
  33. data/lib/active_merchant/billing/gateways/itransact.rb +2 -2
  34. data/lib/active_merchant/billing/gateways/jetpay.rb +3 -3
  35. data/lib/active_merchant/billing/gateways/linkpoint.rb +3 -6
  36. data/lib/active_merchant/billing/gateways/litle.rb +50 -34
  37. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +3 -3
  38. data/lib/active_merchant/billing/gateways/merchant_ware.rb +2 -2
  39. data/lib/active_merchant/billing/gateways/migs.rb +8 -4
  40. data/lib/active_merchant/billing/gateways/modern_payments.rb +2 -0
  41. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +4 -4
  42. data/lib/active_merchant/billing/gateways/moneris.rb +3 -3
  43. data/lib/active_merchant/billing/gateways/moneris_us.rb +3 -3
  44. data/lib/active_merchant/billing/gateways/nab_transact.rb +8 -6
  45. data/lib/active_merchant/billing/gateways/net_registry.rb +2 -2
  46. data/lib/active_merchant/billing/gateways/netaxept.rb +4 -4
  47. data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
  48. data/lib/active_merchant/billing/gateways/ogone.rb +10 -5
  49. data/lib/active_merchant/billing/gateways/optimal_payment.rb +3 -3
  50. data/lib/active_merchant/billing/gateways/orbital.rb +4 -4
  51. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +2 -2
  52. data/lib/active_merchant/billing/gateways/pay_secure.rb +2 -2
  53. data/lib/active_merchant/billing/gateways/paybox_direct.rb +7 -5
  54. data/lib/active_merchant/billing/gateways/payflow.rb +39 -37
  55. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +4 -3
  56. data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
  57. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +98 -85
  58. data/lib/active_merchant/billing/gateways/paystation.rb +2 -2
  59. data/lib/active_merchant/billing/gateways/payway.rb +3 -2
  60. data/lib/active_merchant/billing/gateways/plugnpay.rb +63 -66
  61. data/lib/active_merchant/billing/gateways/psigate.rb +3 -3
  62. data/lib/active_merchant/billing/gateways/psl_card.rb +3 -3
  63. data/lib/active_merchant/billing/gateways/quantum.rb +2 -2
  64. data/lib/active_merchant/billing/gateways/quickpay.rb +2 -2
  65. data/lib/active_merchant/billing/gateways/realex.rb +7 -7
  66. data/lib/active_merchant/billing/gateways/sage.rb +2 -0
  67. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +1 -1
  68. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +2 -3
  69. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +1 -1
  70. data/lib/active_merchant/billing/gateways/sage_pay.rb +8 -6
  71. data/lib/active_merchant/billing/gateways/sallie_mae.rb +2 -2
  72. data/lib/active_merchant/billing/gateways/secure_net.rb +4 -4
  73. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +9 -6
  74. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +2 -2
  75. data/lib/active_merchant/billing/gateways/skip_jack.rb +3 -3
  76. data/lib/active_merchant/billing/gateways/smart_ps.rb +3 -1
  77. data/lib/active_merchant/billing/gateways/stripe.rb +2 -2
  78. data/lib/active_merchant/billing/gateways/trans_first.rb +2 -2
  79. data/lib/active_merchant/billing/gateways/transax.rb +1 -3
  80. data/lib/active_merchant/billing/gateways/trust_commerce.rb +3 -3
  81. data/lib/active_merchant/billing/gateways/usa_epay.rb +2 -0
  82. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +3 -2
  83. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -6
  84. data/lib/active_merchant/billing/gateways/verifi.rb +2 -2
  85. data/lib/active_merchant/billing/gateways/wirecard.rb +4 -4
  86. data/lib/active_merchant/billing/gateways/worldpay.rb +37 -18
  87. data/lib/active_merchant/billing/integrations/action_view_helper.rb +6 -5
  88. data/lib/active_merchant/billing/integrations/first_data.rb +38 -0
  89. data/lib/active_merchant/billing/integrations/first_data/helper.rb +63 -0
  90. data/lib/active_merchant/billing/integrations/first_data/notification.rb +56 -0
  91. data/lib/active_merchant/billing/integrations/helper.rb +4 -0
  92. data/lib/active_merchant/billing/integrations/maksuturva.rb +86 -0
  93. data/lib/active_merchant/billing/integrations/maksuturva/helper.rb +119 -0
  94. data/lib/active_merchant/billing/integrations/maksuturva/notification.rb +48 -0
  95. data/lib/active_merchant/billing/integrations/paxum.rb +44 -0
  96. data/lib/active_merchant/billing/integrations/paxum/common.rb +24 -0
  97. data/lib/active_merchant/billing/integrations/paxum/helper.rb +42 -0
  98. data/lib/active_merchant/billing/integrations/paxum/notification.rb +33 -0
  99. data/lib/active_merchant/billing/integrations/pxpay.rb +31 -0
  100. data/lib/active_merchant/billing/integrations/pxpay/helper.rb +110 -0
  101. data/lib/active_merchant/billing/integrations/pxpay/notification.rb +157 -0
  102. data/lib/active_merchant/billing/integrations/pxpay/return.rb +25 -0
  103. data/lib/active_merchant/billing/integrations/web_pay.rb +45 -0
  104. data/lib/active_merchant/billing/integrations/web_pay/common.rb +50 -0
  105. data/lib/active_merchant/billing/integrations/web_pay/helper.rb +68 -0
  106. data/lib/active_merchant/billing/integrations/web_pay/notification.rb +51 -0
  107. data/lib/active_merchant/version.rb +1 -1
  108. data/lib/support/gateway_support.rb +9 -2
  109. data/lib/support/ssl_verify.rb +93 -0
  110. metadata +45 -71
  111. data.tar.gz.sig +0 -3
  112. 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
- URL = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
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(URL, post_data(action, parameters)))
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 "sha1" (default), "sha256" or "sha512".
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 required from a future release of ActiveMerchant's Ogone Gateway. Please update your Ogone account to use it."
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
- @options[:signature] ? add_signature(parameters) : deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE)
375
+ add_signature(parameters)
374
376
  parameters.to_query
375
377
  end
376
378
 
377
379
  def add_signature(parameters)
378
- deprecated(OGONE_LOW_ENCRYPTION_DEPRECATION_MESSAGE) unless @options[:signature_encryptor] == 'sha512'
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
- TEST_URL = 'https://webservices.test.optimalpayments.com/creditcardWS/CreditCardServlet/v1'
5
- LIVE_URL = 'https://webservices.optimalpayments.com/creditcardWS/CreditCardServlet/v1'
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? ? TEST_URL : LIVE_URL, "txnMode=#{action}&txnRequest=#{txnRequest}"))
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 :primary_test_url, :secondary_test_url, :primary_live_url, :secondary_live_url
44
+ class_attribute :secondary_test_url, :secondary_live_url
45
45
 
46
- self.primary_test_url = "https://orbitalvar1.paymentech.net/authorize"
46
+ self.test_url = "https://orbitalvar1.paymentech.net/authorize"
47
47
  self.secondary_test_url = "https://orbitalvar2.paymentech.net/authorize"
48
48
 
49
- self.primary_live_url = "https://orbital1.paymentech.net/authorize"
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.primary_test_url : self.primary_live_url
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
- LIVE_URL = 'https://www.paygate.co.za/payxml/process.trans'
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(LIVE_URL, request))
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
- URL = 'https://clearance.commsecure.com.au/cgi-bin/PSDirect'
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(URL, post_data(action, parameters)) )
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
- TEST_URL = 'https://preprod-ppps.paybox.com/PPPS.php'
5
- LIVE_URL = 'https://ppps.paybox.com/PPPS.php'
6
- LIVE_URL_BACKUP = 'https://ppps1.paybox.com/PPPS.php'
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? ? TEST_URL : LIVE_URL, request_data))
145
- response = parse(ssl_post(LIVE_URL_BACKUP, request_data)) if service_unavailable?(response) && !test?
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? ? TEST_URL : LIVE_URL, request, headers))
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
- URL = 'https://sec.paymentexpress.com/pxpost.aspx'
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(URL, request.to_s) )
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