activemerchant 1.28.0 → 1.29.1
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 +41 -0
- data/CONTRIBUTORS +12 -0
- data/README.md +6 -0
- data/lib/active_merchant/billing/gateway.rb +2 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +77 -78
- data/lib/active_merchant/billing/gateways/balanced.rb +0 -1
- data/lib/active_merchant/billing/gateways/banwire.rb +1 -2
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +19 -20
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +35 -36
- data/lib/active_merchant/billing/gateways/blue_pay.rb +135 -140
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +12 -4
- data/lib/active_merchant/billing/gateways/card_stream.rb +54 -59
- data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -14
- data/lib/active_merchant/billing/gateways/data_cash.rb +106 -112
- data/lib/active_merchant/billing/gateways/efsnet.rb +29 -34
- data/lib/active_merchant/billing/gateways/elavon.rb +7 -1
- data/lib/active_merchant/billing/gateways/epay.rb +0 -1
- data/lib/active_merchant/billing/gateways/eway.rb +88 -93
- data/lib/active_merchant/billing/gateways/eway_managed.rb +47 -51
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +300 -0
- data/lib/active_merchant/billing/gateways/exact.rb +45 -54
- data/lib/active_merchant/billing/gateways/federated_canada.rb +3 -4
- data/lib/active_merchant/billing/gateways/first_pay.rb +37 -38
- data/lib/active_merchant/billing/gateways/garanti.rb +1 -2
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +5 -8
- data/lib/active_merchant/billing/gateways/inspire.rb +52 -52
- data/lib/active_merchant/billing/gateways/instapay.rb +10 -11
- data/lib/active_merchant/billing/gateways/iridium.rb +38 -39
- data/lib/active_merchant/billing/gateways/itransact.rb +7 -9
- data/lib/active_merchant/billing/gateways/jetpay.rb +45 -46
- data/lib/active_merchant/billing/gateways/linkpoint.rb +104 -108
- data/lib/active_merchant/billing/gateways/litle.rb +1 -5
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +153 -155
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +49 -50
- data/lib/active_merchant/billing/gateways/mercury.rb +272 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +9 -10
- data/lib/active_merchant/billing/gateways/migs.rb +5 -3
- data/lib/active_merchant/billing/gateways/modern_payments.rb +6 -7
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +40 -41
- data/lib/active_merchant/billing/gateways/moneris.rb +46 -50
- data/lib/active_merchant/billing/gateways/moneris_us.rb +52 -55
- data/lib/active_merchant/billing/gateways/nab_transact.rb +0 -5
- data/lib/active_merchant/billing/gateways/net_registry.rb +20 -21
- data/lib/active_merchant/billing/gateways/netaxept.rb +30 -36
- data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
- data/lib/active_merchant/billing/gateways/ogone.rb +0 -5
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -6
- data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +93 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +25 -21
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +1 -6
- data/lib/active_merchant/billing/gateways/pay_junction.rb +62 -63
- data/lib/active_merchant/billing/gateways/pay_secure.rb +29 -30
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +0 -5
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +33 -38
- data/lib/active_merchant/billing/gateways/payment_express.rb +48 -51
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -11
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +7 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +3 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +62 -64
- data/lib/active_merchant/billing/gateways/payway.rb +2 -9
- data/lib/active_merchant/billing/gateways/plugnpay.rb +0 -1
- data/lib/active_merchant/billing/gateways/psigate.rb +102 -94
- data/lib/active_merchant/billing/gateways/psl_card.rb +66 -67
- data/lib/active_merchant/billing/gateways/qbms.rb +0 -6
- data/lib/active_merchant/billing/gateways/quantum.rb +2 -8
- data/lib/active_merchant/billing/gateways/quickpay.rb +2 -3
- data/lib/active_merchant/billing/gateways/realex.rb +6 -16
- data/lib/active_merchant/billing/gateways/redsys.rb +394 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +25 -26
- data/lib/active_merchant/billing/gateways/sage.rb +15 -16
- data/lib/active_merchant/billing/gateways/sage_pay.rb +51 -56
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +1 -2
- data/lib/active_merchant/billing/gateways/samurai.rb +1 -4
- data/lib/active_merchant/billing/gateways/secure_net.rb +0 -1
- data/lib/active_merchant/billing/gateways/secure_pay.rb +5 -8
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +0 -5
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +17 -18
- data/lib/active_merchant/billing/gateways/skip_jack.rb +29 -34
- data/lib/active_merchant/billing/gateways/smart_ps.rb +55 -56
- data/lib/active_merchant/billing/gateways/stripe.rb +8 -3
- data/lib/active_merchant/billing/gateways/trans_first.rb +28 -29
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +85 -87
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +27 -28
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +0 -5
- data/lib/active_merchant/billing/gateways/verifi.rb +86 -87
- data/lib/active_merchant/billing/gateways/viaklix.rb +42 -47
- data/lib/active_merchant/billing/gateways/vindicia.rb +30 -28
- data/lib/active_merchant/billing/gateways/webpay.rb +45 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +0 -6
- data/lib/active_merchant/billing/gateways/worldpay.rb +4 -9
- data/lib/active_merchant/billing/gateways.rb +6 -7
- data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +31 -0
- data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +186 -0
- data/lib/active_merchant/billing/integrations/a1agregator/status.rb +38 -0
- data/lib/active_merchant/billing/integrations/a1agregator.rb +26 -0
- data/lib/active_merchant/billing/integrations/liqpay/helper.rb +43 -0
- data/lib/active_merchant/billing/integrations/liqpay/notification.rb +89 -0
- data/lib/active_merchant/billing/integrations/liqpay/return.rb +83 -0
- data/lib/active_merchant/billing/integrations/liqpay.rb +30 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +17 -1
- data/lib/active_merchant/billing/integrations/notification.rb +4 -0
- data/lib/active_merchant/billing/integrations/pay_fast/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +50 -0
- data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +134 -0
- data/lib/active_merchant/billing/integrations/pay_fast/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/pay_fast.rb +70 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +64 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +10 -7
- data/lib/active_merchant/billing/integrations/webmoney/notification.rb +12 -0
- data/lib/active_merchant/billing/response.rb +17 -4
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +46 -27
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
require "nokogiri"
|
|
2
|
+
require "cgi"
|
|
3
|
+
|
|
4
|
+
module ActiveMerchant #:nodoc:
|
|
5
|
+
module Billing #:nodoc:
|
|
6
|
+
class EwayRapidGateway < Gateway
|
|
7
|
+
self.test_url = "https://api.sandbox.ewaypayments.com/"
|
|
8
|
+
self.live_url = "https://api.ewaypayments.com/"
|
|
9
|
+
|
|
10
|
+
self.money_format = :cents
|
|
11
|
+
self.supported_countries = ["AU"]
|
|
12
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
|
13
|
+
self.homepage_url = "http://www.eway.com.au/"
|
|
14
|
+
self.display_name = "eWAY Rapid 3.0"
|
|
15
|
+
self.default_currency = "AUD"
|
|
16
|
+
|
|
17
|
+
def initialize(options = {})
|
|
18
|
+
requires!(options, :login, :password)
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Public: Run a purchase transaction. Treats the Rapid 3.0 transparent
|
|
23
|
+
# redirect as an API endpoint in order to conform to the standard
|
|
24
|
+
# ActiveMerchant #purchase API.
|
|
25
|
+
#
|
|
26
|
+
# amount - The monetary amount of the transaction in cents.
|
|
27
|
+
# options - A standard ActiveMerchant options hash:
|
|
28
|
+
# :order_id - A merchant-supplied identifier for the
|
|
29
|
+
# transaction (optional).
|
|
30
|
+
# :description - A merchant-supplied description of the
|
|
31
|
+
# transaction (optional).
|
|
32
|
+
# :currency - Three letter currency code for the
|
|
33
|
+
# transaction (default: "AUD")
|
|
34
|
+
# :billing_address - Standard ActiveMerchant address hash
|
|
35
|
+
# (optional).
|
|
36
|
+
# :shipping_address - Standard ActiveMerchant address hash
|
|
37
|
+
# (optional).
|
|
38
|
+
# :ip - The ip of the consumer initiating the
|
|
39
|
+
# transaction (optional).
|
|
40
|
+
# :application_id - A string identifying the application
|
|
41
|
+
# submitting the transaction
|
|
42
|
+
# (default: "https://github.com/Shopify/active_merchant")
|
|
43
|
+
#
|
|
44
|
+
# Returns an ActiveMerchant::Billing::Response object
|
|
45
|
+
def purchase(amount, payment_method, options={})
|
|
46
|
+
MultiResponse.new.tap do |r|
|
|
47
|
+
# Rather than follow the redirect, we detect the 302 and capture the
|
|
48
|
+
# token out of the Location header in the run_purchase step. But we
|
|
49
|
+
# still need a placeholder url to pass to eWay, and that is what
|
|
50
|
+
# example.com is used for here.
|
|
51
|
+
r.process{setup_purchase(amount, options.merge(:redirect_url => "http://example.com/"))}
|
|
52
|
+
r.process{run_purchase(r.authorization, payment_method, r.params["formactionurl"])}
|
|
53
|
+
r.process{status(r.authorization)}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Public: Acquire the token necessary to run a transparent redirect.
|
|
58
|
+
#
|
|
59
|
+
# amount - The monetary amount of the transaction in cents.
|
|
60
|
+
# options - A supplemented ActiveMerchant options hash:
|
|
61
|
+
# :redirect_url - The url to return the customer to after
|
|
62
|
+
# the transparent redirect is completed
|
|
63
|
+
# (required).
|
|
64
|
+
# :order_id - A merchant-supplied identifier for the
|
|
65
|
+
# transaction (optional).
|
|
66
|
+
# :description - A merchant-supplied description of the
|
|
67
|
+
# transaction (optional).
|
|
68
|
+
# :currency - Three letter currency code for the
|
|
69
|
+
# transaction (default: "AUD")
|
|
70
|
+
# :billing_address - Standard ActiveMerchant address hash
|
|
71
|
+
# (optional).
|
|
72
|
+
# :shipping_address - Standard ActiveMerchant address hash
|
|
73
|
+
# (optional).
|
|
74
|
+
# :ip - The ip of the consumer initiating the
|
|
75
|
+
# transaction (optional).
|
|
76
|
+
# :application_id - A string identifying the application
|
|
77
|
+
# submitting the transaction
|
|
78
|
+
# (default: "https://github.com/Shopify/active_merchant")
|
|
79
|
+
#
|
|
80
|
+
# Returns an EwayRapidResponse object, which conforms to the
|
|
81
|
+
# ActiveMerchant::Billing::Response API, but also exposes #form_url.
|
|
82
|
+
def setup_purchase(amount, options={})
|
|
83
|
+
requires!(options, :redirect_url)
|
|
84
|
+
request = build_xml_request("CreateAccessCodeRequest") do |doc|
|
|
85
|
+
add_metadata(doc, options)
|
|
86
|
+
add_invoice(doc, amount, options)
|
|
87
|
+
add_customer_data(doc, options)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
commit(url_for("CreateAccessCode"), request)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Public: Retrieve the status of a transaction.
|
|
94
|
+
#
|
|
95
|
+
# identification - The Eway Rapid 3.0 access code for the transaction
|
|
96
|
+
# (returned as the response.authorization by
|
|
97
|
+
# #setup_purchase).
|
|
98
|
+
#
|
|
99
|
+
# Returns an EwayRapidResponse object.
|
|
100
|
+
def status(identification)
|
|
101
|
+
request = build_xml_request("GetAccessCodeResultRequest") do |doc|
|
|
102
|
+
doc.AccessCode identification
|
|
103
|
+
end
|
|
104
|
+
commit(url_for("GetAccessCodeResult"), request)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def run_purchase(identification, payment_method, endpoint)
|
|
110
|
+
post = {
|
|
111
|
+
"accesscode" => identification
|
|
112
|
+
}
|
|
113
|
+
add_credit_card(post, payment_method)
|
|
114
|
+
|
|
115
|
+
commit_form(endpoint, build_form_request(post))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def add_metadata(doc, options)
|
|
119
|
+
doc.RedirectUrl(options[:redirect_url])
|
|
120
|
+
doc.CustomerIP options[:ip] if options[:ip]
|
|
121
|
+
doc.Method "ProcessPayment"
|
|
122
|
+
doc.DeviceID(options[:application_id] || application_id)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def add_invoice(doc, money, options)
|
|
126
|
+
doc.Payment do
|
|
127
|
+
doc.TotalAmount amount(money)
|
|
128
|
+
doc.InvoiceReference options[:order_id]
|
|
129
|
+
doc.InvoiceDescription options[:description]
|
|
130
|
+
currency_code = (options[:currency] || currency(money) || default_currency)
|
|
131
|
+
doc.CurrencyCode currency_code
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def add_customer_data(doc, options)
|
|
136
|
+
doc.Customer do
|
|
137
|
+
add_address(doc, (options[:billing_address] || options[:address]), {:email => options[:email]})
|
|
138
|
+
end
|
|
139
|
+
doc.ShippingAddress do
|
|
140
|
+
add_address(doc, options[:shipping_address], {:skip_company => true})
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def add_address(doc, address, options={})
|
|
145
|
+
return unless address
|
|
146
|
+
if name = address[:name]
|
|
147
|
+
parts = name.split(/\s+/)
|
|
148
|
+
doc.FirstName parts.shift if parts.size > 1
|
|
149
|
+
doc.LastName parts.join(" ")
|
|
150
|
+
end
|
|
151
|
+
doc.CompanyName address[:company] unless options[:skip_company]
|
|
152
|
+
doc.Street1 address[:address1]
|
|
153
|
+
doc.Street2 address[:address2]
|
|
154
|
+
doc.City address[:city]
|
|
155
|
+
doc.State address[:state]
|
|
156
|
+
doc.PostalCode address[:zip]
|
|
157
|
+
doc.Country address[:country]
|
|
158
|
+
doc.Phone address[:phone]
|
|
159
|
+
doc.Fax address[:fax]
|
|
160
|
+
doc.Email options[:email]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def add_credit_card(post, credit_card)
|
|
164
|
+
post["cardname"] = credit_card.name
|
|
165
|
+
post["cardnumber"] = credit_card.number
|
|
166
|
+
post["cardexpirymonth"] = credit_card.month
|
|
167
|
+
post["cardexpiryyear"] = credit_card.year
|
|
168
|
+
post["cardcvn"] = credit_card.verification_value
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def build_xml_request(root)
|
|
172
|
+
builder = Nokogiri::XML::Builder.new
|
|
173
|
+
builder.__send__(root) do |doc|
|
|
174
|
+
yield(doc)
|
|
175
|
+
end
|
|
176
|
+
builder.to_xml
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def build_form_request(post)
|
|
180
|
+
request = []
|
|
181
|
+
post.each do |key, value|
|
|
182
|
+
request << "EWAY_#{key.upcase}=#{CGI.escape(value.to_s)}"
|
|
183
|
+
end
|
|
184
|
+
request.join("&")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def url_for(action)
|
|
188
|
+
(test? ? test_url : live_url) + action + ".xml"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def commit(url, request, form_post=false)
|
|
192
|
+
headers = {
|
|
193
|
+
"Authorization" => ("Basic " + Base64.strict_encode64(@options[:login].to_s + ":" + @options[:password].to_s).chomp),
|
|
194
|
+
"Content-Type" => "text/xml"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
raw = parse(ssl_post(url, request, headers))
|
|
198
|
+
|
|
199
|
+
succeeded = success?(raw)
|
|
200
|
+
EwayRapidResponse.new(
|
|
201
|
+
succeeded,
|
|
202
|
+
message_from(succeeded, raw),
|
|
203
|
+
raw,
|
|
204
|
+
:authorization => authorization_from(raw),
|
|
205
|
+
:test => test?,
|
|
206
|
+
:avs_result => avs_result_from(raw),
|
|
207
|
+
:cvv_result => cvv_result_from(raw)
|
|
208
|
+
)
|
|
209
|
+
rescue ActiveMerchant::ResponseError => e
|
|
210
|
+
return EwayRapidResponse.new(false, e.response.message, {:status_code => e.response.code}, :test => test?)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def commit_form(url, request)
|
|
214
|
+
http_response = raw_ssl_request(:post, url, request)
|
|
215
|
+
|
|
216
|
+
success = (http_response.code.to_s == "302")
|
|
217
|
+
message = (success ? "Succeeded" : http_response.body)
|
|
218
|
+
if success
|
|
219
|
+
authorization = CGI.unescape(http_response["Location"].split("=").last)
|
|
220
|
+
end
|
|
221
|
+
Response.new(success, message, {:location => http_response["Location"]}, :authorization => authorization, :test => test?)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def parse(xml)
|
|
225
|
+
response = {}
|
|
226
|
+
|
|
227
|
+
doc = Nokogiri::XML(xml)
|
|
228
|
+
doc.root.xpath("*").each do |node|
|
|
229
|
+
if (node.elements.size == 0)
|
|
230
|
+
response[node.name.downcase.to_sym] = node.text
|
|
231
|
+
else
|
|
232
|
+
node.elements.each do |childnode|
|
|
233
|
+
name = "#{node.name.downcase}_#{childnode.name.downcase}"
|
|
234
|
+
response[name.to_sym] = childnode.text
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end unless doc.root.nil?
|
|
238
|
+
|
|
239
|
+
response
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def success?(response)
|
|
243
|
+
if response[:errors]
|
|
244
|
+
false
|
|
245
|
+
elsif response[:transactionstatus]
|
|
246
|
+
(response[:transactionstatus] == "true")
|
|
247
|
+
else
|
|
248
|
+
true
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def message_from(succeeded, response)
|
|
253
|
+
if response[:errors]
|
|
254
|
+
response[:errors]
|
|
255
|
+
elsif response[:responsecode]
|
|
256
|
+
ActiveMerchant::Billing::EwayGateway::MESSAGES[response[:responsecode]]
|
|
257
|
+
elsif response[:responsemessage]
|
|
258
|
+
response[:responsemessage]
|
|
259
|
+
elsif succeeded
|
|
260
|
+
"Succeeded"
|
|
261
|
+
else
|
|
262
|
+
"Failed"
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def authorization_from(response)
|
|
267
|
+
response[:accesscode]
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def avs_result_from(response)
|
|
271
|
+
code = case response[:verification_address]
|
|
272
|
+
when "Valid"
|
|
273
|
+
"M"
|
|
274
|
+
when "Invalid"
|
|
275
|
+
"N"
|
|
276
|
+
else
|
|
277
|
+
"I"
|
|
278
|
+
end
|
|
279
|
+
{:code => code}
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def cvv_result_from(response)
|
|
283
|
+
case response[:verification_cvn]
|
|
284
|
+
when "Valid"
|
|
285
|
+
"M"
|
|
286
|
+
when "Invalid"
|
|
287
|
+
"N"
|
|
288
|
+
else
|
|
289
|
+
"P"
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
class EwayRapidResponse < ActiveMerchant::Billing::Response
|
|
294
|
+
def form_url
|
|
295
|
+
params["formactionurl"]
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
@@ -2,67 +2,58 @@ module ActiveMerchant #:nodoc:
|
|
|
2
2
|
module Billing #:nodoc:
|
|
3
3
|
class ExactGateway < Gateway
|
|
4
4
|
self.live_url = self.test_url = 'https://secure2.e-xact.com/vplug-in/transaction/rpc-enc/service.asmx'
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
API_VERSION = "8.5"
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
TEST_LOGINS = [ {:login => "A00049-01", :password => "test1"},
|
|
9
9
|
{:login => "A00427-01", :password => "testus"} ]
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
TRANSACTIONS = { :sale => "00",
|
|
12
12
|
:authorization => "01",
|
|
13
13
|
:capture => "32",
|
|
14
14
|
:credit => "34" }
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
|
|
17
17
|
ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
|
18
18
|
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
|
19
19
|
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
SEND_AND_COMMIT_ATTRIBUTES = { 'xmlns:n1' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request",
|
|
23
23
|
'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
SEND_AND_COMMIT_SOURCE_ATTRIBUTES = { 'xmlns:n2' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes',
|
|
27
27
|
'xsi:type' => 'n2:Transaction'
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
POST_HEADERS = { 'soapAction' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/SendAndCommit",
|
|
31
|
-
'Content-Type' => 'text/xml'
|
|
31
|
+
'Content-Type' => 'text/xml'
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
SUCCESS = "true"
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ]
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
|
|
39
39
|
self.supported_countries = ['CA', 'US']
|
|
40
40
|
self.homepage_url = 'http://www.e-xact.com'
|
|
41
41
|
self.display_name = 'E-xact'
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
def initialize(options = {})
|
|
44
44
|
requires!(options, :login, :password)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if TEST_LOGINS.include?( { :login => options[:login], :password => options[:password] } )
|
|
48
|
-
@test_mode = true
|
|
49
|
-
end
|
|
50
|
-
|
|
45
|
+
|
|
51
46
|
super
|
|
52
47
|
end
|
|
53
|
-
|
|
54
|
-
def test?
|
|
55
|
-
@test_mode || Base.gateway_mode == :test
|
|
56
|
-
end
|
|
57
|
-
|
|
48
|
+
|
|
58
49
|
def authorize(money, credit_card, options = {})
|
|
59
50
|
commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
|
|
60
51
|
end
|
|
61
|
-
|
|
52
|
+
|
|
62
53
|
def purchase(money, credit_card, options = {})
|
|
63
54
|
commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
|
|
64
55
|
end
|
|
65
|
-
|
|
56
|
+
|
|
66
57
|
def capture(money, authorization, options = {})
|
|
67
58
|
commit(:capture, build_capture_or_credit_request(money, authorization, options))
|
|
68
59
|
end
|
|
@@ -75,11 +66,11 @@ module ActiveMerchant #:nodoc:
|
|
|
75
66
|
def refund(money, authorization, options = {})
|
|
76
67
|
commit(:credit, build_capture_or_credit_request(money, authorization, options))
|
|
77
68
|
end
|
|
78
|
-
|
|
79
|
-
private
|
|
69
|
+
|
|
70
|
+
private
|
|
80
71
|
def build_request(action, body)
|
|
81
72
|
xml = Builder::XmlMarkup.new
|
|
82
|
-
|
|
73
|
+
|
|
83
74
|
xml.instruct!
|
|
84
75
|
xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
|
|
85
76
|
xml.tag! 'env:Body' do
|
|
@@ -94,59 +85,59 @@ module ActiveMerchant #:nodoc:
|
|
|
94
85
|
end
|
|
95
86
|
xml.target!
|
|
96
87
|
end
|
|
97
|
-
|
|
88
|
+
|
|
98
89
|
def build_sale_or_authorization_request(money, credit_card, options)
|
|
99
90
|
xml = Builder::XmlMarkup.new
|
|
100
|
-
|
|
91
|
+
|
|
101
92
|
add_amount(xml, money)
|
|
102
93
|
add_credit_card(xml, credit_card)
|
|
103
94
|
add_customer_data(xml, options)
|
|
104
95
|
add_invoice(xml, options)
|
|
105
|
-
|
|
106
|
-
xml.target!
|
|
96
|
+
|
|
97
|
+
xml.target!
|
|
107
98
|
end
|
|
108
|
-
|
|
99
|
+
|
|
109
100
|
def build_capture_or_credit_request(money, identification, options)
|
|
110
101
|
xml = Builder::XmlMarkup.new
|
|
111
|
-
|
|
102
|
+
|
|
112
103
|
add_identification(xml, identification)
|
|
113
104
|
add_amount(xml, money)
|
|
114
105
|
add_customer_data(xml, options)
|
|
115
|
-
|
|
106
|
+
|
|
116
107
|
xml.target!
|
|
117
108
|
end
|
|
118
|
-
|
|
109
|
+
|
|
119
110
|
def add_credentials(xml)
|
|
120
111
|
xml.tag! 'ExactID', @options[:login]
|
|
121
112
|
xml.tag! 'Password', @options[:password]
|
|
122
113
|
end
|
|
123
|
-
|
|
114
|
+
|
|
124
115
|
def add_transaction_type(xml, action)
|
|
125
116
|
xml.tag! 'Transaction_Type', TRANSACTIONS[action]
|
|
126
117
|
end
|
|
127
|
-
|
|
118
|
+
|
|
128
119
|
def add_identification(xml, identification)
|
|
129
120
|
authorization_num, transaction_tag = identification.split(';')
|
|
130
|
-
|
|
121
|
+
|
|
131
122
|
xml.tag! 'Authorization_Num', authorization_num
|
|
132
123
|
xml.tag! 'Transaction_Tag', transaction_tag
|
|
133
124
|
end
|
|
134
|
-
|
|
125
|
+
|
|
135
126
|
def add_amount(xml, money)
|
|
136
127
|
xml.tag! 'DollarAmount', amount(money)
|
|
137
128
|
end
|
|
138
|
-
|
|
129
|
+
|
|
139
130
|
def add_credit_card(xml, credit_card)
|
|
140
131
|
xml.tag! 'Card_Number', credit_card.number
|
|
141
132
|
xml.tag! 'Expiry_Date', expdate(credit_card)
|
|
142
133
|
xml.tag! 'CardHoldersName', credit_card.name
|
|
143
|
-
|
|
134
|
+
|
|
144
135
|
if credit_card.verification_value?
|
|
145
136
|
xml.tag! 'CVD_Presence_Ind', '1'
|
|
146
137
|
xml.tag! 'VerificationStr2', credit_card.verification_value
|
|
147
138
|
end
|
|
148
139
|
end
|
|
149
|
-
|
|
140
|
+
|
|
150
141
|
def add_customer_data(xml, options)
|
|
151
142
|
xml.tag! 'Customer_Ref', options[:customer]
|
|
152
143
|
xml.tag! 'Client_IP', options[:ip]
|
|
@@ -155,22 +146,22 @@ module ActiveMerchant #:nodoc:
|
|
|
155
146
|
|
|
156
147
|
def add_address(xml, options)
|
|
157
148
|
if address = options[:billing_address] || options[:address]
|
|
158
|
-
xml.tag! 'ZipCode', address[:zip]
|
|
159
|
-
end
|
|
149
|
+
xml.tag! 'ZipCode', address[:zip]
|
|
150
|
+
end
|
|
160
151
|
end
|
|
161
152
|
|
|
162
153
|
def add_invoice(xml, options)
|
|
163
154
|
xml.tag! 'Reference_No', options[:order_id]
|
|
164
155
|
xml.tag! 'Reference_3', options[:description]
|
|
165
156
|
end
|
|
166
|
-
|
|
157
|
+
|
|
167
158
|
def expdate(credit_card)
|
|
168
159
|
"#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
|
|
169
160
|
end
|
|
170
|
-
|
|
161
|
+
|
|
171
162
|
def commit(action, request)
|
|
172
163
|
response = parse(ssl_post(self.live_url, build_request(action, request), POST_HEADERS))
|
|
173
|
-
|
|
164
|
+
|
|
174
165
|
Response.new(successful?(response), message_from(response), response,
|
|
175
166
|
:test => test?,
|
|
176
167
|
:authorization => authorization_from(response),
|
|
@@ -178,19 +169,19 @@ module ActiveMerchant #:nodoc:
|
|
|
178
169
|
:cvv_result => response[:cvv2]
|
|
179
170
|
)
|
|
180
171
|
end
|
|
181
|
-
|
|
172
|
+
|
|
182
173
|
def successful?(response)
|
|
183
174
|
response[:transaction_approved] == SUCCESS
|
|
184
175
|
end
|
|
185
|
-
|
|
176
|
+
|
|
186
177
|
def authorization_from(response)
|
|
187
178
|
if response[:authorization_num] && response[:transaction_tag]
|
|
188
|
-
"#{response[:authorization_num]};#{response[:transaction_tag]}"
|
|
179
|
+
"#{response[:authorization_num]};#{response[:transaction_tag]}"
|
|
189
180
|
else
|
|
190
181
|
''
|
|
191
182
|
end
|
|
192
183
|
end
|
|
193
|
-
|
|
184
|
+
|
|
194
185
|
def message_from(response)
|
|
195
186
|
if response[:faultcode] && response[:faultstring]
|
|
196
187
|
response[:faultstring]
|
|
@@ -202,11 +193,11 @@ module ActiveMerchant #:nodoc:
|
|
|
202
193
|
result
|
|
203
194
|
end
|
|
204
195
|
end
|
|
205
|
-
|
|
196
|
+
|
|
206
197
|
def parse(xml)
|
|
207
198
|
response = {}
|
|
208
199
|
xml = REXML::Document.new(xml)
|
|
209
|
-
|
|
200
|
+
|
|
210
201
|
if root = REXML::XPath.first(xml, "//types:TransactionResult")
|
|
211
202
|
parse_elements(response, root)
|
|
212
203
|
elsif root = REXML::XPath.first(xml, "//soap:Fault")
|
|
@@ -22,7 +22,6 @@ module ActiveMerchant #:nodoc:
|
|
|
22
22
|
|
|
23
23
|
def initialize(options = {})
|
|
24
24
|
requires!(options, :login, :password)
|
|
25
|
-
@options = options
|
|
26
25
|
super
|
|
27
26
|
end
|
|
28
27
|
|
|
@@ -101,7 +100,7 @@ module ActiveMerchant #:nodoc:
|
|
|
101
100
|
post[:orderid] = options[:order_id]
|
|
102
101
|
post[:orderdescription] = options[:description]
|
|
103
102
|
end
|
|
104
|
-
|
|
103
|
+
|
|
105
104
|
def add_creditcard(post, creditcard)
|
|
106
105
|
post[:ccnumber] = creditcard.number
|
|
107
106
|
post[:ccexp] = expdate(creditcard)
|
|
@@ -121,7 +120,7 @@ module ActiveMerchant #:nodoc:
|
|
|
121
120
|
memo
|
|
122
121
|
end
|
|
123
122
|
end
|
|
124
|
-
|
|
123
|
+
|
|
125
124
|
def commit(action, money, parameters)
|
|
126
125
|
parameters[:amount] = amount(money)
|
|
127
126
|
data = ssl_post(self.live_url, post_data(action, parameters))
|
|
@@ -129,7 +128,7 @@ module ActiveMerchant #:nodoc:
|
|
|
129
128
|
message = message_from(response)
|
|
130
129
|
test_mode = test?
|
|
131
130
|
|
|
132
|
-
Response.new(success?(response), message, response,
|
|
131
|
+
Response.new(success?(response), message, response,
|
|
133
132
|
:test => test?,
|
|
134
133
|
:authorization => response['transactionid'],
|
|
135
134
|
:avs_result => {:code => response['avsresponse']},
|