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,218 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class ExactGateway < Gateway
4
+ self.live_url = self.test_url = 'https://secure2.e-xact.com/vplug-in/transaction/rpc-enc/service.asmx'
5
+
6
+ API_VERSION = "8.5"
7
+
8
+ TEST_LOGINS = [ {:login => "A00049-01", :password => "test1"},
9
+ {:login => "A00427-01", :password => "testus"} ]
10
+
11
+ TRANSACTIONS = { :sale => "00",
12
+ :authorization => "01",
13
+ :capture => "32",
14
+ :credit => "34" }
15
+
16
+
17
+ ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
18
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
19
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
20
+ }
21
+
22
+ SEND_AND_COMMIT_ATTRIBUTES = { 'xmlns:n1' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request",
23
+ 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
24
+ }
25
+
26
+ SEND_AND_COMMIT_SOURCE_ATTRIBUTES = { 'xmlns:n2' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes',
27
+ 'xsi:type' => 'n2:Transaction'
28
+ }
29
+
30
+ POST_HEADERS = { 'soapAction' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/SendAndCommit",
31
+ 'Content-Type' => 'text/xml'
32
+ }
33
+
34
+ SUCCESS = "true"
35
+
36
+ SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ]
37
+
38
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
39
+ self.supported_countries = ['CA', 'US']
40
+ self.homepage_url = 'http://www.e-xact.com'
41
+ self.display_name = 'E-xact'
42
+
43
+ def initialize(options = {})
44
+ requires!(options, :login, :password)
45
+
46
+ super
47
+ end
48
+
49
+ def authorize(money, credit_card, options = {})
50
+ commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
51
+ end
52
+
53
+ def purchase(money, credit_card, options = {})
54
+ commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
55
+ end
56
+
57
+ def capture(money, authorization, options = {})
58
+ commit(:capture, build_capture_or_credit_request(money, authorization, options))
59
+ end
60
+
61
+ def credit(money, authorization, options = {})
62
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
63
+ refund(money, authorization, options)
64
+ end
65
+
66
+ def refund(money, authorization, options = {})
67
+ commit(:credit, build_capture_or_credit_request(money, authorization, options))
68
+ end
69
+
70
+ private
71
+ def build_request(action, body)
72
+ xml = Builder::XmlMarkup.new
73
+
74
+ xml.instruct!
75
+ xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
76
+ xml.tag! 'env:Body' do
77
+ xml.tag! 'n1:SendAndCommit', SEND_AND_COMMIT_ATTRIBUTES do
78
+ xml.tag! 'SendAndCommitSource', SEND_AND_COMMIT_SOURCE_ATTRIBUTES do
79
+ add_credentials(xml)
80
+ add_transaction_type(xml, action)
81
+ xml << body
82
+ end
83
+ end
84
+ end
85
+ end
86
+ xml.target!
87
+ end
88
+
89
+ def build_sale_or_authorization_request(money, credit_card, options)
90
+ xml = Builder::XmlMarkup.new
91
+
92
+ add_amount(xml, money)
93
+ add_credit_card(xml, credit_card)
94
+ add_customer_data(xml, options)
95
+ add_invoice(xml, options)
96
+
97
+ xml.target!
98
+ end
99
+
100
+ def build_capture_or_credit_request(money, identification, options)
101
+ xml = Builder::XmlMarkup.new
102
+
103
+ add_identification(xml, identification)
104
+ add_amount(xml, money)
105
+ add_customer_data(xml, options)
106
+
107
+ xml.target!
108
+ end
109
+
110
+ def add_credentials(xml)
111
+ xml.tag! 'ExactID', @options[:login]
112
+ xml.tag! 'Password', @options[:password]
113
+ end
114
+
115
+ def add_transaction_type(xml, action)
116
+ xml.tag! 'Transaction_Type', TRANSACTIONS[action]
117
+ end
118
+
119
+ def add_identification(xml, identification)
120
+ authorization_num, transaction_tag = identification.split(';')
121
+
122
+ xml.tag! 'Authorization_Num', authorization_num
123
+ xml.tag! 'Transaction_Tag', transaction_tag
124
+ end
125
+
126
+ def add_amount(xml, money)
127
+ xml.tag! 'DollarAmount', amount(money)
128
+ end
129
+
130
+ def add_credit_card(xml, credit_card)
131
+ xml.tag! 'Card_Number', credit_card.number
132
+ xml.tag! 'Expiry_Date', expdate(credit_card)
133
+ xml.tag! 'CardHoldersName', credit_card.name
134
+
135
+ if credit_card.verification_value?
136
+ xml.tag! 'CVD_Presence_Ind', '1'
137
+ xml.tag! 'VerificationStr2', credit_card.verification_value
138
+ end
139
+ end
140
+
141
+ def add_customer_data(xml, options)
142
+ xml.tag! 'Customer_Ref', options[:customer]
143
+ xml.tag! 'Client_IP', options[:ip]
144
+ xml.tag! 'Client_Email', options[:email]
145
+ end
146
+
147
+ def add_address(xml, options)
148
+ if address = options[:billing_address] || options[:address]
149
+ xml.tag! 'ZipCode', address[:zip]
150
+ end
151
+ end
152
+
153
+ def add_invoice(xml, options)
154
+ xml.tag! 'Reference_No', options[:order_id]
155
+ xml.tag! 'Reference_3', options[:description]
156
+ end
157
+
158
+ def expdate(credit_card)
159
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
160
+ end
161
+
162
+ def commit(action, request)
163
+ response = parse(ssl_post(self.live_url, build_request(action, request), POST_HEADERS))
164
+
165
+ Response.new(successful?(response), message_from(response), response,
166
+ :test => test?,
167
+ :authorization => authorization_from(response),
168
+ :avs_result => { :code => response[:avs] },
169
+ :cvv_result => response[:cvv2]
170
+ )
171
+ end
172
+
173
+ def successful?(response)
174
+ response[:transaction_approved] == SUCCESS
175
+ end
176
+
177
+ def authorization_from(response)
178
+ if response[:authorization_num] && response[:transaction_tag]
179
+ "#{response[:authorization_num]};#{response[:transaction_tag]}"
180
+ else
181
+ ''
182
+ end
183
+ end
184
+
185
+ def message_from(response)
186
+ if response[:faultcode] && response[:faultstring]
187
+ response[:faultstring]
188
+ elsif response[:error_number] != '0'
189
+ response[:error_description]
190
+ else
191
+ result = response[:exact_message] || ''
192
+ result << " - #{response[:bank_message]}" unless response[:bank_message].blank?
193
+ result
194
+ end
195
+ end
196
+
197
+ def parse(xml)
198
+ response = {}
199
+ xml = REXML::Document.new(xml)
200
+
201
+ if root = REXML::XPath.first(xml, "//types:TransactionResult")
202
+ parse_elements(response, root)
203
+ elsif root = REXML::XPath.first(xml, "//soap:Fault")
204
+ parse_elements(response, root)
205
+ end
206
+
207
+ response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
208
+ end
209
+
210
+ def parse_elements(response, root)
211
+ root.elements.to_a.each do |node|
212
+ response[node.name.gsub(/EXact/, 'Exact').underscore.to_sym] = (node.text || '').strip
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+
@@ -0,0 +1,173 @@
1
+ require 'json'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class FatZebraGateway < Gateway
6
+ self.live_url = "https://gateway.fatzebra.com.au/v1.0"
7
+ self.test_url = "https://gateway.sandbox.fatzebra.com.au/v1.0"
8
+
9
+ self.supported_countries = ['AU']
10
+ self.default_currency = 'AUD'
11
+ self.money_format = :cents
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb]
13
+
14
+ self.homepage_url = 'https://www.fatzebra.com.au/'
15
+ self.display_name = 'Fat Zebra'
16
+
17
+ # Setup a new instance of the gateway.
18
+ #
19
+ # The options hash should include :username and :token
20
+ # You can find your username and token at https://dashboard.fatzebra.com.au
21
+ # Under the Your Account section
22
+ def initialize(options = {})
23
+ requires!(options, :username, :token)
24
+ @username = options[:username]
25
+ @token = options[:token]
26
+ super
27
+ end
28
+
29
+ # To create a purchase on a credit card use:
30
+ #
31
+ # purchase(money, creditcard)
32
+ #
33
+ # To charge a tokenized card
34
+ #
35
+ # purchase(money, "abzy87u", :cvv => "123")
36
+ def purchase(money, creditcard, options = {})
37
+ post = {}
38
+
39
+ add_amount(post, money, options)
40
+ add_creditcard(post, creditcard, options)
41
+ post[:reference] = options[:order_id]
42
+ post[:customer_ip] = options[:ip]
43
+
44
+ commit(:post, 'purchases', post)
45
+ end
46
+
47
+ # Refund a transaction
48
+ #
49
+ # amount - Integer - the amount to refund
50
+ # txn_id - String - the original transaction to be refunded
51
+ # reference - String - your transaction reference
52
+ def refund(money, txn_id, reference)
53
+ post = {}
54
+
55
+ post[:amount] = money
56
+ post[:transaction_id] = txn_id
57
+ post[:reference] = reference
58
+
59
+ commit(:post, "refunds", post)
60
+ end
61
+
62
+ # Tokenize a credit card
63
+ #
64
+ # The token is returned in the Response#authorization
65
+ def store(creditcard)
66
+ post = {}
67
+ add_creditcard(post, creditcard)
68
+
69
+ commit(:post, "credit_cards", post)
70
+ end
71
+
72
+ private
73
+
74
+ # Add the money details to the request
75
+ def add_amount(post, money, options)
76
+ post[:amount] = money
77
+ end
78
+
79
+ # Add the credit card details to the request
80
+ def add_creditcard(post, creditcard, options = {})
81
+ if creditcard.respond_to?(:number)
82
+ post[:card_number] = creditcard.number
83
+ post[:card_expiry] = "#{creditcard.month}/#{creditcard.year}"
84
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
85
+ post[:card_holder] = creditcard.name if creditcard.name
86
+ elsif creditcard.is_a?(String)
87
+ post[:card_token] = creditcard
88
+ post[:cvv] = options[:cvv]
89
+ elsif creditcard.is_a?(Hash)
90
+ ActiveMerchant.deprecated "Passing the credit card as a Hash is deprecated. Use a String and put the (optional) CVV in the options hash instead."
91
+ post[:card_token] = creditcard[:token]
92
+ post[:cvv] = creditcard[:cvv]
93
+ else
94
+ raise ArgumentError.new("Unknown credit card format #{creditcard.inspect}")
95
+ end
96
+ end
97
+
98
+ # Post the data to the gateway
99
+ def commit(method, uri, parameters=nil)
100
+ response = begin
101
+ parse(ssl_request(method, get_url(uri), parameters.to_json, headers))
102
+ rescue ResponseError => e
103
+ return Response.new(false, "Invalid Login") if(e.response.code == "401")
104
+ parse(e.response.body)
105
+ end
106
+
107
+ success = success_from(response)
108
+ Response.new(
109
+ success,
110
+ message_from(response),
111
+ response,
112
+ :test => response["test"],
113
+ :authorization => authorization_from(response, success)
114
+ )
115
+ end
116
+
117
+ def success_from(response)
118
+ (
119
+ response["successful"] &&
120
+ response["response"] &&
121
+ (response["response"]["successful"] || response["response"]["token"])
122
+ )
123
+ end
124
+
125
+ def authorization_from(response, success)
126
+ if success
127
+ (response["response"]["id"] || response["response"]["token"])
128
+ else
129
+ nil
130
+ end
131
+ end
132
+
133
+ def message_from(response)
134
+ if !response["errors"].empty?
135
+ response["errors"].join(", ")
136
+ elsif response["response"]["message"]
137
+ response["response"]["message"]
138
+ else
139
+ "Unknown Error"
140
+ end
141
+ end
142
+
143
+ # Parse the returned JSON, if parse errors are raised then return a detailed error.
144
+ def parse(response)
145
+ begin
146
+ JSON.parse(response)
147
+ rescue JSON::ParserError
148
+ msg = 'Invalid JSON response received from Fat Zebra. Please contact support@fatzebra.com.au if you continue to receive this message.'
149
+ msg += " (The raw response returned by the API was #{response.inspect})"
150
+ {
151
+ "successful" => false,
152
+ "response" => {},
153
+ "errors" => [msg]
154
+ }
155
+ end
156
+ end
157
+
158
+ # Build the URL based on the AM mode and the URI
159
+ def get_url(uri)
160
+ base = test? ? self.test_url : self.live_url
161
+ base + "/" + uri
162
+ end
163
+
164
+ # Builds the auth and U-A headers for the request
165
+ def headers
166
+ {
167
+ "Authorization" => "Basic " + Base64.strict_encode64(@username.to_s + ":" + @token.to_s).strip,
168
+ "User-Agent" => "Fat Zebra v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
169
+ }
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,160 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class FederatedCanadaGateway < Gateway
4
+ # Same URL for both test and live, testing is done by using the test username (demo) and password (password).
5
+ self.live_url = self.test_url = 'https://secure.federatedgateway.com/api/transact.php'
6
+
7
+ APPROVED, DECLINED, ERROR = 1, 2, 3
8
+
9
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
10
+ self.supported_countries = ['CA']
11
+
12
+ self.default_currency = 'CAD'
13
+
14
+ # The card types supported by the payment gateway
15
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
16
+
17
+ # The homepage URL of the gateway
18
+ self.homepage_url = 'http://www.federatedcanada.com/'
19
+
20
+ # The name of the gateway
21
+ self.display_name = 'Federated Canada'
22
+
23
+ def initialize(options = {})
24
+ requires!(options, :login, :password)
25
+ super
26
+ end
27
+
28
+ def purchase(money, creditcard, options = {})
29
+ post = {}
30
+ add_invoice(post, options)
31
+ add_creditcard(post, creditcard)
32
+ add_address(post, options)
33
+ add_customer_data(post, options)
34
+ commit('sale', money, post)
35
+ end
36
+
37
+ def authorize(money, creditcard, options = {})
38
+ post = {}
39
+ add_invoice(post, options)
40
+ add_creditcard(post, creditcard)
41
+ add_address(post, options)
42
+ add_customer_data(post, options)
43
+ commit('auth', money, post)
44
+ end
45
+
46
+ def capture(money, authorization, options = {})
47
+ options[:transactionid] = authorization
48
+ commit('capture', money, options)
49
+ end
50
+
51
+ def void(authorization, options = {})
52
+ options[:transactionid] = authorization
53
+ commit('void', nil, options)
54
+ end
55
+
56
+ def refund(money, authorization, options = {})
57
+ commit('refund', money, options.merge(:transactionid => authorization))
58
+ end
59
+
60
+ def credit(money, authorization, options = {})
61
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
62
+ refund(money, authorization, options)
63
+ end
64
+
65
+ private
66
+
67
+ def add_customer_data(post, options)
68
+ post[:firstname] = options[:first_name]
69
+ post[:lastname] = options[:last_name]
70
+
71
+ post[:email] = options[:email]
72
+ end
73
+
74
+ def add_address(post, options)
75
+ if address = (options[:billing_address] || options[:address])
76
+ post[:company] = address[:company]
77
+ post[:address1] = address[:address1]
78
+ post[:address2] = address[:address2]
79
+ post[:city] = address[:city]
80
+ post[:state] = address[:state]
81
+ post[:zip] = address[:zip]
82
+ post[:country] = address[:country]
83
+ post[:phone] = address[:phone]
84
+ end
85
+ if address = options[:shipping_address]
86
+ post[:shipping_firstname] = address[:first_name]
87
+ post[:shipping_lastname] = address[:last_name]
88
+ post[:shipping_company] = address[:company]
89
+ post[:shipping_address1] = address[:address1]
90
+ post[:shipping_address2] = address[:address2]
91
+ post[:shipping_city] = address[:city]
92
+ post[:shipping_state] = address[:state]
93
+ post[:shipping_zip] = address[:zip]
94
+ post[:shipping_country] = address[:country]
95
+ post[:shipping_email] = address[:email]
96
+ end
97
+ end
98
+
99
+ def add_invoice(post, options)
100
+ post[:orderid] = options[:order_id]
101
+ post[:orderdescription] = options[:description]
102
+ end
103
+
104
+ def add_creditcard(post, creditcard)
105
+ post[:ccnumber] = creditcard.number
106
+ post[:ccexp] = expdate(creditcard)
107
+ post[:cvv] = creditcard.verification_value
108
+ end
109
+
110
+ def parse(body)
111
+ body.split('&').inject({}) do |memo, x|
112
+ k, v = x.split('=')
113
+ memo[k] = v
114
+ memo
115
+ end
116
+ end
117
+
118
+ def commit(action, money, parameters)
119
+ parameters[:amount] = amount(money)
120
+ data = ssl_post(self.live_url, post_data(action, parameters))
121
+ response = parse(data)
122
+ message = message_from(response)
123
+
124
+ Response.new(success?(response), message, response,
125
+ :test => test?,
126
+ :authorization => response['transactionid'],
127
+ :avs_result => {:code => response['avsresponse']},
128
+ :cvv_result => response['cvvresponse']
129
+ )
130
+ end
131
+
132
+ def success?(response)
133
+ response['response'] == '1'
134
+ end
135
+
136
+ def test?
137
+ (@options[:login].eql?('demo')) && (@options[:password].eql?('password'))
138
+ end
139
+
140
+ def message_from(response)
141
+ case response['response'].to_i
142
+ when APPROVED
143
+ "Transaction Approved"
144
+ when DECLINED
145
+ "Transaction Declined"
146
+ else
147
+ "Error in transaction data or system error"
148
+ end
149
+ end
150
+
151
+ def post_data(action, parameters = {})
152
+ parameters[:type] = action
153
+ parameters[:username] = @options[:login]
154
+ parameters[:password] = @options[:password]
155
+ parameters.map{|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
156
+ end
157
+ end
158
+ end
159
+ end
160
+