activemerchant 1.29.3 → 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 (47) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +39 -0
  3. data/CONTRIBUTORS +19 -0
  4. data/README.md +43 -41
  5. data/lib/active_merchant/billing/check.rb +15 -11
  6. data/lib/active_merchant/billing/credit_card.rb +5 -1
  7. data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
  8. data/lib/active_merchant/billing/gateway.rb +1 -1
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
  10. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
  11. data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
  12. data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
  13. data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
  14. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
  15. data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
  16. data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
  17. data/lib/active_merchant/billing/gateways/eway.rb +114 -171
  18. data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
  19. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
  20. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
  21. data/lib/active_merchant/billing/gateways/litle.rb +50 -19
  22. data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
  23. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
  24. data/lib/active_merchant/billing/gateways/moneris.rb +2 -4
  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/integrations/payflow_link/helper.rb +4 -1
  42. data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
  43. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
  44. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
  45. data/lib/active_merchant/version.rb +1 -1
  46. metadata +109 -49
  47. metadata.gz.sig +0 -0
@@ -90,7 +90,9 @@ module ActiveMerchant #:nodoc:
90
90
 
91
91
  Response.new(successful?(response), message_from(response), hash_from_xml(response),
92
92
  :test => test?,
93
- :authorization => authorization_from(response)
93
+ :authorization => authorization_from(response),
94
+ :avs_result => { :code => avs_result_from(response) },
95
+ :cvv_result => cvv_result_from(response)
94
96
  )
95
97
  end
96
98
 
@@ -108,7 +110,15 @@ module ActiveMerchant #:nodoc:
108
110
  end
109
111
 
110
112
  def authorization_from(response)
111
- REXML::XPath.first(response, '//confirmationNumber').text rescue nil
113
+ get_text_from_document(response, '//confirmationNumber')
114
+ end
115
+
116
+ def avs_result_from(response)
117
+ get_text_from_document(response, '//avsResponse')
118
+ end
119
+
120
+ def cvv_result_from(response)
121
+ get_text_from_document(response, '//cvdResponse')
112
122
  end
113
123
 
114
124
  def hash_from_xml(response)
@@ -138,6 +148,11 @@ module ActiveMerchant #:nodoc:
138
148
  xml.target!
139
149
  end
140
150
 
151
+ def get_text_from_document(document, node)
152
+ node = REXML::XPath.first(document, node)
153
+ node && node.text
154
+ end
155
+
141
156
  def cc_auth_request(money, opts)
142
157
  xml_document('ccAuthRequestV1') do |xml|
143
158
  build_merchant_account(xml, @options)
@@ -251,7 +266,7 @@ module ActiveMerchant #:nodoc:
251
266
  xml.tag! 'country', CGI.escape(addr[:country] ) if addr[:country].present?
252
267
  xml.tag! 'zip' , CGI.escape(addr[:zip] ) # this one's actually required
253
268
  xml.tag! 'phone' , CGI.escape(addr[:phone] ) if addr[:phone].present?
254
- #xml.tag! 'email' , ''
269
+ xml.tag! 'email', CGI.escape(opts[:email]) if opts[:email]
255
270
  end
256
271
  end
257
272
 
@@ -125,9 +125,13 @@ module ActiveMerchant #:nodoc:
125
125
  refund(money, authorization, options)
126
126
  end
127
127
 
128
- # setting money to nil will perform a full void
129
- def void(money, authorization, options = {})
130
- order = build_void_request_xml(money, authorization, options)
128
+ def void(authorization, options = {}, deprecated = {})
129
+ if(!options.kind_of?(Hash))
130
+ deprecated("Calling the void method with an amount parameter is deprecated and will be removed in a future version.")
131
+ return void(options, deprecated.merge(:amount => authorization))
132
+ end
133
+
134
+ order = build_void_request_xml(authorization, options)
131
135
  commit(order, :void)
132
136
  end
133
137
 
@@ -396,7 +400,7 @@ module ActiveMerchant #:nodoc:
396
400
  xml.target!
397
401
  end
398
402
 
399
- def build_void_request_xml(money, authorization, parameters = {})
403
+ def build_void_request_xml(authorization, parameters = {})
400
404
  tx_ref_num, order_id = split_authorization(authorization)
401
405
  xml = xml_envelope
402
406
  xml.tag! :Request do
