tlconnor-activemerchant 1.20.4

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 (195) hide show
  1. data/CHANGELOG +805 -0
  2. data/CONTRIBUTORS +274 -0
  3. data/MIT-LICENSE +20 -0
  4. data/gem-public_cert.pem +20 -0
  5. data/lib/active_merchant.rb +63 -0
  6. data/lib/active_merchant/billing.rb +9 -0
  7. data/lib/active_merchant/billing/avs_result.rb +98 -0
  8. data/lib/active_merchant/billing/base.rb +57 -0
  9. data/lib/active_merchant/billing/check.rb +68 -0
  10. data/lib/active_merchant/billing/credit_card.rb +264 -0
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  12. data/lib/active_merchant/billing/credit_card_methods.rb +129 -0
  13. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  14. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  15. data/lib/active_merchant/billing/gateway.rb +170 -0
  16. data/lib/active_merchant/billing/gateways.rb +18 -0
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +694 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +944 -0
  19. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +167 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +388 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  24. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  25. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  26. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  27. data/lib/active_merchant/billing/gateways/braintree_blue.rb +308 -0
  28. data/lib/active_merchant/billing/gateways/braintree_orange.rb +21 -0
  29. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  30. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  31. data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -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 +135 -0
  36. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  37. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/eway_managed.rb +265 -0
  39. data/lib/active_merchant/billing/gateways/exact.rb +227 -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 +157 -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 +239 -0
  57. data/lib/active_merchant/billing/gateways/nab_transact.rb +244 -0
  58. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  59. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  60. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  61. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  62. data/lib/active_merchant/billing/gateways/ogone.rb +330 -0
  63. data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
  64. data/lib/active_merchant/billing/gateways/orbital.rb +344 -0
  65. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  66. data/lib/active_merchant/billing/gateways/pay_junction.rb +397 -0
  67. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  68. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  69. data/lib/active_merchant/billing/gateways/payflow.rb +261 -0
  70. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +208 -0
  71. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  72. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  73. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  74. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  75. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  76. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  77. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  78. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +354 -0
  79. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  80. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  81. data/lib/active_merchant/billing/gateways/paypal_express.rb +229 -0
  82. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  83. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  84. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  85. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  86. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  87. data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
  88. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  89. data/lib/active_merchant/billing/gateways/quickpay.rb +298 -0
  90. data/lib/active_merchant/billing/gateways/realex.rb +315 -0
  91. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  92. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  93. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  94. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  95. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  96. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  97. data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
  98. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  99. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  100. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +280 -0
  101. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  102. data/lib/active_merchant/billing/gateways/skip_jack.rb +458 -0
  103. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  104. data/lib/active_merchant/billing/gateways/stripe.rb +244 -0
  105. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  106. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  107. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  108. data/lib/active_merchant/billing/gateways/usa_epay.rb +23 -0
  109. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
  110. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
  111. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  112. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  113. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  114. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  115. data/lib/active_merchant/billing/integrations.rb +17 -0
  116. data/lib/active_merchant/billing/integrations/action_view_helper.rb +72 -0
  117. data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
  118. data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
  119. data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
  120. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  121. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  122. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  123. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  124. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  125. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  126. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  127. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  128. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  129. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  130. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  131. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  132. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  133. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  134. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  135. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  136. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  137. data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
  138. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
  139. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
  140. data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
  141. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  142. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  143. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  144. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  145. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  146. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  147. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  148. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  149. data/lib/active_merchant/billing/integrations/helper.rb +113 -0
  150. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  151. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  152. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  153. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  154. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  155. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  156. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  157. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  158. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  159. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  160. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  161. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  162. data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
  163. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
  164. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
  165. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  166. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  167. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  168. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  169. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  170. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  171. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  172. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  173. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  174. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  175. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +127 -0
  176. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  177. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  178. data/lib/active_merchant/billing/integrations/two_checkout.rb +22 -0
  179. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  180. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  181. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  182. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  183. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  184. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  185. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  186. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  187. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  188. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  189. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  190. data/lib/active_merchant/billing/response.rb +32 -0
  191. data/lib/active_merchant/version.rb +3 -0
  192. data/lib/activemerchant.rb +1 -0
  193. data/lib/support/gateway_support.rb +58 -0
  194. data/lib/support/outbound_hosts.rb +25 -0
  195. metadata +411 -0
