activemerchant 1.18.1 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
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