activemerchant 1.18.1 → 1.20.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.
Files changed (27) hide show
  1. data.tar.gz.sig +5 -0
  2. data/CHANGELOG +15 -0
  3. data/CONTRIBUTORS +4 -0
  4. data/lib/active_merchant.rb +1 -0
  5. data/lib/active_merchant/billing/credit_card.rb +1 -1
  6. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +5 -1
  7. data/lib/active_merchant/billing/gateways/braintree_blue.rb +6 -2
  8. data/lib/active_merchant/billing/gateways/elavon.rb +2 -1
  9. data/lib/active_merchant/billing/gateways/exact.rb +5 -0
  10. data/lib/active_merchant/billing/gateways/moneris.rb +4 -0
  11. data/lib/active_merchant/billing/gateways/ogone.rb +94 -56
  12. data/lib/active_merchant/billing/gateways/orbital.rb +34 -26
  13. data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -1
  14. data/lib/active_merchant/billing/gateways/samurai.rb +120 -0
  15. data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -1
  16. data/lib/active_merchant/billing/gateways/usa_epay.rb +13 -184
  17. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
  18. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +194 -0
  19. data/lib/active_merchant/billing/integrations/dwolla.rb +2 -2
  20. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +7 -4
  21. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +5 -0
  22. data/lib/active_merchant/billing/integrations/helper.rb +6 -1
  23. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +46 -4
  24. data/lib/active_merchant/billing/integrations/two_checkout.rb +1 -2
  25. data/lib/active_merchant/version.rb +1 -1
  26. metadata +66 -40
  27. metadata.gz.sig +0 -0
data.tar.gz.sig ADDED
@@ -0,0 +1,5 @@
1
+ n�j�����c��;7r7x�@�����:v&��!O7���%�K�wB�����B���
2
+
3
+ O����(�� <?�@K�O�����17���C�p��g�_U�1�b�p.�
4
+ e9 u�*_"'�`J��J�(��V��ݙ0�U�8�$Th@I3C A[>� ^z]�x�`�=��W�TEK8o!��`�ݛ�+n z�l}�G�@TS!M^ӥ�`J�w(�p_2�������C�=wV2��$$�
5
+ �����_.���*��]���
data/CHANGELOG CHANGED
@@ -1,5 +1,20 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
+ == Version 1.20.0 (November 14, 2011)
4
+
5
+ * Add support for USA ePay Advanced SOAP interface [matthewcalebsmith/jduff]
6
+ * Beanstram: fix purchase with Secure Profile [pitr/jduff]
7
+ * Orbital: various fixes [Soleone]
8
+ * Add Samuari gateway by Fee Fighters [jkrall/odorcicd]
9
+ * Lock money gem to 3.7.1 or less since newer versions break in 1.9 [jduff]
10
+ * Braintree: handle gateway rejected transactions gracefully [braintreeps/jduff]
11
+ * Ogone: support different signature encryptors, custom currency and eci [ZenCocoon/rymai/jduff]
12
+ * Payflow Link: use secure token [jduff]
13
+ * Added refund method to Exact, Pay Junction and Skip Jack gateways [jduff]
14
+ * Elavon: added test url [kylekeesling/jduff]
15
+ * Fix redundent errors when credit card is expired [castiglione/jduff]
16
+ * Two Checkout: update service url [vampirechicken/jduff]
17
+
3
18
  == Version 1.18.1 (September 23, 2011)
4
19
 
5
20
  * Braintree: allow setting merchant_account_id on initialize [jduff]
data/CONTRIBUTORS CHANGED
@@ -255,3 +255,7 @@ CardSave (August, 2011)
255
255
  Dwolla (September, 2011)
256
256
 
257
257
  * James Armstead (armsteadj1)
258
+
259
+ Samurai (November, 2011)
260
+
261
+ * Joshua Krall (jkrall)
@@ -25,6 +25,7 @@ require 'active_support'
25
25
  require 'active_support/core_ext/string/inflections'
26
26
  require 'active_support/core_ext/hash/indifferent_access'
27
27
  require 'active_support/core_ext/hash/conversions'
28
+ require 'active_support/core_ext/object/conversions'
28
29
  require 'active_support/core_ext/class/attribute'
29
30
  require 'active_support/core_ext/class/attribute_accessors'
30
31
  require 'active_support/core_ext/class/delegating_attributes'
