activemerchant 1.29.3 → 1.30.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -71,7 +71,13 @@ module ActiveMerchant #:nodoc:
71
71
  end
72
72
 
73
73
  def commit(money, parameters)
74
- response = parse(ssl_post(URL, post_data(parameters)))
74
+ raw_response = ssl_post(URL, post_data(parameters))
75
+ begin
76
+ response = parse(raw_response)
77
+ rescue JSON::ParserError
78
+ response = json_error(raw_response)
79
+ end
80
+
75
81
  Response.new(success?(response),
76
82
  response["message"],
77
83
  response,
@@ -86,6 +92,14 @@ module ActiveMerchant #:nodoc:
86
92
  def post_data(parameters = {})
87
93
  parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
88
94
  end
95
+
96
+ def json_error(raw_response)
97
+ msg = 'Invalid response received from the Banwire API. Please contact Banwire support if you continue to receive this message.'
98
+ msg += " (The raw response returned by the API was #{raw_response.inspect})"
99
+ {
100
+ "message" => msg
101
+ }
102
+ end
89
103
  end
90
104
  end
91
105
  end
@@ -6,34 +6,34 @@ module ActiveMerchant #:nodoc:
6
6
  # It is also named TD Canada Trust Online Mart payment gateway.
7
7
  # To learn more about the specification of Beanstream gateway, please read the OM_Direct_Interface_API.pdf,
8
8
  # which you can get from your Beanstream account or get from me by email.
9
- #
9
+ #
10
10
  # == Supported transaction types by Beanstream:
11
11
  # * +P+ - Purchase
12
12
  # * +PA+ - Pre Authorization
13
13
  # * +PAC+ - Pre Authorization Completion
14
- #
14
+ #
15
15
  # == Secure Payment Profiles:
16
16
  # BeanStream supports payment profiles (vaults). This allows you to store cc information with BeanStream and process subsequent transactions with a customer id.
17
17
  # Secure Payment Profiles must be enabled on your account (must be done over the phone).
18
18
  # Your API Access Passcode must be set in Administration => account settings => order settings.
19
19
  # To learn more about storing credit cards with the Beanstream gateway, please read the BEAN_Payment_Profiles.pdf (I had to phone BeanStream to request it.)
20
- #
21
- # == Notes
20
+ #
21
+ # == Notes
22
22
  # * Adding of order products information is not implemented.
23
23
  # * Ensure that country and province data is provided as a code such as "CA", "US", "QC".
24
24
  # * login is the Beanstream merchant ID, username and password should be enabled in your Beanstream account and passed in using the <tt>:user</tt> and <tt>:password</tt> options.
25
25
  # * Test your app with your true merchant id and test credit card information provided in the api pdf document.
26
- # * Beanstream does not allow Payment Profiles to be deleted with their API. The accounts are 'closed', but have to be deleted manually.
27
- #
26
+ # * Beanstream does not allow Payment Profiles to be deleted with their API. The accounts are 'closed', but have to be deleted manually.
27
+ #
28
28
  # Example authorization (Beanstream PA transaction type):
29
- #
29
+ #
30
30
  # twenty = 2000
31
31
  # gateway = BeanstreamGateway.new(
32
32
  # :login => '100200000',
33
33
  # :user => 'xiaobozz',
34
34
  # :password => 'password'
35
35
  # )
36
- #
36
+ #
37
37
  # credit_card = CreditCard.new(
38
38
  # :number => '4030000010001234',
39
39
  # :month => 8,
@@ -63,37 +63,39 @@ module ActiveMerchant #:nodoc:
63
63
  # )
64
64
  class BeanstreamGateway < Gateway
65
65
  include BeanstreamCore
66
-
66
+
67
67
  def authorize(money, source, options = {})
68
68
  post = {}
69
69
  add_amount(post, money)
70
70
  add_invoice(post, options)
71
- add_source(post, source)
71
+ add_source(post, source)
72
72
  add_address(post, options)
73
73
  add_transaction_type(post, :authorization)
74
+ add_customer_ip(post, options)
74
75
  commit(post)
75
76
  end
76
-
77
+
77
78
  def purchase(money, source, options = {})
78
79
  post = {}
79
- add_amount(post, money)
80
+ add_amount(post, money)
80
81
  add_invoice(post, options)
81
82
  add_source(post, source)
82
83
  add_address(post, options)
83
84
  add_transaction_type(post, purchase_action(source))
85
+ add_customer_ip(post, options)
84
86
  commit(post)
85
- end
86
-
87
+ end
88
+
87
89
  def void(authorization, options = {})
88
90
  reference, amount, type = split_auth(authorization)
89
-
91
+
90
92
  post = {}
91
93
  add_reference(post, reference)
92
94
  add_original_amount(post, amount)
93
95
  add_transaction_type(post, void_action(type))
94
96
  commit(post)
95
97
  end
96
-
98
+
97
99
  def recurring(money, source, options = {})
98
100
  post = {}
99
101
  add_amount(post, money)
@@ -104,7 +106,7 @@ module ActiveMerchant #:nodoc:
104
106
  add_recurring_type(post, options)
105
107
  commit(post)
106
108
  end
107
-
109
+
108
110
  def update_recurring(amount, source, options = {})
109
111
  post = {}
110
112
  add_recurring_amount(post, amount)
@@ -115,7 +117,7 @@ module ActiveMerchant #:nodoc:
115
117
  add_recurring_service(post, options)
116
118
  recurring_commit(post)
117
119
  end
118
-
120
+
119
121
  def cancel_recurring(options = {})
120
122
  post = {}
121
123
  add_recurring_operation_type(post, :cancel)
@@ -126,25 +128,25 @@ module ActiveMerchant #:nodoc:
126
128
  def interac
127
129
  @interac ||= BeanstreamInteracGateway.new(@options)
128
130
  end
129
-
131
+
130
132
  # To match the other stored-value gateways, like TrustCommerce,
131
133
  # store and unstore need to be defined
132
134
  def store(credit_card, options = {})
133
- post = {}
135
+ post = {}
134
136
  add_address(post, options)
135
- add_credit_card(post, credit_card)
137
+ add_credit_card(post, credit_card)
136
138
  add_secure_profile_variables(post,options)
137
139
  commit(post, true)
138
140
  end
139
-
141
+
140
142
  #can't actually delete a secure profile with the supplicaed API. This function sets the status of the profile to closed (C).
141
143
  #Closed profiles will have to removed manually.
142
144
  def delete(vault_id)
143
145
  update(vault_id, false, {:status => "C"})
144
146
  end
145
-
147
+
146
148
  alias_method :unstore, :delete
147
-
149
+
148
150
  # Update the values (such as CC expiration) stored at
149
151
  # the gateway. The CC number must be supplied in the
150
152
  # CreditCard object.
@@ -66,7 +66,7 @@ module ActiveMerchant #:nodoc:
66
66
  base.supported_countries = ['CA']
67
67
 
68
68
  # The card types supported by the payment gateway
69
- base.supported_cardtypes = [:visa, :master, :american_express]
69
+ base.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
70
70
 
71
71
  # The homepage URL of the gateway
72
72
  base.homepage_url = 'http://www.beanstream.com/'
@@ -119,6 +119,10 @@ module ActiveMerchant #:nodoc:
119
119
  end
120
120
  end
121
121
 
122
+ def add_customer_ip(post, options)
123
+ post[:customerIP] = options[:ip] if options[:ip]
124
+ end
125
+
122
126
  def void_action(original_transaction_type)
123
127
  (original_transaction_type == TRANSACTIONS[:refund]) ? :void_refund : :void_purchase
124
128
  end
@@ -288,7 +292,7 @@ module ActiveMerchant #:nodoc:
288
292
  results = {}
289
293
  if !body.nil?
290
294
  body.split(/&/).each do |pair|
291
- key, val = pair.split(/=/)
295
+ key, val = pair.split(/\=/)
292
296
  results[key.to_sym] = val.nil? ? nil : CGI.unescape(val)
293
297
  end
294
298
  end
@@ -68,8 +68,10 @@ module ActiveMerchant #:nodoc:
68
68
  Braintree::Configuration.custom_user_agent = "ActiveMerchant #{ActiveMerchant::VERSION}"
69
69
 
70
70
  if wiredump_device
71
- Braintree::Configuration.logger = wiredump_device
71
+ Braintree::Configuration.logger = ((Logger === wiredump_device) ? wiredump_device : Logger.new(wiredump_device))
72
72
  Braintree::Configuration.logger.level = Logger::DEBUG
73
+ else
74
+ Braintree::Configuration.logger.level = Logger::WARN
73
75
  end
74
76
  end
75
77
 
@@ -135,7 +137,8 @@ module ActiveMerchant #:nodoc:
135
137
  {
136
138
  :braintree_customer => (customer_hash(result.customer) if result.success?),
137
139
  :customer_vault_id => (result.customer.id if result.success?)
138
- }
140
+ },
141
+ :authorization => (result.customer.id if result.success?)
139
142
  )
