activemerchant 1.29.1 → 1.30.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 (50) hide show
  1. data/CHANGELOG +48 -0
  2. data/CONTRIBUTORS +19 -0
  3. data/README.md +43 -41
  4. data/lib/active_merchant/billing/check.rb +15 -11
  5. data/lib/active_merchant/billing/credit_card.rb +5 -1
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
  7. data/lib/active_merchant/billing/gateway.rb +1 -1
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
  10. data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
  11. data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
  12. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
  13. data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
  15. data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
  16. data/lib/active_merchant/billing/gateways/eway.rb +114 -171
  17. data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
  18. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
  19. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
  20. data/lib/active_merchant/billing/gateways/litle.rb +50 -19
  21. data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
  22. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
  23. data/lib/active_merchant/billing/gateways/moneris.rb +3 -5
  24. data/lib/active_merchant/billing/gateways/moneris_us.rb +1 -1
  25. data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
  26. data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
  27. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  28. data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
  29. data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
  30. data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
  31. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  32. data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
  33. data/lib/active_merchant/billing/gateways/pin.rb +157 -0
  34. data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
  35. data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
  36. data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -0
  37. data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
  39. data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
  40. data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
  41. data/lib/active_merchant/billing/gateways/worldpay.rb +15 -4
  42. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
  43. data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
  44. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
  45. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
  46. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +2 -2
  47. data/lib/active_merchant/version.rb +1 -1
  48. data.tar.gz.sig +0 -0
  49. metadata +109 -49
  50. metadata.gz.sig +0 -0
@@ -9,12 +9,23 @@ module ActiveMerchant #:nodoc:
9
9
  #
10
10
  # ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, 10 EUR becomes 1000.
11
11
  #
12
+ # Create certificates for authentication:
13
+ #
14
+ # The PEM file expected should contain both the certificate and the generated PEM file.
15
+ # Some sample shell commands to generate the certificates:
16
+ #
17
+ # openssl genrsa -aes128 -out priv.pem -passout pass:[YOUR PASSWORD] 1024
18
+ # openssl req -x509 -new -key priv.pem -passin pass:[YOUR PASSWORD] -days 3000 -out cert.cer
19
+ # cat cert.cer priv.pem > ideal.pem
20
+ #
21
+ # Following the steps above, upload cert.cer to the ideal web interface and pass the path of ideal.pem to the :pem option.
22
+ #
12
23
  # Configure the gateway using your iDEAL bank account info and security settings:
13
24
  #
14
25
  # Create gateway:
15
26
  # gateway = ActiveMerchant::Billing::IdealRabobankGateway.new(
16
- # :login => '123456789', # merchant number
17
- # :pem => File.read(RAILS_ROOT + '/config/ideal.pem'), # put certificate and PEM in this file
27
+ # :login => '123456789', # 9 digit merchant number
28
+ # :pem => File.read(Rails.root + 'config/ideal.pem'),
18
29
  # :password => 'password' # password for the PEM key
19
30
  # )
20
31
  #
@@ -71,13 +71,13 @@ module ActiveMerchant #:nodoc:
71
71
  super
72
72
  end
73
73
 
74
- def authorize(money, creditcard, options = {})
75
- to_pass = create_credit_card_hash(money, creditcard, options)
74
+ def authorize(money, creditcard_or_token, options = {})
75
+ to_pass = build_authorize_request(money, creditcard_or_token, options)
76
76
  build_response(:authorization, @litle.authorization(to_pass))
77
77
  end
78
78
 
79
- def purchase(money, creditcard, options = {})
80
- to_pass = create_credit_card_hash(money, creditcard, options)
79
+ def purchase(money, creditcard_or_token, options = {})
80
+ to_pass = build_purchase_request(money, creditcard_or_token, options)
81
81
  build_response(:sale, @litle.sale(to_pass))
82
82
  end
83
83
 