@@ -236,7 +236,7 @@ module ActiveMerchant #:nodoc:
236
236
  else
237
237
  errors.add :month, "is not a valid month" unless valid_month?(@month)
238
238
  errors.add :year, "expired" if expired?
239
- errors.add :year, "is not a valid year" unless valid_expiry_year?(@year)
239
+ errors.add :year, "is not a valid year" unless expired? || valid_expiry_year?(@year)
240
240
  end
241
241
  end
242
242
 
@@ -90,7 +90,11 @@ module ActiveMerchant #:nodoc:
90
90
 
91
91
  private
92
92
  def purchase_action(source)
93
- (card_brand(source) == "check") ? :check_purchase : :purchase
93
+ if source.is_a?(Check)
94
+ :check_purchase
95
+ else
96
+ :purchase
97
+ end
94
98
  end
95
99
 
96
100
  def void_action(original_transaction_type)
@@ -22,7 +22,7 @@ module ActiveMerchant #:nodoc:
22
22
  Braintree::Configuration.merchant_id = options[:merchant_id]
23
23
  Braintree::Configuration.public_key = options[:public_key]
24
24
  Braintree::Configuration.private_key = options[:private_key]
25
- Braintree::Configuration.environment = test? ? :sandbox : :production
25
+ Braintree::Configuration.environment = (options[:environment] || (test? ? :sandbox : :production)).to_sym
26
26
  Braintree::Configuration.logger.level = Logger::ERROR if Braintree::Configuration.logger
27
27
  Braintree::Configuration.custom_user_agent = "ActiveMerchant #{ActiveMerchant::VERSION}"
28
28
  super
@@ -176,7 +176,11 @@ module ActiveMerchant #:nodoc:
176
176
  :postal_match => result.transaction.avs_postal_code_response_code
177
177
  }
178
178
  response_options[:cvv_result] = result.transaction.cvv_response_code
179
- message = "#{result.transaction.processor_response_code} #{result.transaction.processor_response_text}"
179
+ if result.transaction.status == "gateway_rejected"
180
+ message = "Transaction declined - gateway rejected"
181
+ else
182
+ message = "#{result.transaction.processor_response_code} #{result.transaction.processor_response_text}"
183
+ end
180
184
  else
181
185
  message = message_from_result(result)
182
186
  end
@@ -30,7 +30,8 @@ module ActiveMerchant #:nodoc:
30
30
  # puts response.authorization # Retrieve the unique transaction ID returned by Elavon
31
31
  #
32
32
  class ElavonGateway < ViaklixGateway
33
- self.test_url = self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
33
+ self.test_url = 'https://demo.myvirtualmerchant.com/VirtualMerchantDemo/process.do'
34
+ self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
34
35
 
35
36
  self.display_name = 'Elavon MyVirtualMerchant'
36
37
  self.supported_countries = ['US', 'CA']
@@ -68,6 +68,11 @@ module ActiveMerchant #:nodoc:
68
68
  end
69
69
 
70
70
  def credit(money, authorization, options = {})
71
+ deprecated CREDIT_DEPRECATION_MESSAGE
72
+ refund(money, authorization, options)
73
+ end
74
+
75
+ def refund(money, authorization, options = {})
71
76
  commit(:credit, build_capture_or_credit_request(money, authorization, options))
72
77
  end
73
78
 
@@ -78,6 +78,10 @@ module ActiveMerchant #:nodoc:
78
78
  def refund(money, authorization, options = {})
79
79
  commit 'refund', crediting_params(authorization, :amount => amount(money))
80
80
  end
81
+
82
+ def test?
83
+ @options[:test] || super
84
+ end
81
85
  private # :nodoc: all
82
86
 
83
87
  def expdate(creditcard)
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'rexml/document'
2
3
 
3
4
  module ActiveMerchant #:nodoc:
@@ -8,27 +9,32 @@ module ActiveMerchant #:nodoc:
8
9
  # communication between Ogone systems and your e-commerce website.
9
10
  #
10
11
  # This implementation follows the specification provided in the DirectLink integration
11
- # guide version 2.4 (December 2008), available here:
12
+ # guide version 4.2.0 (26 October 2011), available here:
12
13
  # https://secure.ogone.com/ncol/Ogone_DirectLink_EN.pdf
13
14
  #
14
15
  # It also features aliases, which allow to store/unstore credit cards, as specified in