140
143
  end
141
144
  end
@@ -13,6 +13,7 @@ module ActiveMerchant #:nodoc:
13
13
  # names.
14
14
  #
15
15
  # Important Notes
16
+ # * For checks you can purchase and store.
16
17
  # * AVS and CVV only work against the production server. You will always
17
18
  # get back X for AVS and no response for CVV against the test server.
18
19
  # * Nexus is the list of states or provinces where you have a physical
@@ -131,10 +132,10 @@ module ActiveMerchant #:nodoc:
131
132
 
132
133
  # Purchase is an auth followed by a capture
133
134
  # You must supply an order_id in the options hash
134
- def purchase(money, creditcard_or_reference, options = {})
135
+ def purchase(money, payment_method_or_reference, options = {})
135
136
  requires!(options, :order_id)
136
137
  setup_address_hash(options)
137
- commit(build_purchase_request(money, creditcard_or_reference, options), options)
138
+ commit(build_purchase_request(money, payment_method_or_reference, options), options)
138
139
  end
139
140
 
140
141
  def void(identification, options = {})
@@ -154,10 +155,10 @@ module ActiveMerchant #:nodoc:
154
155
  # Stores a customer subscription/profile with type "on-demand".
155
156
  # To charge the card while creating a profile, pass
156
157
  # options[:setup_fee] => money
