aktivemerchant 2.0.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 (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1596 -0
  3. data/CONTRIBUTORS +511 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +18 -0
  6. data/lib/active_merchant.rb +108 -0
  7. data/lib/active_merchant/billing.rb +13 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +72 -0
  11. data/lib/active_merchant/billing/check.rb +76 -0
  12. data/lib/active_merchant/billing/compatibility.rb +120 -0
  13. data/lib/active_merchant/billing/credit_card.rb +352 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +268 -0
  18. data/lib/active_merchant/billing/gateways.rb +17 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
  20. data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
  21. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  24. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  25. data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
  28. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
  35. data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
  36. data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
  37. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  38. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
  44. data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
  45. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  46. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  47. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  48. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  49. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  50. data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
  51. data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
  52. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  53. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  54. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  55. data/lib/active_merchant/billing/gateways/epay.rb +275 -0
  56. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  57. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  59. data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
  60. data/lib/active_merchant/billing/gateways/exact.rb +218 -0
  61. data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
  62. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  63. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  64. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  65. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  66. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
  67. data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
  68. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  69. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  70. data/lib/active_merchant/billing/gateways/hps.rb +288 -0
  71. data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
  72. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  73. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  74. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  75. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  76. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  77. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  78. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  79. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  80. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  81. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  82. data/lib/active_merchant/billing/gateways/litle.rb +346 -0
  83. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  84. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  85. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  86. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  87. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  88. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  89. data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
  90. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  91. data/lib/active_merchant/billing/gateways/migs.rb +265 -0
  92. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  93. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  94. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  95. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  96. data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
  97. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  98. data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
  99. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  100. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  101. data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
  102. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  103. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  104. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  105. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  106. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
  108. data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
  109. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  110. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  111. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  112. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
  113. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  114. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  115. data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
  116. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  117. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
  119. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
  120. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  121. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  122. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  123. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  124. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  125. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  126. data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
  127. data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
  128. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
  129. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  130. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  131. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  132. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  133. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  134. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  135. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  136. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  137. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  138. data/lib/active_merchant/billing/gateways/pin.rb +197 -0
  139. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  140. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  141. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  142. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  143. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  144. data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
  145. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  146. data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
  147. data/lib/active_merchant/billing/gateways/sage.rb +175 -0
  148. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
  149. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
  150. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  151. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
  152. data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
  153. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  154. data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
  155. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  156. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  157. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  158. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  159. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  160. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  161. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  162. data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
  163. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  164. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  165. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  166. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  167. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  168. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  169. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  170. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  171. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
  172. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  173. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  174. data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
  175. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  176. data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
  177. data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
  178. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  179. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  180. data/lib/active_merchant/billing/model.rb +30 -0
  181. data/lib/active_merchant/billing/payment_token.rb +21 -0
  182. data/lib/active_merchant/billing/rails.rb +3 -0
  183. data/lib/active_merchant/billing/response.rb +91 -0
  184. data/lib/active_merchant/country.rb +332 -0
  185. data/lib/active_merchant/empty.rb +20 -0
  186. data/lib/active_merchant/errors.rb +29 -0
  187. data/lib/active_merchant/offsite_payments_shim.rb +19 -0
  188. data/lib/active_merchant/version.rb +3 -0
  189. data/lib/activemerchant.rb +1 -0
  190. data/lib/support/gateway_support.rb +71 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. data/lib/support/ssl_verify.rb +93 -0
  193. metadata +400 -0
@@ -0,0 +1,198 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ # Gateway for netregistry.com.au.
4
+ #
5
+ # Note that NetRegistry itself uses gateway service providers. At the
6
+ # time of this writing, there are at least two (Quest and Ingenico).
7
+ # This module has only been tested with Quest.
8
+ #
9
+ # Also note that NetRegistry does not offer a test mode, nor does it
10
+ # have support for the authorize/capture/void functionality by default
11
+ # (you may arrange for this as described in "Programming for
12
+ # NetRegistry's E-commerce Gateway." [http://rubyurl.com/hNG]), and no
13
+ # #void functionality is documented. As a result, the #authorize and
14
+ # #capture have not yet been tested through a live gateway, and #void
15
+ # will raise an error.
16
+ #
17
+ # If you have this functionality enabled, please consider contributing
18
+ # to ActiveMerchant by writing tests/code for these methods, and
19
+ # submitting a patch.
20
+ #
21
+ # In addition to the standard ActiveMerchant functionality, the
22
+ # response will contain a 'receipt' parameter
23
+ # (response.params['receipt']) if a receipt was issued by the gateway.
24
+ class NetRegistryGateway < Gateway
25
+ self.live_url = self.test_url = 'https://paygate.ssllock.net/external2.pl'
26
+
27
+ FILTERED_PARAMS = [ 'card_no', 'card_expiry', 'receipt_array' ]
28
+
29
+ self.supported_countries = ['AU']
30
+
31
+ # Note that support for Diners, Amex, and JCB require extra
32
+ # steps in setting up your account, as detailed in
33
+ # "Programming for NetRegistry's E-commerce Gateway."
34
+ # [http://rubyurl.com/hNG]
35
+ self.supported_cardtypes = [:visa, :master, :diners_club, :american_express, :jcb]
36
+ self.display_name = 'NetRegistry'
37
+ self.homepage_url = 'http://www.netregistry.com.au'
38
+
39
+ TRANSACTIONS = {
40
+ :authorization => 'preauth',
41
+ :purchase => 'purchase',
42
+ :capture => 'completion',
43
+ :status => 'status',
44
+ :refund => 'refund'
45
+ }
46
+
47
+ # Create a new NetRegistry gateway.
48
+ #
49
+ # Options :login and :password must be given.
50
+ def initialize(options = {})
51
+ requires!(options, :login, :password)
52
+ super
53
+ end
54
+
55
+ # Note that #authorize and #capture only work if your account
56
+ # vendor is St George, and if your account has been setup as
57
+ # described in "Programming for NetRegistry's E-commerce
58
+ # Gateway." [http://rubyurl.com/hNG]
59
+ def authorize(money, credit_card, options = {})
60
+ params = {
61
+ 'AMOUNT' => amount(money),
62
+ 'CCNUM' => credit_card.number,
63
+ 'CCEXP' => expiry(credit_card)
64
+ }
65
+ add_request_details(params, options)
66
+ commit(:authorization, params)
67
+ end
68
+
69
+ # Note that #authorize and #capture only work if your account
70
+ # vendor is St George, and if your account has been setup as
71
+ # described in "Programming for NetRegistry's E-commerce
72
+ # Gateway." [http://rubyurl.com/hNG]
73
+ def capture(money, authorization, options = {})
74
+ requires!(options, :credit_card)
75
+ credit_card = options[:credit_card]
76
+
77
+ params = {
78
+ 'PREAUTHNUM' => authorization,
79
+ 'AMOUNT' => amount(money),
80
+ 'CCNUM' => credit_card.number,
81
+ 'CCEXP' => expiry(credit_card)
82
+ }
83
+ add_request_details(params, options)
84
+ commit(:capture, params)
85
+ end
86
+
87
+ def purchase(money, credit_card, options = {})
88
+ params = {
89
+ 'AMOUNT' => amount(money),
90
+ 'CCNUM' => credit_card.number,
91
+ 'CCEXP' => expiry(credit_card)
92
+ }
93
+ add_request_details(params, options)
94
+ commit(:purchase, params)
95
+ end
96
+
97
+ def refund(money, identification, options = {})
98
+ params = {
99
+ 'AMOUNT' => amount(money),
100
+ 'TXNREF' => identification
101
+ }
102
+ add_request_details(params, options)
103
+ commit(:refund, params)
104
+ end
105
+
106
+ def credit(money, identification, options = {})
107
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
108
+ refund(money, identification, options)
109
+ end
110
+
111
+ # Specific to NetRegistry.
112
+ #
113
+ # Run a 'status' command. This lets you view the status of a
114
+ # completed transaction.
115
+ #
116
+ def status(identification)
117
+ params = {
118
+ 'TXNREF' => identification
119
+ }
120
+
121
+ commit(:status, params)
122
+ end
123
+
124
+ private
125
+ def add_request_details(params, options)
126
+ params['COMMENT'] = options[:description] unless options[:description].blank?
127
+ end
128
+
129
+ # Return the expiry for the given creditcard in the required
130
+ # format for a command.
131
+ def expiry(credit_card)
132
+ month = format(credit_card.month, :two_digits)
133
+ year = format(credit_card.year , :two_digits)
134
+ "#{month}/#{year}"
135
+ end
136
+
137
+ # Post the a request with the given parameters and return the
138
+ # response object.
139
+ #
140
+ # Login and password are added automatically, and the comment is
141
+ # omitted if nil.
142
+ def commit(action, params)
143
+ # get gateway response
144
+ response = parse( ssl_post(self.live_url, post_data(action, params)) )
145
+
146
+ Response.new(response['status'] == 'approved', message_from(response), response,
147
+ :authorization => authorization_from(response, action)
148
+ )
149
+ end
150
+
151
+ def post_data(action, params)
152
+ params['COMMAND'] = TRANSACTIONS[action]
153
+ params['LOGIN'] = "#{@options[:login]}/#{@options[:password]}"
154
+ escape_uri(params.map{|k,v| "#{k}=#{v}"}.join('&'))
155
+ end
156
+
157
+ # The upstream is picky and so we can't use CGI.escape like we want to
158
+ def escape_uri(uri)
159
+ URI::DEFAULT_PARSER.escape(uri)
160
+ end
161
+
162
+ def parse(response)
163
+ params = {}
164
+
165
+ lines = response.split("\n")
166
+
167
+ # Just incase there is no real response returned
168
+ params['status'] = lines[0]
169
+ params['response_text'] = lines[1]
170
+
171
+ started = false
172
+ lines.each do |line|
173
+ if started
174
+ key, val = line.chomp.split(/=/, 2)
175
+ params[key] = val unless FILTERED_PARAMS.include?(key)
176
+ end
177
+
178
+ started = line.chomp =~ /^\.$/ unless started
179
+ end
180
+
181
+ params
182
+ end
183
+
184
+ def message_from(response)
185
+ response['response_text']
186
+ end
187
+
188
+ def authorization_from(response, command)
189
+ case command
190
+ when :purchase
191
+ response['txn_ref']
192
+ when :authorization
193
+ response['transaction_no']
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,181 @@
1
+ require 'digest/md5'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class NetaxeptGateway < Gateway
6
+ self.test_url = 'https://epayment-test.bbs.no/'
7
+ self.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
+ super
28
+ end
29
+
30
+ def purchase(money, creditcard, options = {})
31
+ requires!(options, :order_id)
32
+
33
+ MultiResponse.run do |r|
34
+ r.process{authorize(money, creditcard, options)}
35
+ r.process{capture(money, r.authorization, options)}
36
+ end
37
+ end
38
+
39
+ def authorize(money, creditcard, options = {})
40
+ requires!(options, :order_id)
41
+
42
+ MultiResponse.run do |r|
43
+ r.process{setup_transaction(money, options)}
44
+ r.process{add_and_auth_credit_card(r.authorization, creditcard, options)}
45
+ r.process{query_transaction(r.authorization, options)}
46
+ end
47
+ end
48
+
49
+ def capture(money, authorization, options = {})
50
+ post = {}
51
+ add_credentials(post, options)
52
+ add_authorization(post, authorization, money)
53
+ post[:operation] = "Capture"
54
+ commit("Netaxept/process.aspx", post)
55
+ end
56
+
57
+ def refund(money, authorization, options = {})
58
+ post = {}
59
+ add_credentials(post, options)
60
+ add_authorization(post, authorization, money)
61
+ post[:operation] = "Credit"
62
+ commit("Netaxept/process.aspx", post)
63
+ end
64
+
65
+ def void(authorization, options = {})
66
+ post = {}
67
+ add_credentials(post, options)
68
+ add_authorization(post, authorization)
69
+ post[:operation] = "Annul"
70
+ commit("Netaxept/process.aspx", post)
71
+ end
72
+
73
+ private
74
+
75
+ def setup_transaction(money, options)
76
+ post = {}
77
+ add_credentials(post, options)
78
+ add_order(post, money, options)
79
+ commit("Netaxept/Register.aspx", post)
80
+ end
81
+
82
+ def add_and_auth_credit_card(authorization, creditcard, options)
83
+ post = {}
84
+ add_credentials(post, options, false)
85
+ add_authorization(post, authorization)
86
+ add_creditcard(post, creditcard)
87
+ commit("terminal/default.aspx", post, false)
88
+ end
89
+
90
+ def query_transaction(authorization, options)
91
+ post = {}
92
+ add_credentials(post, options)
93
+ add_authorization(post, authorization)
94
+ commit("Netaxept/query.aspx", post)
95
+ end
96
+
97
+ def add_credentials(post, options, secure=true)
98
+ post[:merchantId] = @options[:login]
99
+ post[:token] = @options[:password] if secure
100
+ end
101
+
102
+ def add_authorization(post, authorization, money=nil)
103
+ post[:transactionId] = authorization
104
+ post[:transactionAmount] = amount(money) if money
105
+ end
106
+
107
+ def add_order(post, money, options)
108
+ post[:serviceType] = 'M'
109
+ post[:orderNumber] = options[:order_id]
110
+ post[:amount] = amount(money)
111
+ post[:currencyCode] = (options[:currency] || currency(money))
112
+ post[:autoAuth] = "true"
113
+ end
114
+
115
+ def add_creditcard(post, options)
116
+ post[:pan] = options.number
117
+ post[:expiryDate] = format(options.month, :two_digits) + format(options.year, :two_digits)
118
+ post[:securityCode] = options.verification_value
119
+ end
120
+
121
+ def commit(path, parameters, xml=true)
122
+ raw = parse(ssl_get(build_url(path, parameters)), xml)
123
+
124
+ success = false
125
+ authorization = (raw["TransactionId"] || parameters[:transactionId])
126
+ if raw[:container] =~ /Exception|Error/
127
+ message = (raw["Message"] || raw["Error"]["Message"])
128
+ elsif raw["Error"] && !raw["Error"].empty?
129
+ message = (raw["Error"]["ResponseText"] || raw["Error"]["ResponseCode"])
130
+ else
131
+ message = (raw["ResponseText"] || raw["ResponseCode"] || "OK")
132
+ success = true
133
+ end
134
+
135
+ Response.new(
136
+ success,
137
+ message,
138
+ raw,
139
+ :test => test?,
140
+ :authorization => authorization
141
+ )
142
+ end
143
+
144
+ def parse(result, expects_xml=true)
145
+ if expects_xml
146
+ doc = REXML::Document.new(result)
147
+ extract_xml(doc.root).merge(:container => doc.root.name)
148
+ else
149
+ {:result => result}
150
+ end
151
+ end
152
+
153
+ def extract_xml(element)
154
+ if element.has_elements?
155
+ hash = {}
156
+ element.elements.each do |e|
157
+ hash[e.name] = extract_xml(e)
158
+ end
159
+ hash
160
+ else
161
+ element.text
162
+ end
163
+ end
164
+
165
+ def build_url(base, parameters=nil)
166
+ url = (test? ? self.test_url : self.live_url).dup
167
+ url << base
168
+ if parameters
169
+ url << '?'
170
+ url << encode(parameters)
171
+ end
172
+ url
173
+ end
174
+
175
+ def encode(hash)
176
+ hash.collect{|(k,v)| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join('&')
177
+ end
178
+ end
179
+ end
180
+ end
181
+
@@ -0,0 +1,190 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class NetbillingGateway < Gateway
4
+ self.live_url = self.test_url = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
5
+
6
+ TRANSACTIONS = {
7
+ :authorization => 'A',
8
+ :purchase => 'S',
9
+ :refund => 'R',
10
+ :credit => 'C',
11
+ :capture => 'D',
12
+ :void => 'U'
13
+ }
14
+
15
+ SUCCESS_CODES = [ '1', 'T' ]
16
+ SUCCESS_MESSAGE = 'The transaction was approved'
17
+ FAILURE_MESSAGE = 'The transaction failed'
18
+ TEST_LOGIN = '104901072025'
19
+
20
+ self.display_name = 'NETbilling'
21
+ self.homepage_url = 'http://www.netbilling.com'
22
+ self.supported_countries = ['US']
23
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
24
+
25
+ def initialize(options = {})
26
+ requires!(options, :login)
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, 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, post)
50
+ end
51
+
52
+ def capture(money, authorization, options = {})
53
+ post = {}
54
+ add_reference(post, authorization)
55
+ commit(:capture, post)
56
+ end
57
+
58
+ def refund(money, source, options = {})
59
+ post = {}
60
+ add_amount(post, money)
61
+ add_reference(post, source)
62
+ commit(:refund, post)
63
+ end
64
+
65
+ def credit(money, credit_card, options = {})
66
+ post = {}
67
+ add_amount(post, money)
68
+ add_invoice(post, options)
69
+ add_credit_card(post, credit_card)
70
+ add_address(post, credit_card, options)
71
+ add_customer_data(post, options)
72
+
73
+ commit(:credit, post)
74
+ end
75
+
76
+ def void(source, options = {})
77
+ post = {}
78
+ add_reference(post, source)
79
+ commit(:void, post)
80
+ end
81
+
82
+ def test?
83
+ (@options[:login] == TEST_LOGIN || super)
84
+ end
85
+
86
+ private
87
+
88
+ def add_amount(post, money)
89
+ post[:amount] = amount(money)
90
+ end
91
+
92
+ def add_reference(post, reference)
93
+ post[:orig_id] = reference
94
+ end
95
+
96
+ def add_customer_data(post, options)
97
+ post[:cust_email] = options[:email]
98
+ post[:cust_ip] = options[:ip]
99
+ end
100
+
101
+ def add_address(post, credit_card, options)
102
+ if billing_address = options[:billing_address] || options[:address]
103
+ post[:bill_street] = billing_address[:address1]
104
+ post[:cust_phone] = billing_address[:phone]
105
+ post[:bill_zip] = billing_address[:zip]
106
+ post[:bill_city] = billing_address[:city]
107
+ post[:bill_country] = billing_address[:country]
108
+ post[:bill_state] = billing_address[:state]
109
+ end
110
+
111
+ if shipping_address = options[:shipping_address]
112
+ first_name, last_name = parse_first_and_last_name(shipping_address[:name])
113
+
114
+ post[:ship_name1] = first_name
115
+ post[:ship_name2] = last_name
116
+ post[:ship_street] = shipping_address[:address1]
117
+ post[:ship_zip] = shipping_address[:zip]
118
+ post[:ship_city] = shipping_address[:city]
119
+ post[:ship_country] = shipping_address[:country]
120
+ post[:ship_state] = shipping_address[:state]
121
+ end
122
+ end
123
+
124
+ def add_invoice(post, options)
125
+ post[:description] = options[:description]
126
+ end
127
+
128
+ def add_credit_card(post, credit_card)
129
+ post[:bill_name1] = credit_card.first_name
130
+ post[:bill_name2] = credit_card.last_name
131
+ post[:card_number] = credit_card.number
132
+ post[:card_expire] = expdate(credit_card)
133
+ post[:card_cvv2] = credit_card.verification_value
134
+ end
135
+
136
+ def parse(body)
137
+ results = {}
138
+ body.split(/&/).each do |pair|
139
+ key,val = pair.split(/\=/)
140
+ results[key.to_sym] = CGI.unescape(val)
141
+ end
142
+ results
143
+ end
144
+
145
+ def commit(action, parameters)
146
+ response = parse(ssl_post(self.live_url, post_data(action, parameters)))
147
+
148
+ Response.new(success?(response), message_from(response), response,
149
+ :test => test_response?(response),
150
+ :authorization => response[:trans_id],
151
+ :avs_result => { :code => response[:avs_code]},
152
+ :cvv_result => response[:cvv2_code]
153
+ )
154
+ rescue ActiveMerchant::ResponseError => e
155
+ raise unless(e.response.code =~ /^[67]\d\d$/)
156
+ return Response.new(false, e.response.message, {:status_code => e.response.code}, :test => test?)
157
+ end
158
+
159
+ def test_response?(response)
160
+ !!(test? || response[:auth_msg] =~ /TEST/)
161
+ end
162
+
163
+ def success?(response)
164
+ SUCCESS_CODES.include?(response[:status_code])
165
+ end
166
+
167
+ def message_from(response)
168
+ success?(response) ? SUCCESS_MESSAGE : (response[:auth_msg] || FAILURE_MESSAGE)
169
+ end
170
+
171
+ def post_data(action, parameters = {})
172
+ parameters[:account_id] = @options[:login]
173
+ parameters[:site_tag] = @options[:site_tag] if @options[:site_tag].present?
174
+ parameters[:pay_type] = 'C'
175
+ parameters[:tran_type] = TRANSACTIONS[action]
176
+
177
+ parameters.reject{|k,v| v.blank?}.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
178
+ end
179
+
180
+ def parse_first_and_last_name(value)
181
+ name = value.to_s.split(' ')
182
+
183
+ last_name = name.pop || ''
184
+ first_name = name.join(' ')
185
+ [ first_name, last_name ]
186
+ end
187
+ end
188
+ end
189
+ end
190
+