@@ -404,7 +408,7 @@ module ActiveMerchant #:nodoc:
404
408
  add_xml_credentials(xml)
405
409
  xml.tag! :TxRefNum, tx_ref_num
406
410
  xml.tag! :TxRefIdx, parameters[:transaction_index]
407
- xml.tag! :AdjustedAmt, amount(money)
411
+ xml.tag! :AdjustedAmt, parameters[:amount] # setting adjusted amount to nil will void entire amount
408
412
  xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
409
413
  add_bin_merchant_and_terminal(xml, parameters)
410
414
  end
@@ -140,6 +140,7 @@ module ActiveMerchant #:nodoc:
140
140
  add_amount(result, money, options)
141
141
  add_invoice(result, options)
142
142
  add_address_verification_data(result, options)
143
+ add_optional_elements(result, options)
143
144
  result
144
145
  end
145
146
 
@@ -149,6 +150,7 @@ module ActiveMerchant #:nodoc:
149
150
  add_amount(result, money, options)
150
151
  add_invoice(result, options)
151
152
  add_reference(result, identification)
153
+ add_optional_elements(result, options)
152
154
  result
153
155
  end
154
156
 
@@ -157,6 +159,7 @@ module ActiveMerchant #:nodoc:
157
159
  add_credit_card(result, credit_card)
158
160
  add_amount(result, 100, options) #need to make an auth request for $1
159
161
  add_token_request(result, options)
162
+ add_optional_elements(result, options)
160
163
  result
161
164
  end
162
165
 
@@ -209,7 +212,7 @@ module ActiveMerchant #:nodoc:
209
212
 
210
213
  def add_invoice(xml, options)
211
214
  xml.add_element("TxnId").text = options[:order_id].to_s.slice(0, 16) unless options[:order_id].blank?
212
- xml.add_element("MerchantReference").text = options[:description] unless options[:description].blank?
215
+ xml.add_element("MerchantReference").text = options[:description].to_s.slice(0, 50) unless options[:description].blank?
213
216
  end
214
217
 
215
218
  def add_address_verification_data(xml, options)
@@ -223,6 +226,52 @@ module ActiveMerchant #:nodoc:
223
226
  xml.add_element("AvsPostCode").text = address[:zip]
224
227
  end
225
228
 
229
+ # The options hash may contain optional data which will be passed
230
+ # through the the specialized optional fields at PaymentExpress
231
+ # as follows:
232
+ #
233
+ # {
234
+ # :client_type => :web, # Possible values are: :web, :ivr, :moto, :unattended, :internet, or :recurring
235
+ # :txn_data1 => "String up to 255 characters",
236
+ # :txn_data2 => "String up to 255 characters",
237
+ # :txn_data3 => "String up to 255 characters"
238
+ # }
239
+ #
240
+ # +:client_type+, while not documented for PxPost, will be sent as
241
+ # the +ClientType+ XML element as described in the documentation for
242
+ # the PaymentExpress WebService: http://www.paymentexpress.com/Technical_Resources/Ecommerce_NonHosted/WebService#clientType
243
+ # (PaymentExpress have confirmed that this value works the same in PxPost).
244
+ # The value sent for +:client_type+ will be normalized and sent
245
+ # as one of the explicit values allowed by PxPost:
246
+ #
247
+ # :web => "Web"
248
+ # :ivr => "IVR"
249
+ # :moto => "MOTO"
250
+ # :unattended => "Unattended"
251
+ # :internet => "Internet"
252
+ # :recurring => "Recurring"
253
+ #
254
+ # If you set the +:client_type+ to any value not listed above,
255
+ # the ClientType element WILL NOT BE INCLUDED at all in the
256
+ # POST data.
257
+ #
258
+ # +:txn_data1+, +:txn_data2+, and +:txn_data3+ will be sent as
259
+ # +TxnData1+, +TxnData2+, and +TxnData3+, respectively, and are
260
+ # free form fields of the merchant's choosing, as documented here:
261
+ # http://www.paymentexpress.com/technical_resources/ecommerce_nonhosted/pxpost.html#txndata
262
+ #
263
+ # These optional elements are added to all transaction types:
264
+ # +purchase+, +authorize+, +capture+, +refund+, +store+
265
+ def add_optional_elements(xml, options)
266
+ if client_type = normalized_client_type(options[:client_type])
267
+ xml.add_element("ClientType").text = client_type
268
+ end
269
+
270
+ xml.add_element("TxnData1").text = options[:txn_data1].to_s.slice(0,255) unless options[:txn_data1].blank?
271
+ xml.add_element("TxnData2").text = options[:txn_data2].to_s.slice(0,255) unless options[:txn_data2].blank?
272
+ xml.add_element("TxnData3").text = options[:txn_data3].to_s.slice(0,255) unless options[:txn_data3].blank?
273
+ end
274
+
226
275
  def new_transaction