157
- def store(creditcard, options = {})
158
+ def store(payment_method, options = {})
158
159
  requires!(options, :order_id)
159
160
  setup_address_hash(options)
160
- commit(build_create_subscription_request(creditcard, options), options)
161
+ commit(build_create_subscription_request(payment_method, options), options)
161
162
  end
162
163
 
163
164
  # Updates a customer subscription/profile
@@ -222,7 +223,7 @@ module ActiveMerchant #:nodoc:
222
223
 
223
224
  def build_auth_request(money, creditcard_or_reference, options)
224
225
  xml = Builder::XmlMarkup.new :indent => 2
225
- add_creditcard_or_subscription(xml, money, creditcard_or_reference, options)
226
+ add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
226
227
  add_auth_service(xml)
227
228
  add_business_rules_data(xml)
228
229
  xml.target!
@@ -250,11 +251,15 @@ module ActiveMerchant #:nodoc:
250
251
  xml.target!
251
252
  end
252
253
 
253
- def build_purchase_request(money, creditcard_or_reference, options)
254
+ def build_purchase_request(money, payment_method_or_reference, options)
254
255
  xml = Builder::XmlMarkup.new :indent => 2
255
- add_creditcard_or_subscription(xml, money, creditcard_or_reference, options)
256
- add_purchase_service(xml, options)
257
- add_business_rules_data(xml)
256
+ add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
257
+ if(payment_method_or_reference.respond_to?(:check?) && payment_method_or_reference.check?)
258
+ add_check_service(xml)
259
+ else
260
+ add_purchase_service(xml, options)
261
+ add_business_rules_data(xml)
262
+ end
258
263
  xml.target!
259
264
  end
260
265
 
@@ -297,16 +302,22 @@ module ActiveMerchant #:nodoc:
297
302
  xml.target!
298
303
  end
299
304
 
