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.
- data/CHANGELOG +143 -0
- data/CONTRIBUTORS +43 -0
- data/README.md +59 -51
- data/lib/active_merchant/billing/check.rb +15 -14
- data/lib/active_merchant/billing/credit_card.rb +14 -5
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +2 -2
- data/lib/active_merchant/billing/gateways/authorize_net.rb +36 -8
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +17 -5
- 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/barclays_epdq.rb +8 -1
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -2
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -187
- data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +7 -3
- data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +156 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- data/lib/active_merchant/billing/gateways/data_cash.rb +3 -3
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- 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/finansbank.rb +22 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +314 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/iridium.rb +8 -2
- data/lib/active_merchant/billing/gateways/litle.rb +354 -105
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +28 -7
- 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 +4 -6
- data/lib/active_merchant/billing/gateways/moneris_us.rb +1 -1
- data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
- data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
- data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
- 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/ogone.rb +7 -5
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +43 -18
- data/lib/active_merchant/billing/gateways/orbital.rb +190 -53
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paymill.rb +179 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +12 -7
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +14 -9
- data/lib/active_merchant/billing/gateways/paypal_express.rb +59 -18
- data/lib/active_merchant/billing/gateways/pin.rb +165 -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/sage_bankcard.rb +16 -11
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
- data/lib/active_merchant/billing/gateways/sage.rb +10 -5
- data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +233 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +49 -21
- data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
- data/lib/active_merchant/billing/gateways/webpay.rb +8 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/gateways/worldpay.rb +60 -24
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
- data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
- data/lib/active_merchant/billing/integrations/dwolla/common.rb +23 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +18 -6
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +16 -7
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +16 -5
- data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
- data/lib/active_merchant/billing/integrations/notification.rb +13 -8
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +19 -3
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
- data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
- data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
- data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
- data/lib/active_merchant/billing/integrations/pxpay/helper.rb +1 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +78 -15
- data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
- data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
- data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
- data/lib/active_merchant/billing/integrations/robokassa/common.rb +1 -1
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +7 -3
- data/lib/active_merchant/billing/integrations/world_pay.rb +15 -8
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +124 -50
- metadata.gz.sig +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
|
2
2
|
module Billing #:nodoc:
|
|
3
3
|
class MerchantWareGateway < Gateway
|
|
4
|
+
class_attribute :v4_live_url
|
|
5
|
+
|
|
4
6
|
self.live_url = self.test_url = 'https://ps1.merchantware.net/MerchantWARE/ws/RetailTransaction/TXRetail.asmx'
|
|
7
|
+
self.v4_live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
|
5
8
|
|
|
6
9
|
self.supported_countries = ['US']
|
|
7
10
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
|
@@ -12,13 +15,19 @@ module ActiveMerchant #:nodoc:
|
|
|
12
15
|
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
|
13
16
|
"xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/"
|
|
14
17
|
}
|
|
18
|
+
ENV_NAMESPACES_V4 = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
|
19
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
|
20
|
+
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
TX_NAMESPACE = "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail"
|
|
24
|
+
TX_NAMESPACE_V4 = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
|
|
16
25
|
|
|
17
26
|
ACTIONS = {
|
|
18
27
|
:purchase => "IssueKeyedSale",
|
|
19
28
|
:authorize => "IssueKeyedPreAuth",
|
|
20
29
|
:capture => "IssuePostAuth",
|
|
21
|
-
:void => "
|
|
30
|
+
:void => "VoidPreAuthorization",
|
|
22
31
|
:credit => "IssueKeyedRefund",
|
|
23
32
|
:reference_credit => "IssueRefundByReference"
|
|
24
33
|
}
|
|
@@ -80,11 +89,10 @@ module ActiveMerchant #:nodoc:
|
|
|
80
89
|
# * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
|
|
81
90
|
def void(authorization, options = {})
|
|
82
91
|
reference, options[:order_id] = split_reference(authorization)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
add_reference(xml, reference)
|
|
92
|
+
request = v4_soap_request(:void) do |xml|
|
|
93
|
+
add_reference_token(xml, reference)
|
|
86
94
|
end
|
|
87
|
-
commit(:void, request)
|
|
95
|
+
commit(:void, request, true)
|
|
88
96
|
end
|
|
89
97
|
|
|
90
98
|
# Refund an amount back a cardholder
|
|
@@ -108,7 +116,6 @@ module ActiveMerchant #:nodoc:
|
|
|
108
116
|
perform_reference_credit(money, reference, options)
|
|
109
117
|
end
|
|
110
118
|
|
|
111
|
-
|
|
112
119
|
private
|
|
113
120
|
|
|
114
121
|
def soap_request(action)
|
|
@@ -125,6 +132,22 @@ module ActiveMerchant #:nodoc:
|
|
|
125
132
|
xml.target!
|
|
126
133
|
end
|
|
127
134
|
|
|
135
|
+
def v4_soap_request(action)
|
|
136
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
|
137
|
+
xml.instruct!
|
|
138
|
+
xml.tag! "soap:Envelope", ENV_NAMESPACES_V4 do
|
|
139
|
+
xml.tag! "soap:Body" do
|
|
140
|
+
xml.tag! ACTIONS[:void], "xmlns" => TX_NAMESPACE_V4 do
|
|
141
|
+
xml.tag! "merchantName", @options[:name]
|
|
142
|
+
xml.tag! "merchantSiteId", @options[:login]
|
|
143
|
+
xml.tag! "merchantKey", @options[:password]
|
|
144
|
+
yield xml
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
xml.target!
|
|
149
|
+
end
|
|
150
|
+
|
|
128
151
|
def build_purchase_request(action, money, credit_card, options)
|
|
129
152
|
requires!(options, :order_id)
|
|
130
153
|
|
|
@@ -195,6 +218,10 @@ module ActiveMerchant #:nodoc:
|
|
|
195
218
|
xml.tag! "strReferenceCode", reference
|
|
196
219
|
end
|
|
197
220
|
|
|
221
|
+
def add_reference_token(xml, reference)
|
|
222
|
+
xml.tag! "token", reference
|
|
223
|
+
end
|
|
224
|
+
|
|
198
225
|
def add_address(xml, options)
|
|
199
226
|
if address = options[:billing_address] || options[:address]
|
|
200
227
|
xml.tag! "strAVSStreetAddress", address[:address1]
|
|
@@ -258,11 +285,19 @@ module ActiveMerchant #:nodoc:
|
|
|
258
285
|
response
|
|
259
286
|
end
|
|
260
287
|
|
|
261
|
-
def
|
|
288
|
+
def soap_action(action, v4 = false)
|
|
289
|
+
v4 ? "#{TX_NAMESPACE_V4}#{ACTIONS[action]}" : "#{TX_NAMESPACE}/#{ACTIONS[action]}"
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def url(v4 = false)
|
|
293
|
+
v4 ? v4_live_url : live_url
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def commit(action, request, v4 = false)
|
|
262
297
|
begin
|
|
263
|
-
data = ssl_post(
|
|
298
|
+
data = ssl_post(url(v4), request,
|
|
264
299
|
"Content-Type" => 'text/xml; charset=utf-8',
|
|
265
|
-
"SOAPAction" =>
|
|
300
|
+
"SOAPAction" => soap_action(action, v4)
|
|
266
301
|
)
|
|
267
302
|
response = parse(action, data)
|
|
268
303
|
rescue ActiveMerchant::ResponseError => e
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
require 'rexml/document'
|
|
3
|
+
|
|
4
|
+
module ActiveMerchant #:nodoc:
|
|
5
|
+
module Billing #:nodoc:
|
|
6
|
+
class MerchantWarriorGateway < Gateway
|
|
7
|
+
TOKEN_TEST_URL = 'https://base.merchantwarrior.com/token/'
|
|
8
|
+
TOKEN_LIVE_URL = 'https://api.merchantwarrior.com/token/'
|
|
9
|
+
|
|
10
|
+
POST_TEST_URL = 'https://base.merchantwarrior.com/post/'
|
|
11
|
+
POST_LIVE_URL = 'https://api.merchantwarrior.com/post/'
|
|
12
|
+
|
|
13
|
+
self.supported_countries = ['AU']
|
|
14
|
+
self.supported_cardtypes = [:visa, :master, :american_express,
|
|
15
|
+
:diners_club, :discover]
|
|
16
|
+
self.homepage_url = 'http://www.merchantwarrior.com/'
|
|
17
|
+
self.display_name = 'MerchantWarrior'
|
|
18
|
+
|
|
19
|
+
self.money_format = :dollars
|
|
20
|
+
self.default_currency = 'AUD'
|
|
21
|
+
|
|
22
|
+
def initialize(options = {})
|
|
23
|
+
requires!(options, :merchant_uuid, :api_key, :api_passphrase)
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def authorize(money, payment_method, options = {})
|
|
28
|
+
post = {}
|
|
29
|
+
add_amount(post, money, options)
|
|
30
|
+
add_product(post, options)
|
|
31
|
+
add_address(post, options)
|
|
32
|
+
add_payment_method(post, payment_method)
|
|
33
|
+
commit('processAuth', post)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def purchase(money, payment_method, options = {})
|
|
37
|
+
post = {}
|
|
38
|
+
add_amount(post, money, options)
|
|
39
|
+
add_product(post, options)
|
|
40
|
+
add_address(post, options)
|
|
41
|
+
add_payment_method(post, payment_method)
|
|
42
|
+
commit('processCard', post)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def capture(money, identification)
|
|
46
|
+
post = {}
|
|
47
|
+
add_amount(post, money, options)
|
|
48
|
+
add_transaction(post, identification)
|
|
49
|
+
post.merge!('captureAmount' => money.to_s)
|
|
50
|
+
commit('processCapture', post)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def refund(money, identification)
|
|
54
|
+
post = {}
|
|
55
|
+
add_amount(post, money, options)
|
|
56
|
+
add_transaction(post, identification)
|
|
57
|
+
post['refundAmount'] = money
|
|
58
|
+
commit('refundCard', post)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def store(creditcard, options = {})
|
|
62
|
+
post = {
|
|
63
|
+
'cardName' => creditcard.name,
|
|
64
|
+
'cardNumber' => creditcard.number,
|
|
65
|
+
'cardExpiryMonth' => format(creditcard.month, :two_digits),
|
|
66
|
+
'cardExpiryYear' => format(creditcard.year, :two_digits)
|
|
67
|
+
}
|
|
68
|
+
commit('addCard', post)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def add_transaction(post, identification)
|
|
74
|
+
post['transactionID'] = identification
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def add_address(post, options)
|
|
78
|
+
return unless(address = options[:address])
|
|
79
|
+
|
|
80
|
+
post['customerName'] = address[:name]
|
|
81
|
+
post['customerCountry'] = address[:country]
|
|
82
|
+
post['customerState'] = address[:state]
|
|
83
|
+
post['customerCity'] = address[:city]
|
|
84
|
+
post['customerAddress'] = address[:address1]
|
|
85
|
+
post['customerPostCode'] = address[:zip]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def add_product(post, options)
|
|
89
|
+
post['transactionProduct'] = options[:transaction_product]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def add_payment_method(post, payment_method)
|
|
93
|
+
if payment_method.respond_to?(:number)
|
|
94
|
+
add_creditcard(post, payment_method)
|
|
95
|
+
else
|
|
96
|
+
add_token(post, payment_method)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def add_token(post, token)
|
|
101
|
+
post['cardID'] = token
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def add_creditcard(post, creditcard)
|
|
105
|
+
post['paymentCardNumber'] = creditcard.number
|
|
106
|
+
post['paymentCardName'] = creditcard.name
|
|
107
|
+
post['paymentCardExpiry'] = creditcard.expiry_date.expiration.strftime("%m%y")
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def add_amount(post, money, options)
|
|
111
|
+
currency = (options[:currency] || currency(money))
|
|
112
|
+
|
|
113
|
+
post['transactionAmount'] = money.to_s
|
|
114
|
+
post['transactionCurrency'] = currency
|
|
115
|
+
post['hash'] = verification_hash(money, currency)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def verification_hash(money, currency)
|
|
119
|
+
Digest::MD5.hexdigest(
|
|
120
|
+
(
|
|
121
|
+
@options[:api_passphrase].to_s +
|
|
122
|
+
@options[:merchant_uuid].to_s +
|
|
123
|
+
money.to_s +
|
|
124
|
+
currency
|
|
125
|
+
).downcase
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def parse(body)
|
|
130
|
+
xml = REXML::Document.new(body)
|
|
131
|
+
|
|
132
|
+
response = {}
|
|
133
|
+
xml.root.elements.to_a.each do |node|
|
|
134
|
+
parse_element(response, node)
|
|
135
|
+
end
|
|
136
|
+
response
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def parse_element(response, node)
|
|
140
|
+
if node.has_elements?
|
|
141
|
+
node.elements.each{|element| parse_element(response, element)}
|
|
142
|
+
else
|
|
143
|
+
response[node.name.underscore.to_sym] = node.text
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def commit(action, post)
|
|
148
|
+
add_auth(action, post)
|
|
149
|
+
|
|
150
|
+
response = parse(ssl_post(url_for(action, post), post_data(post)))
|
|
151
|
+
|
|
152
|
+
Response.new(
|
|
153
|
+
success?(response),
|
|
154
|
+
response[:response_message],
|
|
155
|
+
response,
|
|
156
|
+
:test => test?,
|
|
157
|
+
:authorization => (response[:card_id] || response[:transaction_id])
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def add_auth(action, post)
|
|
162
|
+
post['merchantUUID'] = @options[:merchant_uuid]
|
|
163
|
+
post['apiKey'] = @options[:api_key]
|
|
164
|
+
unless token?(post)
|
|
165
|
+
post['method'] = action
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def url_for(action, post)
|
|
170
|
+
if token?(post)
|
|
171
|
+
[(test? ? TOKEN_TEST_URL : TOKEN_LIVE_URL), action].join("/")
|
|
172
|
+
else
|
|
173
|
+
(test? ? POST_TEST_URL : POST_LIVE_URL)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def token?(post)
|
|
178
|
+
(post["cardID"] || post["cardName"])
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def success?(response)
|
|
182
|
+
(response[:response_code] == '0')
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def post_data(post)
|
|
186
|
+
post.collect{|k,v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -22,7 +22,7 @@ module ActiveMerchant #:nodoc:
|
|
|
22
22
|
# password is your API Token
|
|
23
23
|
def initialize(options = {})
|
|
24
24
|
requires!(options, :login, :password)
|
|
25
|
-
|
|
25
|
+
options = { :crypt_type => 7 }.merge(options)
|
|
26
26
|
super
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -70,15 +70,13 @@ module ActiveMerchant #:nodoc:
|
|
|
70
70
|
commit 'completion', crediting_params(authorization, :comp_amount => amount(money))
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
# Voiding
|
|
74
|
-
# transaction. Closed transactions must be refunded. Note that the only
|
|
75
|
-
# methods which may be voided are +capture+ and +purchase+.
|
|
73
|
+
# Voiding cancels an open authorization.
|
|
76
74
|
#
|
|
77
75
|
# Concatenate your transaction number and order_id by using a semicolon
|
|
78
76
|
# (';'). This is to keep the Moneris interface consistent with other
|
|
79
77
|
# gateways. (See +capture+ for details.)
|
|
80
78
|
def void(authorization, options = {})
|
|
81
|
-
|
|
79
|
+
capture(0, authorization, options)
|
|
82
80
|
end
|
|
83
81
|
|
|
84
82
|
# Performs a refund. This method requires that the original transaction
|
|
@@ -103,7 +101,7 @@ module ActiveMerchant #:nodoc:
|
|
|
103
101
|
commit('res_add_cc', post)
|
|
104
102
|
end
|
|
105
103
|
|
|
106
|
-
def unstore(data_key)
|
|
104
|
+
def unstore(data_key, options = {})
|
|
107
105
|
post = {}
|
|
108
106
|
post[:data_key] = data_key
|
|
109
107
|
commit('res_delete', post)
|
|
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
|
|
|
34
34
|
#Transactions currently accepted by NAB Transact XML API
|
|
35
35
|
TRANSACTIONS = {
|
|
36
36
|
:purchase => 0, #Standard Payment
|
|
37
|
-
:
|
|
37
|
+
:refund => 4, #Refund
|
|
38
38
|
:void => 6, #Client Reversal (Void)
|
|
39
39
|
:authorization => 10, #Preauthorise
|
|
40
40
|
:capture => 11 #Preauthorise Complete (Advice)
|
|
@@ -66,6 +66,10 @@ module ActiveMerchant #:nodoc:
|
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
def refund(money, authorization, options = {})
|
|
70
|
+
commit :refund, build_reference_request(money, authorization)
|
|
71
|
+
end
|
|
72
|
+
|
|
69
73
|
def store(creditcard, options = {})
|
|
70
74
|
requires!(options, :billing_id, :amount)
|
|
71
75
|
commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
|
|
@@ -104,10 +108,23 @@ module ActiveMerchant #:nodoc:
|
|
|
104
108
|
xml.target!
|
|
105
109
|
end
|
|
106
110
|
|
|
111
|
+
def build_reference_request(money, reference)
|
|
112
|
+
xml = Builder::XmlMarkup.new
|
|
113
|
+
|
|
114
|
+
transaction_id, order_id, preauth_id, original_amount = reference.split('*')
|
|
115
|
+
|
|
116
|
+
xml.tag! 'amount', (money ? amount(money) : original_amount)
|
|
117
|
+
xml.tag! 'currency', options[:currency] || currency(money)
|
|
118
|
+
xml.tag! 'txnID', transaction_id
|
|
119
|
+
xml.tag! 'purchaseOrderNo', order_id
|
|
120
|
+
xml.tag! 'preauthID', preauth_id
|
|
121
|
+
|
|
122
|
+
xml.target!
|
|
123
|
+
end
|
|
124
|
+
|
|
107
125
|
#Generate payment request XML
|
|
108
126
|
# - API is set to allow multiple Txn's but currentlu only allows one
|
|
109
127
|
# - txnSource = 23 - (XML)
|
|
110
|
-
|
|
111
128
|
def build_request(action, body)
|
|
112
129
|
xml = Builder::XmlMarkup.new
|
|
113
130
|
xml.instruct!
|
|
@@ -210,7 +227,7 @@ module ActiveMerchant #:nodoc:
|
|
|
210
227
|
end
|
|
211
228
|
|
|
212
229
|
def authorization_from(response)
|
|
213
|
-
response[:txn_id]
|
|
230
|
+
[response[:txn_id], response[:purchase_order_no], response[:preauth_id], response[:amount]].join('*')
|
|
214
231
|
end
|
|
215
232
|
|
|
216
233
|
def message_from(response)
|
|
@@ -41,7 +41,7 @@ module ActiveMerchant
|
|
|
41
41
|
:purchase => 'purchase',
|
|
42
42
|
:capture => 'completion',
|
|
43
43
|
:status => 'status',
|
|
44
|
-
:
|
|
44
|
+
:refund => 'refund'
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
# Create a new NetRegistry gateway.
|
|
@@ -94,13 +94,18 @@ module ActiveMerchant
|
|
|
94
94
|
commit(:purchase, params)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
def
|
|
97
|
+
def refund(money, identification, options = {})
|
|
98
98
|
params = {
|
|
99
99
|
'AMOUNT' => amount(money),
|
|
100
100
|
'TXNREF' => identification
|
|
101
101
|
}
|
|
102
102
|
add_request_details(params, options)
|
|
103
|
-
commit(:
|
|
103
|
+
commit(:refund, params)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def credit(money, identification, options = {})
|
|
107
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
|
108
|
+
refund(money, identification, options)
|
|
104
109
|
end
|
|
105
110
|
|
|
106
111
|
# Specific to NetRegistry.
|
|
@@ -30,56 +30,73 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
def purchase(money, creditcard, options = {})
|
|
31
31
|
requires!(options, :order_id)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
add_creditcard(post, creditcard)
|
|
38
|
-
commit('Sale', post)
|
|
33
|
+
MultiResponse.run do |r|
|
|
34
|
+
r.process{authorize(money, creditcard, options)}
|
|
35
|
+
r.process{capture(money, r.authorization, options)}
|
|
36
|
+
end
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
def authorize(money, creditcard, options = {})
|
|
42
40
|
requires!(options, :order_id)
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
commit('Auth', post)
|
|
42
|
+
MultiResponse.run do |r|
|
|
43
|
+
r.process{setup_transaction(money, options)}
|
|
44
|
+
r.process{add_and_auth_credit_card(r.authorization, creditcard, options)}
|
|
45
|
+
r.process{query_transaction(r.authorization, options)}
|
|
46
|
+
end
|
|
50
47
|
end
|
|
51
48
|
|
|
52
49
|
def capture(money, authorization, options = {})
|
|
53
50
|
post = {}
|
|
54
51
|
add_credentials(post, options)
|
|
55
52
|
add_authorization(post, authorization, money)
|
|
56
|
-
|
|
53
|
+
post[:operation] = "Capture"
|
|
54
|
+
commit("Netaxept/process.aspx", post)
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
def refund(money, authorization, options = {})
|
|
60
58
|
post = {}
|
|
61
59
|
add_credentials(post, options)
|
|
62
60
|
add_authorization(post, authorization, money)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def credit(money, authorization, options = {})
|
|
67
|
-
deprecated CREDIT_DEPRECATION_MESSAGE
|
|
68
|
-
refund(money, authorization, options)
|
|
61
|
+
post[:operation] = "Credit"
|
|
62
|
+
commit("Netaxept/process.aspx", post)
|
|
69
63
|
end
|
|
70
64
|
|
|
71
65
|
def void(authorization, options = {})
|
|
72
66
|
post = {}
|
|
73
67
|
add_credentials(post, options)
|
|
74
68
|
add_authorization(post, authorization)
|
|
75
|
-
|
|
69
|
+
post[:operation] = "Annul"
|
|
70
|
+
commit("Netaxept/process.aspx", post)
|
|
76
71
|
end
|
|
77
72
|
|
|
78
73
|
private
|
|
79
74
|
|
|
80
|
-
def
|
|
75
|
+
def setup_transaction(money, options)
|
|
76
|
+
post = {}
|
|
77
|
+
add_credentials(post, options)
|
|
78
|
+
add_order(post, money, options)
|
|
79
|
+
commit("Netaxept/Register.aspx", post)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_and_auth_credit_card(authorization, creditcard, options)
|
|
83
|
+
post = {}
|
|
84
|
+
add_credentials(post, options, false)
|
|
85
|
+
add_authorization(post, authorization)
|
|
86
|
+
add_creditcard(post, creditcard)
|
|
87
|
+
commit("terminal/default.aspx", post, false)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def query_transaction(authorization, options)
|
|
91
|
+
post = {}
|
|
92
|
+
add_credentials(post, options)
|
|
93
|
+
add_authorization(post, authorization)
|
|
94
|
+
commit("Netaxept/query.aspx", post)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def add_credentials(post, options, secure=true)
|
|
81
98
|
post[:merchantId] = @options[:login]
|
|
82
|
-
post[:token] = @options[:password]
|
|
99
|
+
post[:token] = @options[:password] if secure
|
|
83
100
|
end
|
|
84
101
|
|
|
85
102
|
def add_authorization(post, authorization, money=nil)
|
|
@@ -87,92 +104,45 @@ module ActiveMerchant #:nodoc:
|
|
|
87
104
|
post[:transactionAmount] = amount(money) if money
|
|
88
105
|
end
|
|
89
106
|
|
|
90
|
-
def add_transaction(post, options)
|
|
91
|
-
post[:transactionId] = generate_transaction_id(options)
|
|
92
|
-
post[:serviceType] = 'M'
|
|
93
|
-
post[:redirectUrl] = 'http://example.com'
|
|
94
|
-
end
|
|
95
|
-
|
|
96
107
|
def add_order(post, money, options)
|
|
108
|
+
post[:serviceType] = 'M'
|
|
97
109
|
post[:orderNumber] = options[:order_id]
|
|
98
110
|
post[:amount] = amount(money)
|
|
99
111
|
post[:currencyCode] = (options[:currency] || currency(money))
|
|
112
|
+
post[:autoAuth] = "true"
|
|
100
113
|
end
|
|
101
114
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
def add_creditcard(post, creditcard)
|
|
108
|
-
brand = Gateway.card_brand(creditcard)
|
|
109
|
-
prefix = CARD_TYPE_PREFIXES[brand]
|
|
110
|
-
unless prefix
|
|
111
|
-
raise ArgumentError.new("Card type #{brand} not supported.")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
post[:creditcard] = {}
|
|
115
|
-
post[:creditcard][:"#{prefix}a"] = creditcard.number
|
|
116
|
-
post[:creditcard][:"#{prefix}m"] = format(creditcard.month, :two_digits)
|
|
117
|
-
post[:creditcard][:"#{prefix}y"] = format(creditcard.year, :two_digits)
|
|
118
|
-
post[:creditcard][:"#{prefix}c"] = creditcard.verification_value
|
|
115
|
+
def add_creditcard(post, options)
|
|
116
|
+
post[:pan] = options.number
|
|
117
|
+
post[:expiryDate] = format(options.month, :two_digits) + format(options.year, :two_digits)
|
|
118
|
+
post[:securityCode] = options.verification_value
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
def commit(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
response = {:success => false}
|
|
125
|
-
|
|
126
|
-
catch(:exception) do
|
|
127
|
-
if setup
|
|
128
|
-
commit_transaction_setup(response, parameters)
|
|
129
|
-
commit_payment_details(response, parameters)
|
|
130
|
-
commit_process_setup(response, parameters)
|
|
131
|
-
end
|
|
132
|
-
commit_transaction(response, parameters)
|
|
133
|
-
response[:success] = true
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
Response.new(response[:success], response[:message], response, :test => test?, :authorization => response[:authorization])
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def commit_transaction_setup(response, parameters)
|
|
140
|
-
response[:setup] = parse(ssl_get(build_url("REST/Setup.aspx", pick(parameters, :merchantId, :token, :serviceType, :amount, :currencyCode, :redirectUrl, :orderNumber, :transactionId))))
|
|
141
|
-
process(response, :setup)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def commit_payment_details(response, parameters)
|
|
145
|
-
data = encode(parameters[:creditcard].merge(:BBSePay_transaction => response[:setup]['SetupString']))
|
|
146
|
-
response[:paymentDetails] = parse(ssl_post(build_url("terminal/default.aspx"), data), false)
|
|
147
|
-
process(response, :paymentDetails)
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def commit_process_setup(response, parameters)
|
|
151
|
-
result = ssl_get(build_url("REST/ProcessSetup.aspx", pick(parameters, :merchantId, :token, :transactionId).merge(:transactionString => response[:paymentDetails][:result])))
|
|
152
|
-
response[:processSetup] = parse(result)
|
|
153
|
-
process(response, :processSetup)
|
|
154
|
-
end
|
|
121
|
+
def commit(path, parameters, xml=true)
|
|
122
|
+
raw = parse(ssl_get(build_url(path, parameters)), xml)
|
|
155
123
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def process(response, step)
|
|
163
|
-
if response[step][:container] =~ /Exception|Error/
|
|
164
|
-
response[:message] = response[step]['Message']
|
|
165
|
-
throw :exception
|
|
124
|
+
success = false
|
|
125
|
+
authorization = (raw["TransactionId"] || parameters[:transactionId])
|
|
126
|
+
if raw[:container] =~ /Exception|Error/
|
|
127
|
+
message = (raw["Message"] || raw["Error"]["Message"])
|
|
128
|
+
elsif raw["Error"] && !raw["Error"].empty?
|
|
129
|
+
message = (raw["Error"]["ResponseText"] || raw["Error"]["ResponseCode"])
|
|
166
130
|
else
|
|
167
|
-
message = (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
response[:authorization] = response[step]['TransactionId']
|
|
131
|
+
message = (raw["ResponseText"] || raw["ResponseCode"] || "OK")
|
|
132
|
+
success = true
|
|
171
133
|
end
|
|
134
|
+
|
|
135
|
+
Response.new(
|
|
136
|
+
success,
|
|
137
|
+
message,
|
|
138
|
+
raw,
|
|
139
|
+
:test => test?,
|
|
140
|
+
:authorization => authorization
|
|
141
|
+
)
|
|
172
142
|
end
|
|
173
143
|
|
|
174
144
|
def parse(result, expects_xml=true)
|
|
175
|
-
if expects_xml
|
|
145
|
+
if expects_xml
|
|
176
146
|
doc = REXML::Document.new(result)
|
|
177
147
|
extract_xml(doc.root).merge(:container => doc.root.name)
|
|
178
148
|
else
|
|
@@ -192,20 +162,8 @@ module ActiveMerchant #:nodoc:
|
|
|
192
162
|
end
|
|
193
163
|
end
|
|
194
164
|
|
|
195
|
-
def url
|
|
196
|
-
(test? ? self.test_url : self.live_url)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def generate_transaction_id(options)
|
|
200
|
-
Digest::MD5.hexdigest("#{options.inspect}+#{Time.now}+#{rand}")
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def pick(hash, *keys)
|
|
204
|
-
keys.inject({}){|h,key| h[key] = hash[key] if hash[key]; h}
|
|
205
|
-
end
|
|
206
|
-
|
|
207
165
|
def build_url(base, parameters=nil)
|
|
208
|
-
url =
|
|
166
|
+
url = (test? ? self.test_url : self.live_url).dup
|
|
209
167
|
url << base
|
|
210
168
|
if parameters
|
|
211
169
|
url << '?'
|
|
@@ -217,16 +175,6 @@ module ActiveMerchant #:nodoc:
|
|
|
217
175
|
def encode(hash)
|
|
218
176
|
hash.collect{|(k,v)| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join('&')
|
|
219
177
|
end
|
|
220
|
-
|
|
221
|
-
class Response < Billing::Response
|
|
222
|
-
attr_reader :error_detail
|
|
223
|
-
def initialize(success, message, raw, options)
|
|
224
|
-
super
|
|
225
|
-
unless success
|
|
226
|
-
@error_detail = raw[:processSetup]['Result']['ResponseText'] if raw[:processSetup] && raw[:processSetup]['Result']
|
|
227
|
-
end
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
178
|
end
|
|
231
179
|
end
|
|
232
180
|
end
|