@@ -98,7 +98,7 @@ module ActiveMerchant #:nodoc:
98
98
 
99
99
  def store(creditcard, options = {})
100
100
  to_pass = create_token_hash(creditcard, options)
101
- build_response(:registerToken, @litle.register_token_request(to_pass), %w(801 802))
101
+ build_response(:registerToken, @litle.register_token_request(to_pass), %w(000 801 802))
102
102
  end
103
103
 
104
104
  private
@@ -142,11 +142,17 @@ module ActiveMerchant #:nodoc:
142
142
  if response['response'] == "0"
143
143
  detail = response["#{kind}Response"]
144
144
  fraud = fraud_result(detail)
145
+ authorization = case kind
146
+ when :registerToken
147
+ response['registerTokenResponse']['litleToken']
148
+ else
149
+ detail['litleTxnId']
150
+ end
145
151
  Response.new(
146
152
  valid_responses.include?(detail['response']),
147
153
  detail['message'],
148
154
  {:litleOnlineResponse => response},
149
- :authorization => detail['litleTxnId'],
155
+ :authorization => authorization,
150
156
  :avs_result => {:code => fraud['avs']},
151
157
  :cvv_result => fraud['cvv'],
152
158
  :test => test?
@@ -156,27 +162,52 @@ module ActiveMerchant #:nodoc:
156
162
  end
157
163
  end
158
164
 
159
- def create_credit_card_hash(money, creditcard, options)
160
- cc_type = CARD_TYPE[creditcard.brand]
165
+ def build_authorize_request(money, creditcard_or_token, options)
166
+ hash = create_hash(money, options)
167
+
168
+ add_credit_card_or_token_hash(hash, creditcard_or_token)
169
+
170
+ hash
171
+ end
172
+
173
+ def build_purchase_request(money, creditcard_or_token, options)
174
+ hash = create_hash(money, options)
175
+
176
+ add_credit_card_or_token_hash(hash, creditcard_or_token)
161
177
 
162
- exp_date_yr = creditcard.year.to_s()[2..3]
178
+ hash
179
+ end
163
180
 
164
- if( creditcard.month.to_s().length == 1 )
165
- exp_date_mo = '0' + creditcard.month.to_s()
181
+ def add_credit_card_or_token_hash(hash, creditcard_or_token)
182
+ if creditcard_or_token.is_a?(String)
183
+ add_token_hash(hash, creditcard_or_token)
166
184
  else
167
- exp_date_mo = creditcard.month.to_s()
185
+ add_credit_card_hash(hash, creditcard_or_token)
168
186
  end
187
+ end
169
188
 
170
- exp_date = exp_date_mo + exp_date_yr
189
+ def add_token_hash(hash, creditcard_or_token)
190
+ token_info = {
191
+ 'litleToken' => creditcard_or_token
192
+ }
193
+
194
+ hash['token'] = token_info
195
+ hash
196
+ end
197
+
198
+ def add_credit_card_hash(hash, creditcard)
199
+ cc_type = CARD_TYPE[creditcard.brand]
200
+ exp_date_yr = creditcard.year.to_s[2..3]
201
+ exp_date_mo = '%02d' % creditcard.month.to_i
202
+ exp_date = exp_date_mo + exp_date_yr
171
203
 
172
204
  card_info = {
173
- 'type' => cc_type,
174
- 'number' => creditcard.number,
175
- 'expDate' => exp_date,
176
- 'cardValidationNum' => creditcard.verification_value
205
+ 'type' => cc_type,
206
+ 'number' => creditcard.number,
207
+ 'expDate' => exp_date,
208
+ 'cardValidationNum' => creditcard.verification_value
177
209
  }
178
210
 
179
- hash = create_hash(money, options)
180
211
  hash['card'] = card_info
181
212
  hash
182
213
  end
@@ -258,7 +289,7 @@ module ActiveMerchant #:nodoc:
258
289
  'customerId' => options[:customer],
259
290
  'reportGroup' => (options[:merchant] || @options[:merchant]),
260
291
  'merchantId' => (options[:merchant_id] || @options[:merchant_id]),
261
- 'orderSource' => 'ecommerce',
292
+ 'orderSource' => (options[:order_source] || 'ecommerce'),
262
293
  'enhancedData' => enhanced_data,
263
294
  'fraudCheckType' => fraud_check_type,
264
295
  'user' => (options[:user] || @options[:user]),
@@ -1,7 +1,10 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class MerchantWareGateway < Gateway
4
+ class_attribute :v4_live_url
5
+
4
6
  self.live_url = self.test_url = 'https://ps1.merchantware.net/MerchantWARE/ws/RetailTransaction/TXRetail.asmx'
7
+ self.v4_live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
5
8
 
6
9
  self.supported_countries = ['US']
7
10
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
@@ -12,13 +15,19 @@ module ActiveMerchant #:nodoc:
12
15
  "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
13
16
  "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/"
14
17
  }