227
276
  REXML::Document.new.add_element("Txn")
228
277
  end
@@ -266,6 +315,18 @@ module ActiveMerchant #:nodoc:
266
315
  def format_date(month, year)
267
316
  "#{format(month, :two_digits)}#{format(year, :two_digits)}"
268
317
  end
318
+
319
+ def normalized_client_type(client_type_from_options)
320
+ case client_type_from_options.to_s.downcase
321
+ when 'web' then "Web"
322
+ when 'ivr' then "IVR"
323
+ when 'moto' then "MOTO"
324
+ when 'unattended' then "Unattended"
325
+ when 'internet' then "Internet"
326
+ when 'recurring' then "Recurring"
327
+ else nil
328
+ end
329
+ end
269
330
  end
270
331
 
271
332
  class PaymentExpressResponse < Response
@@ -397,7 +397,7 @@ module ActiveMerchant #:nodoc:
397
397
  transaction_search_optional_fields = %w{ Payer ReceiptID Receiver
398
398
  TransactionID InvoiceID CardNumber
399
399
  AuctionItemNumber TransactionClass
400
- CurrencyCode Status }
400
+ CurrencyCode Status ProfileID }
401
401
  build_request_wrapper('TransactionSearch') do |xml|
402
402
  xml.tag! 'StartDate', date_to_iso(options[:start_date])
403
403
  xml.tag! 'EndDate', date_to_iso(options[:end_date]) unless options[:end_date].blank?
@@ -1,5 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/paypal/paypal_common_api'
2
2
  require File.dirname(__FILE__) + '/paypal/paypal_express_response'
3
+ require File.dirname(__FILE__) + '/paypal/paypal_recurring_api'
3
4
  require File.dirname(__FILE__) + '/paypal_express_common'
4
5
 
5
6
  module ActiveMerchant #:nodoc:
@@ -7,6 +8,7 @@ module ActiveMerchant #:nodoc:
7
8
  class PaypalExpressGateway < Gateway
8
9
  include PaypalCommonAPI
9
10
  include PaypalExpressCommon
11
+ include PaypalRecurringApi
10
12
 