15
- # the Alias Manager Option guide version 2.2 available here:
16
+ # the Alias Manager Option guide version 3.2.0 (26 October 2011) available here:
16
17
  # https://secure.ogone.com/ncol/Ogone_Alias_EN.pdf
17
18
  #
18
- # It was last tested on Release 04.79 of Ogone e-Commerce (dated 11/02/2009).
19
+ # It was last tested on Release 4.89 of Ogone DirectLink + AliasManager (26 October 2011).
19
20
  #
20
- # For any questions or comments, please contact Nicolas Jacobeus (nj@belighted.com).
21
+ # For any questions or comments, please contact one of the following:
22
+ # - Nicolas Jacobeus (nj@belighted.com),
23
+ # - Sébastien Grosjean (public@zencocoon.com),
24
+ # - Rémy Coutable (remy@jilion.com).
21
25
  #
22
- # == Example use:
26
+ # == Usage
23
27
  #
24
28
  # gateway = ActiveMerchant::Billing::OgoneGateway.new(
25
- # :login => "my_ogone_psp_id",
26
- # :user => "my_ogone_user_id",
27
- # :password => "my_ogone_pswd",
28
- # :signature => "my_ogone_sha1_signature" # extra security, only if you configured your Ogone environment so
29
+ # :login => "my_ogone_psp_id",
30
+ # :user => "my_ogone_user_id",
31
+ # :password => "my_ogone_pswd",
32
+ # :signature => "my_ogone_sha_signature", # Only if you configured your Ogone environment so.
33
+ # :signature_encryptor => "sha512", # Can be "sha1" (default), "sha256" or "sha512".
34
+ # # Must be the same as the one configured in your Ogone account.
29
35
  # )
30
36
  #
31
- # # set up credit card obj as in main ActiveMerchant example
37
+ # # set up credit card object as in main ActiveMerchant example
32
38
  # creditcard = ActiveMerchant::Billing::CreditCard.new(
33
39
  # :type => 'visa',
34
40
  # :number => '4242424242424242',
@@ -47,18 +53,21 @@ module ActiveMerchant #:nodoc:
47
53
  # puts response.message # Retrieve the message returned by Ogone
48
54
  # puts response.authorization # Retrieve the unique transaction ID returned by Ogone
49
55
  #
50
- # To use the alias feature, simply add :alias in the options hash:
56
+ # == Alias feature
51
57
  #
52
- # gateway.purchase(1000, creditcard, :order_id => "1", :alias => "myawesomecustomer") # associates the alias to that creditcard
53
- # gateway.purchase(2000, nil, :order_id => "2", :alias => "myawesomecustomer") # don't need to know the creditcard for subsequent orders
58
+ # To use the alias feature, simply add :store in the options hash:
59
+ #
60
+ # # Associate the alias to that credit card
61
+ # gateway.purchase(1000, creditcard, :order_id => "1", :store => "myawesomecustomer")
62
+ #
63
+ # # You can use the alias instead of the credit card for subsequent orders
64
+ # gateway.purchase(2000, "myawesomecustomer", :order_id => "2")
54
65
  #
55
66
  class OgoneGateway < Gateway
56
67
 
57
68
  URLS = {
58
- :test => { :order => 'https://secure.ogone.com/ncol/test/orderdirect.asp',
59
- :maintenance => 'https://secure.ogone.com/ncol/test/maintenancedirect.asp' },
60
- :production => { :order => 'https://secure.ogone.com/ncol/prod/orderdirect.asp',
61
- :maintenance => 'https://secure.ogone.com/ncol/prod/maintenancedirect.asp' }
69
+ :order => 'https://secure.ogone.com/ncol/%s/orderdirect.asp',
70
+ :maintenance => 'https://secure.ogone.com/ncol/%s/maintenancedirect.asp'
62
71
  }
63
72
 
