activemerchant 1.7.3 → 1.8.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 +12 -0
- data/CONTRIBUTORS +8 -0
- data/README.rdoc +4 -2
- data/lib/active_merchant/billing/gateways/iridium.rb +253 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +233 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_express.rb +9 -1
- data/lib/active_merchant/common/country.rb +14 -5
- data/lib/active_merchant/version.rb +1 -1
- metadata +7 -5
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.8.0 (September 24, 2010)
|
4
|
+
|
5
|
+
* PayPal Express: Add support for billing agreements [Nathaniel Talbott]
|
6
|
+
* Allow comparing countries [Nathaniel Talbott]
|
7
|
+
* Iridium: Fix country handling [Nathaniel Talbott]
|
8
|
+
* Iridium: Fix missing billing address [Nathaniel Talbott]
|
9
|
+
* Iridium: Do not pass CV2 if not present [Nathaniel Talbott]
|
10
|
+
* Add Iridium support [Phil Smy]
|
11
|
+
* Add Netaxept support [Nathaniel Talbott]
|
12
|
+
* PaymentExpress: Use Card Holder Help Text for the response message [Nathaniel Talbott]
|
13
|
+
* Sort the country name list [Duff OMelia]
|
14
|
+
|
3
15
|
== Version 1.7.3 (September 14, 2010)
|
4
16
|
|
5
17
|
* Fix SagePay special handling for Japanese YEN currency to not send fractional amounts [Soleone]
|
data/CONTRIBUTORS
CHANGED
@@ -109,6 +109,10 @@ Instapay Gateway (May 3, 2009)
|
|
109
109
|
|
110
110
|
* Thomas Rideout
|
111
111
|
|
112
|
+
Iridium Gateway (June 13, 2009)
|
113
|
+
|
114
|
+
* Phil Smy
|
115
|
+
|
112
116
|
MerchantWARE (July 7, 2009)
|
113
117
|
|
114
118
|
* Cody Fauser
|
@@ -133,6 +137,10 @@ SallieMae (October 2, 2009)
|
|
133
137
|
|
134
138
|
* iamjwc
|
135
139
|
|
140
|
+
Netaxept (February 08, 2010)
|
141
|
+
|
142
|
+
* Nathaniel Talbott
|
143
|
+
|
136
144
|
Garanti (May 05, 2010)
|
137
145
|
|
138
146
|
* Selem Delul (moon@mac.home)
|
data/README.rdoc
CHANGED
@@ -21,10 +21,12 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
21
21
|
* {Efsnet}[http://www.concordefsnet.com/] - US
|
22
22
|
* {eWAY}[http://www.eway.com.au/] - AU
|
23
23
|
* {E-xact}[http://www.e-xact.com] - CA, US
|
24
|
+
* {Iridium}[http://www.iridiumcorp.co.uk/] - UK, ES
|
24
25
|
* {LinkPoint}[http://www.linkpoint.com/] - US
|
25
26
|
* {Merchant e-Solutions}[http://merchante-solutions.com/] - US
|
26
27
|
* {Modern Payments}[http://www.modpay.com] - US
|
27
28
|
* {Moneris}[http://www.moneris.com/] - CA
|
29
|
+
* {Netaxept}[http://www.betalingsterminal.no/Netthandel-forside] - NO, DK, SE, FI
|
28
30
|
* {NetRegistry}[http://www.netregistry.com.au] - AU
|
29
31
|
* {NELiX TransaX Gateway}[http://www.nelixtransax.com] - US
|
30
32
|
* {NETbilling}[http://www.netbilling.com] - US
|
@@ -59,8 +61,8 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
59
61
|
== Supported Offsite Payment Gateways
|
60
62
|
|
61
63
|
* {PayPal Website Payments Standard}[https://www.paypal.com/cgi-bin/webscr?cmd=_wp-standard-overview-outside]
|
62
|
-
* Chronopay[http://www.chronopay.com]
|
63
|
-
* Nochex[http://www.nochex.com]
|
64
|
+
* {Chronopay}[http://www.chronopay.com]
|
65
|
+
* {Nochex}[http://www.nochex.com]
|
64
66
|
* {Banca Sella GestPay}[https://www.sella.it/banca/ecommerce/gestpay/gestpay.jsp]
|
65
67
|
* {2 Checkout}[http://www.2checkout.com]
|
66
68
|
* {HiTRUST}[http://www.hitrust.com.hk/]
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# For more information on the Iridium Gateway please download the
|
4
|
+
# documentation from their Merchant Management System.
|
5
|
+
#
|
6
|
+
# The login and password are not the username and password you use to
|
7
|
+
# login to the Iridium Merchant Management System. Instead, you will
|
8
|
+
# use the API username and password you were issued separately.
|
9
|
+
class IridiumGateway < Gateway
|
10
|
+
TEST_URL = 'https://gw1.iridiumcorp.net/'
|
11
|
+
LIVE_URL = 'https://gw1.iridiumcorp.net/'
|
12
|
+
|
13
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
14
|
+
self.supported_countries = ['GB', 'ES']
|
15
|
+
self.default_currency = 'EUR'
|
16
|
+
self.money_format = :cents
|
17
|
+
|
18
|
+
# The card types supported by the payment gateway
|
19
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
20
|
+
|
21
|
+
# The homepage URL of the gateway
|
22
|
+
self.homepage_url = 'http://www.iridiumcorp.co.uk/'
|
23
|
+
|
24
|
+
# The name of the gateway
|
25
|
+
self.display_name = 'Iridium'
|
26
|
+
|
27
|
+
CURRENCY_CODES = {
|
28
|
+
"AUD" => '036',
|
29
|
+
"CAD" => '124',
|
30
|
+
"EUR" => '978',
|
31
|
+
"GBP" => '826',
|
32
|
+
"MXN" => '484',
|
33
|
+
"NZD" => '554',
|
34
|
+
"USD" => '840',
|
35
|
+
}
|
36
|
+
|
37
|
+
def initialize(options = {})
|
38
|
+
requires!(options, :login, :password)
|
39
|
+
@options = options
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def authorize(money, creditcard, options = {})
|
44
|
+
commit(build_purchase_request('PREAUTH', money, creditcard, options), options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def purchase(money, payment_source, options = {})
|
48
|
+
setup_address_hash(options)
|
49
|
+
|
50
|
+
if payment_source.is_a?(CreditCard)
|
51
|
+
commit(build_purchase_request('SALE', money, payment_source, options), options)
|
52
|
+
else
|
53
|
+
commit(build_reference_request('SALE', money, payment_source, options), options)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def capture(money, authorization, options = {})
|
58
|
+
commit(build_reference_request('COLLECTION', money, authorization, options), options)
|
59
|
+
end
|
60
|
+
|
61
|
+
def credit(money, authorization, options={})
|
62
|
+
commit(build_reference_request('REFUND', money, authorization, options), options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def void(authorization, options={})
|
66
|
+
commit(build_reference_request('VOID', nil, authorization, options), options)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def build_purchase_request(type, money, creditcard, options)
|
72
|
+
options.merge!(:action => 'CardDetailsTransaction')
|
73
|
+
build_request(options) do |xml|
|
74
|
+
add_purchase_data(xml, type, money, options)
|
75
|
+
add_creditcard(xml, creditcard)
|
76
|
+
add_customerdetails(xml, creditcard, options[:billing_address], options)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_reference_request(type, money, authorization, options)
|
81
|
+
options.merge!(:action => 'CrossReferenceTransaction')
|
82
|
+
order_id, cross_reference, auth_id = authorization.split(";")
|
83
|
+
build_request(options) do |xml|
|
84
|
+
if money
|
85
|
+
details = {'CurrencyCode' => currency_code(options[:currency] || default_currency), 'Amount' => amount(money)}
|
86
|
+
else
|
87
|
+
details = {'CurrencyCode' => currency_code(default_currency), 'Amount' => '0'}
|
88
|
+
end
|
89
|
+
xml.tag! 'TransactionDetails', details do
|
90
|
+
xml.tag! 'MessageDetails', {'TransactionType' => type, 'CrossReference' => cross_reference}
|
91
|
+
xml.tag! 'OrderID', (options[:order_id] || order_id)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_request(options)
|
97
|
+
requires!(options, :action)
|
98
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
99
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
|
100
|
+
xml.tag! 'soap:Envelope', { 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
101
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
102
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do
|
103
|
+
xml.tag! 'soap:Body' do
|
104
|
+
xml.tag! options[:action], {'xmlns' => "https://www.thepaymentgateway.net/"} do
|
105
|
+
xml.tag! 'PaymentMessage' do
|
106
|
+
add_merchant_data(xml, options)
|
107
|
+
yield(xml)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
xml.target!
|
113
|
+
end
|
114
|
+
|
115
|
+
def setup_address_hash(options)
|
116
|
+
options[:billing_address] = options[:billing_address] || options[:address] || {}
|
117
|
+
options[:shipping_address] = options[:shipping_address] || {}
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_purchase_data(xml, type, money, options)
|
121
|
+
requires!(options, :order_id)
|
122
|
+
xml.tag! 'TransactionDetails', {'Amount' => amount(money), 'CurrencyCode' => currency_code(options[:currency] || currency(money))} do
|
123
|
+
xml.tag! 'MessageDetails', {'TransactionType' => type}
|
124
|
+
xml.tag! 'OrderID', options[:order_id]
|
125
|
+
xml.tag! 'TransactionControl' do
|
126
|
+
xml.tag! 'ThreeDSecureOverridePolicy', 'FALSE'
|
127
|
+
xml.tag! 'EchoAVSCheckResult', 'TRUE'
|
128
|
+
xml.tag! 'EchoCV2CheckResult', 'TRUE'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def add_customerdetails(xml, creditcard, address, options, shipTo = false)
|
134
|
+
xml.tag! 'CustomerDetails' do
|
135
|
+
if address
|
136
|
+
unless address[:country].blank?
|
137
|
+
country_code = Country.find(address[:country]).code(:numeric)
|
138
|
+
end
|
139
|
+
xml.tag! 'BillingAddress' do
|
140
|
+
xml.tag! 'Address1', address[:address1]
|
141
|
+
xml.tag! 'Address2', address[:address2]
|
142
|
+
xml.tag! 'City', address[:city]
|
143
|
+
xml.tag! 'State', address[:state]
|
144
|
+
xml.tag! 'PostCode', address[:zip]
|
145
|
+
xml.tag! 'CountryCode', country_code if country_code
|
146
|
+
end
|
147
|
+
xml.tag! 'PhoneNumber', address[:phone]
|
148
|
+
end
|
149
|
+
|
150
|
+
xml.tag! 'EmailAddress', options[:email]
|
151
|
+
xml.tag! 'CustomerIPAddress', options[:ip] || "127.0.0.1"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def add_creditcard(xml, creditcard)
|
156
|
+
xml.tag! 'CardDetails' do
|
157
|
+
xml.tag! 'CardName', creditcard.name
|
158
|
+
xml.tag! 'CV2', creditcard.verification_value if creditcard.verification_value
|
159
|
+
xml.tag! 'CardNumber', creditcard.number
|
160
|
+
xml.tag! 'ExpiryDate', { 'Month' => creditcard.expiry_date.month.to_s.rjust(2, "0"), 'Year' => creditcard.expiry_date.year.to_s[/\d\d$/] }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_merchant_data(xml, options)
|
165
|
+
xml.tag! 'MerchantAuthentication', {"MerchantID" => @options[:login], "Password" => @options[:password]}
|
166
|
+
end
|
167
|
+
|
168
|
+
def commit(request, options)
|
169
|
+
requires!(options, :action)
|
170
|
+
response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, request,
|
171
|
+
{"SOAPAction" => "https://www.thepaymentgateway.net/#{options[:action]}",
|
172
|
+
"Content-Type" => "text/xml; charset=utf-8" }))
|
173
|
+
|
174
|
+
success = response[:transaction_result][:status_code] == "0"
|
175
|
+
message = response[:transaction_result][:message]
|
176
|
+
authorization = success ? [ options[:order_id], response[:transaction_output_data][:cross_reference], response[:transaction_output_data][:auth_code] ].compact.join(";") : nil
|
177
|
+
|
178
|
+
Response.new(success, message, response,
|
179
|
+
:test => test?,
|
180
|
+
:authorization => authorization)
|
181
|
+
end
|
182
|
+
|
183
|
+
def parse(xml)
|
184
|
+
reply = {}
|
185
|
+
xml = REXML::Document.new(xml)
|
186
|
+
if (root = REXML::XPath.first(xml, "//CardDetailsTransactionResponse")) or
|
187
|
+
(root = REXML::XPath.first(xml, "//CrossReferenceTransactionResponse"))
|
188
|
+
root.elements.to_a.each do |node|
|
189
|
+
case node.name
|
190
|
+
when 'Message'
|
191
|
+
reply[:message] = reply(node.text)
|
192
|
+
else
|
193
|
+
parse_element(reply, node)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
elsif root = REXML::XPath.first(xml, "//soap:Fault")
|
197
|
+
parse_element(reply, root)
|
198
|
+
reply[:message] = "#{reply[:faultcode]}: #{reply[:faultstring]}"
|
199
|
+
end
|
200
|
+
reply
|
201
|
+
end
|
202
|
+
|
203
|
+
def parse_element(reply, node)
|
204
|
+
case node.name
|
205
|
+
when "CrossReferenceTransactionResult"
|
206
|
+
reply[:transaction_result] = {}
|
207
|
+
node.attributes.each do |a,b|
|
208
|
+
reply[:transaction_result][a.underscore.to_sym] = b
|
209
|
+
end
|
210
|
+
node.elements.each{|e| parse_element(reply[:transaction_result], e) } if node.has_elements?
|
211
|
+
|
212
|
+
when "CardDetailsTransactionResult"
|
213
|
+
reply[:transaction_result] = {}
|
214
|
+
node.attributes.each do |a,b|
|
215
|
+
reply[:transaction_result][a.underscore.to_sym] = b
|
216
|
+
end
|
217
|
+
node.elements.each{|e| parse_element(reply[:transaction_result], e) } if node.has_elements?
|
218
|
+
|
219
|
+
when "TransactionOutputData"
|
220
|
+
reply[:transaction_output_data] = {}
|
221
|
+
node.attributes.each{|a,b| reply[:transaction_output_data][a.underscore.to_sym] = b }
|
222
|
+
node.elements.each{|e| parse_element(reply[:transaction_output_data], e) } if node.has_elements?
|
223
|
+
when "CustomVariables"
|
224
|
+
reply[:custom_variables] = {}
|
225
|
+
node.attributes.each{|a,b| reply[:custom_variables][a.underscore.to_sym] = b }
|
226
|
+
node.elements.each{|e| parse_element(reply[:custom_variables], e) } if node.has_elements?
|
227
|
+
when "GatewayEntryPoints"
|
228
|
+
reply[:gateway_entry_points] = {}
|
229
|
+
node.attributes.each{|a,b| reply[:gateway_entry_points][a.underscore.to_sym] = b }
|
230
|
+
node.elements.each{|e| parse_element(reply[:gateway_entry_points], e) } if node.has_elements?
|
231
|
+
else
|
232
|
+
k = node.name.underscore.to_sym
|
233
|
+
if node.has_elements?
|
234
|
+
reply[k] = {}
|
235
|
+
node.elements.each{|e| parse_element(reply[k], e) }
|
236
|
+
else
|
237
|
+
if node.has_attributes?
|
238
|
+
reply[k] = {}
|
239
|
+
node.attributes.each{|a,b| reply[k][a.underscore.to_sym] = b }
|
240
|
+
else
|
241
|
+
reply[k] = node.text
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
reply
|
246
|
+
end
|
247
|
+
|
248
|
+
def currency_code(currency)
|
249
|
+
CURRENCY_CODES[currency]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class NetaxeptGateway < Gateway
|
6
|
+
TEST_URL = 'https://epayment-test.bbs.no/'
|
7
|
+
LIVE_URL = 'https://epayment.bbs.no/'
|
8
|
+
|
9
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
10
|
+
self.supported_countries = ['NO', 'DK', 'SE', 'FI']
|
11
|
+
|
12
|
+
# The card types supported by the payment gateway
|
13
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
14
|
+
|
15
|
+
# The homepage URL of the gateway
|
16
|
+
self.homepage_url = 'http://www.betalingsterminal.no/Netthandel-forside/'
|
17
|
+
|
18
|
+
# The name of the gateway
|
19
|
+
self.display_name = 'BBS Netaxept'
|
20
|
+
|
21
|
+
self.money_format = :cents
|
22
|
+
|
23
|
+
self.default_currency = 'NOK'
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
requires!(options, :login, :password)
|
27
|
+
@options = options
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def purchase(money, creditcard, options = {})
|
32
|
+
requires!(options, :order_id)
|
33
|
+
|
34
|
+
post = {}
|
35
|
+
add_credentials(post, options)
|
36
|
+
add_transaction(post, options)
|
37
|
+
add_order(post, money, options)
|
38
|
+
add_creditcard(post, creditcard)
|
39
|
+
commit('Sale', post)
|
40
|
+
end
|
41
|
+
|
42
|
+
def authorize(money, creditcard, options = {})
|
43
|
+
requires!(options, :order_id)
|
44
|
+
|
45
|
+
post = {}
|
46
|
+
add_credentials(post, options)
|
47
|
+
add_transaction(post, options)
|
48
|
+
add_order(post, money, options)
|
49
|
+
add_creditcard(post, creditcard)
|
50
|
+
commit('Auth', post)
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture(money, authorization, options = {})
|
54
|
+
post = {}
|
55
|
+
add_credentials(post, options)
|
56
|
+
add_authorization(post, authorization, money)
|
57
|
+
commit('Capture', post, false)
|
58
|
+
end
|
59
|
+
|
60
|
+
def credit(money, authorization, options = {})
|
61
|
+
post = {}
|
62
|
+
add_credentials(post, options)
|
63
|
+
add_authorization(post, authorization, money)
|
64
|
+
commit('Credit', post, false)
|
65
|
+
end
|
66
|
+
|
67
|
+
def void(authorization, options = {})
|
68
|
+
post = {}
|
69
|
+
add_credentials(post, options)
|
70
|
+
add_authorization(post, authorization)
|
71
|
+
commit('Annul', post, false)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test?
|
75
|
+
@options[:test] || Base.gateway_mode == :test
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def add_credentials(post, options)
|
82
|
+
post[:merchantId] = @options[:login]
|
83
|
+
post[:token] = @options[:password]
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_authorization(post, authorization, money=nil)
|
87
|
+
post[:transactionId] = authorization
|
88
|
+
post[:transactionAmount] = amount(money) if money
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_transaction(post, options)
|
92
|
+
post[:transactionId] = generate_transaction_id(options)
|
93
|
+
post[:serviceType] = 'C'
|
94
|
+
post[:redirectUrl] = 'http://example.com'
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_order(post, money, options)
|
98
|
+
post[:orderNumber] = options[:order_id]
|
99
|
+
post[:amount] = amount(money)
|
100
|
+
post[:currencyCode] = (options[:currency] || currency(money))
|
101
|
+
end
|
102
|
+
|
103
|
+
CARD_TYPE_PREFIXES = {
|
104
|
+
'visa' => 'v',
|
105
|
+
'master' => 'm',
|
106
|
+
'american_express' => 'a',
|
107
|
+
}
|
108
|
+
def add_creditcard(post, creditcard)
|
109
|
+
prefix = CARD_TYPE_PREFIXES[creditcard.type]
|
110
|
+
unless prefix
|
111
|
+
raise ArgumentError.new("Card type #{creditcard.type} 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
|
119
|
+
end
|
120
|
+
|
121
|
+
def commit(action, parameters, setup=true)
|
122
|
+
parameters[:action] = action
|
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
|
155
|
+
|
156
|
+
def commit_transaction(response, parameters)
|
157
|
+
result = ssl_get(build_url("REST/#{parameters[:action]}.aspx", pick(parameters, :merchantId, :token, :transactionId, :transactionAmount)))
|
158
|
+
response[:action] = parse(result)
|
159
|
+
process(response, :action)
|
160
|
+
end
|
161
|
+
|
162
|
+
def process(response, step)
|
163
|
+
if response[step][:container] =~ /Exception|Error/
|
164
|
+
response[:message] = response[step]['Message']
|
165
|
+
throw :exception
|
166
|
+
else
|
167
|
+
message = (response[step]['ResponseText'] || response[step]['ResponseCode'])
|
168
|
+
response[:message] = (message || response[:message])
|
169
|
+
|
170
|
+
response[:authorization] = response[step]['TransactionId']
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def parse(result, expects_xml=true)
|
175
|
+
if expects_xml || /^</ =~ result
|
176
|
+
doc = REXML::Document.new(result)
|
177
|
+
extract_xml(doc.root).merge(:container => doc.root.name)
|
178
|
+
else
|
179
|
+
{:result => result}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def extract_xml(element)
|
184
|
+
if element.has_elements?
|
185
|
+
hash = {}
|
186
|
+
element.elements.each do |e|
|
187
|
+
hash[e.name] = extract_xml(e)
|
188
|
+
end
|
189
|
+
hash
|
190
|
+
else
|
191
|
+
element.text
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def url
|
196
|
+
(test? ? TEST_URL : 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
|
+
def build_url(base, parameters=nil)
|
208
|
+
url = "#{test? ? TEST_URL : LIVE_URL}"
|
209
|
+
url << base
|
210
|
+
if parameters
|
211
|
+
url << '?'
|
212
|
+
url << encode(parameters)
|
213
|
+
end
|
214
|
+
url
|
215
|
+
end
|
216
|
+
|
217
|
+
def encode(hash)
|
218
|
+
hash.collect{|(k,v)| "#{URI.encode(k.to_s)}=#{URI.encode(v.to_s)}"}.join('&')
|
219
|
+
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
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
@@ -187,7 +187,7 @@ module ActiveMerchant #:nodoc:
|
|
187
187
|
response = parse( ssl_post(URL, request.to_s) )
|
188
188
|
|
189
189
|
# Return a response
|
190
|
-
PaymentExpressResponse.new(response[:success] == APPROVED, response[:
|
190
|
+
PaymentExpressResponse.new(response[:success] == APPROVED, response[:card_holder_help_text], response,
|
191
191
|
:test => response[:test_mode] == '1',
|
192
192
|
:authorization => response[:dps_txn_ref]
|
193
193
|
)
|
@@ -102,10 +102,18 @@ module ActiveMerchant #:nodoc:
|
|
102
102
|
xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
|
103
103
|
xml.tag! 'n2:ReturnURL', options[:return_url]
|
104
104
|
xml.tag! 'n2:CancelURL', options[:cancel_return_url]
|
105
|
-
xml.tag! 'n2:IPAddress', options[:ip]
|
105
|
+
xml.tag! 'n2:IPAddress', options[:ip] unless options[:ip].blank?
|
106
106
|
xml.tag! 'n2:OrderDescription', options[:description]
|
107
107
|
xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
|
108
108
|
xml.tag! 'n2:InvoiceID', options[:order_id]
|
109
|
+
|
110
|
+
if options[:billing_agreement]
|
111
|
+
xml.tag! 'n2:BillingAgreementDetails' do
|
112
|
+
xml.tag! 'n2:BillingType', options[:billing_agreement][:type]
|
113
|
+
xml.tag! 'n2:BillingAgreementDescription', options[:billing_agreement][:description]
|
114
|
+
xml.tag! 'n2:PaymentType', options[:billing_agreement][:payment_type] || 'InstantOnly'
|
115
|
+
end
|
116
|
+
end
|
109
117
|
|
110
118
|
# Customization of the payment page
|
111
119
|
xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
|
@@ -48,6 +48,15 @@ module ActiveMerchant #:nodoc:
|
|
48
48
|
def code(format)
|
49
49
|
@codes.select{|c| c.format == format}
|
50
50
|
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
(@name == other.name)
|
54
|
+
end
|
55
|
+
alias eql? ==
|
56
|
+
|
57
|
+
def hash
|
58
|
+
@name.hash
|
59
|
+
end
|
51
60
|
|
52
61
|
def to_s
|
53
62
|
@name
|
@@ -67,7 +76,6 @@ module ActiveMerchant #:nodoc:
|
|
67
76
|
{ :alpha2 => 'AW', :name => 'Aruba', :alpha3 => 'ABW', :numeric => '533' },
|
68
77
|
{ :alpha2 => 'AU', :name => 'Australia', :alpha3 => 'AUS', :numeric => '036' },
|
69
78
|
{ :alpha2 => 'AT', :name => 'Austria', :alpha3 => 'AUT', :numeric => '040' },
|
70
|
-
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' },
|
71
79
|
{ :alpha2 => 'AZ', :name => 'Azerbaijan', :alpha3 => 'AZE', :numeric => '031' },
|
72
80
|
{ :alpha2 => 'BS', :name => 'Bahamas', :alpha3 => 'BHS', :numeric => '044' },
|
73
81
|
{ :alpha2 => 'BH', :name => 'Bahrain', :alpha3 => 'BHR', :numeric => '048' },
|
@@ -84,8 +92,8 @@ module ActiveMerchant #:nodoc:
|
|
84
92
|
{ :alpha2 => 'BW', :name => 'Botswana', :alpha3 => 'BWA', :numeric => '072' },
|
85
93
|
{ :alpha2 => 'BV', :name => 'Bouvet Island', :alpha3 => 'BVD', :numeric => '074' },
|
86
94
|
{ :alpha2 => 'BR', :name => 'Brazil', :alpha3 => 'BRA', :numeric => '076' },
|
87
|
-
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
88
95
|
{ :alpha2 => 'IO', :name => 'British Indian Ocean Territory', :alpha3 => 'IOT', :numeric => '086' },
|
96
|
+
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
89
97
|
{ :alpha2 => 'BG', :name => 'Bulgaria', :alpha3 => 'BGR', :numeric => '100' },
|
90
98
|
{ :alpha2 => 'BF', :name => 'Burkina Faso', :alpha3 => 'BFA', :numeric => '854' },
|
91
99
|
{ :alpha2 => 'BI', :name => 'Burundi', :alpha3 => 'BDI', :numeric => '108' },
|
@@ -142,15 +150,15 @@ module ActiveMerchant #:nodoc:
|
|
142
150
|
{ :alpha2 => 'GP', :name => 'Guadeloupe', :alpha3 => 'GLP', :numeric => '312' },
|
143
151
|
{ :alpha2 => 'GU', :name => 'Guam', :alpha3 => 'GUM', :numeric => '316' },
|
144
152
|
{ :alpha2 => 'GT', :name => 'Guatemala', :alpha3 => 'GTM', :numeric => '320' },
|
153
|
+
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
145
154
|
{ :alpha2 => 'GN', :name => 'Guinea', :alpha3 => 'GIN', :numeric => '324' },
|
146
155
|
{ :alpha2 => 'GW', :name => 'Guinea-Bissau', :alpha3 => 'GNB', :numeric => '624' },
|
147
156
|
{ :alpha2 => 'GY', :name => 'Guyana', :alpha3 => 'GUY', :numeric => '328' },
|
148
|
-
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
149
157
|
{ :alpha2 => 'HT', :name => 'Haiti', :alpha3 => 'HTI', :numeric => '332' },
|
158
|
+
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
150
159
|
{ :alpha2 => 'VA', :name => 'Holy See (Vatican City State)', :alpha3 => 'VAT', :numeric => '336' },
|
151
160
|
{ :alpha2 => 'HN', :name => 'Honduras', :alpha3 => 'HND', :numeric => '340' },
|
152
161
|
{ :alpha2 => 'HK', :name => 'Hong Kong', :alpha3 => 'HKG', :numeric => '344' },
|
153
|
-
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
154
162
|
{ :alpha2 => 'HU', :name => 'Hungary', :alpha3 => 'HUN', :numeric => '348' },
|
155
163
|
{ :alpha2 => 'IS', :name => 'Iceland', :alpha3 => 'ISL', :numeric => '352' },
|
156
164
|
{ :alpha2 => 'IN', :name => 'India', :alpha3 => 'IND', :numeric => '356' },
|
@@ -298,7 +306,8 @@ module ActiveMerchant #:nodoc:
|
|
298
306
|
{ :alpha2 => 'EH', :name => 'Western Sahara', :alpha3 => 'ESH', :numeric => '732' },
|
299
307
|
{ :alpha2 => 'YE', :name => 'Yemen', :alpha3 => 'YEM', :numeric => '887' },
|
300
308
|
{ :alpha2 => 'ZM', :name => 'Zambia', :alpha3 => 'ZMB', :numeric => '894' },
|
301
|
-
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' }
|
309
|
+
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' },
|
310
|
+
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' }
|
302
311
|
]
|
303
312
|
|
304
313
|
def self.find(name)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 55
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 1.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tobias Luetke
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
hPaSTyVU0yCSnw==
|
37
37
|
-----END CERTIFICATE-----
|
38
38
|
|
39
|
-
date: 2010-09-
|
39
|
+
date: 2010-09-24 00:00:00 -04:00
|
40
40
|
default_executable:
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- lib/active_merchant/billing/gateways/first_pay.rb
|
131
131
|
- lib/active_merchant/billing/gateways/garanti.rb
|
132
132
|
- lib/active_merchant/billing/gateways/instapay.rb
|
133
|
+
- lib/active_merchant/billing/gateways/iridium.rb
|
133
134
|
- lib/active_merchant/billing/gateways/jetpay.rb
|
134
135
|
- lib/active_merchant/billing/gateways/linkpoint.rb
|
135
136
|
- lib/active_merchant/billing/gateways/merchant_e_solutions.rb
|
@@ -138,6 +139,7 @@ files:
|
|
138
139
|
- lib/active_merchant/billing/gateways/modern_payments_cim.rb
|
139
140
|
- lib/active_merchant/billing/gateways/moneris.rb
|
140
141
|
- lib/active_merchant/billing/gateways/net_registry.rb
|
142
|
+
- lib/active_merchant/billing/gateways/netaxept.rb
|
141
143
|
- lib/active_merchant/billing/gateways/netbilling.rb
|
142
144
|
- lib/active_merchant/billing/gateways/ogone.rb
|
143
145
|
- lib/active_merchant/billing/gateways/pay_junction.rb
|
metadata.gz.sig
CHANGED
Binary file
|