activemerchant 1.29.3 → 1.30.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +39 -0
- data/CONTRIBUTORS +19 -0
- data/README.md +43 -41
- data/lib/active_merchant/billing/check.rb +15 -11
- data/lib/active_merchant/billing/credit_card.rb +5 -1
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
- data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
- data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- data/lib/active_merchant/billing/gateways/eway.rb +114 -171
- data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/litle.rb +50 -19
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +2 -4
- data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
- data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
- data/lib/active_merchant/billing/gateways/pin.rb +157 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
- data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
- data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
- data/lib/active_merchant/version.rb +1 -1
- metadata +109 -49
- metadata.gz.sig +0 -0
@@ -71,7 +71,13 @@ module ActiveMerchant #:nodoc:
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def commit(money, parameters)
|
74
|
-
|
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,
|
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,
|
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(
|
158
|
+
def store(payment_method, options = {})
|
158
159
|
requires!(options, :order_id)
|
159
160
|
setup_address_hash(options)
|
160
|
-
commit(build_create_subscription_request(
|
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
|
-
|
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,
|
254
|
+
def build_purchase_request(money, payment_method_or_reference, options)
|
254
255
|
xml = Builder::XmlMarkup.new :indent => 2
|
255
|
-
|
256
|
-
|
257
|
-
|
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(
|
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,
|
309
|
+
add_address(xml, payment_method, options[:billing_address], options)
|
305
310
|
add_purchase_data(xml, options[:setup_fee] || 0, true, options)
|
306
|
-
|
307
|
-
|
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,
|
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',
|
380
|
-
xml.tag! 'lastName',
|
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
|
495
|
-
|
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
|
-
|
530
|
+
add_check(xml, payment_method_or_reference)
|
498
531
|
else
|
499
|
-
add_address(xml,
|
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,
|
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
|
-
#
|
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.
|
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
|
-
|
32
|
+
add_customer_id(post)
|
156
33
|
add_invoice_data(post, options)
|
157
|
-
|
158
|
-
|
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
|
-
|
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
|
188
|
-
post[:
|
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
|
197
|
-
post[:
|
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
|
-
|
98
|
+
def commit(url, money, parameters)
|
99
|
+
raw_response = ssl_post(url, post_data(parameters))
|
100
|
+
response = parse(raw_response)
|
205
101
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
:authorization => response[:
|
210
|
-
:test =>
|
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
|
273
|
-
|
274
|
-
|
275
|
-
|
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
|