300
- def build_create_subscription_request(creditcard, options)
305
+ def build_create_subscription_request(payment_method, options)
301
306
  options[:subscription] = (options[:subscription] || {}).merge(:frequency => "on-demand", :amount => 0, :automatic_renew => false)
302
307
 
303
308
  xml = Builder::XmlMarkup.new :indent => 2
304
- add_address(xml, creditcard, options[:billing_address], options)
309
+ add_address(xml, payment_method, options[:billing_address], options)
305
310
  add_purchase_data(xml, options[:setup_fee] || 0, true, options)
306
- add_creditcard(xml, creditcard)
307
- add_creditcard_payment_method(xml)
311
+ if payment_method.check?
312
+ add_check(xml, payment_method)
313
+ add_check_payment_method(xml)
314
+ add_check_service(xml, options) if options[:setup_fee]
315
+ else
316
+ add_creditcard(xml, payment_method)
317
+ add_creditcard_payment_method(xml)
318
+ add_purchase_service(xml, options) if options[:setup_fee]
319
+ end
308
320
  add_subscription(xml, options)
309
- add_purchase_service(xml, options) if options[:setup_fee]
310
321
  add_subscription_create_service(xml, options)
311
322
  add_business_rules_data(xml)
312
323
  xml.target!
@@ -372,12 +383,12 @@ module ActiveMerchant #:nodoc:
372
383
  end
373
384
  end
374
385
 
375
- def add_address(xml, creditcard, address, options, shipTo = false)
386
+ def add_address(xml, payment_method, address, options, shipTo = false)
376
387
  requires!(options, :email)
377
388
 
378
389
  xml.tag! shipTo ? 'shipTo' : 'billTo' do
379
- xml.tag! 'firstName', creditcard.first_name if creditcard
380
- xml.tag! 'lastName', creditcard.last_name if creditcard
390
+ xml.tag! 'firstName', payment_method.first_name if payment_method
391
+ xml.tag! 'lastName', payment_method.last_name if payment_method
381
392
  xml.tag! 'street1', address[:address1]
382
393
  xml.tag! 'street2', address[:address2] unless address[:address2].blank?
383
394
  xml.tag! 'city', address[:city]
@@ -403,6 +414,14 @@ module ActiveMerchant #:nodoc:
403
414
  end
404
415
  end
405
416
 
417
+ def add_check(xml, check)
418
+ xml.tag! 'check' do
419
+ xml.tag! 'accountNumber', check.account_number
420
+ xml.tag! 'accountType', check.account_type[0]
421
+ xml.tag! 'bankTransitNumber', check.routing_number
422
+ end
423
+ end
424
+
406
425
  def add_tax_service(xml)
407
426
  xml.tag! 'taxService', {'run' => 'true'} do
408
427
  xml.tag!('nexus', @options[:nexus]) unless @options[:nexus].blank?
@@ -447,6 +466,10 @@ module ActiveMerchant #:nodoc:
447
466
  end
448
467
  end
449
468
 
469
+ def add_check_service(xml)
470
+ xml.tag! 'ecDebitService', {'run' => 'true'}
471
+ end
472
+
450
473
  def add_subscription_create_service(xml, options)
451
474
  xml.tag! 'paySubscriptionCreateService', {'run' => 'true'}
452
475
  end
@@ -491,14 +514,24 @@ module ActiveMerchant #:nodoc:
491
514
  end
492
515
  end
493
516
 
494
- def add_creditcard_or_subscription(xml, money, creditcard_or_reference, options)
495
- if creditcard_or_reference.is_a?(String)
517
+ def add_check_payment_method(xml)
518
+ xml.tag! 'subscription' do
519
+ xml.tag! 'paymentMethod', "check"
520
+ end
521
+ end
522
+
523
+ def add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
524
+ if payment_method_or_reference.is_a?(String)
525
+ add_purchase_data(xml, money, true, options)
526
+ add_subscription(xml, options, payment_method_or_reference)
527
+ elsif payment_method_or_reference.check?
528
+ add_address(xml, payment_method_or_reference, options[:billing_address], options)
496
529
  add_purchase_data(xml, money, true, options)
