activemerchant 1.29.3 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|