64
73
  CVV_MAPPING = { 'OK' => 'M',
@@ -68,8 +77,12 @@ module ActiveMerchant #:nodoc:
68
77
  AVS_MAPPING = { 'OK' => 'M',
69
78
  'KO' => 'N',
70
79
  'NO' => 'R' }
80
+
71
81
  SUCCESS_MESSAGE = "The transaction was successful"
72
82
 
83
+ 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."
84
+ 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."
85
+
73
86
  self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
74
87
  # also supports Airplus and UATP
75
88
  self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
@@ -108,7 +121,7 @@ module ActiveMerchant #:nodoc:
108
121
 
109
122
  # Complete a previously authorized transaction.
110
123
  def capture(money, authorization, options = {})
111
- post = {}
124
+ post = {}
112
125
  add_authorization(post, reference_from(authorization))
113
126
  add_invoice(post, options)
114
127
  add_customer_data(post, options)
@@ -124,7 +137,7 @@ module ActiveMerchant #:nodoc:
124
137
  end
125
138
 
126
139
  # Credit the specified account by a specific amount.
127
- def credit(money, identification_or_credit_card, options = {})
140
+ def credit(money, identification_or_credit_card, options = {})
128
141
  if reference_transaction?(identification_or_credit_card)
129
142
  deprecated CREDIT_DEPRECATION_MESSAGE
130
143
  # Referenced credit: refund of a settled transaction
@@ -133,34 +146,35 @@ module ActiveMerchant #:nodoc:
133
146
  perform_non_referenced_credit(money, identification_or_credit_card, options)
134
147
  end
135
148
  end
136
-
149
+
137
150
  # Refund of a settled transaction
138
- def refund(money, reference, options = {})
151
+ def refund(money, reference, options = {})
139
152
  perform_reference_credit(money, reference, options)
140
153
  end
141
154
 
142
155
  def test?
143
156
  @options[:test] || super
144
157
  end
145
-
158
+
146
159
  private
160
+
147
161
  def reference_from(authorization)
148
162
  authorization.split(";").first
149
163
  end
150
-
164
+
151
165
  def reference_transaction?(identifier)
152
- return false unless identifier.is_a?(String)
166
+ return false unless identifier.is_a?(String)
153
167
  reference, action = identifier.split(";")
154
168
  !action.nil?
155
169
  end
156
-
170
+
157
171
  def perform_reference_credit(money, payment_target, options = {})
158
172
  post = {}
159
173
  add_authorization(post, reference_from(payment_target))
160
174
  add_money(post, money, options)
161
- commit('RFD', post)
175
+ commit('RFD', post)
162
176
  end
163
-
177
+
164
178
  def perform_non_referenced_credit(money, payment_target, options = {})
165
179
  # Non-referenced credit: acts like a reverse purchase
166
180
  post = {}
@@ -171,31 +185,32 @@ module ActiveMerchant #:nodoc:
171
185
  add_money(post, money, options)
172
186
  commit('RFD', post)
173
187
  end
174
-
188
+
175
189
  def add_payment_source(post, payment_source, options)
176
190
  if payment_source.is_a?(String)
177
191
  add_alias(post, payment_source)
178
- add_eci(post, '9')
192
+ add_eci(post, options[:eci] || '9')
179
193
  else
180
194
  add_alias(post, options[:store])
195
+ add_eci(post, options[:eci] || '7')
181
196
  add_creditcard(post, payment_source)
182
197
  end
183
- end
184
-
198
+ end
199
+
185
200
  def add_eci(post, eci)
186
- add_pair post, 'ECI', eci
201
+ add_pair post, 'ECI', eci.to_s
187
202
  end
188
-
203
+
189
204
  def add_alias(post, _alias)
190
- add_pair post, 'ALIAS', _alias
205
+ add_pair post, 'ALIAS', _alias
191
206
  end
192
207
 
193
208
  def add_authorization(post, authorization)
194
- add_pair post, 'PAYID', authorization
209
+ add_pair post, 'PAYID', authorization
195
210
  end
196
211
 
197
212
  def add_money(post, money, options)
198
- add_pair post, 'currency', options[:currency] || currency(money)
213
+ add_pair post, 'currency', options[:currency] || @options[:currency] || currency(money)
199
214
  add_pair post, 'amount', amount(money)
200
215
  end
201
216
 
@@ -226,35 +241,39 @@ module ActiveMerchant #:nodoc:
226
241
  end
227
242
 
228
243
  def parse(body)
229
- xml = REXML::Document.new(body)
230
- convert_attributes_to_hash(xml.root.attributes)
244
+ xml_root = REXML::Document.new(body).root
245
+ convert_attributes_to_hash(xml_root.attributes)
231
246
  end
232
247
 
233
248
  def commit(action, parameters)
234
- add_pair parameters, 'PSPID', @options[:login]
235
- add_pair parameters, 'USERID', @options[:user]
236
- add_pair parameters, 'PSWD', @options[:password]
237
- url = URLS[test? ? :test : :production][parameters['PAYID'] ? :maintenance : :order ]
249
+ add_pair parameters, 'PSPID', @options[:login]
250
+ add_pair parameters, 'USERID', @options[:user]
251
+ add_pair parameters, 'PSWD', @options[:password]
252
+
253
+ url = URLS[parameters['PAYID'] ? :maintenance : :order] % [test? ? "test" : "prod"]
238
254
  response = parse(ssl_post(url, post_data(action, parameters)))
239
- options = { :authorization => [response["PAYID"], action].join(";"),
240
- :test => test?,
241
- :avs_result => { :code => AVS_MAPPING[response["AAVCheck"]] },
242
- :cvv_result => CVV_MAPPING[response["CVCCheck"]] }
255
+
256
+ options = {
257
+ :authorization => [response["PAYID"], action].join(";"),
258
+ :test => test?,
259
+ :avs_result => { :code => AVS_MAPPING[response["AAVCheck"]] },
260
+ :cvv_result => CVV_MAPPING[response["CVCCheck"]]
261
+ }
243
262
  Response.new(successful?(response), message_from(response), response, options)
244
263
  end
245
-
264
+
246
265
  def successful?(response)
247
266
  response["NCERROR"] == "0"
248
267
  end
249
268
 
250
269
  def message_from(response)
251
- if successful?(response)
270
+ if successful?(response)
252
271
  SUCCESS_MESSAGE
253
272
  else
254
273
  format_error_message(response["NCERRORPLUS"])
255
274
  end
256
275
  end
257
-
276
+
258
277
  def format_error_message(message)
259
278
  raw_message = message.to_s.strip
260
279
  case raw_message
@@ -268,16 +287,35 @@ module ActiveMerchant #:nodoc:
268
287
  end
269
288
 
270
289
  def post_data(action, parameters = {})
271
- add_pair parameters, 'Operation' , action
272
- if @options[:signature] # the user wants a SHA-1 signature
273
- string = ['orderID','amount','currency','CARDNO','PSPID','Operation','ALIAS'].map{|s|parameters[s]}.join + @options[:signature]
274
- add_pair parameters, 'SHASign' , Digest::SHA1.hexdigest(string)
290
+ add_pair parameters, 'Operation', action
291
+ @options[:signature] ? add_signature(parameters) : deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE)
292
+ parameters.to_query
293
+ end
294
+
295
+ def add_signature(parameters)
296
+ deprecated(OGONE_LOW_ENCRYPTION_DEPRECATION_MESSAGE) unless @options[:signature_encryptor] == 'sha512'
297
+
298
+ sha_encryptor = case @options[:signature_encryptor]
299
+ when 'sha256'
300
+ Digest::SHA256
301
+ when 'sha512'
302
+ Digest::SHA512
303
+ else
304
+ Digest::SHA1
305
+ end
306
+
307
+ string_to_digest = if @options[:signature_encryptor]
308
+ parameters.sort { |a, b| a[0].upcase <=> b[0].upcase }.map { |k, v| "#{k.upcase}=#{v}" }.join(@options[:signature])
309
+ else
310
+ %w[orderID amount currency CARDNO PSPID Operation ALIAS].map { |key| parameters[key] }.join
275
311
  end