497
- add_subscription(xml, options, creditcard_or_reference)
530
+ add_check(xml, payment_method_or_reference)
498
531
  else
499
- add_address(xml, creditcard_or_reference, options[:billing_address], options)
532
+ add_address(xml, payment_method_or_reference, options[:billing_address], options)
500
533
  add_purchase_data(xml, money, true, options)
501
- add_creditcard(xml, creditcard_or_reference)
534
+ add_creditcard(xml, payment_method_or_reference)
502
535
  end
503
536
  end
504
537
 
@@ -2,137 +2,10 @@ require 'rexml/document'
2
2
 
3
3
  module ActiveMerchant #:nodoc:
4
4
  module Billing #:nodoc:
5
- # First, make sure you have everything setup correctly and all of your dependencies in place with:
6
- #
7
- # require 'rubygems'
8
- # require 'active_merchant'
9
- #
10
- # ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, $10 US becomes 1000.
11
- #
12
- # tendollar = 1000
13
- #
14
- # The transaction result is based on the cent value of the transaction. $10.15 will return a failed transaction
15
- # with a response code of "15 – No Issuer", while $10.00 will return "00 – Transaction Approved."
16
- #
17
- # Next, create a credit card object using a eWay approved test card number (4444333322221111).
18
- #
19
- # creditcard = ActiveMerchant::Billing::CreditCard.new(
20
- # :number => '4444333322221111',
21
- # :month => 8,
22
- # :year => 2006,
23
- # :first_name => 'Longbob',
24
- # :last_name => 'Longsen',
25
- # :verification_value => '123'
26
- # )
27
- # options = {
28
- # :order_id => '1230123',
29
- # :email => 'bob@testbob.com',
30
- # :address => { :address1 => '47 Bobway',
31
- # :city => 'Bobville',
32
- # :state => 'WA',
33
- # :country => 'Australia',
34
- # :zip => '2000'
35
- # },
36
- # :description => 'purchased items'
37
- # }
38
- #
39
- # To finish setting up, create the active_merchant object you will be using, with the eWay gateway. If you have a
40
- # functional eWay account, replace :login with your Customer ID.
41
- #
42
- # gateway = ActiveMerchant::Billing::Base.gateway(:eway).new(:login => '87654321')
43
- #
44
- # Now we are ready to process our transaction
45
- #
46
- # response = gateway.purchase(tendollar, creditcard, options)
47
- #
48
- # Sending a transaction to eWay with active_merchant returns a Response object, which consistently allows you to:
49
- #
50
- # 1) Check whether the transaction was successful
51
- #
52
- # response.success?
53
- #
54
- # 2) Retrieve any message returned by eWay, either a "transaction was successful" note or an explanation of why the
55
- # transaction was rejected.
56
- #
57
- # response.message
58
- #
59
- # 3) Retrieve and store the unique transaction ID returned by eWway, for use in referencing the transaction in the future.
60
- #
61
- # response.authorization
62
- #
63
- # This should be enough to get you started with eWay and active_merchant. For further information, review the methods
64
- # below and the rest of active_merchant's documentation.
65
-
5
+ # Public: For more information on the Eway Gateway please visit their
6
+ # {Developers Area}[http://www.eway.com.au/developers/api/direct-payments]
66
7
  class EwayGateway < Gateway