11
13
  NON_STANDARD_LOCALE_CODES = {
12
14
  'DK' => 'da_DK',
@@ -0,0 +1,157 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PinGateway < Gateway
4
+ self.test_url = 'https://test-api.pin.net.au/1'
5
+ self.live_url = 'https://api.pin.net.au/1'
6
+
7
+ self.default_currency = 'AUD'
8
+ self.money_format = :cents
9
+ self.supported_countries = ['AU']
10
+ self.supported_cardtypes = [:visa, :master]
11
+ self.homepage_url = 'http://www.pin.net.au/'
12
+ self.display_name = 'Pin'
13
+
14
+ def initialize(options = {})
15
+ requires!(options, :api_key)
16
+ super
17
+ end
18
+
19
+ # Create a charge using a credit card, card token or customer token
20
+ #
21
+ # To charge a credit card: purchase([money], [creditcard hash], ...)
22
+ # To charge a customer: purchase([money], [token], ...)
23
+ def purchase(money, creditcard, options = {})
24
+ post = {}
25
+
26
+ add_amount(post, money, options)
27
+ add_customer_data(post, options)
28
+ add_invoice(post, options)
29
+ add_creditcard(post, creditcard)
30
+ add_address(post, creditcard, options)
31
+
32
+ commit('charges', post)
33
+ end
34
+
35
+ # Create a customer and associated credit card. The token that is returned
36
+ # can be used instead of a credit card parameter in the purchase method
37
+ def store(creditcard, options = {})
38
+ post = {}
39
+
40
+ add_creditcard(post, creditcard)
41
+ add_customer_data(post, options)
42
+ add_address(post, creditcard, options)
43
+ commit('customers', post)
44
+ end
45
+
46
+ # Refund a transaction, note that the money attribute is ignored at the
47
+ # moment as the API does not support partial refunds. The parameter is
48
+ # kept for compatibility reasons
49
+ def refund(money, token, options = {})
50
+ commit("charges/#{CGI.escape(token)}/refunds", :amount => amount(money))
51
+ end
52
+
53
+ private
54
+ def add_amount(post, money, options)
55
+ post[:amount] = amount(money)
56
+ post[:currency] = (options[:currency] || currency(money))
57
+ post[:currency] = post[:currency].upcase if post[:currency]
58
+ end
59
+
60
+ def add_customer_data(post, options)
61
+ post[:email] = options[:email]
62
+ post[:ip_address] = options[:ip]
63
+ end
64
+
65
+ def add_address(post, creditcard, options)
66
+ return if creditcard.kind_of?(String)
67
+ address = (options[:billing_address] || options[:address])
68
+ return unless address
69
+
70
+ post[:card] ||= {}
71
+ post[:card].merge!(
72
+ :address_line1 => address[:address1],
73
+ :address_city => address[:city],
74
+ :address_postcode => address[:zip],
75
+ :address_state => address[:state],
76
+ :address_country => address[:country]
77
+ )
78
+ end
79
+
80
+ def add_invoice(post, options)
81
+ post[:description] = options[:description]
82
+ end
83
+
84
+ def add_creditcard(post, creditcard)
85
+ if creditcard.respond_to?(:number)
86
+ post[:card] ||= {}
87
+
88
+ post[:card].merge!(
89
+ :number => creditcard.number,
90
+ :expiry_month => creditcard.month,
91
+ :expiry_year => creditcard.year,
92
+ :cvc => creditcard.verification_value,
93
+ :name => "#{creditcard.first_name} #{creditcard.last_name}"
94
+ )
95
+ elsif creditcard.kind_of?(String)
96
+ post[:customer_token] = creditcard
97
+ end
98
+ end
99
+
100
+ def headers
101
+ {
102
+ "Content-Type" => "application/json",
103
+ "Authorization" => "Basic #{Base64.strict_encode64(options[:api_key] + ':').strip}"
104
+ }
105
+ end
106
+
107
+ def commit(action, params)
108
+ url = "#{test? ? test_url : live_url}/#{action}"
109
+
110
+ begin
111
+ body = parse(ssl_post(url, post_data(params), headers))
112
+ rescue ResponseError => e
113
+ body = parse(e.response.body)
114
+ end
115
+
116
+ if body["response"]
117
+ success_response(body)
118
+ elsif body["error"]
119
+ error_response(body)
120
+ end
121
+ end
122
+
123
+ def success_response(body)
124
+ response = body["response"]
125
+ Response.new(
126
+ true,
127
+ response['status_message'],
128
+ body,
129
+ :authorization => token(response),
130
+ :test => test?
131
+ )
132
+ end
133
+
134
+ def error_response(body)
135
+ Response.new(
136
+ false,
137
+ body['error_description'],
138
+ body,
139
+ :authorization => nil,
140
+ :test => test?
141
+ )
142
+ end
143
+
144
+ def token(response)
145
+ response['token']
146
+ end
147
+
148
+ def parse(body)
149
+ JSON.parse(body)
150
+ end
151
+
152
+ def post_data(parameters = {})
153
+ parameters.to_json
154
+ end
155
+ end
156
+ end
157
+ end
@@ -126,6 +126,7 @@ module ActiveMerchant #:nodoc:
126
126
  parameters[:trans_request_id] ||= SecureRandom.hex(10)
127
127
 
128
128
  req = build_request(type, money, parameters)
129
+
129
130
  data = ssl_post(url, req, "Content-Type" => "application/x-qbmsxml")
130
131
  response = parse(type, data)
131
132
  message = (response[:status_message] || '').strip
@@ -260,8 +261,8 @@ module ActiveMerchant #:nodoc:
260
261
 
261
262
  def add_address(xml, parameters)
262
263
  if address = parameters[:billing_address] || parameters[:address]
263
- xml.tag!("CreditCardAddress", address[:address1][0...30])
264
- xml.tag!("CreditCardPostalCode", address[:zip][0...9])
264
+ xml.tag!("CreditCardAddress", (address[:address1] || "")[0...30])
265
+ xml.tag!("CreditCardPostalCode", (address[:zip] || "")[0...9])
265
266
  end
266
267
  end
267
268
 
@@ -44,22 +44,40 @@ module ActiveMerchant #:nodoc:
44
44
  fraud_http_accept_encoding fraud_http_accept_charset
45
45
  fraud_http_referer fraud_http_user_agent apikey),
