activemerchant 1.4.1 → 1.4.2

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 (46) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +28 -0
  3. data/Rakefile +2 -4
  4. data/lib/active_merchant/billing/credit_card.rb +2 -0
  5. data/lib/active_merchant/billing/gateways/authorize_net.rb +13 -0
  6. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/bogus.rb +13 -1
  8. data/lib/active_merchant/billing/gateways/braintree.rb +13 -5
  9. data/lib/active_merchant/billing/gateways/card_stream.rb +1 -5
  10. data/lib/active_merchant/billing/gateways/moneris.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/pay_junction.rb +9 -3
  12. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +2 -8
  13. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  14. data/lib/active_merchant/billing/gateways/psl_card.rb +7 -3
  15. data/lib/active_merchant/billing/gateways/quickpay.rb +84 -54
  16. data/lib/active_merchant/billing/gateways/sage.rb +1 -0
  17. data/lib/active_merchant/billing/gateways/trust_commerce.rb +5 -1
  18. data/lib/active_merchant/billing/gateways/wirecard.rb +20 -19
  19. data/lib/active_merchant/billing/integrations.rb +1 -0
  20. data/lib/active_merchant/billing/integrations/quickpay.rb +18 -0
  21. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  22. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  23. data/lib/active_merchant/lib/country.rb +21 -3
  24. data/lib/active_merchant/lib/posts_data.rb +54 -34
  25. data/lib/active_merchant/lib/requires_parameters.rb +1 -1
  26. data/test/fixtures.yml +19 -3
  27. data/test/remote/gateways/remote_braintree_test.rb +11 -4
  28. data/test/remote/gateways/remote_card_stream_test.rb +20 -20
  29. data/test/remote/gateways/remote_psl_card_test.rb +23 -4
  30. data/test/remote/gateways/remote_quickpay_test.rb +17 -9
  31. data/test/remote/gateways/remote_wirecard_test.rb +3 -2
  32. data/test/test_helper.rb +3 -2
  33. data/test/unit/credit_card_test.rb +7 -0
  34. data/test/unit/gateways/authorize_net_cim_test.rb +2 -5
  35. data/test/unit/gateways/authorize_net_test.rb +16 -6
  36. data/test/unit/gateways/bogus_test.rb +4 -0
  37. data/test/unit/gateways/moneris_test.rb +1 -1
  38. data/test/unit/gateways/payflow_test.rb +6 -2
  39. data/test/unit/gateways/quickpay_test.rb +8 -8
  40. data/test/unit/gateways/trust_commerce_test.rb +12 -0
  41. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  42. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  43. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  44. metadata +10 -5
  45. metadata.gz.sig +0 -0
  46. data/lib/tasks/cia.rb +0 -90
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,5 +1,33 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
+ == Version 1.4.2 (April 24, 2009)
4
+
5
+ * Fix typo in Authorize.net CIM [infused]
6
+ * Add missing ISO countries [Edward Ocampo-Gooding]
7
+ * Add support for Guernsey to country.rb [cody]
8
+ * Add American Express to the MonerisGateway [cody]
9
+ * Use :words_connector instead of connector in RequiresParameters [cody]
10
+ * Fixed CreditCard not validating start_month and start_year when set as string [Tekin]
11
+ * Update PostsData to support get requests [cody]
12
+ * Fix broken Quickpay remote test [cody]
13
+ * Update Quickpay gateway to v3. Add support for offsite integration for Danish Dankort cards [Lars Pind]
14
+ * Use default partner id when passed in :partner is blank with PayflowGateway [cody]
15
+ * Remove PayflowGateway.certification_id [cody]
16
+ * Set Response#test? to true in TrustCommerce gateway when using the demo account in production [cody]
17
+ * Correctly set Sage.supported_countries [cody]
18
+ * Add BogusGateway#void [Donald Ball]
19
+ * Fix PSL gateway capturing [cody]
20
+ * Fix failed Visa debit purchases with PSL gateway start date info is present [cody]
21
+ * Support personal fixtures file on Windows [cody]
22
+ * Clearer variable naming for BraintreeGateway#authorize [Jonathan S. Katz]
23
+ * Fix brittle Authorize.net tests [cody]
24
+ * Add support for Authorize.net duplicate window [Seamus Abshere]
25
+ * Return transaction id for PayPal refunds [jxtps435]
26
+ * Allow storage of e-checks with BraintreeGateway [jimiray]
27
+ * Add test URL to PayJunction gateway [boomtowndesigngroup]
28
+ * More robust parsing for Wirecard gateway [Soleone]
29
+ * Pass the issue number to CardStream verbatim and update test card numbers [Soleone]
30
+
3
31
  == Version 1.4.1 (December 9, 2008)