67
- self.test_url = 'https://www.eway.com.au/gateway/xmltest/testpage.asp'
68
- self.live_url = 'https://www.eway.com.au/gateway/xmlpayment.asp'
69
-
70
- class_attribute :test_cvn_url, :live_cvn_url
71
- self.test_cvn_url = 'https://www.eway.com.au/gateway_cvn/xmltest/testpage.asp'
72
- self.live_cvn_url = 'https://www.eway.com.au/gateway_cvn/xmlpayment.asp'
73
-
74
- MESSAGES = {
75
- "00" => "Transaction Approved",
76
- "01" => "Refer to Issuer",
77
- "02" => "Refer to Issuer, special",
78
- "03" => "No Merchant",
79
- "04" => "Pick Up Card",
80
- "05" => "Do Not Honour",
81
- "06" => "Error",
82
- "07" => "Pick Up Card, Special",
83
- "08" => "Honour With Identification",
84
- "09" => "Request In Progress",
85
- "10" => "Approved For Partial Amount",
86
- "11" => "Approved, VIP",
87
- "12" => "Invalid Transaction",
88
- "13" => "Invalid Amount",
89
- "14" => "Invalid Card Number",
90
- "15" => "No Issuer",
91
- "16" => "Approved, Update Track 3",
92
- "19" => "Re-enter Last Transaction",
93
- "21" => "No Action Taken",
94
- "22" => "Suspected Malfunction",
95
- "23" => "Unacceptable Transaction Fee",
96
- "25" => "Unable to Locate Record On File",
97
- "30" => "Format Error",
98
- "31" => "Bank Not Supported By Switch",
99
- "33" => "Expired Card, Capture",
100
- "34" => "Suspected Fraud, Retain Card",
101
- "35" => "Card Acceptor, Contact Acquirer, Retain Card",
102
- "36" => "Restricted Card, Retain Card",
103
- "37" => "Contact Acquirer Security Department, Retain Card",
104
- "38" => "PIN Tries Exceeded, Capture",
105
- "39" => "No Credit Account",
106
- "40" => "Function Not Supported",
107
- "41" => "Lost Card",
108
- "42" => "No Universal Account",
109
- "43" => "Stolen Card",
110
- "44" => "No Investment Account",
111
- "51" => "Insufficient Funds",
112
- "52" => "No Cheque Account",
113
- "53" => "No Savings Account",
114
- "54" => "Expired Card",
115
- "55" => "Incorrect PIN",
116
- "56" => "No Card Record",
117
- "57" => "Function Not Permitted to Cardholder",
118
- "58" => "Function Not Permitted to Terminal",
119
- "59" => "Suspected Fraud",
120
- "60" => "Acceptor Contact Acquirer",
121
- "61" => "Exceeds Withdrawal Limit",
122
- "62" => "Restricted Card",
123
- "63" => "Security Violation",
124
- "64" => "Original Amount Incorrect",
125
- "66" => "Acceptor Contact Acquirer, Security",
126
- "67" => "Capture Card",
127
- "75" => "PIN Tries Exceeded",
128
- "82" => "CVV Validation Error",
129
- "90" => "Cutoff In Progress",
130
- "91" => "Card Issuer Unavailable",
131
- "92" => "Unable To Route Transaction",
132
- "93" => "Cannot Complete, Violation Of The Law",
133
- "94" => "Duplicate Transaction",
134
- "96" => "System Error"
135
- }
8
+ self.live_url = 'https://www.eway.com.au'
136
9
 
137
10
  self.money_format = :cents
138
11
  self.supported_countries = ['AU']
@@ -140,28 +13,46 @@ module ActiveMerchant #:nodoc:
140
13
  self.homepage_url = 'http://www.eway.com.au/'
141
14
  self.display_name = 'eWAY'
142
15
 
16
+ # Public: Create a new Eway Gateway.
17
+ # options - A hash of options:
18
+ # :login - Your Customer ID.
19
+ # :password - Your XML Refund Password that you
20
+ # specified on the Eway site. (optional)
143
21
  def initialize(options = {})
144
22
  requires!(options, :login)
145
23
  super
146
24
  end
147
25
 
148
- # ewayCustomerEmail, ewayCustomerAddress, ewayCustomerPostcode
149
26
  def purchase(money, creditcard, options = {})
150
27
  requires_address!(options)
151
28
 
152
29
  post = {}
153
30
  add_creditcard(post, creditcard)
154
31
  add_address(post, options)
155
- add_customer_data(post, options)
32
+ add_customer_id(post)
156
33
  add_invoice_data(post, options)
157
- # The request fails if all of the fields aren't present
158
- add_optional_data(post)
34
+ add_non_optional_data(post)
35
+ add_amount(post, money)
36
+ post[:CustomerEmail] = options[:email]
159
37
 
160
- commit(money, post)
38
+ commit(purchase_url(post[:CVN]), money, post)
161
39
  end
162
40
 