46
46
 
47
- :capture => %w(protocol msgtype merchant amount transaction
48
- fraud_remote_addr fraud_http_accept
49
- fraud_http_accept_language fraud_http_accept_encoding
50
- fraud_http_accept_charset fraud_http_referer
51
- fraud_http_user_agent apikey),
47
+ :capture => %w(protocol msgtype merchant amount transaction apikey),
52
48
 
53
- :cancel => %w(protocol msgtype merchant transaction fraud_remote_addr
54
- fraud_http_accept fraud_http_accept_language
49
+ :cancel => %w(protocol msgtype merchant transaction apikey),
50
+
51
+ :refund => %w(protocol msgtype merchant amount transaction apikey),
52
+
53
+ :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
54
+ expirationdate cvd cardtypelock description testmode
55
+ fraud_remote_addr fraud_http_accept fraud_http_accept_language
55
56
  fraud_http_accept_encoding fraud_http_accept_charset
56
57
  fraud_http_referer fraud_http_user_agent apikey),
57
58
 
58
- :refund => %w(protocol msgtype merchant amount transaction
59
- fraud_remote_addr fraud_http_accept fraud_http_accept_language
59
+ :recurring => %w(protocol msgtype merchant ordernumber amount currency
60
+ autocapture transaction apikey),
61
+
62
+ :status => %w(protocol msgtype merchant transaction apikey),
63
+
64
+ :chstatus => %w(protocol msgtype merchant apikey)
65
+ },
66
+
67
+ 5 => {
68
+ :authorize => %w(protocol msgtype merchant ordernumber amount
69
+ currency autocapture cardnumber expirationdate cvd
70
+ cardtypelock testmode fraud_remote_addr
71
+ fraud_http_accept fraud_http_accept_language
60
72
  fraud_http_accept_encoding fraud_http_accept_charset
61
73
  fraud_http_referer fraud_http_user_agent apikey),
62
74
 
75
+ :capture => %w(protocol msgtype merchant amount transaction apikey),
76
+
77
+ :cancel => %w(protocol msgtype merchant transaction apikey),
78
+
79
+ :refund => %w(protocol msgtype merchant amount transaction apikey),
80
+
63
81
  :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
64
82
  expirationdate cvd cardtypelock description testmode
65
83
  fraud_remote_addr fraud_http_accept fraud_http_accept_language
@@ -67,20 +85,40 @@ module ActiveMerchant #:nodoc:
67
85
  fraud_http_referer fraud_http_user_agent apikey),
68
86
 
69
87
  :recurring => %w(protocol msgtype merchant ordernumber amount currency
70
- autocapture transaction fraud_remote_addr fraud_http_accept
71
- fraud_http_accept_language fraud_http_accept_encoding
72
- fraud_http_accept_charset fraud_http_referer
73
- fraud_http_user_agent apikey),
88
+ autocapture transaction apikey),
89
+
90
+ :status => %w(protocol msgtype merchant transaction apikey),
74
91
 
75
- :status => %w(protocol msgtype merchant transaction fraud_remote_addr
92
+ :chstatus => %w(protocol msgtype merchant apikey)
93
+ },
94
+
95
+ 6 => {
96
+ :authorize => %w(protocol msgtype merchant ordernumber amount
97
+ currency autocapture cardnumber expirationdate cvd
98
+ cardtypelock testmode fraud_remote_addr
76
99
  fraud_http_accept fraud_http_accept_language
77
100
  fraud_http_accept_encoding fraud_http_accept_charset
78
101
  fraud_http_referer fraud_http_user_agent apikey),
79
102
 
80
- :chstatus => %w(protocol msgtype merchant fraud_remote_addr fraud_http_accept
81
- fraud_http_accept_language fraud_http_accept_encoding
82
- fraud_http_accept_charset fraud_http_referer
83
- fraud_http_user_agent apikey)
103
+ :capture => %w(protocol msgtype merchant amount transaction
104
+ apikey),
105
+
106
+ :cancel => %w(protocol msgtype merchant transaction apikey),
107
+
108
+ :refund => %w(protocol msgtype merchant amount transaction apikey),
109
+
110
+ :subscribe => %w(protocol msgtype merchant ordernumber cardnumber
111
+ expirationdate cvd cardtypelock description testmode
112
+ fraud_remote_addr fraud_http_accept fraud_http_accept_language
113
+ fraud_http_accept_encoding fraud_http_accept_charset
114
+ fraud_http_referer fraud_http_user_agent apikey),
115
+
116
+ :recurring => %w(protocol msgtype merchant ordernumber amount currency
117
+ autocapture transaction apikey),
118
+
119
+ :status => %w(protocol msgtype merchant transaction apikey),
120
+
121
+ :chstatus => %w(protocol msgtype merchant apikey)
84
122
  }