4
32
 
5
33
  * Update CardStream URL. Note that you will also need to update your login id. [cody]
data/Rakefile CHANGED
@@ -4,11 +4,9 @@ require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
  require 'rake/gempackagetask'
6
6
  require 'rake/contrib/rubyforgepublisher'
7
- require File.dirname(__FILE__) + '/lib/tasks/cia'
8
7
  require File.dirname(__FILE__) + '/lib/support/gateway_support'
9
8
 
10
-
11
- PKG_VERSION = "1.4.1"
9
+ PKG_VERSION = "1.4.2"
12
10
  PKG_NAME = "activemerchant"
13
11
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
14
12
 
@@ -86,7 +84,7 @@ spec = Gem::Specification.new do |s|
86
84
  s.email = "tobi@leetsoft.com"
87
85
  s.homepage = "http://activemerchant.org/"
88
86
 
89
- s.add_dependency('activesupport', '>= 1.4.1')
87
+ s.add_dependency('activesupport', '>= 2.3.2')
90
88
  s.add_dependency('builder', '>= 2.0.0')
91
89
 
92
90
  s.signing_key = ENV['GEM_PRIVATE_KEY']
@@ -112,6 +112,8 @@ module ActiveMerchant #:nodoc:
112
112
  def before_validate #:nodoc:
113
113
  self.month = month.to_i
114
114
  self.year = year.to_i
115
+ self.start_month = start_month.to_i unless start_month.nil?
116
+ self.start_year = start_year.to_i unless start_year.nil?
115
117
  self.number = number.to_s.gsub(/[^\d]/, "")
116
118
  self.type.downcase! if type.respond_to?(:downcase)
117
119
  self.type = self.class.type?(number) if type.blank?
@@ -33,6 +33,8 @@ module ActiveMerchant #:nodoc:
33
33
 
34
34
  self.arb_test_url = 'https://apitest.authorize.net/xml/v1/request.api'
35
35
  self.arb_live_url = 'https://api.authorize.net/xml/v1/request.api'
36
+
37
+ class_inheritable_accessor :duplicate_window
36
38
 
37
39
  APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
38
40
 
@@ -86,6 +88,7 @@ module ActiveMerchant #:nodoc:
86
88
  add_creditcard(post, creditcard)
87
89
  add_address(post, options)
88
90
  add_customer_data(post, options)
91
+ add_duplicate_window(post)
89
92
 
90
93
  commit('AUTH_ONLY', money, post)
91
94
  end
@@ -103,6 +106,7 @@ module ActiveMerchant #:nodoc:
103
106
  add_creditcard(post, creditcard)
104
107
  add_address(post, options)
105
108
  add_customer_data(post, options)
109
+ add_duplicate_window(post)
106
110
 
107
111
  commit('AUTH_CAPTURE', money, post)
108
112
  end
@@ -319,6 +323,15 @@ module ActiveMerchant #:nodoc:
319
323
  post[:customer_ip] = options[:ip]
320
324
  end
321
325
  end
326
+
327
+ # x_duplicate_window won't be sent by default, because sending it changes the response.
328
+ # "If this field is present in the request with or without a value, an enhanced duplicate transaction response will be sent."
329
+ # (as of 2008-12-30) http://www.authorize.net/support/AIM_guide_SCC.pdf
330
+ def add_duplicate_window(post)
331
+ unless duplicate_window.nil?
332
+ post[:duplicate_window] = duplicate_window
333
+ end
334
+ end
322
335
 
323
336
  def add_address(post, options)
324
337
 
@@ -1,6 +1,6 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
- # ==== Custotmer Information Manager (CIM)
3
+ # ==== Customer Information Manager (CIM)
4
4
  #
5
5
  # The Authorize.Net Customer Information Manager (CIM) is an optional additional service that allows you to store sensitive payment information on
6
6
  # Authorize.Net's servers, simplifying payments for returning customers and recurring transactions. It can also help with Payment Card Industry (PCI)
@@ -10,6 +10,7 @@ module ActiveMerchant #:nodoc:
10
10
  CREDIT_ERROR_MESSAGE = "Bogus Gateway: Use trans_id 1 for success, 2 for exception and anything else for error"
11
11
  UNSTORE_ERROR_MESSAGE = "Bogus Gateway: Use trans_id 1 for success, 2 for exception and anything else for error"