163
- private
41
+ def refund(money, authorization, options={})
42
+ post = {}
164
43
 
44
+ add_customer_id(post)
45
+ add_amount(post, money)
46
+ add_non_optional_data(post)
47
+ post[:OriginalTrxnNumber] = authorization
48
+ post[:RefundPassword] = @options[:password]
49
+ post[:CardExpiryMonth] = nil
50
+ post[:CardExpiryYear] = nil
51
+
52
+ commit(refund_url, money, post)
53
+ end
54
+
55
+ private
165
56
  def requires_address!(options)
166
57
  raise ArgumentError.new("Missing eWay required parameters: address or billing_address") unless (options.has_key?(:address) or options.has_key?(:billing_address))
167
58
  end
@@ -184,8 +75,8 @@ module ActiveMerchant #:nodoc:
184
75
  end
185
76
  end
186
77
 
187
- def add_customer_data(post, options)
188
- post[:CustomerEmail] = options[:email]
78
+ def add_customer_id(post)
79
+ post[:CustomerID] = @options[:login]
189
80
  end
190
81
 
191
82
  def add_invoice_data(post, options)
@@ -193,21 +84,26 @@ module ActiveMerchant #:nodoc:
193
84
  post[:CustomerInvoiceDescription] = options[:description]
194
85
  end
195
86
 
196
- def add_optional_data(post)
197
- post[:TrxnNumber] = nil
87
+ def add_amount(post, money)
88
+ post[:TotalAmount] = amount(money)
89
+ end
90
+
91
+ def add_non_optional_data(post)
198
92
  post[:Option1] = nil
199
93
  post[:Option2] = nil
200
94
  post[:Option3] = nil
95
+ post[:TrxnNumber] = nil
201
96
  end
202
97
 
203
- def commit(money, parameters)
204
- parameters[:TotalAmount] = amount(money)
98
+ def commit(url, money, parameters)
99
+ raw_response = ssl_post(url, post_data(parameters))
100
+ response = parse(raw_response)
205
101
 