85
123
  }
86
124
 
@@ -89,7 +127,7 @@ module ActiveMerchant #:nodoc:
89
127
  # The login is the QuickpayId
90
128
  # The password is the md5checkword from the Quickpay manager
91
129
  # To use the API-key from the Quickpay manager, specify :api-key
92
- # Using the API-key, requires that you use version 4. Specify :version => 4 in options.
130
+ # Using the API-key, requires that you use version 4+. Specify :version => 4/5/6 in options.
93
131
  def initialize(options = {})
94
132
  requires!(options, :login, :password)
95
133
  @protocol = options.delete(:version) || 3 # default to protocol version 3
@@ -99,26 +137,30 @@ module ActiveMerchant #:nodoc:
99
137
  def authorize(money, credit_card_or_reference, options = {})
100
138
  post = {}
101
139
 
140
+ action = recurring_or_authorize(credit_card_or_reference)
141
+
102
142
  add_amount(post, money, options)
103
143
  add_invoice(post, options)
104
144
  add_creditcard_or_reference(post, credit_card_or_reference, options)
105
145
  add_autocapture(post, false)
106
- add_fraud_parameters(post, options)
146
+ add_fraud_parameters(post, options) if action.eql?(:authorize)
107
147
  add_testmode(post)
108
148
 
109
- commit(recurring_or_authorize(credit_card_or_reference), post)
149
+ commit(action, post)
110
150
  end
111
151
 
112
152
  def purchase(money, credit_card_or_reference, options = {})
113
153
  post = {}
114
154
 
155
+ action = recurring_or_authorize(credit_card_or_reference)
156
+
115
157
  add_amount(post, money, options)
116
158
  add_creditcard_or_reference(post, credit_card_or_reference, options)
117
159
  add_invoice(post, options)
118
- add_fraud_parameters(post, options)
160
+ add_fraud_parameters(post, options) if action.eql?(:authorize)
119
161
  add_autocapture(post, true)
120
162
 
121
- commit(recurring_or_authorize(credit_card_or_reference), post)
163
+ commit(action, post)
122
164
  end
123
165
 
124
166
  def capture(money, authorization, options = {})
@@ -126,8 +168,6 @@ module ActiveMerchant #:nodoc:
126
168
 
127
169
  add_reference(post, authorization)
128
170
  add_amount_without_currency(post, money)
129
- add_fraud_parameters(post, options)
130
-
131
171
  commit(:capture, post)
132
172
  end
133
173
 
@@ -135,7 +175,6 @@ module ActiveMerchant #:nodoc:
135
175
  post = {}
136
176
 
137
177
  add_reference(post, identification)
138
- add_fraud_parameters(post, options)
139
178
 
140
179
  commit(:cancel, post)
141
180
  end
@@ -145,7 +184,6 @@ module ActiveMerchant #:nodoc:
145
184
 
146
185
  add_amount_without_currency(post, money)
147
186
  add_reference(post, identification)
148
- add_fraud_parameters(post, options)
149
187
 
150
188
  commit(:refund, post)
151
189
  end
@@ -219,7 +257,7 @@ module ActiveMerchant #:nodoc:
219
257
  end
220
258
 
221
259
  def add_fraud_parameters(post, options)
222
- if @protocol == 4
260
+ if @protocol >= 4
223
261
  post[:fraud_remote_addr] = options[:fraud_remote_addr] if options[:fraud_remote_addr]
224
262
  post[:fraud_http_accept] = options[:fraud_http_accept] if options[:fraud_http_accept]
225
263
  post[:fraud_http_accept_language] = options[:fraud_http_accept_language] if options[:fraud_http_accept_language]