12
12
  CAPTURE_ERROR_MESSAGE = "Bogus Gateway: Use authorization number 1 for exception, 2 for error and anything else for success"
13
+ VOID_ERROR_MESSAGE = "Bogus Gateway: Use authorization number 1 for exception, 2 for error and anything else for success"
13
14
 
14
15
  self.supported_countries = ['US']
15
16
  self.supported_cardtypes = [:bogus]
@@ -59,6 +60,17 @@ module ActiveMerchant #:nodoc:
59
60
  Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money.to_s}, :test => true)
60
61
  end
61
62
  end
63
+
64
+ def void(ident, options = {})
65
+ case ident
66
+ when '1'
67
+ raise Error, VOID_ERROR_MESSAGE
68
+ when '2'
69
+ Response.new(false, FAILURE_MESSAGE, {:authorization => ident, :error => FAILURE_MESSAGE }, :test => true)
70
+ else
71
+ Response.new(true, SUCCESS_MESSAGE, {:authorization => ident}, :test => true)
72
+ end
73
+ end
62
74
 
63
75
  def store(creditcard, options = {})
64
76
  case creditcard.number
@@ -83,4 +95,4 @@ module ActiveMerchant #:nodoc:
83
95
  end
84
96
  end
85
97
  end
86
- end
98
+ end
@@ -22,11 +22,11 @@ module ActiveMerchant #:nodoc:
22
22
  # Pass :store => some_number_or_string to specify the
23
23
  # customer_vault_id BrainTree should use (make sure it's
24
24
  # unique).
25
- def authorize(money, creditcard, options = {})
25
+ def authorize(money, payment_source, options = {})
26
26
  post = {}
27
27
  add_invoice(post, options)
28
- add_payment_source(post, creditcard,options)
29
- add_address(post, creditcard, options)
28
+ add_payment_source(post, payment_source, options)
29
+ add_address(post, payment_source, options)
30
30
  add_customer_data(post, options)
31
31
 
32
32
  commit('auth', money, post)
@@ -77,9 +77,17 @@ module ActiveMerchant #:nodoc:
77
77
 
78
78
  # To match the other stored-value gateways, like TrustCommerce,
79
79
  # store and unstore need to be defined
80
- def store(creditcard, options = {})
80
+ def store(payment_source, options = {})
81
81
  billing_id = options.delete(:billing_id).to_s || true
82
- authorize(100, creditcard, options.merge(:store => billing_id))
82
+ post = {}
83
+ post[:customer_vault] = 'add_customer'
84
+ if billing_id
85
+ post[:customer_vault_id] = billing_id
86
+ end
87
+ add_payment_source(post, payment_source, options)
88
+ add_address(post, payment_source, options)
89
+ add_customer_data(post, options)
90
+ commit(nil,nil, post)
83
91
  end
84
92
 
85
93
  alias_method :unstore, :delete
@@ -151,16 +151,12 @@ module ActiveMerchant #:nodoc:
151
151
  add_pair(post, :StartDateMM, format(credit_card.start_month, :two_digits))
152
152
  add_pair(post, :StartDateYY, format(credit_card.start_year, :two_digits))
153
153
 
154
- add_pair(post, :IssueNumber, format_issue_number(credit_card))
154
+ add_pair(post, :IssueNumber, credit_card.issue_number)
155
155
  end
156
156
 
157
157
  add_pair(post, :CV2, credit_card.verification_value)
158
158
  end
159
159
 
160
- def format_issue_number(credit_card)
161
- card_brand(credit_card).to_s == 'solo' ? format(credit_card.issue_number, :two_digits) : credit_card.issue_number
162
- end
163
-
164
160
  def commit(action, parameters)
165
161
  response = parse( ssl_post(URL, post_data(action, parameters)) )
166
162
 
@@ -14,7 +14,7 @@ module ActiveMerchant #:nodoc:
14
14
  LIVE_URL = 'https://www3.moneris.com/gateway2/servlet/MpgRequest'
15
15
 
16
16
  self.supported_countries = ['CA']
17
- self.supported_cardtypes = [:visa, :master]
17
+ self.supported_cardtypes = [:visa, :master, :american_express]
18
18
  self.homepage_url = 'http://www.moneris.com/'
19
19
  self.display_name = 'Moneris'
20
20
 
@@ -98,8 +98,12 @@ module ActiveMerchant #:nodoc:
98
98
  # See #recurring for periodic transaction fields