206
- response = parse( ssl_post(gateway_url(parameters[:CVN], test?), post_data(parameters)) )
207
-
208
- Response.new(success?(response), message_from(response[:ewaytrxnerror]), response,
209
- :authorization => response[:ewayauthcode],
210
- :test => /\(Test( CVN)? Gateway\)/ === response[:ewaytrxnerror]
102
+ Response.new(success?(response),
103
+ message_from(response[:ewaytrxnerror]),
104
+ response,
105
+ :authorization => response[:ewaytrxnnumber],
106
+ :test => test?
211
107
  )
212
108
  end
213
109
 
@@ -215,35 +111,17 @@ module ActiveMerchant #:nodoc:
215
111
  response[:ewaytrxnstatus] == "True"
216
112
  end
217
113
 
218
- # Parse eway response xml into a convinient hash
219
114
  def parse(xml)
220
- # "<?xml version=\"1.0\"?>".
221
- # <ewayResponse>
222
- # <ewayTrxnError></ewayTrxnError>
223
- # <ewayTrxnStatus>True</ewayTrxnStatus>
224
- # <ewayTrxnNumber>10002</ewayTrxnNumber>
225
- # <ewayTrxnOption1></ewayTrxnOption1>
226
- # <ewayTrxnOption2></ewayTrxnOption2>
227
- # <ewayTrxnOption3></ewayTrxnOption3>
228
- # <ewayReturnAmount>10</ewayReturnAmount>
229
- # <ewayAuthCode>123456</ewayAuthCode>
230
- # <ewayTrxnReference>987654321</ewayTrxnReference>
231
- # </ewayResponse>
232
-
233
115
  response = {}
234
116
  xml = REXML::Document.new(xml)
235
117
  xml.elements.each('//ewayResponse/*') do |node|
236
-
237
118
  response[node.name.downcase.to_sym] = normalize(node.text)
238
-
239
119
  end unless xml.root.nil?
240
120
 
241
121
  response
242
122
  end
243
123
 
244
124
  def post_data(parameters = {})
245
- parameters[:CustomerID] = @options[:login]
246
-
247
125
  xml = REXML::Document.new
248
126
  root = xml.add_element("ewaygateway")
249
127
 
@@ -269,14 +147,79 @@ module ActiveMerchant #:nodoc:
269
147
  end
270
148
  end
271
149
 
272
- def gateway_url(cvn, test)
273
- if cvn
274
- test ? self.test_cvn_url : self.live_cvn_url
275
- else
276
- test ? self.test_url : self.live_url
277
- end
150
+ def purchase_url(cvn)
151
+ suffix = test? ? 'xmltest/testpage.asp' : 'xmlpayment.asp'
152
+ gateway_part = cvn ? 'gateway_cvn' : 'gateway'
153
+ "#{live_url}/#{gateway_part}/#{suffix}"
278
154
  end
279
155
 
156
+ def refund_url
157
+ suffix = test? ? 'xmltest/refund_test.asp' : 'xmlpaymentrefund.asp'
158
+ "#{live_url}/gateway/#{suffix}"
159
+ end
160
+
161
+ MESSAGES = {
162
+ "00" => "Transaction Approved",
163
+ "01" => "Refer to Issuer",
164
+ "02" => "Refer to Issuer, special",
165
+ "03" => "No Merchant",
166
+ "04" => "Pick Up Card",
167
+ "05" => "Do Not Honour",
168
+ "06" => "Error",
169
+ "07" => "Pick Up Card, Special",
170
+ "08" => "Honour With Identification",
171
+ "09" => "Request In Progress",
172
+ "10" => "Approved For Partial Amount",
173
+ "11" => "Approved, VIP",
174
+ "12" => "Invalid Transaction",
175
+ "13" => "Invalid Amount",
176
+ "14" => "Invalid Card Number",
177
+ "15" => "No Issuer",
178
+ "16" => "Approved, Update Track 3",
179
+ "19" => "Re-enter Last Transaction",
180
+ "21" => "No Action Taken",
181
+ "22" => "Suspected Malfunction",
182
+ "23" => "Unacceptable Transaction Fee",
183
+ "25" => "Unable to Locate Record On File",
184
+ "30" => "Format Error",
185
+ "31" => "Bank Not Supported By Switch",
186
+ "33" => "Expired Card, Capture",
187
+ "34" => "Suspected Fraud, Retain Card",
188
+ "35" => "Card Acceptor, Contact Acquirer, Retain Card",
189
+ "36" => "Restricted Card, Retain Card",
190
+ "37" => "Contact Acquirer Security Department, Retain Card",
191
+ "38" => "PIN Tries Exceeded, Capture",
192
+ "39" => "No Credit Account",
193
+ "40" => "Function Not Supported",
194
+ "41" => "Lost Card",
195
+ "42" => "No Universal Account",
196
+ "43" => "Stolen Card",
197
+ "44" => "No Investment Account",
198
+ "51" => "Insufficient Funds",
199
+ "52" => "No Cheque Account",
200
+ "53" => "No Savings Account",
201
+ "54" => "Expired Card",
202
+ "55" => "Incorrect PIN",
203
+ "56" => "No Card Record",
204
+ "57" => "Function Not Permitted to Cardholder",
205
+ "58" => "Function Not Permitted to Terminal",
206
+ "59" => "Suspected Fraud",
207
+ "60" => "Acceptor Contact Acquirer",
208
+ "61" => "Exceeds Withdrawal Limit",
209
+ "62" => "Restricted Card",
210
+ "63" => "Security Violation",
211
+ "64" => "Original Amount Incorrect",
212
+ "66" => "Acceptor Contact Acquirer, Security",
213
+ "67" => "Capture Card",
214
+ "75" => "PIN Tries Exceeded",
215
+ "82" => "CVV Validation Error",
216
+ "90" => "Cutoff In Progress",
217
+ "91" => "Card Issuer Unavailable",
218
+ "92" => "Unable To Route Transaction",
219
+ "93" => "Cannot Complete, Violation Of The Law",
220
+ "94" => "Duplicate Transaction",
221
+ "96" => "System Error"
222
+ }
280
223
  end
281
224
  end
282
225
  end