@@ -0,0 +1,244 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # The National Australia Bank provide a payment gateway that seems to
6
+ # be a rebadged Securepay Australia service, though some differences exist.
7
+ class NabTransactGateway < Gateway
8
+ API_VERSION = 'xml-4.2'
9
+ PERIODIC_API_VERSION = "spxml-4.2"
10
+
11
+ TEST_URL = 'https://transact.nab.com.au/test/xmlapi/payment'
12
+ LIVE_URL = 'https://transact.nab.com.au/live/xmlapi/payment'
13
+ TEST_PERIODIC_URL = "https://transact.nab.com.au/xmlapidemo/periodic"
14
+ LIVE_PERIODIC_URL = "https://transact.nab.com.au/xmlapi/periodic"
15
+
16
+ self.supported_countries = ['AU']
17
+
18
+ # The card types supported by the payment gateway
19
+ # Note that support for Diners, Amex, and JCB require extra
20
+ # steps in setting up your account, as detailed in the NAB Transact API
21
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
22
+
23
+ self.homepage_url = 'http://transact.nab.com.au'
24
+ self.display_name = 'NAB Transact'
25
+
26
+ cattr_accessor :request_timeout
27
+ self.request_timeout = 60
28
+
29
+ self.money_format = :cents
30
+ self.default_currency = 'AUD'
31
+
32
+ #Transactions currently accepted by NAB Transact XML API
33
+ TRANSACTIONS = {
34
+ :purchase => 0, #Standard Payment
35
+ :credit => 4, #Refund
36
+ :void => 6, #Client Reversal (Void)
37
+ :authorization => 10, #Preauthorise
38
+ :capture => 11 #Preauthorise Complete (Advice)
39
+ }
40
+
41
+ PERIODIC_TYPES = {
42
+ :addcrn => 5,
43
+ :editcrn => 5,
44
+ :deletecrn => 5,
45
+ :trigger => 8
46
+ }
47
+
48
+ SUCCESS_CODES = [ '00', '08', '11', '16', '77' ]
49
+
50
+
51
+ def initialize(options = {})
52
+ requires!(options, :login, :password)
53
+ @options = options
54
+ super
55
+ end
56
+
57
+ def test?
58
+ @options[:test] || super
59
+ end
60
+
61
+ def purchase(money, credit_card_or_stored_id, options = {})
62
+ if credit_card_or_stored_id.is_a?(ActiveMerchant::Billing::CreditCard)
63
+ #Credit card for instant payment
64
+ commit :purchase, build_purchase_request(money, credit_card_or_stored_id, options)
65
+ else
66
+ #Triggered payment for an existing stored credit card
67
+ options[:billing_id] = credit_card_or_stored_id.to_s
68
+ commit_periodic build_periodic_item(:trigger, money, nil, options)
69
+ end
70
+ end
71
+
72
+ def store(creditcard, options = {})
73
+ requires!(options, :billing_id, :amount)
74
+ commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
75
+ end
76
+
77
+ def unstore(identification, options = {})
78
+ options[:billing_id] = identification
79
+ commit_periodic(build_periodic_item(:deletecrn, options[:amount], nil, options))
80
+ end
81
+
82
+ private
83
+
84
+ def build_purchase_request(money, credit_card, options)
85
+ xml = Builder::XmlMarkup.new
86
+ xml.tag! 'amount', amount(money)
87
+ xml.tag! 'currency', options[:currency] || currency(money)
88
+ xml.tag! 'purchaseOrderNo', options[:order_id].to_s.gsub(/[ ']/, '')
89
+
90
+ xml.tag! 'CreditCardInfo' do
91
+ xml.tag! 'cardNumber', credit_card.number
92
+ xml.tag! 'expiryDate', expdate(credit_card)
93
+ xml.tag! 'cvv', credit_card.verification_value if credit_card.verification_value?
94
+ end
95
+
96
+ xml.target!
97
+ end
98
+
99
+ #Generate payment request XML
100
+ # - API is set to allow multiple Txn's but currentlu only allows one
101
+ # - txnSource = 23 - (XML)
102
+
103
+ def build_request(action, body)
104
+ xml = Builder::XmlMarkup.new
105
+ xml.instruct!
106
+ xml.tag! 'NABTransactMessage' do
107
+ xml.tag! 'MessageInfo' do
108
+ xml.tag! 'messageID', Utils.generate_unique_id.slice(0, 30)
109
+ xml.tag! 'messageTimestamp', generate_timestamp
110
+ xml.tag! 'timeoutValue', request_timeout
111
+ xml.tag! 'apiVersion', API_VERSION
112
+ end
113
+
114
+ xml.tag! 'MerchantInfo' do
115
+ xml.tag! 'merchantID', @options[:login]
116
+ xml.tag! 'password', @options[:password]
117
+ end
118
+
119
+ xml.tag! 'RequestType', 'Payment'
120
+ xml.tag! 'Payment' do
121
+ xml.tag! 'TxnList', "count" => 1 do
122
+ xml.tag! 'Txn', "ID" => 1 do
123
+ xml.tag! 'txnType', TRANSACTIONS[action]
124
+ xml.tag! 'txnSource', 23
125
+ xml << body
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ xml.target!
132
+ end
133
+
134
+ def build_periodic_item(action, money, credit_card, options)
135
+ xml = Builder::XmlMarkup.new
136
+
137
+ xml.tag! 'actionType', action.to_s
138
+ xml.tag! 'periodicType', PERIODIC_TYPES[action] if PERIODIC_TYPES[action]
139
+ xml.tag! 'currency', options[:currency] || currency(money)
140
+ xml.tag! 'crn', options[:billing_id]
141
+
142
+ if credit_card
143
+ xml.tag! 'CreditCardInfo' do
144
+ xml.tag! 'cardNumber', credit_card.number
145
+ xml.tag! 'expiryDate', expdate(credit_card)
146
+ xml.tag! 'cvv', credit_card.verification_value if credit_card.verification_value?
147
+ end
148
+ end
149
+ xml.tag! 'amount', amount(money)
150
+
151
+ xml.target!
152
+ end
153
+
154
+ def build_periodic_request(body)
155
+ xml = Builder::XmlMarkup.new
156
+ xml.instruct!
157
+ xml.tag! 'NABTransactMessage' do
158
+ xml.tag! 'MessageInfo' do
159
+ xml.tag! 'messageID', ActiveMerchant::Utils.generate_unique_id.slice(0, 30)
160
+ xml.tag! 'messageTimestamp', generate_timestamp
161
+ xml.tag! 'timeoutValue', request_timeout
162
+ xml.tag! 'apiVersion', PERIODIC_API_VERSION
163
+ end
164
+
165
+ xml.tag! 'MerchantInfo' do
166
+ xml.tag! 'merchantID', @options[:login]
167
+ xml.tag! 'password', @options[:password]
168
+ end
169
+
170
+ xml.tag! 'RequestType', 'Periodic'
171
+ xml.tag! 'Periodic' do
172
+ xml.tag! 'PeriodicList', "count" => 1 do
173
+ xml.tag! 'PeriodicItem', "ID" => 1 do
174
+ xml << body
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ xml.target!
181
+ end
182
+
183
+ def commit(action, request)
184
+ response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, build_request(action, request)))
185
+
186
+ Response.new(success?(response), message_from(response), response,
187
+ :test => test?,
188
+ :authorization => authorization_from(response)
189
+ )
190
+ end
191
+
192
+ def commit_periodic(request)
193
+ response = parse(ssl_post(test? ? TEST_PERIODIC_URL : LIVE_PERIODIC_URL, build_periodic_request(request)))
194
+ Response.new(success?(response), message_from(response), response,
195
+ :test => test?,
196
+ :authorization => authorization_from(response)
197
+ )
198
+ end
199
+
200
+ def success?(response)
201
+ SUCCESS_CODES.include?(response[:response_code])
202
+ end
203
+
204
+ def authorization_from(response)
205
+ response[:txn_id]
206
+ end
207
+
208
+ def message_from(response)
209
+ response[:response_text] || response[:status_description]
210
+ end
211
+
212
+ def expdate(credit_card)
213
+ "#{format(credit_card.month, :two_digits)}/#{format(credit_card.year, :two_digits)}"
214
+ end
215
+
216
+ def parse(body)
217
+ xml = REXML::Document.new(body)
218
+
219
+ response = {}
220
+
221
+ xml.root.elements.to_a.each do |node|
222
+ parse_element(response, node)
223
+ end
224
+
225
+ response
226
+ end
227
+
228
+ def parse_element(response, node)
229
+ if node.has_elements?
230
+ node.elements.each{|element| parse_element(response, element) }
231
+ else
232
+ response[node.name.underscore.to_sym] = node.text
233
+ end
234
+ end
235
+
236
+ # YYYYDDMMHHNNSSKKK000sOOO
237
+ def generate_timestamp
238
+ time = Time.now.utc
239
+ time.strftime("%Y%d%m%H%M%S#{time.usec}+000")
240
+ end
241
+
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,189 @@
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
+ URL = 'https://4tknox.au.com/cgi-bin/themerchant.au.com/ecom/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
+ :credit => '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
+ @options = options
53
+ super
54
+ end
55
+
56
+ # Note that #authorize and #capture only work if your account
57
+ # vendor is St George, and if your account has been setup as
58
+ # described in "Programming for NetRegistry's E-commerce
59
+ # Gateway." [http://rubyurl.com/hNG]
60
+ def authorize(money, credit_card, options = {})
61
+ params = {
62
+ 'AMOUNT' => amount(money),
63
+ 'CCNUM' => credit_card.number,
64
+ 'CCEXP' => expiry(credit_card)
65
+ }
66
+ add_request_details(params, options)
67
+ commit(:authorization, params)
68
+ end
69
+
70
+ # Note that #authorize and #capture only work if your account
71
+ # vendor is St George, and if your account has been setup as
72
+ # described in "Programming for NetRegistry's E-commerce
73
+ # Gateway." [http://rubyurl.com/hNG]
74
+ def capture(money, authorization, options = {})
75
+ requires!(options, :credit_card)
76
+ credit_card = options[:credit_card]
77
+
78
+ params = {
79
+ 'PREAUTHNUM' => authorization,
80
+ 'AMOUNT' => amount(money),
81
+ 'CCNUM' => credit_card.number,
82
+ 'CCEXP' => expiry(credit_card)
83
+ }
84
+ add_request_details(params, options)
85
+ commit(:capture, params)
86
+ end
87
+
88
+ def purchase(money, credit_card, options = {})
89
+ params = {
90
+ 'AMOUNT' => amount(money),
91
+ 'CCNUM' => credit_card.number,
92
+ 'CCEXP' => expiry(credit_card)
93
+ }
94
+ add_request_details(params, options)
95
+ commit(:purchase, params)
96
+ end
97
+
98
+ def credit(money, identification, options = {})
99
+ params = {
100
+ 'AMOUNT' => amount(money),
101
+ 'TXNREF' => identification
102
+ }
103
+ add_request_details(params, options)
104
+ commit(:credit, params)
105
+ end
106
+
107
+ # Specific to NetRegistry.
108
+ #
109
+ # Run a 'status' command. This lets you view the status of a
110
+ # completed transaction.
111
+ #
112
+ def status(identification)
113
+ params = {
114
+ 'TXNREF' => identification
115
+ }
116
+
117
+ commit(:status, params)
118
+ end
119
+
120
+ private
121
+ def add_request_details(params, options)
122
+ params['COMMENT'] = options[:description] unless options[:description].blank?
123
+ end
124
+
125
+ # Return the expiry for the given creditcard in the required
126
+ # format for a command.
127
+ def expiry(credit_card)
128
+ month = format(credit_card.month, :two_digits)
129
+ year = format(credit_card.year , :two_digits)
130
+ "#{month}/#{year}"
131
+ end
132
+
133
+ # Post the a request with the given parameters and return the
134
+ # response object.
135
+ #
136
+ # Login and password are added automatically, and the comment is
137
+ # omitted if nil.
138
+ def commit(action, params)
139
+ # get gateway response
140
+ response = parse( ssl_post(URL, post_data(action, params)) )
141
+
142
+ Response.new(response['status'] == 'approved', message_from(response), response,
143
+ :authorization => authorization_from(response, action)
144
+ )
145
+ end
146
+
147
+ def post_data(action, params)
148
+ params['COMMAND'] = TRANSACTIONS[action]
149
+ params['LOGIN'] = "#{@options[:login]}/#{@options[:password]}"
150
+ URI.encode(params.map{|k,v| "#{k}=#{v}"}.join('&'))
151
+ end
152
+
153
+ def parse(response)
154
+ params = {}
155
+
156
+ lines = response.split("\n")
157
+
158
+ # Just incase there is no real response returned
159
+ params['status'] = lines[0]
160
+ params['response_text'] = lines[1]
161
+
162
+ started = false
163
+ lines.each do |line|
164
+ if started
165
+ key, val = line.chomp.split(/=/, 2)
166
+ params[key] = val unless FILTERED_PARAMS.include?(key)
167
+ end
168
+
169
+ started = line.chomp =~ /^\.$/ unless started
170
+ end
171
+
172
+ params
173
+ end
174
+
175
+ def message_from(response)
176
+ response['response_text']
177
+ end
178
+
179
+ def authorization_from(response, command)
180
+ case command
181
+ when :purchase
182
+ response['txn_ref']
183
+ when :authorization
184
+ response['transaction_no']
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
@@ -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
+