99
99
  class PayJunctionGateway < Gateway
100
100
  API_VERSION = '1.2'
101
- URL = 'https://payjunction.com/quick_link' # also handles test requests
102
-
101
+
102
+ class_inheritable_accessor :test_url, :live_url
103
+
104
+ self.test_url = "https://demo.payjunction.com/quick_link"
105
+ self.live_url = "https://payjunction.com/quick_link"
106
+
103
107
  TEST_LOGIN = 'pj-ql-01'
104
108
  TEST_PASSWORD = 'pj-ql-01p'
105
109
 
@@ -318,7 +322,9 @@ module ActiveMerchant #:nodoc:
318
322
  end
319
323
 
320
324
  def commit(action, parameters)
321
- response = parse( ssl_post(URL, post_data(action, parameters)) )
325
+ url = test? ? self.test_url : self.live_url
326
+
327
+ response = parse( ssl_post(url, post_data(action, parameters)) )
322
328
 
323
329
  Response.new(successful?(response), message_from(response), response,
324
330
  :test => test?,
@@ -4,10 +4,6 @@ module ActiveMerchant #:nodoc:
4
4
  def self.included(base)
5
5
  base.default_currency = 'USD'
6
6
 
7
- # The certification id requirement has been removed by Payflow
8
- # This is no longer being sent in the requests to the gateway
9
- base.class_inheritable_accessor :certification_id
10
-
11
7
  base.class_inheritable_accessor :partner
12
8
 
13
9
  # Set the default partner to PayPal
@@ -59,11 +55,9 @@ module ActiveMerchant #:nodoc:
59
55
 
60
56
  def initialize(options = {})
61
57
  requires!(options, :login, :password)
62
- @options = {
63
- :certification_id => self.class.certification_id,
64
- :partner => self.class.partner
65
- }.update(options)
66
58
 
59
+ @options = options
60
+ @options[:partner] = partner if @options[:partner].blank?
67
61
  super
68
62
  end
69
63
 
@@ -310,7 +310,7 @@ module ActiveMerchant #:nodoc:
310
310
  end
311
311
 
312
312
  def authorization_from(response)
313
- response[:transaction_id] || response[:authorization_id] # latter one is from reauthorization
313
+ response[:transaction_id] || response[:authorization_id] || response[:refund_transaction_id] # middle one is from reauthorization
314
314
  end
315
315
 
316
316
  def successful?(response)
@@ -163,6 +163,7 @@ module ActiveMerchant
163
163
 
164
164
  add_amount(post, money, DISPATCH_NOW, options)
165
165
  add_reference(post, authorization)
166
+ add_purchase_details(post)
166
167
 
167
168
  commit(post)
168
169
  end
@@ -175,9 +176,12 @@ module ActiveMerchant
175
176
  post[:EMVTerminalType] = EMV_TERMINAL_TYPE
176
177
  post[:ExpMonth] = credit_card.month
177
178
  post[:ExpYear] = credit_card.year
178
- post[:IssueNumber] = credit_card.issue_number unless credit_card.issue_number.blank?
179
- post[:StartMonth] = credit_card.start_month unless credit_card.start_month.blank?
180
- post[:StartYear] = credit_card.start_year unless credit_card.start_year.blank?
179
+
180
+ if requires_start_date_or_issue_number?(credit_card)
181
+ post[:IssueNumber] = credit_card.issue_number unless credit_card.issue_number.blank?
182
+ post[:StartMonth] = credit_card.start_month unless credit_card.start_month.blank?
183
+ post[:StartYear] = credit_card.start_year unless credit_card.start_year.blank?
184
+ end
181
185
 
182
186
  # CV2 check
183
187
  post[:AVSCV2Check] = credit_card.verification_value? ? 'YES' : 'NO'
@@ -4,7 +4,7 @@ require 'digest/md5'
4
4
  module ActiveMerchant #:nodoc:
5
5
  module Billing #:nodoc:
6
6
  class QuickpayGateway < Gateway
7
- URL = 'https://secure.quickpay.dk/transaction.php'
7
+ URL = 'https://secure.quickpay.dk/api'
8
8
 
9
9
  self.default_currency = 'DKK'
10
10
  self.money_format = :cents
@@ -13,31 +13,19 @@ module ActiveMerchant #:nodoc:
13
13
  self.homepage_url = 'http://quickpay.dk/'
14
14
  self.display_name = 'Quickpay'
15
15
 
16
- TRANSACTIONS = {
17
- :authorization => '1100',
18
- :capture => '1220',
19
- :void => '1420',
20
- :credit => 'credit'
21
- }
22
-
23
- POS_CODES = {
24
- :mail => '100020100110',
25
- :phone => '100030100110',
26
- :internet => 'L00500L00130',
27
- :internet_secure => 'K00500K00130',
28
- :internet_edankort => 'KM0500R00130',
29
- :internet_recurring => 'K00540K00130'
30
- }
16
+ PROTOCOL = 3
31
17
 
32
18
  MD5_CHECK_FIELDS = {
33
- :authorization => [:msgtype, :cardnumber, :amount, :expirationdate, :posc, :ordernum, :currency, :cvd, :merchant, :authtype, :reference, :transaction],
34
- :capture => [:msgtype, :amount, :merchant, :transaction],
35
- :void => [:msgtype, :merchant, :transaction],
36
- :credit => [:msgtype, :amount, :merchant, :transaction]
19
+ :authorize => [:protocol, :msgtype, :merchant, :ordernumber, :amount, :currency, :autocapture, :cardnumber, :expirationdate, :cvd, :cardtypelock],
20
+ :capture => [:protocol, :msgtype, :merchant, :amount, :transaction],
21
+ :cancel => [:protocol, :msgtype, :merchant, :transaction],
22
+ :refund => [:protocol, :msgtype, :merchant, :amount, :transaction],
23
+ :subscribe => [:protocol, :msgtype, :merchant, :ordernumber, :cardnumber, :expirationdate, :cvd, :cardtypelock, :description],
24
+ :recurring => [:protocol, :msgtype, :merchant, :ordernumber, :amount, :currency, :autocapture, :transaction],
25
+ :status => [:protocol, :msgtype, :merchant, :transaction],
26
+ :chstatus => [:protocol, :msgtype, :merchant],
37
27
  }
38
28
 
39
- CURRENCIES = [ 'DKK', 'EUR', 'NOK', 'GBP', 'USD' ]
40
-
41
29
  APPROVED = '000'
42
30
 
43
31
  # The login is the QuickpayId
@@ -48,26 +36,33 @@ module ActiveMerchant #:nodoc:
48
36
  super
49
37
  end
50
38
 
51
- def authorize(money, creditcard, options = {})
39
+ def authorize(money, credit_card_or_reference, options = {})
40
+ post = {}
41
+
42
+ add_amount(post, money, options)
43
+ add_invoice(post, options)
44
+ add_creditcard_or_reference(post, credit_card_or_reference, options)
45
+ add_autocapture(post, false)
46
+
47
+ commit(recurring_or_authorize(credit_card_or_reference), post)
48
+ end
49
+
50
+ def purchase(money, credit_card_or_reference, options = {})
52
51
  post = {}
53
52
 
54
53
  add_amount(post, money, options)
55
- add_creditcard(post, creditcard)
54
+ add_creditcard_or_reference(post, credit_card_or_reference, options)
56
55
  add_invoice(post, options)
56
+ add_autocapture(post, true)
57
57
 
58
- commit(:authorization, post)
58
+ commit(recurring_or_authorize(credit_card_or_reference), post)
59
59
  end
60
60
 
61
- def purchase(money, creditcard, options = {})
62
- auth = authorize(money, creditcard, options)
63
- auth.success? ? capture(money, auth.authorization) : auth
64
- end
65
-
66
61
  def capture(money, authorization, options = {})
67
62
  post = {}
68
63
 
69
64
  add_reference(post, authorization)
70
- add_amount(post, money)
65
+ add_amount_without_currency(post, money)
71
66
 
72
67
  commit(:capture, post)
73
68
  end
@@ -77,18 +72,28 @@ module ActiveMerchant #:nodoc:
77
72
 
78
73
  add_reference(post, identification)
79
74
 
80
- commit(:void, post)
75
+ commit(:cancel, post)
81
76
  end
82
77
 
83
78
  def credit(money, identification, options = {})
84
79
  post = {}
85
-
86
- add_amount(post, money)
80
+
81
+ add_amount_without_currency(post, money)
87
82
  add_reference(post, identification)
83
+
84
+ commit(:refund, post)
85
+ end
86
+
87
+ def store(creditcard, options = {})
88
+ post = {}
88
89
 
89
- commit(:credit, post)
90
+ add_creditcard(post, creditcard, options)
91
+ add_invoice(post, options)
92
+ add_description(post, options)
93
+
94
+ commit(:subscribe, post)
90
95
  end
91
-
96
+
92
97
  private
93
98
 
94
99
  def add_amount(post, money, options = {})
@@ -96,21 +101,45 @@ module ActiveMerchant #:nodoc:
96
101
  post[:currency] = options[:currency] || currency(money)
97
102
  end
98
103
 
104
+ def add_amount_without_currency(post, money, options = {})
105
+ post[:amount] = amount(money)
106
+ end
107
+
99
108
  def add_invoice(post, options)
100
- post[:ordernum] = format_order_number(options[:order_id])
101
- post[:posc] = POS_CODES[:internet_secure]
109
+ post[:ordernumber] = format_order_number(options[:order_id])
102
110
  end
103
111
 
104
- def add_creditcard(post, credit_card)
112
+ def add_creditcard(post, credit_card, options)
105
113
  post[:cardnumber] = credit_card.number
106
114
  post[:cvd] = credit_card.verification_value
107
- post[:expirationdate] = expdate(credit_card)
115
+ post[:expirationdate] = expdate(credit_card)
116
+ post[:cardtypelock] = options[:cardtypelock] unless options[:cardtypelock].blank?
108
117
  end
109
118
 
110
119
  def add_reference(post, identification)
111
120
  post[:transaction] = identification
112
121
  end
113
122
 
123
+ def add_creditcard_or_reference(post, credit_card_or_reference, options)
124
+ if credit_card_or_reference.is_a?(String)
125
+ add_reference(post, credit_card_or_reference)
126
+ else
127
+ add_creditcard(post, credit_card_or_reference, options)
128
+ end
129
+ end
130
+
131
+ def add_autocapture(post, autocapture)
132
+ post[:autocapture] = autocapture ? 1 : 0
133
+ end
134
+
135
+ def recurring_or_authorize(credit_card_or_reference)
136
+ credit_card_or_reference.is_a?(String) ? :recurring : :authorize
137
+ end
138
+
139
+ def add_description(post, options)
140
+ post[:description] = options[:description]
141
+ end
142
+
114
143
  def commit(action, params)
115
144
  response = parse(ssl_post(URL, post_data(action, params)))
116
145
 
@@ -129,8 +158,8 @@ module ActiveMerchant #:nodoc:
129
158
 
130
159
  doc = REXML::Document.new(data)
131
160
 
132
- doc.root.attributes.each do |name, value|
133
- response[name.to_sym] = value
161
+ doc.root.elements.each do |element|
162
+ response[element.name.to_sym] = element.text
134
163
  end
135
164
 
136
165
  response
@@ -138,22 +167,22 @@ module ActiveMerchant #:nodoc:
138
167
 
139
168
  def message_from(response)
140
169
  case response[:qpstat]
141
- when '008'
142
- response[:qpstatmsg].to_s.scan(/[A-Z][a-z0-9 \/]+/).to_sentence
143
- else
170
+ when '008' # Error in request data
171
+ response[:qpstatmsg].to_s
172
+ #.scan(/[A-Z][a-z0-9 \/]+/).to_sentence
173
+ else
144
174
  response[:qpstatmsg].to_s
145
175
  end
146
176
  end
147
177
 
148
178
  def post_data(action, params = {})
149
- params[:merchant] = @options[:login]
150
- params[:msgtype] = TRANSACTIONS[action]
151
-
152
- check_field = (action == :authorization) ? :md5checkV2 : :md5check
153
- params[check_field] = generate_check_hash(action, params)
179
+ params[:protocol] = PROTOCOL
180
+ params[:msgtype] = action.to_s
181
+ params[:merchant] = @options[:login]
182
+ #params[:testmode] = '1' if test?
183
+ params[:md5check] = generate_check_hash(action, params)
154
184
 
155
- request = params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
156
- request
185
+ params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
157
186
  end
158
187
 
159
188
  def generate_check_hash(action, params)
@@ -163,7 +192,7 @@ module ActiveMerchant #:nodoc:
163
192
 
164
193
  # Add the md5checkword
165
194
  string << @options[:password].to_s
166
-
195
+
167
196
  Digest::MD5.hexdigest(string)
168
197
  end
169
198
 
@@ -174,8 +203,9 @@ module ActiveMerchant #:nodoc:
174
203
  "#{year}#{month}"
175
204
  end
176
205
 
206
+ # Limited to 20 digits max
177
207
  def format_order_number(number)
178
- number.to_s.gsub(/[^0-9]/, '').rjust(4, "0")
208
+ number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20]
179
209
  end
180
210
  end
181
211
  end