276
- parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
312
+ string_to_digest << @options[:signature]
313
+
314
+ add_pair parameters, 'SHASign', sha_encryptor.hexdigest(string_to_digest).upcase
277
315
  end
278
316
 
279
- def add_pair(post, key, value, options = {})
280
- post[key] = value if !value.blank? || options[:required]
317
+ def add_pair(post, key, value)
318
+ post[key] = value if !value.blank?
281
319
  end
282
320
 
283
321
  def convert_attributes_to_hash(rexml_attributes)
@@ -122,8 +122,8 @@ module ActiveMerchant #:nodoc:
122
122
  end
123
123
 
124
124
  # setting money to nil will perform a full void
125
- def void(money, authorization, options = {})
126
- order = build_void_request_xml(money, authorization, options)
125
+ def void(authorization, options = {})
126
+ order = build_void_request_xml(authorization, options)
127
127
  commit(order)
128
128
  end
129
129
 
@@ -167,7 +167,7 @@ module ActiveMerchant #:nodoc:
167
167
  xml.tag! :CurrencyCode, currency_code(currency)
168
168
  xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
169
169
 
170
- xml.tag! :CardSecValInd, 1 if creditcard.verification_value? && %w( visa discover ).include?(creditcard.type)
170
+ xml.tag! :CardSecValInd, 1 if creditcard.verification_value? && %w( visa discover ).include?(creditcard.brand)
171
171
  xml.tag! :CardSecVal, creditcard.verification_value if creditcard.verification_value?
