activemerchant 1.29.1 → 1.34.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 (92) hide show
  1. data/CHANGELOG +143 -0
  2. data/CONTRIBUTORS +43 -0
  3. data/README.md +59 -51
  4. data/lib/active_merchant/billing/check.rb +15 -14
  5. data/lib/active_merchant/billing/credit_card.rb +14 -5
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
  7. data/lib/active_merchant/billing/gateway.rb +2 -2
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +36 -8
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +17 -5
  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/barclays_epdq.rb +8 -1
  13. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -2
  14. data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
  15. data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -187
  16. data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
  17. data/lib/active_merchant/billing/gateways/braintree_blue.rb +7 -3
  18. data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
  19. data/lib/active_merchant/billing/gateways/cc5.rb +156 -0
  20. data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
  21. data/lib/active_merchant/billing/gateways/data_cash.rb +3 -3
  22. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  23. data/lib/active_merchant/billing/gateways/eway.rb +114 -171
  24. data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
  25. data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
  26. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +314 -0
  27. data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
  28. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
  29. data/lib/active_merchant/billing/gateways/iridium.rb +8 -2
  30. data/lib/active_merchant/billing/gateways/litle.rb +354 -105
  31. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +28 -7
  32. data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
  33. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
  34. data/lib/active_merchant/billing/gateways/moneris.rb +4 -6
  35. data/lib/active_merchant/billing/gateways/moneris_us.rb +1 -1
  36. data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
  37. data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
  38. data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
  39. data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
  40. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  41. data/lib/active_merchant/billing/gateways/ogone.rb +7 -5
  42. data/lib/active_merchant/billing/gateways/optimal_payment.rb +43 -18
  43. data/lib/active_merchant/billing/gateways/orbital.rb +190 -53
  44. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
  45. data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
  46. data/lib/active_merchant/billing/gateways/paymill.rb +179 -0
  47. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +12 -7
  48. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +14 -9
  49. data/lib/active_merchant/billing/gateways/paypal_express.rb +59 -18
  50. data/lib/active_merchant/billing/gateways/pin.rb +165 -0
  51. data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
  52. data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
  53. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
  54. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
  55. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
  56. data/lib/active_merchant/billing/gateways/sage.rb +10 -5
  57. data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -0
  58. data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
  59. data/lib/active_merchant/billing/gateways/spreedly_core.rb +233 -0
  60. data/lib/active_merchant/billing/gateways/stripe.rb +49 -21
  61. data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
  62. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
  63. data/lib/active_merchant/billing/gateways/webpay.rb +8 -0
  64. data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
  65. data/lib/active_merchant/billing/gateways/worldpay.rb +60 -24
  66. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
  67. data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
  68. data/lib/active_merchant/billing/integrations/dwolla/common.rb +23 -0
  69. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +18 -6
  70. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +16 -7
  71. data/lib/active_merchant/billing/integrations/dwolla/return.rb +16 -5
  72. data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
  73. data/lib/active_merchant/billing/integrations/notification.rb +13 -8
  74. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +19 -3
  75. data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
  76. data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
  77. data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
  78. data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
  79. data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
  80. data/lib/active_merchant/billing/integrations/pxpay/helper.rb +1 -0
  81. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
  82. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +78 -15
  83. data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
  84. data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
  85. data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
  86. data/lib/active_merchant/billing/integrations/robokassa/common.rb +1 -1
  87. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +7 -3
  88. data/lib/active_merchant/billing/integrations/world_pay.rb +15 -8
  89. data/lib/active_merchant/version.rb +1 -1
  90. data.tar.gz.sig +0 -0
  91. metadata +124 -50
  92. metadata.gz.sig +0 -0