18
+ ENV_NAMESPACES_V4 = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
19
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
20
+ "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"
21
+ }
22
+
15
23
  TX_NAMESPACE = "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail"
24
+ TX_NAMESPACE_V4 = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
16
25
 
17
26
  ACTIONS = {
18
27
  :purchase => "IssueKeyedSale",
19
28
  :authorize => "IssueKeyedPreAuth",
20
29
  :capture => "IssuePostAuth",
21
- :void => "IssueVoid",
30
+ :void => "VoidPreAuthorization",
22
31
  :credit => "IssueKeyedRefund",
23
32
  :reference_credit => "IssueRefundByReference"
24
33
  }
@@ -80,11 +89,10 @@ module ActiveMerchant #:nodoc:
80
89
  # * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
81
90
  def void(authorization, options = {})
82
91
  reference, options[:order_id] = split_reference(authorization)
83
-
84
- request = soap_request(:void) do |xml|
85
- add_reference(xml, reference)
92
+ request = v4_soap_request(:void) do |xml|
93
+ add_reference_token(xml, reference)
86
94
  end
87
- commit(:void, request)
95
+ commit(:void, request, true)
88
96
  end
89
97
 
90
98
  # Refund an amount back a cardholder
@@ -108,7 +116,6 @@ module ActiveMerchant #:nodoc:
108
116
  perform_reference_credit(money, reference, options)
109
117
  end
110
118
 
111
-
112
119
  private
113
120
 
114
121
  def soap_request(action)
@@ -125,6 +132,22 @@ module ActiveMerchant #:nodoc:
125
132
  xml.target!
126
133
  end
127
134
 
135
+ def v4_soap_request(action)
136
+ xml = Builder::XmlMarkup.new :indent => 2
137
+ xml.instruct!
138
+ xml.tag! "soap:Envelope", ENV_NAMESPACES_V4 do
139
+ xml.tag! "soap:Body" do
140
+ xml.tag! ACTIONS[:void], "xmlns" => TX_NAMESPACE_V4 do
141
+ xml.tag! "merchantName", @options[:name]
142
+ xml.tag! "merchantSiteId", @options[:login]
143
+ xml.tag! "merchantKey", @options[:password]
144
+ yield xml
145
+ end
146
+ end
147
+ end
148
+ xml.target!
149
+ end
150
+
128
151
  def build_purchase_request(action, money, credit_card, options)
129
152
  requires!(options, :order_id)
130
153
 
@@ -195,6 +218,10 @@ module ActiveMerchant #:nodoc:
195
218
  xml.tag! "strReferenceCode", reference
196
219
  end
197
220
 
221
+ def add_reference_token(xml, reference)
222
+ xml.tag! "token", reference
223
+ end
224
+
198
225
  def add_address(xml, options)
199
226
  if address = options[:billing_address] || options[:address]
