gonow-activemerchant 1.15.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 +690 -0
- data/CONTRIBUTORS +237 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +165 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +47 -0
- data/lib/active_merchant/billing.rb +9 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +57 -0
- data/lib/active_merchant/billing/check.rb +68 -0
- data/lib/active_merchant/billing/credit_card.rb +178 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/expiry_date.rb +34 -0
- data/lib/active_merchant/billing/gateway.rb +170 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +664 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +132 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +293 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
- data/lib/active_merchant/billing/gateways/braspag.rb +188 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
- data/lib/active_merchant/billing/gateways/epay.rb +268 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
- data/lib/active_merchant/billing/gateways/exact.rb +222 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +351 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +177 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +295 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +218 -0
- data/lib/active_merchant/billing/gateways/realex.rb +311 -0
- data/lib/active_merchant/billing/gateways/sage.rb +146 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
- data/lib/active_merchant/billing/gateways/transax.rb +25 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
- data/lib/active_merchant/billing/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
- data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
- data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
- data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
- data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
- data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
- data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
- data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
- data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/helper.rb +96 -0
- data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
- data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
- data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
- data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
- data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/notification.rb +62 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
- data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
- data/lib/active_merchant/billing/integrations/return.rb +42 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
- data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
- data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
- data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
- data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
- data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
- data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
- data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
- data/lib/active_merchant/billing/response.rb +32 -0
- data/lib/active_merchant/common.rb +14 -0
- data/lib/active_merchant/common/connection.rb +177 -0
- data/lib/active_merchant/common/country.rb +328 -0
- data/lib/active_merchant/common/error.rb +26 -0
- data/lib/active_merchant/common/post_data.rb +24 -0
- data/lib/active_merchant/common/posts_data.rb +63 -0
- data/lib/active_merchant/common/requires_parameters.rb +16 -0
- data/lib/active_merchant/common/utils.rb +22 -0
- data/lib/active_merchant/common/validateable.rb +81 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/certs/cacert.pem +7815 -0
- data/lib/support/gateway_support.rb +58 -0
- data/lib/support/outbound_hosts.rb +25 -0
- metadata +276 -0
@@ -0,0 +1,239 @@
|
|
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 refund(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 credit(money, authorization, options = {})
|
68
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
69
|
+
refund(money, authorization, options)
|
70
|
+
end
|
71
|
+
|
72
|
+
def void(authorization, options = {})
|
73
|
+
post = {}
|
74
|
+
add_credentials(post, options)
|
75
|
+
add_authorization(post, authorization)
|
76
|
+
commit('Annul', post, false)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test?
|
80
|
+
@options[:test] || Base.gateway_mode == :test
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def add_credentials(post, options)
|
87
|
+
post[:merchantId] = @options[:login]
|
88
|
+
post[:token] = @options[:password]
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_authorization(post, authorization, money=nil)
|
92
|
+
post[:transactionId] = authorization
|
93
|
+
post[:transactionAmount] = amount(money) if money
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_transaction(post, options)
|
97
|
+
post[:transactionId] = generate_transaction_id(options)
|
98
|
+
post[:serviceType] = 'M'
|
99
|
+
post[:redirectUrl] = 'http://example.com'
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_order(post, money, options)
|
103
|
+
post[:orderNumber] = options[:order_id]
|
104
|
+
post[:amount] = amount(money)
|
105
|
+
post[:currencyCode] = (options[:currency] || currency(money))
|
106
|
+
end
|
107
|
+
|
108
|
+
CARD_TYPE_PREFIXES = {
|
109
|
+
'visa' => 'v',
|
110
|
+
'master' => 'm',
|
111
|
+
'american_express' => 'a',
|
112
|
+
}
|
113
|
+
def add_creditcard(post, creditcard)
|
114
|
+
brand = Gateway.card_brand(creditcard)
|
115
|
+
prefix = CARD_TYPE_PREFIXES[brand]
|
116
|
+
unless prefix
|
117
|
+
raise ArgumentError.new("Card type #{brand} not supported.")
|
118
|
+
end
|
119
|
+
|
120
|
+
post[:creditcard] = {}
|
121
|
+
post[:creditcard][:"#{prefix}a"] = creditcard.number
|
122
|
+
post[:creditcard][:"#{prefix}m"] = format(creditcard.month, :two_digits)
|
123
|
+
post[:creditcard][:"#{prefix}y"] = format(creditcard.year, :two_digits)
|
124
|
+
post[:creditcard][:"#{prefix}c"] = creditcard.verification_value
|
125
|
+
end
|
126
|
+
|
127
|
+
def commit(action, parameters, setup=true)
|
128
|
+
parameters[:action] = action
|
129
|
+
|
130
|
+
response = {:success => false}
|
131
|
+
|
132
|
+
catch(:exception) do
|
133
|
+
if setup
|
134
|
+
commit_transaction_setup(response, parameters)
|
135
|
+
commit_payment_details(response, parameters)
|
136
|
+
commit_process_setup(response, parameters)
|
137
|
+
end
|
138
|
+
commit_transaction(response, parameters)
|
139
|
+
response[:success] = true
|
140
|
+
end
|
141
|
+
|
142
|
+
Response.new(response[:success], response[:message], response, :test => test?, :authorization => response[:authorization])
|
143
|
+
end
|
144
|
+
|
145
|
+
def commit_transaction_setup(response, parameters)
|
146
|
+
response[:setup] = parse(ssl_get(build_url("REST/Setup.aspx", pick(parameters, :merchantId, :token, :serviceType, :amount, :currencyCode, :redirectUrl, :orderNumber, :transactionId))))
|
147
|
+
process(response, :setup)
|
148
|
+
end
|
149
|
+
|
150
|
+
def commit_payment_details(response, parameters)
|
151
|
+
data = encode(parameters[:creditcard].merge(:BBSePay_transaction => response[:setup]['SetupString']))
|
152
|
+
response[:paymentDetails] = parse(ssl_post(build_url("terminal/default.aspx"), data), false)
|
153
|
+
process(response, :paymentDetails)
|
154
|
+
end
|
155
|
+
|
156
|
+
def commit_process_setup(response, parameters)
|
157
|
+
result = ssl_get(build_url("REST/ProcessSetup.aspx", pick(parameters, :merchantId, :token, :transactionId).merge(:transactionString => response[:paymentDetails][:result])))
|
158
|
+
response[:processSetup] = parse(result)
|
159
|
+
process(response, :processSetup)
|
160
|
+
end
|
161
|
+
|
162
|
+
def commit_transaction(response, parameters)
|
163
|
+
result = ssl_get(build_url("REST/#{parameters[:action]}.aspx", pick(parameters, :merchantId, :token, :transactionId, :transactionAmount)))
|
164
|
+
response[:action] = parse(result)
|
165
|
+
process(response, :action)
|
166
|
+
end
|
167
|
+
|
168
|
+
def process(response, step)
|
169
|
+
if response[step][:container] =~ /Exception|Error/
|
170
|
+
response[:message] = response[step]['Message']
|
171
|
+
throw :exception
|
172
|
+
else
|
173
|
+
message = (response[step]['ResponseText'] || response[step]['ResponseCode'])
|
174
|
+
response[:message] = (message || response[:message])
|
175
|
+
|
176
|
+
response[:authorization] = response[step]['TransactionId']
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def parse(result, expects_xml=true)
|
181
|
+
if expects_xml || /^</ =~ result
|
182
|
+
doc = REXML::Document.new(result)
|
183
|
+
extract_xml(doc.root).merge(:container => doc.root.name)
|
184
|
+
else
|
185
|
+
{:result => result}
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def extract_xml(element)
|
190
|
+
if element.has_elements?
|
191
|
+
hash = {}
|
192
|
+
element.elements.each do |e|
|
193
|
+
hash[e.name] = extract_xml(e)
|
194
|
+
end
|
195
|
+
hash
|
196
|
+
else
|
197
|
+
element.text
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def url
|
202
|
+
(test? ? TEST_URL : LIVE_URL)
|
203
|
+
end
|
204
|
+
|
205
|
+
def generate_transaction_id(options)
|
206
|
+
Digest::MD5.hexdigest("#{options.inspect}+#{Time.now}+#{rand}")
|
207
|
+
end
|
208
|
+
|
209
|
+
def pick(hash, *keys)
|
210
|
+
keys.inject({}){|h,key| h[key] = hash[key] if hash[key]; h}
|
211
|
+
end
|
212
|
+
|
213
|
+
def build_url(base, parameters=nil)
|
214
|
+
url = "#{test? ? TEST_URL : LIVE_URL}"
|
215
|
+
url << base
|
216
|
+
if parameters
|
217
|
+
url << '?'
|
218
|
+
url << encode(parameters)
|
219
|
+
end
|
220
|
+
url
|
221
|
+
end
|
222
|
+
|
223
|
+
def encode(hash)
|
224
|
+
hash.collect{|(k,v)| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join('&')
|
225
|
+
end
|
226
|
+
|
227
|
+
class Response < Billing::Response
|
228
|
+
attr_reader :error_detail
|
229
|
+
def initialize(success, message, raw, options)
|
230
|
+
super
|
231
|
+
unless success
|
232
|
+
@error_detail = raw[:processSetup]['Result']['ResponseText'] if raw[:processSetup] && raw[:processSetup]['Result']
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class NetbillingGateway < Gateway
|
4
|
+
URL = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
|
5
|
+
|
6
|
+
TRANSACTIONS = {
|
7
|
+
:authorization => 'A',
|
8
|
+
:purchase => 'S',
|
9
|
+
:referenced_credit => 'R',
|
10
|
+
:unreferenced_credit => 'C',
|
11
|
+
:capture => 'D'
|
12
|
+
}
|
13
|
+
|
14
|
+
SUCCESS_CODES = [ '1', 'T' ]
|
15
|
+
SUCCESS_MESSAGE = 'The transaction was approved'
|
16
|
+
FAILURE_MESSAGE = 'The transaction failed'
|
17
|
+
TEST_LOGIN = '104901072025'
|
18
|
+
|
19
|
+
self.display_name = 'NETbilling'
|
20
|
+
self.homepage_url = 'http://www.netbilling.com'
|
21
|
+
self.supported_countries = ['US']
|
22
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
|
23
|
+
|
24
|
+
def initialize(options = {})
|
25
|
+
requires!(options, :login)
|
26
|
+
@options = options
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def authorize(money, credit_card, options = {})
|
31
|
+
post = {}
|
32
|
+
add_amount(post, money)
|
33
|
+
add_invoice(post, options)
|
34
|
+
add_credit_card(post, credit_card)
|
35
|
+
add_address(post, credit_card, options)
|
36
|
+
add_customer_data(post, options)
|
37
|
+
|
38
|
+
commit(:authorization, money, post)
|
39
|
+
end
|
40
|
+
|
41
|
+
def purchase(money, credit_card, options = {})
|
42
|
+
post = {}
|
43
|
+
add_amount(post, money)
|
44
|
+
add_invoice(post, options)
|
45
|
+
add_credit_card(post, credit_card)
|
46
|
+
add_address(post, credit_card, options)
|
47
|
+
add_customer_data(post, options)
|
48
|
+
|
49
|
+
commit(:purchase, money, post)
|
50
|
+
end
|
51
|
+
|
52
|
+
def capture(money, authorization, options = {})
|
53
|
+
post = {}
|
54
|
+
add_reference(post, authorization)
|
55
|
+
commit(:capture, money, post)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test?
|
59
|
+
@options[:login] == TEST_LOGIN || super
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def add_amount(post, money)
|
64
|
+
post[:amount] = amount(money)
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_reference(post, reference)
|
68
|
+
post[:orig_id] = reference
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_customer_data(post, options)
|
72
|
+
post[:cust_email] = options[:email]
|
73
|
+
post[:cust_ip] = options[:ip]
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_address(post, credit_card, options)
|
77
|
+
if billing_address = options[:billing_address] || options[:address]
|
78
|
+
post[:bill_street] = billing_address[:address1]
|
79
|
+
post[:cust_phone] = billing_address[:phone]
|
80
|
+
post[:bill_zip] = billing_address[:zip]
|
81
|
+
post[:bill_city] = billing_address[:city]
|
82
|
+
post[:bill_country] = billing_address[:country]
|
83
|
+
post[:bill_state] = billing_address[:state]
|
84
|
+
end
|
85
|
+
|
86
|
+
if shipping_address = options[:shipping_address]
|
87
|
+
first_name, last_name = parse_first_and_last_name(shipping_address[:name])
|
88
|
+
|
89
|
+
post[:ship_name1] = first_name
|
90
|
+
post[:ship_name2] = last_name
|
91
|
+
post[:ship_street] = shipping_address[:address1]
|
92
|
+
post[:ship_zip] = shipping_address[:zip]
|
93
|
+
post[:ship_city] = shipping_address[:city]
|
94
|
+
post[:ship_country] = shipping_address[:country]
|
95
|
+
post[:ship_state] = shipping_address[:state]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_invoice(post, options)
|
100
|
+
post[:description] = options[:description]
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_credit_card(post, credit_card)
|
104
|
+
post[:bill_name1] = credit_card.first_name
|
105
|
+
post[:bill_name2] = credit_card.last_name
|
106
|
+
post[:card_number] = credit_card.number
|
107
|
+
post[:card_expire] = expdate(credit_card)
|
108
|
+
post[:card_cvv2] = credit_card.verification_value
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse(body)
|
112
|
+
results = {}
|
113
|
+
body.split(/&/).each do |pair|
|
114
|
+
key,val = pair.split(/=/)
|
115
|
+
results[key.to_sym] = CGI.unescape(val)
|
116
|
+
end
|
117
|
+
results
|
118
|
+
end
|
119
|
+
|
120
|
+
def commit(action, money, parameters)
|
121
|
+
response = parse(ssl_post(URL, post_data(action, parameters)))
|
122
|
+
|
123
|
+
Response.new(success?(response), message_from(response), response,
|
124
|
+
:test => test_response?(response),
|
125
|
+
:authorization => response[:trans_id],
|
126
|
+
:avs_result => { :code => response[:avs_code]},
|
127
|
+
:cvv_result => response[:cvv2_code]
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_response?(response)
|
132
|
+
!!(test? || response[:auth_msg] =~ /TEST/)
|
133
|
+
end
|
134
|
+
|
135
|
+
def success?(response)
|
136
|
+
SUCCESS_CODES.include?(response[:status_code])
|
137
|
+
end
|
138
|
+
|
139
|
+
def message_from(response)
|
140
|
+
success?(response) ? SUCCESS_MESSAGE : (response[:auth_msg] || FAILURE_MESSAGE)
|
141
|
+
end
|
142
|
+
|
143
|
+
def expdate(credit_card)
|
144
|
+
year = sprintf("%.4i", credit_card.year)
|
145
|
+
month = sprintf("%.2i", credit_card.month)
|
146
|
+
|
147
|
+
"#{month}#{year[-2..-1]}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def post_data(action, parameters = {})
|
151
|
+
parameters[:account_id] = @options[:login]
|
152
|
+
parameters[:pay_type] = 'C'
|
153
|
+
parameters[:tran_type] = TRANSACTIONS[action]
|
154
|
+
|
155
|
+
parameters.reject{|k,v| v.blank?}.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
156
|
+
end
|
157
|
+
|
158
|
+
def parse_first_and_last_name(value)
|
159
|
+
name = value.to_s.split(' ')
|
160
|
+
|
161
|
+
last_name = name.pop || ''
|
162
|
+
first_name = name.join(' ')
|
163
|
+
[ first_name, last_name ]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class NmiGateway < AuthorizeNetGateway
|
4
|
+
self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
5
|
+
self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
6
|
+
self.homepage_url = 'http://nmi.com/'
|
7
|
+
self.display_name = 'NMI'
|
8
|
+
self.supported_countries = ['US']
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# = Ogone DirectLink Gateway
|
6
|
+
#
|
7
|
+
# DirectLink is the API version of the Ogone Payment Platform. It allows server to server
|
8
|
+
# communication between Ogone systems and your e-commerce website.
|
9
|
+
#
|
10
|
+
# This implementation follows the specification provided in the DirectLink integration
|
11
|
+
# guide version 2.4 (December 2008), available here:
|
12
|
+
# https://secure.ogone.com/ncol/Ogone_DirectLink_EN.pdf
|
13
|
+
#
|
14
|
+
# It also features aliases, which allow to store/unstore credit cards, as specified in
|
15
|
+
# the Alias Manager Option guide version 2.2 available here:
|
16
|
+
# https://secure.ogone.com/ncol/Ogone_Alias_EN.pdf
|
17
|
+
#
|
18
|
+
# It was last tested on Release 04.79 of Ogone e-Commerce (dated 11/02/2009).
|
19
|
+
#
|
20
|
+
# For any questions or comments, please contact Nicolas Jacobeus (nj@belighted.com).
|
21
|
+
#
|
22
|
+
# == Example use:
|
23
|
+
#
|
24
|
+
# gateway = ActiveMerchant::Billing::OgoneGateway.new(
|
25
|
+
# :login => "my_ogone_psp_id",
|
26
|
+
# :user => "my_ogone_user_id",
|
27
|
+
# :password => "my_ogone_pswd",
|
28
|
+
# :signature => "my_ogone_sha1_signature" # extra security, only if you configured your Ogone environment so
|
29
|
+
# )
|
30
|
+
#
|
31
|
+
# # set up credit card obj as in main ActiveMerchant example
|
32
|
+
# creditcard = ActiveMerchant::Billing::CreditCard.new(
|
33
|
+
# :type => 'visa',
|
34
|
+
# :number => '4242424242424242',
|
35
|
+
# :month => 8,
|
36
|
+
# :year => 2009,
|
37
|
+
# :first_name => 'Bob',
|
38
|
+
# :last_name => 'Bobsen'
|
39
|
+
# )
|
40
|
+
#
|
41
|
+
# # run request
|
42
|
+
# response = gateway.purchase(1000, creditcard, :order_id => "1") # charge 10 EUR
|
43
|
+
#
|
44
|
+
# If you don't provide an :order_id, the gateway will generate a random one for you.
|
45
|
+
#
|
46
|
+
# puts response.success? # Check whether the transaction was successful
|
47
|
+
# puts response.message # Retrieve the message returned by Ogone
|
48
|
+
# puts response.authorization # Retrieve the unique transaction ID returned by Ogone
|
49
|
+
#
|
50
|
+
# To use the alias feature, simply add :alias in the options hash:
|
51
|
+
#
|
52
|
+
# gateway.purchase(1000, creditcard, :order_id => "1", :alias => "myawesomecustomer") # associates the alias to that creditcard
|
53
|
+
# gateway.purchase(2000, nil, :order_id => "2", :alias => "myawesomecustomer") # don't need to know the creditcard for subsequent orders
|
54
|
+
#
|
55
|
+
class OgoneGateway < Gateway
|
56
|
+
|
57
|
+
URLS = {
|
58
|
+
:test => { :order => 'https://secure.ogone.com/ncol/test/orderdirect.asp',
|
59
|
+
:maintenance => 'https://secure.ogone.com/ncol/test/maintenancedirect.asp' },
|
60
|
+
:production => { :order => 'https://secure.ogone.com/ncol/prod/orderdirect.asp',
|
61
|
+
:maintenance => 'https://secure.ogone.com/ncol/prod/maintenancedirect.asp' }
|
62
|
+
}
|
63
|
+
|
64
|
+
CVV_MAPPING = { 'OK' => 'M',
|
65
|
+
'KO' => 'N',
|
66
|
+
'NO' => 'P' }
|
67
|
+
|
68
|
+
AVS_MAPPING = { 'OK' => 'M',
|
69
|
+
'KO' => 'N',
|
70
|
+
'NO' => 'R' }
|
71
|
+
SUCCESS_MESSAGE = "The transaction was successful"
|
72
|
+
|
73
|
+
self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
|
74
|
+
# also supports Airplus and UATP
|
75
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
|
76
|
+
self.homepage_url = 'http://www.ogone.com/'
|
77
|
+
self.display_name = 'Ogone'
|
78
|
+
self.default_currency = 'EUR'
|
79
|
+
self.money_format = :cents
|
80
|
+
|
81
|
+
def initialize(options = {})
|
82
|
+
requires!(options, :login, :user, :password)
|
83
|
+
@options = options
|
84
|
+
super
|
85
|
+
end
|
86
|
+
|
87
|
+
# Verify and reserve the specified amount on the account, without actually doing the transaction.
|
88
|
+
def authorize(money, payment_source, options = {})
|
89
|
+
post = {}
|
90
|
+
add_invoice(post, options)
|
91
|
+
add_payment_source(post, payment_source, options)
|
92
|
+
add_address(post, payment_source, options)
|
93
|
+
add_customer_data(post, options)
|
94
|
+
add_money(post, money, options)
|
95
|
+
commit('RES', post)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Verify and transfer the specified amount.
|
99
|
+
def purchase(money, payment_source, options = {})
|
100
|
+
post = {}
|
101
|
+
add_invoice(post, options)
|
102
|
+
add_payment_source(post, payment_source, options)
|
103
|
+
add_address(post, payment_source, options)
|
104
|
+
add_customer_data(post, options)
|
105
|
+
add_money(post, money, options)
|
106
|
+
commit('SAL', post)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Complete a previously authorized transaction.
|
110
|
+
def capture(money, authorization, options = {})
|
111
|
+
post = {}
|
112
|
+
add_authorization(post, reference_from(authorization))
|
113
|
+
add_invoice(post, options)
|
114
|
+
add_customer_data(post, options)
|
115
|
+
add_money(post, money, options)
|
116
|
+
commit('SAL', post)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Cancels a previously authorized transaction.
|
120
|
+
def void(identification, options = {})
|
121
|
+
post = {}
|
122
|
+
add_authorization(post, reference_from(identification))
|
123
|
+
commit('DES', post)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Credit the specified account by a specific amount.
|
127
|
+
def credit(money, identification_or_credit_card, options = {})
|
128
|
+
if reference_transaction?(identification_or_credit_card)
|
129
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
130
|
+
# Referenced credit: refund of a settled transaction
|
131
|
+
refund(money, identification_or_credit_card, options)
|
132
|
+
else # must be a credit card or card reference
|
133
|
+
perform_non_referenced_credit(money, identification_or_credit_card, options)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Refund of a settled transaction
|
138
|
+
def refund(money, reference, options = {})
|
139
|
+
perform_reference_credit(money, reference, options)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test?
|
143
|
+
@options[:test] || super
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def reference_from(authorization)
|
148
|
+
authorization.split(";").first
|
149
|
+
end
|
150
|
+
|
151
|
+
def reference_transaction?(identifier)
|
152
|
+
return false unless identifier.is_a?(String)
|
153
|
+
reference, action = identifier.split(";")
|
154
|
+
!action.nil?
|
155
|
+
end
|
156
|
+
|
157
|
+
def perform_reference_credit(money, payment_target, options = {})
|
158
|
+
post = {}
|
159
|
+
add_authorization(post, reference_from(payment_target))
|
160
|
+
add_money(post, money, options)
|
161
|
+
commit('RFD', post)
|
162
|
+
end
|
163
|
+
|
164
|
+
def perform_non_referenced_credit(money, payment_target, options = {})
|
165
|
+
# Non-referenced credit: acts like a reverse purchase
|
166
|
+
post = {}
|
167
|
+
add_invoice(post, options)
|
168
|
+
add_payment_source(post, payment_target, options)
|
169
|
+
add_address(post, payment_target, options)
|
170
|
+
add_customer_data(post, options)
|
171
|
+
add_money(post, money, options)
|
172
|
+
commit('RFD', post)
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_payment_source(post, payment_source, options)
|
176
|
+
if payment_source.is_a?(String)
|
177
|
+
add_alias(post, payment_source)
|
178
|
+
add_eci(post, '9')
|
179
|
+
else
|
180
|
+
add_alias(post, options[:store])
|
181
|
+
add_creditcard(post, payment_source)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def add_eci(post, eci)
|
186
|
+
add_pair post, 'ECI', eci
|
187
|
+
end
|
188
|
+
|
189
|
+
def add_alias(post, _alias)
|
190
|
+
add_pair post, 'ALIAS', _alias
|
191
|
+
end
|
192
|
+
|
193
|
+
def add_authorization(post, authorization)
|
194
|
+
add_pair post, 'PAYID', authorization
|
195
|
+
end
|
196
|
+
|
197
|
+
def add_money(post, money, options)
|
198
|
+
add_pair post, 'currency', options[:currency] || currency(money)
|
199
|
+
add_pair post, 'amount', amount(money)
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_customer_data(post, options)
|
203
|
+
add_pair post, 'EMAIL', options[:email]
|
204
|
+
add_pair post, 'REMOTE_ADDR', options[:ip]
|
205
|
+
end
|
206
|
+
|
207
|
+
def add_address(post, creditcard, options)
|
208
|
+
return unless options[:billing_address]
|
209
|
+
add_pair post, 'Owneraddress', options[:billing_address][:address1]
|
210
|
+
add_pair post, 'OwnerZip', options[:billing_address][:zip]
|
211
|
+
add_pair post, 'ownertown', options[:billing_address][:city]
|
212
|
+
add_pair post, 'ownercty', options[:billing_address][:country]
|
213
|
+
add_pair post, 'ownertelno', options[:billing_address][:phone]
|
214
|
+
end
|
215
|
+
|
216
|
+
def add_invoice(post, options)
|
217
|
+
add_pair post, 'orderID', options[:order_id] || generate_unique_id[0...30]
|
218
|
+
add_pair post, 'COM', options[:description]
|
219
|
+
end
|
220
|
+
|
221
|
+
def add_creditcard(post, creditcard)
|
222
|
+
add_pair post, 'CN', creditcard.name
|
223
|
+
add_pair post, 'CARDNO', creditcard.number
|
224
|
+
add_pair post, 'ED', "%02d%02s" % [creditcard.month, creditcard.year.to_s[-2..-1]]
|
225
|
+
add_pair post, 'CVC', creditcard.verification_value
|
226
|
+
end
|
227
|
+
|
228
|
+
def parse(body)
|
229
|
+
xml = REXML::Document.new(body)
|
230
|
+
convert_attributes_to_hash(xml.root.attributes)
|
231
|
+
end
|
232
|
+
|
233
|
+
def commit(action, parameters)
|
234
|
+
add_pair parameters, 'PSPID', @options[:login]
|
235
|
+
add_pair parameters, 'USERID', @options[:user]
|
236
|
+
add_pair parameters, 'PSWD', @options[:password]
|
237
|
+
url = URLS[test? ? :test : :production][parameters['PAYID'] ? :maintenance : :order ]
|
238
|
+
response = parse(ssl_post(url, post_data(action, parameters)))
|
239
|
+
options = { :authorization => [response["PAYID"], action].join(";"),
|
240
|
+
:test => test?,
|
241
|
+
:avs_result => { :code => AVS_MAPPING[response["AAVCheck"]] },
|
242
|
+
:cvv_result => CVV_MAPPING[response["CVCCheck"]] }
|
243
|
+
Response.new(successful?(response), message_from(response), response, options)
|
244
|
+
end
|
245
|
+
|
246
|
+
def successful?(response)
|
247
|
+
response["NCERROR"] == "0"
|
248
|
+
end
|
249
|
+
|
250
|
+
def message_from(response)
|
251
|
+
if successful?(response)
|
252
|
+
SUCCESS_MESSAGE
|
253
|
+
else
|
254
|
+
format_error_message(response["NCERRORPLUS"])
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def format_error_message(message)
|
259
|
+
raw_message = message.to_s.strip
|
260
|
+
case raw_message
|
261
|
+
when /\|/
|
262
|
+
raw_message.split("|").join(", ").capitalize
|
263
|
+
when /\//
|
264
|
+
raw_message.split("/").first.to_s.capitalize
|
265
|
+
else
|
266
|
+
raw_message.to_s.capitalize
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def post_data(action, parameters = {})
|
271
|
+
add_pair parameters, 'Operation' , action
|
272
|
+
if @options[:signature] # the user wants a SHA-1 signature
|
273
|
+
string = ['orderID','amount','currency','CARDNO','PSPID','Operation','ALIAS'].map{|s|parameters[s]}.join + @options[:signature]
|
274
|
+
add_pair parameters, 'SHASign' , Digest::SHA1.hexdigest(string)
|
275
|
+
end
|
276
|
+
parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
277
|
+
end
|
278
|
+
|
279
|
+
def add_pair(post, key, value, options = {})
|
280
|
+
post[key] = value if !value.blank? || options[:required]
|
281
|
+
end
|
282
|
+
|
283
|
+
def convert_attributes_to_hash(rexml_attributes)
|
284
|
+
response_hash = {}
|
285
|
+
rexml_attributes.each do |key, value|
|
286
|
+
response_hash[key] = value
|
287
|
+
end
|
288
|
+
response_hash
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|