@@ -0,0 +1,308 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # === EVO Canada payment gateway.
4
+ #
5
+ # EVO returns two different identifiers for most transactions, the
6
+ # +authcode+ and the +transactionid+. Since +transactionid+ is used more
7
+ # often (i.e. for {#capture}, {#refund}, {#void} and {#update}) we store it in the
8
+ # Response#authorization attribute. The +authcode+ from the merchant
9
+ # account is accessible via {Response#params}.
10
+ #
11
+ # Two different but related response messages are also returned from EVO.
12
+ # The message indicated by EVO's <tt>response_code</tt> parameter is returned as
13
+ # {Response#message} (Those messages can be seen in the {MESSAGES} hash.)
14
+ # The other, shorter message is available via {Response#params}.
15
+ #
16
+ # It's recommended to save the contents of the {Response#params} in your
17
+ # transaction log for future reference.
18
+ #
19
+ # === Sample Use
20
+ #
21
+ # gateway = ActiveMerchant::Billing::EvoCaGateway.new(username: 'demo', password: 'password')
22
+ #
23
+ # response = gateway.authorize(1000, credit_card, options)
24
+ #
25
+ # puts response.authorization # the transactionid
26
+ # puts response.params['authcode'] # the authcode from the merchant account
27
+ # puts response.message # the 'pretty' response message
28
+ # puts response.params['responsetext'] # the 'terse' response message
29
+ #
30
+ # gateway.capture(1000, response.authorization)
31
+ # gateway.update(response.authorization, shipping_carrier: 'fedex')
32
+ # gateway.refund(500, response.authorization)
33
+ #
34
+ class EvoCaGateway < Gateway
35
+ self.test_url = 'https://secure.evoepay.com/api/transact.php'
36
+ self.live_url = 'https://secure.evoepay.com/api/transact.php'
37
+
38
+ self.supported_countries = ['CA']
39
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
40
+ self.money_format = :dollars
41
+ self.homepage_url = 'http://www.evocanada.com/'
42
+ self.display_name = 'EVO Canada'
43
+
44
+ APPROVED, DECLINED, ERROR = 1, 2, 3
45
+
46
+ MESSAGES = {
47
+ 100 => 'Transaction was approved',
48
+ 200 => 'Transaction was declined by processor',
49
+ 201 => 'Do not honor',
50
+ 202 => 'Insufficient funds',
51
+ 203 => 'Over limit',
52
+ 204 => 'Transaction not allowed',
53
+ 220 => 'Incorrect payment data',
54
+ 221 => 'No such card issuer',
55
+ 222 => 'No card number on file with issuer',
56
+ 223 => 'Expired card',
57
+ 224 => 'Invalid expiration date',
58
+ 225 => 'Invalid card security code',
59
+ 240 => 'Call issuer for futher information',
60
+ 250 => 'Pick up card',
61
+ 251 => 'Lost card',
62
+ 252 => 'Stolen card',
63
+ 253 => 'Fraudulant card',
64
+ 260 => 'Declined with further instructions available',
65
+ 261 => 'Declined - stop all recurring payments',
66
+ 262 => 'Declined - stop this recurring program',
67
+ 263 => 'Declined - updated cardholder data available',
68
+ 264 => 'Declined - retry in a few days',
69
+ 300 => 'Transaction was rejected by gateway',
70
+ 400 => 'Transaction error returned by processor',
71
+ 410 => 'Invalid merchant configuration',
72
+ 411 => 'Merchant account is inactive',
73
+ 420 => 'Communication error',
74
+ 421 => 'Communication error with issuer',
75
+ 430 => 'Duplicate transaction at processor',
76
+ 440 => 'Processor format error',
77
+ 441 => 'Invalid transaction information',
78
+ 460 => 'Processor feature not available',
79
+ 461 => 'Unsupported card type'
80
+ }
81
+
82
+ # This gateway requires that a valid username and password be passed
83
+ # in the +options+ hash.
84
+ #
85
+ # === Required Options
86
+ #
87
+ # * <tt>:username</tt>
88
+ # * <tt>:password</tt>
89
+ def initialize(options = {})
90
+ requires!(options, :username, :password)
91
+ super
92
+ end
93
+
94
+ # Transaction sales are submitted and immediately flagged for settlement.
95
+ # These transactions will automatically be settled.
96
+ #
97
+ # Payment source can be either a {CreditCard} or {Check}.
98
+ #
99
+ # === Additional Options
100
+ # In addition to the standard options, this gateway supports
101
+ #
102
+ # * <tt>:tracking_number</tt> - Shipping tracking number
103
+ # * <tt>:shipping_carrier</tt> - ups/fedex/dhl/usps
104
+ # * <tt>:po_number</tt> - Purchase order
105
+ # * <tt>:tax</tt> - Tax amount
106
+ # * <tt>:shipping</tt> - Shipping cost
107
+ def purchase(money, credit_card_or_check, options = {})
108
+ post = {}
109
+ add_invoice(post, options)
110
+ add_order(post, options)
111
+ add_paymentmethod(post, credit_card_or_check)
112
+ add_address(post, options)
113
+ add_customer_data(post, options)
114
+ commit('sale', money, post)
115
+ end
116
+
117
+ # Transaction authorizations are authorized immediately but are not
118
+ # flagged for settlement. These transactions must be flagged for
119
+ # settlement using the _capture_ transaction type. Authorizations
120
+ # typically remain activate for three to seven business days.
121
+ #
122
+ # Payment source must be a {CreditCard}.
123
+ def authorize(money, credit_card, options = {})
124
+ post = {}
125
+ add_invoice(post, options)
126
+ add_order(post, options)
127
+ add_paymentmethod(post, credit_card)
128
+ add_address(post, options)
129
+ add_customer_data(post, options)
130
+ commit('auth', money, post)
131
+ end
132
+
133
+ # Transaction captures flag existing _authorizations_ for settlement. Only
134
+ # authorizations can be captured. Captures can be submitted for an amount
135
+ # equal to or less than the original authorization.
136
+ #
137
+ # The <tt>authorization</tt> parameter is the transaction ID, retrieved
138
+ # from Response#authorization. See EvoCaGateway#purchase for the
139
+ # <tt>options</tt>.
140
+ def capture(money, authorization, options = {})
141
+ post = {
142
+ :amount => amount(money),
143
+ :transactionid => authorization
144
+ }
145
+ add_order(post, options)
146
+ commit('capture', money, post)
147
+ end
148
+
149
+ # Transaction refunds will reverse a previously settled transaction. If
150
+ # the transaction has not been settled, it must be _voided_ instead of
151
+ # refunded.
152
+ #
153
+ # The <tt>identification</tt> parameter is the transaction ID, retrieved
154
+ # from {Response#authorization}.
155
+ def refund(money, identification)
156
+ post = {:transactionid => identification}
157
+ commit('refund', money, post)
158
+ end
159
+
160
+ # Transaction credits apply a negative amount to the cardholder's card.
161
+ # In most situations credits are disabled as transaction refunds should
162
+ # be used instead.
163
+ #
164
+ # Note that this is different from a {#refund} (which is usually what
165
+ # you'll be looking for).
166
+ def credit(money, credit_card, options = {})
167
+ post = {}
168
+ add_invoice(post, options)
169
+ add_order(post, options)
170
+ add_paymentmethod(post, credit_card)
171
+ add_address(post, options)
172
+ add_customer_data(post, options)
173
+ commit('credit', money, post)
174
+ end
175
+
176
+ # Transaction voids will cancel an existing sale or captured
177
+ # authorization. In addition, non-captured authorizations can be voided to
178
+ # prevent any future capture. Voids can only occur if the transaction has
179
+ # not been settled.
180
+ #
181
+ # The <tt>identification</tt> parameter is the transaction ID, retrieved
182
+ # from {Response#authorization}.
183
+ def void(identification)
184
+ post = {:transactionid => identification}
185
+ commit('void', nil, post)
186
+ end
187
+
188
+ # Transaction updates can be used to update previous transactions with
189
+ # specific order information, such as a tracking number and shipping
190
+ # carrier. See EvoCaGateway#purchase for <tt>options</tt>.
191
+ #
192
+ # The <tt>identification</tt> parameter is the transaction ID, retrieved
193
+ # from {Response#authorization}.
194
+ def update(identification, options)
195
+ post = {:transactionid => identification}
196
+ add_order(post, options)
197
+ commit('update', nil, post)
198
+ end
199
+
200
+ private
201
+
202
+ def add_customer_data(post, options)
203
+ post[:email] = options[:email]
204
+ post[:ipaddress] = options[:ip]
205
+ end
206
+
207
+ def add_address(post, options)
208
+ if address = options[:billing_address] || options[:address]
209
+ post[:firstname] = address[:first_name]
210
+ post[:lastname] = address[:last_name]
211
+ post[:address1] = address[:address1]
212
+ post[:address2] = address[:address2]
213
+ post[:company] = address[:company]
214
+ post[:phone] = address[:phone]
215
+ post[:city] = address[:city]
216
+ post[:state] = address[:state]
217
+ post[:zip] = address[:zip]
218
+ post[:country] = address[:country]
219
+ end
220
+
221
+ if address = options[:shipping_address]
222
+ post[:shipping_firstname] = address[:first_name]
223
+ post[:shipping_lastname] = address[:last_name]
224
+ post[:shipping_address1] = address[:address1]
225
+ post[:shipping_address2] = address[:address2]
226
+ post[:shipping_company] = address[:company]
227
+ post[:shipping_zip] = address[:zip]
228
+ post[:shipping_city] = address[:city]
229
+ post[:shipping_state] = address[:state]
230
+ post[:shipping_country] = address[:country]
231
+ end
232
+ end
233
+
234
+ def add_order(post, options)
235
+ post[:orderid] = options[:order_id]
236
+ post[:tracking_number] = options[:tracking_number]
237
+ post[:shipping_carrier] = options[:shipping_carrier]
238
+ end
239
+
240
+ def add_invoice(post, options)
241
+ post[:orderdescription] = options[:description]
242
+ post[:ponumber] = options[:po_number]
243
+ post[:shipping] = amount(options[:shipping])
244
+ post[:tax] = amount(options[:tax])
245
+ end
246
+
247
+ def add_paymentmethod(post, payment)
248
+ if card_brand(payment)=='check'
249
+ post[:payment] = 'check'
250
+ post[:checkname] = payment.name
251
+ post[:checkaba] = payment.routing_number
252
+ post[:checkaccount] = payment.account_number
253
+ post[:account_holder_type] = payment.account_holder_type
254
+ post[:account_type] = payment.account_type
255
+ else
256
+ post[:payment] = 'creditcard'
257
+ post[:ccnumber] = payment.number
258
+ post[:ccexp] = "#{format(payment.month, :two_digits)}#{format(payment.year, :two_digits)}"
259
+ post[:cvv] = payment.verification_value
260
+ end
261
+ end
262
+
263
+ def parse(body)
264
+ fields = {}
265
+ CGI::parse(body).each do |k, v|
266
+ fields[k.to_s] = v.kind_of?(Array) ? v[0] : v
267
+ end
268
+ fields
269
+ end
270
+
271
+ def success?(response)
272
+ response['response'].to_i == APPROVED
273
+ end
274
+
275
+ def commit(action, money, parameters)
276
+ parameters[:amount] = amount(money) unless action == 'void'
277
+
278
+ data = ssl_post self.live_url, post_data(action, parameters)
279
+ response = parse(data)
280
+ message = message_from(response)
281
+
282
+ Response.new(success?(response), message, response,
283
+ :test => test?,
284
+ :authorization => response['transactionid'],
285
+ :avs_result => { :code => response['avsresponse'] },
286
+ :cvv_result => response['cvvresponse']
287
+ )
288
+ end
289
+
290
+ def message_from(response)
291
+ MESSAGES.fetch(response['response_code'].to_i, false) || response['message']
292
+ end
293
+
294
+ def post_data(action, parameters = {})
295
+ post = {:type => action}
296
+
297
+ if test?
298
+ post[:username] = 'demo'
299
+ post[:password] = 'password'
300
+ else
301
+ post[:username] = options[:username]
302
+ post[:password] = options[:password]
303
+ end
304
+ post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" unless value.nil? }.compact.join("&")
305
+ end
306
+ end
307
+ end
308
+ end
@@ -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