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.
Files changed (189) hide show
  1. data/CHANGELOG +690 -0
  2. data/CONTRIBUTORS +237 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +165 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant.rb +47 -0
  7. data/lib/active_merchant/billing.rb +9 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +57 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +178 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  15. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  16. data/lib/active_merchant/billing/gateway.rb +170 -0
  17. data/lib/active_merchant/billing/gateways.rb +18 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +664 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
  20. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  21. data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
  22. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
  23. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  24. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  25. data/lib/active_merchant/billing/gateways/bogus.rb +132 -0
  26. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  27. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  28. data/lib/active_merchant/billing/gateways/braintree_blue.rb +293 -0
  29. data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
  30. data/lib/active_merchant/billing/gateways/braspag.rb +188 -0
  31. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  32. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  33. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  34. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  35. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  36. data/lib/active_merchant/billing/gateways/epay.rb +268 -0
  37. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
  39. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  40. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  41. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  42. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  43. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  44. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  45. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  46. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  47. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  48. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  49. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  50. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  51. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  52. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
  53. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  54. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  55. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  56. data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
  57. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  58. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  59. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  60. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  61. data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
  62. data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
  63. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  64. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  65. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  66. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  67. data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
  68. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  69. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  70. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  71. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  72. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  73. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  74. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  75. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  76. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +351 -0
  77. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  78. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  79. data/lib/active_merchant/billing/gateways/paypal_express.rb +177 -0
  80. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  81. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  82. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  83. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  84. data/lib/active_merchant/billing/gateways/qbms.rb +295 -0
  85. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  86. data/lib/active_merchant/billing/gateways/quickpay.rb +218 -0
  87. data/lib/active_merchant/billing/gateways/realex.rb +311 -0
  88. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  89. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  90. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  91. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  92. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  93. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  94. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  95. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  96. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
  97. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  98. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  99. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  100. data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
  101. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  102. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  103. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  104. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  105. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  106. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  107. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  108. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  109. data/lib/active_merchant/billing/integrations.rb +17 -0
  110. data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
  111. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  112. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  113. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  114. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  115. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  116. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  117. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  118. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  119. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  120. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  121. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  122. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  123. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  124. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  125. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  126. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  127. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  128. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  129. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  130. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  131. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  132. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  133. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  134. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  135. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  136. data/lib/active_merchant/billing/integrations/helper.rb +96 -0
  137. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  138. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  139. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  140. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  141. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  142. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  143. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  144. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  145. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  146. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  147. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  148. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  149. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  150. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  151. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  152. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  153. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  154. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  155. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  156. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  157. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  158. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  159. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
  160. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  161. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  162. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  163. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  164. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  165. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  166. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  167. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  168. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  169. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  170. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  171. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  172. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  173. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  174. data/lib/active_merchant/billing/response.rb +32 -0
  175. data/lib/active_merchant/common.rb +14 -0
  176. data/lib/active_merchant/common/connection.rb +177 -0
  177. data/lib/active_merchant/common/country.rb +328 -0
  178. data/lib/active_merchant/common/error.rb +26 -0
  179. data/lib/active_merchant/common/post_data.rb +24 -0
  180. data/lib/active_merchant/common/posts_data.rb +63 -0
  181. data/lib/active_merchant/common/requires_parameters.rb +16 -0
  182. data/lib/active_merchant/common/utils.rb +22 -0
  183. data/lib/active_merchant/common/validateable.rb +81 -0
  184. data/lib/active_merchant/version.rb +3 -0
  185. data/lib/activemerchant.rb +1 -0
  186. data/lib/certs/cacert.pem +7815 -0
  187. data/lib/support/gateway_support.rb +58 -0
  188. data/lib/support/outbound_hosts.rb +25 -0
  189. 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