172
172
  end
173
173
 
@@ -242,17 +242,13 @@ module ActiveMerchant #:nodoc:
242
242
 
243
243
  def build_new_order_xml(action, money, parameters = {})
244
244
  requires!(parameters, :order_id)
245
- xml = Builder::XmlMarkup.new(:indent => 2)
246
- xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
245
+ xml = xml_envelope
247
246
  xml.tag! :Request do
248
247
  xml.tag! :NewOrder do
249
- xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
250
- xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
248
+ add_xml_credentials(xml)
251
249
  xml.tag! :IndustryType, parameters[:industry_type] || "EC"
252
250
  xml.tag! :MessageType, action
253
- xml.tag! :BIN, '000002' # PNS Tampa
254
- xml.tag! :MerchantID, @options[:merchant_id]
255
- xml.tag! :TerminalID, parameters[:terminal_id] || '001'
251
+ add_bin_merchant_and_terminal(xml, parameters)
256
252
 
257
253
  yield xml if block_given?
258
254
 
@@ -272,38 +268,29 @@ module ActiveMerchant #:nodoc:
272
268
 
273
269
  def build_mark_for_capture_xml(money, authorization, parameters = {})
274
270
  tx_ref_num, order_id = authorization.split(';')
275
- xml = Builder::XmlMarkup.new(:indent => 2)
276
- xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
271
+ xml = xml_envelope
277
272
  xml.tag! :Request do
278
273
  xml.tag! :MarkForCapture do
279
- xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
280
- xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
274
+ add_xml_credentials(xml)
281
275
  xml.tag! :OrderID, order_id
282
276
  xml.tag! :Amount, amount(money)
283
- xml.tag! :BIN, '000002' # PNS Tampa
284
- xml.tag! :MerchantID, @options[:merchant_id]
285
- xml.tag! :TerminalID, parameters[:terminal_id] || '001'
277
+ add_bin_merchant_and_terminal(xml, parameters)
286
278
  xml.tag! :TxRefNum, tx_ref_num
287
279
  end
288
280
  end
289
281
  xml.target!
290
282
  end
291
283
 
292
- def build_void_request_xml(money, authorization, parameters = {})
284
+ def build_void_request_xml(authorization, parameters = {})
293
285
  tx_ref_num, order_id = authorization.split(';')
294
- xml = Builder::XmlMarkup.new(:indent => 2)
295
- xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
286
+ xml = xml_envelope
296
287
  xml.tag! :Request do
297
288
  xml.tag! :Reversal do
298
- xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
299
- xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
289
+ add_xml_credentials(xml)
300
290
  xml.tag! :TxRefNum, tx_ref_num
301
291
  xml.tag! :TxRefIdx, parameters[:transaction_index]
302
- xml.tag! :AdjustedAmt, amount(money)
303
292
  xml.tag! :OrderID, order_id
304
- xml.tag! :BIN, '000002' # PNS Tampa
305
- xml.tag! :MerchantID, @options[:merchant_id]
306
- xml.tag! :TerminalID, parameters[:terminal_id] || '001'
293
+ add_bin_merchant_and_terminal(xml, parameters)
307
294
  end
308
295
  end
309
296
  xml.target!
@@ -316,6 +303,27 @@ module ActiveMerchant #:nodoc:
316
303
  def expiry_date(credit_card)
317
304
  "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
318
305
  end
306
+
307
+ def bin
308
+ @options[:bin] || '000001' # default is Salem Global
309
+ end
310
+
311
+ def xml_envelope
312
+ xml = Builder::XmlMarkup.new(:indent => 2)
313
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
314
+ xml
315
+ end
316
+
317
+ def add_xml_credentials(xml)
318
+ xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
319
+ xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
320
+ end
321
+
322
+ def add_bin_merchant_and_terminal(xml, parameters)
323
+ xml.tag! :BIN, bin
324
+ xml.tag! :MerchantID, @options[:merchant_id]
325
+ xml.tag! :TerminalID, parameters[:terminal_id] || '001'
326
+ end
319
327
  end
320
328
  end
321
329
  end