200
227
  xml.tag! "strAVSStreetAddress", address[:address1]
@@ -258,11 +285,19 @@ module ActiveMerchant #:nodoc:
258
285
  response
259
286
  end
260
287
 
261
- def commit(action, request)
288
+ def soap_action(action, v4 = false)
289
+ v4 ? "#{TX_NAMESPACE_V4}#{ACTIONS[action]}" : "#{TX_NAMESPACE}/#{ACTIONS[action]}"
290
+ end
291
+
292
+ def url(v4 = false)
293
+ v4 ? v4_live_url : live_url
294
+ end
295
+
296
+ def commit(action, request, v4 = false)
262
297
  begin
263
- data = ssl_post(self.live_url, request,
298
+ data = ssl_post(url(v4), request,
264
299
  "Content-Type" => 'text/xml; charset=utf-8',
265
- "SOAPAction" => "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail/#{ACTIONS[action]}"
300
+ "SOAPAction" => soap_action(action, v4)
266
301
  )
267
302
  response = parse(action, data)
268
303
  rescue ActiveMerchant::ResponseError => e
@@ -0,0 +1,190 @@
1
+ require 'digest/md5'
2
+ require 'rexml/document'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class MerchantWarriorGateway < Gateway
7
+ TOKEN_TEST_URL = 'https://base.merchantwarrior.com/token/'
8
+ TOKEN_LIVE_URL = 'https://api.merchantwarrior.com/token/'
9
+
10
+ POST_TEST_URL = 'https://base.merchantwarrior.com/post/'
11
+ POST_LIVE_URL = 'https://api.merchantwarrior.com/post/'
12
+
13
+ self.supported_countries = ['AU']
14
+ self.supported_cardtypes = [:visa, :master, :american_express,
15
+ :diners_club, :discover]
16
+ self.homepage_url = 'http://www.merchantwarrior.com/'
17
+ self.display_name = 'MerchantWarrior'
18
+
19
+ self.money_format = :dollars
20
+ self.default_currency = 'AUD'
21
+
22
+ def initialize(options = {})
23
+ requires!(options, :merchant_uuid, :api_key, :api_passphrase)
24
+ super
25
+ end
26
+
27
+ def authorize(money, payment_method, options = {})
28
+ post = {}
29
+ add_amount(post, money, options)
30
+ add_product(post, options)
31
+ add_address(post, options)
32
+ add_payment_method(post, payment_method)
33
+ commit('processAuth', post)
34
+ end
35
+
36
+ def purchase(money, payment_method, options = {})
37
+ post = {}
38
+ add_amount(post, money, options)
39
+ add_product(post, options)
40
+ add_address(post, options)
41
+ add_payment_method(post, payment_method)
42
+ commit('processCard', post)
43
+ end
44
+
45
+ def capture(money, identification)
46
+ post = {}
47
+ add_amount(post, money, options)
48
+ add_transaction(post, identification)
49
+ post.merge!('captureAmount' => money.to_s)
50
+ commit('processCapture', post)
51
+ end
52
+
53
+ def refund(money, identification)
54
+ post = {}
55
+ add_amount(post, money, options)
56
+ add_transaction(post, identification)
57
+ post['refundAmount'] = money
58
+ commit('refundCard', post)
59
+ end
60
+
61
+ def store(creditcard, options = {})
62
+ post = {
63
+ 'cardName' => creditcard.name,
64
+ 'cardNumber' => creditcard.number,
65
+ 'cardExpiryMonth' => sprintf('%02d', creditcard.month),
66
+ 'cardExpiryYear' => sprintf('%02d', creditcard.year)
67
+ }
68
+ commit('addCard', post)
69
+ end
70
+
71
+ private
72
+
73
+ def add_transaction(post, identification)
74
+ post['transactionID'] = identification
75
+ end
76
+
77
+ def add_address(post, options)
78
+ return unless(address = options[:address])
79
+
80
+ post['customerName'] = address[:name]
81
+ post['customerCountry'] = address[:country]
82
+ post['customerState'] = address[:state]
83
+ post['customerCity'] = address[:city]
84
+ post['customerAddress'] = address[:address1]
85
+ post['customerPostCode'] = address[:zip]
86
+ end
87
+
88
+ def add_product(post, options)
89
+ post['transactionProduct'] = options[:transaction_product]
90
+ end
91
+
92
+ def add_payment_method(post, payment_method)
93
+ if payment_method.respond_to?(:number)
94
+ add_creditcard(post, payment_method)
95
+ else
96
+ add_token(post, payment_method)
97
+ end
98
+ end
99
+
100
+ def add_token(post, token)
101
+ post['cardID'] = token
102
+ end
103
+
104
+ def add_creditcard(post, creditcard)
105
+ post['paymentCardNumber'] = creditcard.number
106
+ post['paymentCardName'] = creditcard.name
107
+ post['paymentCardExpiry'] = creditcard.expiry_date.expiration.strftime("%m%y")
108
+ end
109
+
110
+ def add_amount(post, money, options)
111
+ currency = (options[:currency] || currency(money))
112
+
113
+ post['transactionAmount'] = money.to_s
114
+ post['transactionCurrency'] = currency
115
+ post['hash'] = verification_hash(money, currency)
116
+ end
117
+
118
+ def verification_hash(money, currency)
119
+ Digest::MD5.hexdigest(
120
+ (
121
+ @options[:api_passphrase].to_s +
122
+ @options[:merchant_uuid].to_s +
123
+ money.to_s +
124
+ currency
125
+ ).downcase
126
+ )
127
+ end
128
+
129
+ def parse(body)
130
+ xml = REXML::Document.new(body)
131
+
132
+ response = {}
133
+ xml.root.elements.to_a.each do |node|
134
+ parse_element(response, node)
135
+ end
136
+ response
137
+ end
138
+
139
+ def parse_element(response, node)
140
+ if node.has_elements?
141
+ node.elements.each{|element| parse_element(response, element)}
142
+ else
143
+ response[node.name.underscore.to_sym] = node.text
144
+ end
145
+ end
146
+
147
+ def commit(action, post)
148
+ add_auth(action, post)
149
+
150
+ response = parse(ssl_post(url_for(action, post), post_data(post)))
151
+
152
+ Response.new(
153
+ success?(response),
154
+ response[:response_message],
155
+ response,
156
+ :test => test?,
157
+ :authorization => (response[:card_id] || response[:transaction_id])
158
+ )
159
+ end
160
+
161
+ def add_auth(action, post)
162
+ post['merchantUUID'] = @options[:merchant_uuid]
163
+ post['apiKey'] = @options[:api_key]
164
+ unless token?(post)
165
+ post['method'] = action
166
+ end
167
+ end
168
+
169
+ def url_for(action, post)
170
+ if token?(post)
171
+ [(test? ? TOKEN_TEST_URL : TOKEN_LIVE_URL), action].join("/")
172
+ else
173
+ (test? ? POST_TEST_URL : POST_LIVE_URL)
174
+ end
175
+ end
176
+
177
+ def token?(post)
178
+ (post["cardID"] || post["cardName"])
179
+ end
180
+
181
+ def success?(response)
182
+ (response[:response_code] == '0')
183
+ end
184
+
185
+ def post_data(post)
186
+ post.collect{|k,v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
187
+ end
188
+ end
189
+ end
190
+ end
@@ -22,7 +22,7 @@ module ActiveMerchant #:nodoc:
22
22
  # password is your API Token
23
23
  def initialize(options = {})
24
24
  requires!(options, :login, :password)
25
- @options = { :crypt_type => 7 }.update(options)
25
+ options = { :crypt_type => 7 }.merge(options)
26
26
  super
27
27
  end
28
28
 
@@ -70,15 +70,13 @@ module ActiveMerchant #:nodoc:
70
70
  commit 'completion', crediting_params(authorization, :comp_amount => amount(money))
71
71
  end
72
72
 
73
- # Voiding requires the original transaction ID and order ID of some open
74
- # transaction. Closed transactions must be refunded. Note that the only
75
- # methods which may be voided are +capture+ and +purchase+.
73
+ # Voiding cancels an open authorization.
76
74
  #
77
75
  # Concatenate your transaction number and order_id by using a semicolon
78
76
  # (';'). This is to keep the Moneris interface consistent with other
79
77
  # gateways. (See +capture+ for details.)
80
78
  def void(authorization, options = {})
81
- commit 'purchasecorrection', crediting_params(authorization)
79
+ capture(0, authorization, options)
82
80
  end
83
81
 
84
82
  # Performs a refund. This method requires that the original transaction
@@ -22,7 +22,7 @@ module ActiveMerchant #:nodoc:
22
22
  # password is your API Token
23
23
  def initialize(options = {})
24
24
  requires!(options, :login, :password)
25
- @options = { :crypt_type => 7 }.update(options)
25
+ options = { :crypt_type => 7 }.merge(options)
26
26
  super
27
27
  end
28
28
 
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
34
34
  #Transactions currently accepted by NAB Transact XML API
35
35
  TRANSACTIONS = {
36
36
  :purchase => 0, #Standard Payment
37
- :credit => 4, #Refund
37
+ :refund => 4, #Refund
38
38
  :void => 6, #Client Reversal (Void)
39
39
  :authorization => 10, #Preauthorise
40
40
  :capture => 11 #Preauthorise Complete (Advice)
@@ -66,6 +66,10 @@ module ActiveMerchant #:nodoc:
66
66
  end
67
67
  end
68
68
 
69
+ def refund(money, authorization, options = {})
70
+ commit :refund, build_reference_request(money, authorization)
71
+ end
72
+
69
73
  def store(creditcard, options = {})
70
74
  requires!(options, :billing_id, :amount)
71
75
  commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
@@ -104,10 +108,23 @@ module ActiveMerchant #:nodoc:
104
108
  xml.target!
105
109
  end
106
110
 
111
+ def build_reference_request(money, reference)
112
+ xml = Builder::XmlMarkup.new
113
+
114
+ transaction_id, order_id, preauth_id, original_amount = reference.split('*')
115
+
116
+ xml.tag! 'amount', (money ? amount(money) : original_amount)
117
+ xml.tag! 'currency', options[:currency] || currency(money)
118
+ xml.tag! 'txnID', transaction_id
119
+ xml.tag! 'purchaseOrderNo', order_id
120
+ xml.tag! 'preauthID', preauth_id
121
+
122
+ xml.target!
123
+ end
124
+
107
125
  #Generate payment request XML
108
126
  # - API is set to allow multiple Txn's but currentlu only allows one
109
127
  # - txnSource = 23 - (XML)
110
-
111
128
  def build_request(action, body)
112
129
  xml = Builder::XmlMarkup.new
113
130
  xml.instruct!
@@ -210,7 +227,7 @@ module ActiveMerchant #:nodoc:
210
227
  end
211
228
 
212
229
  def authorization_from(response)
213
- response[:txn_id]
230
+ [response[:txn_id], response[:purchase_order_no], response[:preauth_id], response[:amount]].join('*')
214
231
  end
215
232
 
216
233
  def message_from(response)
@@ -177,6 +177,7 @@ module ActiveMerchant #:nodoc:
177
177
 
178
178
  def post_data(action, parameters = {})
179
179
  parameters[:account_id] = @options[:login]
180
+ parameters[:site_tag] = @options[:site_tag] if @options[:site_tag].present?
180
181
  parameters[:pay_type] = 'C'
181
182
  parameters[:tran_type] = TRANSACTIONS[action]
182
183