start_activemerchant 1.50.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 (218) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1769 -0
  3. data/CONTRIBUTORS +540 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +226 -0
  6. data/lib/active_merchant.rb +67 -0
  7. data/lib/active_merchant/billing.rb +15 -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 +404 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +195 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +291 -0
  18. data/lib/active_merchant/billing/gateways.rb +14 -0
  19. data/lib/active_merchant/billing/gateways/allied_wallet.rb +203 -0
  20. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net.rb +510 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  24. data/lib/active_merchant/billing/gateways/axcessms.rb +181 -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 +192 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +389 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +58 -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 +211 -0
  37. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  39. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  40. data/lib/active_merchant/billing/gateways/braintree_blue.rb +574 -0
  41. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  42. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  43. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  44. data/lib/active_merchant/billing/gateways/card_stream.rb +238 -0
  45. data/lib/active_merchant/billing/gateways/cashnet.rb +202 -0
  46. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  47. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  48. data/lib/active_merchant/billing/gateways/cenpos.rb +262 -0
  49. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  50. data/lib/active_merchant/billing/gateways/checkout.rb +216 -0
  51. data/lib/active_merchant/billing/gateways/checkout_v2.rb +200 -0
  52. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  53. data/lib/active_merchant/billing/gateways/conekta.rb +210 -0
  54. data/lib/active_merchant/billing/gateways/cyber_source.rb +720 -0
  55. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  56. data/lib/active_merchant/billing/gateways/dibs.rb +206 -0
  57. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  58. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  59. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  60. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  61. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  62. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  63. data/lib/active_merchant/billing/gateways/eway_rapid.rb +522 -0
  64. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  65. data/lib/active_merchant/billing/gateways/ezic.rb +206 -0
  66. data/lib/active_merchant/billing/gateways/fat_zebra.rb +213 -0
  67. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  68. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  69. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  70. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  71. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +413 -0
  72. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  73. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  74. data/lib/active_merchant/billing/gateways/garanti.rb +261 -0
  75. data/lib/active_merchant/billing/gateways/global_transport.rb +179 -0
  76. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  77. data/lib/active_merchant/billing/gateways/hps.rb +287 -0
  78. data/lib/active_merchant/billing/gateways/iats_payments.rb +277 -0
  79. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  80. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  81. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  82. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  83. data/lib/active_merchant/billing/gateways/inspire.rb +219 -0
  84. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  85. data/lib/active_merchant/billing/gateways/ipp.rb +175 -0
  86. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  87. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  88. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  89. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  90. data/lib/active_merchant/billing/gateways/litle.rb +345 -0
  91. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  92. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  93. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  94. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  95. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  96. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  97. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  98. data/lib/active_merchant/billing/gateways/mercury.rb +326 -0
  99. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  100. data/lib/active_merchant/billing/gateways/migs.rb +280 -0
  101. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  102. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  103. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  104. data/lib/active_merchant/billing/gateways/monei.rb +307 -0
  105. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  106. data/lib/active_merchant/billing/gateways/moneris_us.rb +298 -0
  107. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  108. data/lib/active_merchant/billing/gateways/nab_transact.rb +290 -0
  109. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  110. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  111. data/lib/active_merchant/billing/gateways/netbilling.rb +224 -0
  112. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  113. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  114. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  115. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  116. data/lib/active_merchant/billing/gateways/omise.rb +319 -0
  117. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  118. data/lib/active_merchant/billing/gateways/optimal_payment.rb +314 -0
  119. data/lib/active_merchant/billing/gateways/orbital.rb +834 -0
  120. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  121. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  122. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  123. data/lib/active_merchant/billing/gateways/pay_conex.rb +246 -0
  124. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
  125. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  126. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  127. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  128. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  129. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  130. data/lib/active_merchant/billing/gateways/payflow.rb +308 -0
  131. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +220 -0
  132. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  133. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  134. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  135. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  136. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  137. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  138. data/lib/active_merchant/billing/gateways/paymill.rb +282 -0
  139. data/lib/active_merchant/billing/gateways/paypal.rb +129 -0
  140. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +679 -0
  141. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  142. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  143. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  144. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  145. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  146. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  147. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  148. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  149. data/lib/active_merchant/billing/gateways/payu_in.rb +247 -0
  150. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  151. data/lib/active_merchant/billing/gateways/pin.rb +207 -0
  152. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  153. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  154. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  155. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  156. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  157. data/lib/active_merchant/billing/gateways/quickbooks.rb +280 -0
  158. data/lib/active_merchant/billing/gateways/quickpay.rb +26 -0
  159. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +188 -0
  160. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +240 -0
  161. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +227 -0
  162. data/lib/active_merchant/billing/gateways/qvalent.rb +179 -0
  163. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  164. data/lib/active_merchant/billing/gateways/redsys.rb +406 -0
  165. data/lib/active_merchant/billing/gateways/s5.rb +226 -0
  166. data/lib/active_merchant/billing/gateways/sage.rb +173 -0
  167. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +89 -0
  168. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +115 -0
  169. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  170. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  171. data/lib/active_merchant/billing/gateways/sage_pay.rb +399 -0
  172. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  173. data/lib/active_merchant/billing/gateways/secure_net.rb +263 -0
  174. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  175. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  176. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  177. data/lib/active_merchant/billing/gateways/skip_jack.rb +451 -0
  178. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  179. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  180. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  181. data/lib/active_merchant/billing/gateways/stripe.rb +489 -0
  182. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  183. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  184. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  185. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  186. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  187. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  188. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  189. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  190. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +259 -0
  191. data/lib/active_merchant/billing/gateways/vanco.rb +280 -0
  192. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  193. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  194. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  195. data/lib/active_merchant/billing/gateways/wepay.rb +205 -0
  196. data/lib/active_merchant/billing/gateways/wirecard.rb +420 -0
  197. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  198. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +204 -0
  199. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  200. data/lib/active_merchant/billing/model.rb +30 -0
  201. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +24 -0
  202. data/lib/active_merchant/billing/payment_token.rb +21 -0
  203. data/lib/active_merchant/billing/rails.rb +3 -0
  204. data/lib/active_merchant/billing/response.rb +92 -0
  205. data/lib/active_merchant/connection.rb +172 -0
  206. data/lib/active_merchant/country.rb +332 -0
  207. data/lib/active_merchant/empty.rb +20 -0
  208. data/lib/active_merchant/errors.rb +35 -0
  209. data/lib/active_merchant/network_connection_retries.rb +79 -0
  210. data/lib/active_merchant/post_data.rb +24 -0
  211. data/lib/active_merchant/posts_data.rb +84 -0
  212. data/lib/active_merchant/version.rb +3 -0
  213. data/lib/activemerchant.rb +1 -0
  214. data/lib/certs/cacert.pem +3866 -0
  215. data/lib/support/gateway_support.rb +71 -0
  216. data/lib/support/outbound_hosts.rb +28 -0
  217. data/lib/support/ssl_verify.rb +93 -0
  218. metadata +387 -0
@@ -0,0 +1,227 @@
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
+
72
+ def build_request(action, body)
73
+ xml = Builder::XmlMarkup.new
74
+
75
+ xml.instruct!
76
+ xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
77
+ xml.tag! 'env:Body' do
78
+ xml.tag! 'n1:SendAndCommit', SEND_AND_COMMIT_ATTRIBUTES do
79
+ xml.tag! 'SendAndCommitSource', SEND_AND_COMMIT_SOURCE_ATTRIBUTES do
80
+ add_credentials(xml)
81
+ add_transaction_type(xml, action)
82
+ xml << body
83
+ end
84
+ end
85
+ end
86
+ end
87
+ xml.target!
88
+ end
89
+
90
+ def build_sale_or_authorization_request(money, credit_card, options)
91
+ xml = Builder::XmlMarkup.new
92
+
93
+ add_amount(xml, money)
94
+ add_credit_card(xml, credit_card)
95
+ add_customer_data(xml, options)
96
+ add_invoice(xml, options)
97
+
98
+ xml.target!
99
+ end
100
+
101
+ def build_capture_or_credit_request(money, identification, options)
102
+ xml = Builder::XmlMarkup.new
103
+
104
+ add_identification(xml, identification)
105
+ add_amount(xml, money)
106
+ add_customer_data(xml, options)
107
+
108
+ xml.target!
109
+ end
110
+
111
+ def add_credentials(xml)
112
+ xml.tag! 'ExactID', @options[:login]
113
+ xml.tag! 'Password', @options[:password]
114
+ end
115
+
116
+ def add_transaction_type(xml, action)
117
+ xml.tag! 'Transaction_Type', TRANSACTIONS[action]
118
+ end
119
+
120
+ def add_identification(xml, identification)
121
+ authorization_num, transaction_tag = identification.split(';')
122
+
123
+ xml.tag! 'Authorization_Num', authorization_num
124
+ xml.tag! 'Transaction_Tag', transaction_tag
125
+ end
126
+
127
+ def add_amount(xml, money)
128
+ xml.tag! 'DollarAmount', amount(money)
129
+ end
130
+
131
+ def add_credit_card(xml, credit_card)
132
+ xml.tag! 'Card_Number', credit_card.number
133
+ xml.tag! 'Expiry_Date', expdate(credit_card)
134
+ xml.tag! 'CardHoldersName', credit_card.name
135
+
136
+ if credit_card.verification_value?
137
+ xml.tag! 'CVD_Presence_Ind', '1'
138
+ xml.tag! 'VerificationStr2', credit_card.verification_value
139
+ end
140
+ end
141
+
142
+ def add_customer_data(xml, options)
143
+ xml.tag! 'Customer_Ref', options[:customer]
144
+ xml.tag! 'Client_IP', options[:ip]
145
+ xml.tag! 'Client_Email', options[:email]
146
+ end
147
+
148
+ def add_address(xml, options)
149
+ if address = options[:billing_address] || options[:address]
150
+ xml.tag! 'ZipCode', address[:zip]
151
+ end
152
+ end
153
+
154
+ def add_invoice(xml, options)
155
+ xml.tag! 'Reference_No', options[:order_id]
156
+ xml.tag! 'Reference_3', options[:description]
157
+ end
158
+
159
+ def expdate(credit_card)
160
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
161
+ end
162
+
163
+ def commit(action, request)
164
+ response = parse(ssl_post(self.live_url, build_request(action, request), POST_HEADERS))
165
+
166
+ Response.new(successful?(response), message_from(response), response,
167
+ :test => test?,
168
+ :authorization => authorization_from(response),
169
+ :avs_result => { :code => response[:avs] },
170
+ :cvv_result => response[:cvv2]
171
+ )
172
+
173
+ rescue ResponseError => e
174
+ case e.response.code
175
+ when '401'
176
+ return Response.new(false, "Invalid Login: #{e.response.body}", {}, :test => test?)
177
+ else
178
+ raise
179
+ end
180
+ end
181
+
182
+ def successful?(response)
183
+ response[:transaction_approved] == SUCCESS
184
+ end
185
+
186
+ def authorization_from(response)
187
+ if response[:authorization_num] && response[:transaction_tag]
188
+ "#{response[:authorization_num]};#{response[:transaction_tag]}"
189
+ else
190
+ ''
191
+ end
192
+ end
193
+
194
+ def message_from(response)
195
+ if response[:faultcode] && response[:faultstring]
196
+ response[:faultstring]
197
+ elsif response[:error_number] != '0'
198
+ response[:error_description]
199
+ else
200
+ result = response[:exact_message] || ''
201
+ result << " - #{response[:bank_message]}" unless response[:bank_message].blank?
202
+ result
203
+ end
204
+ end
205
+
206
+ def parse(xml)
207
+ response = {}
208
+ xml = REXML::Document.new(xml)
209
+
210
+ if root = REXML::XPath.first(xml, "//types:TransactionResult")
211
+ parse_elements(response, root)
212
+ elsif root = REXML::XPath.first(xml, "//soap:Fault")
213
+ parse_elements(response, root)
214
+ end
215
+
216
+ response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
217
+ end
218
+
219
+ def parse_elements(response, root)
220
+ root.elements.to_a.each do |node|
221
+ response[node.name.gsub(/EXact/, 'Exact').underscore.to_sym] = (node.text || '').strip
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+
@@ -0,0 +1,206 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class EzicGateway < Gateway
4
+ self.live_url = 'https://secure-dm3.ezic.com/gw/sas/direct3.2'
5
+
6
+ self.supported_countries = %w(AU CA CN FR DE GI IL MT MU MX NL NZ PA PH RU SG KR ES KN GB US)
7
+ self.default_currency = 'USD'
8
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
9
+
10
+ self.homepage_url = 'http://www.ezic.com/'
11
+ self.display_name = 'Ezic'
12
+
13
+ def initialize(options={})
14
+ requires!(options, :account_id)
15
+ super
16
+ end
17
+
18
+ def purchase(money, payment, options={})
19
+ post = {}
20
+
21
+ add_account_id(post)
22
+ add_invoice(post, money, options)
23
+ add_payment(post, payment)
24
+ add_customer_data(post, options)
25
+
26
+ commit("S", post)
27
+ end
28
+
29
+ def authorize(money, payment, options={})
30
+ post = {}
31
+
32
+ add_account_id(post)
33
+ add_invoice(post, money, options)
34
+ add_payment(post, payment)
35
+ add_customer_data(post, options)
36
+
37
+ commit("A", post)
38
+ end
39
+
40
+ def capture(money, authorization, options={})
41
+ post = {}
42
+
43
+ add_account_id(post)
44
+ add_invoice(post, money, options)
45
+ add_authorization(post, authorization)
46
+ add_pay_type(post)
47
+
48
+ commit("D", post)
49
+ end
50
+
51
+ def refund(money, authorization, options={})
52
+ post = {}
53
+
54
+ add_account_id(post)
55
+ add_invoice(post, money, options)
56
+ add_authorization(post, authorization)
57
+ add_pay_type(post)
58
+
59
+ commit("R", post)
60
+ end
61
+
62
+ def void(authorization, options={})
63
+ post = {}
64
+
65
+ add_account_id(post)
66
+ add_authorization(post, authorization)
67
+ add_pay_type(post)
68
+
69
+ commit("U", post)
70
+ end
71
+
72
+ def verify(credit_card, options={})
73
+ MultiResponse.run(:use_first_response) do |r|
74
+ r.process { authorize(100, credit_card, options) }
75
+ r.process(:ignore_result) { void(r.authorization, options) }
76
+ end
77
+ end
78
+
79
+ def supports_scrubbing?
80
+ true
81
+ end
82
+
83
+ def scrub(transcript)
84
+ transcript.
85
+ gsub(%r((card_number=)\w+), '\1[FILTERED]').
86
+ gsub(%r((card_cvv2=)\w+), '\1[FILTERED]')
87
+ end
88
+
89
+ private
90
+
91
+ def add_account_id(post)
92
+ post[:account_id] = @options[:account_id]
93
+ end
94
+
95
+ def add_addresses(post, options)
96
+ add_billing_address(post, options)
97
+ add_shipping_address(post, options)
98
+ end
99
+
100
+ def add_billing_address(post, options)
101
+ address = options[:billing_address] || {}
102
+
103
+ if address[:name]
104
+ names = address[:name].split
105
+ post[:bill_name2] = names.pop
106
+ post[:bill_name1] = names.join(" ")
107
+ end
108
+
109
+ post[:bill_street] = address[:address1] if address[:address1]
110
+ post[:bill_city] = address[:city] if address[:city]
111
+ post[:bill_state] = address[:state] if address[:state]
112
+ post[:bill_zip] = address[:zip] if address[:zip]
113
+ post[:bill_country] = address[:country] if address[:country]
114
+ post[:cust_phone] = address[:phone] if address[:phone]
115
+ end
116
+
117
+ def add_shipping_address(post, options)
118
+ address = options[:shipping_address] || {}
119
+
120
+ if address[:name]
121
+ names = address[:name].split
122
+ post[:ship_name2] = names.pop
123
+ post[:ship_name1] = names.join(" ")
124
+ end
125
+
126
+ post[:ship_street] = address[:address1] if address[:address1]
127
+ post[:ship_city] = address[:city] if address[:city]
128
+ post[:ship_state] = address[:state] if address[:state]
129
+ post[:ship_zip] = address[:zip] if address[:zip]
130
+ post[:ship_country] = address[:country] if address[:country]
131
+ end
132
+
133
+ def add_customer_data(post, options)
134
+ post[:cust_ip] = options[:ip] if options[:ip]
135
+ post[:cust_email] = options[:email] if options[:email]
136
+ add_addresses(post, options)
137
+ end
138
+
139
+ def add_invoice(post, money, options)
140
+ post[:amount] = amount(money)
141
+ post[:description] = options[:description] if options[:description]
142
+ end
143
+
144
+ def add_payment(post, payment)
145
+ add_pay_type(post)
146
+ post[:card_number] = payment.number
147
+ post[:card_cvv2] = payment.verification_value
148
+ post[:card_expire] = expdate(payment)
149
+ end
150
+
151
+ def add_authorization(post, authorization)
152
+ post[:orig_id] = authorization
153
+ end
154
+
155
+ def add_pay_type(post)
156
+ post[:pay_type] = "C"
157
+ end
158
+
159
+ def parse(body)
160
+ CGI::parse(body).inject({}) { |hash, (key, value)| hash[key] = value.first; hash }
161
+ end
162
+
163
+ def commit(transaction_type, parameters)
164
+ parameters[:tran_type] = transaction_type
165
+
166
+ begin
167
+ response = parse(ssl_post(live_url, post_data(parameters), headers))
168
+ Response.new(
169
+ success_from(response),
170
+ message_from(response),
171
+ response,
172
+ authorization: authorization_from(response),
173
+ avs_result: AVSResult.new(code: response["avs_code"]),
174
+ cvv_result: CVVResult.new(response["cvv2_code"]),
175
+ test: test?
176
+ )
177
+ rescue ResponseError => e
178
+ Response.new(false, e.response.message)
179
+ end
180
+ end
181
+
182
+ def success_from(response)
183
+ response["status_code"] == "1" || response["status_code"] == "T"
184
+ end
185
+
186
+ def message_from(response)
187
+ response["auth_msg"]
188
+ end
189
+
190
+ def authorization_from(response)
191
+ response["trans_id"]
192
+ end
193
+
194
+ def post_data(parameters = {})
195
+ parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
196
+ end
197
+
198
+ def headers
199
+ {
200
+ "User-Agent" => "ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
201
+ }
202
+ end
203
+ end
204
+
205
+ end
206
+ end
@@ -0,0 +1,213 @@
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
+ super
25
+ end
26
+
27
+ # To create a purchase on a credit card use:
28
+ #
29
+ # purchase(money, creditcard)
30
+ #
31
+ # To charge a tokenized card
32
+ #
33
+ # purchase(money, "abzy87u", :cvv => "123")
34
+ def purchase(money, creditcard, options = {})
35
+ post = {}
36
+
37
+ add_amount(post, money, options)
38
+ add_creditcard(post, creditcard, options)
39
+ add_extra_options(post, options)
40
+ add_order_id(post, options)
41
+ add_ip(post, options)
42
+
43
+ commit(:post, 'purchases', post)
44
+ end
45
+
46
+ def authorize(money, creditcard, options = {})
47
+ post = {}
48
+
49
+ add_amount(post, money, options)
50
+ add_creditcard(post, creditcard, options)
51
+ add_extra_options(post, options)
52
+ add_order_id(post, options)
53
+ add_ip(post, options)
54
+
55
+ post[:capture] = false
56
+
57
+ commit(:post, 'purchases', post)
58
+ end
59
+
60
+ def capture(money, authorization, options = {})
61
+ post = {}
62
+ add_amount(post, money, options)
63
+ add_extra_options(post, options)
64
+
65
+ commit(:post, "purchases/#{CGI.escape(authorization)}/capture", post)
66
+ end
67
+
68
+ # Refund a transaction
69
+ #
70
+ # amount - Integer - the amount to refund
71
+ # txn_id - String - the original transaction to be refunded
72
+ # reference - String - your transaction reference
73
+ def refund(money, txn_id, options={})
74
+ post = {}
75
+
76
+ add_extra_options(post, options)
77
+ add_amount(post, money, options)
78
+ post[:transaction_id] = txn_id
79
+ add_order_id(post, options)
80
+
81
+ commit(:post, "refunds", post)
82
+ end
83
+
84
+ # Tokenize a credit card
85
+ #
86
+ # The token is returned in the Response#authorization
87
+ def store(creditcard, options={})
88
+ post = {}
89
+ add_creditcard(post, creditcard)
90
+
91
+ commit(:post, "credit_cards", post)
92
+ end
93
+
94
+ private
95
+
96
+ # Add the money details to the request
97
+ def add_amount(post, money, options)
98
+ post[:currency] = (options[:currency] || currency(money))
99
+ post[:currency] = post[:currency].upcase if post[:currency]
100
+ post[:amount] = money
101
+ end
102
+
103
+ # Add the credit card details to the request
104
+ def add_creditcard(post, creditcard, options = {})
105
+ if creditcard.respond_to?(:number)
106
+ post[:card_number] = creditcard.number
107
+ post[:card_expiry] = "#{creditcard.month}/#{creditcard.year}"
108
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
109
+ post[:card_holder] = creditcard.name if creditcard.name
110
+ elsif creditcard.is_a?(String)
111
+ post[:card_token] = creditcard
112
+ post[:cvv] = options[:cvv]
113
+ elsif creditcard.is_a?(Hash)
114
+ ActiveMerchant.deprecated "Passing the credit card as a Hash is deprecated. Use a String and put the (optional) CVV in the options hash instead."
115
+ post[:card_token] = creditcard[:token]
116
+ post[:cvv] = creditcard[:cvv]
117
+ else
118
+ raise ArgumentError.new("Unknown credit card format #{creditcard.inspect}")
119
+ end
120
+ end
121
+
122
+ def add_extra_options(post, options)
123
+ extra = {}
124
+ extra[:name] = options[:merchant] if options[:merchant]
125
+ extra[:location] = options[:merchant_location] if options[:merchant_location]
126
+ extra[:ecm] = "32" if options[:recurring]
127
+ post[:extra] = extra if extra.any?
128
+ end
129
+
130
+ def add_order_id(post, options)
131
+ post[:reference] = options[:order_id] || SecureRandom.hex(15)
132
+ end
133
+
134
+ def add_ip(post, options)
135
+ post[:customer_ip] = options[:ip] || "127.0.0.1"
136
+ end
137
+
138
+ # Post the data to the gateway
139
+ def commit(method, uri, parameters=nil)
140
+ response = begin
141
+ parse(ssl_request(method, get_url(uri), parameters.to_json, headers))
142
+ rescue ResponseError => e
143
+ return Response.new(false, "Invalid Login") if(e.response.code == "401")
144
+ parse(e.response.body)
145
+ end
146
+
147
+ success = success_from(response)
148
+ Response.new(
149
+ success,
150
+ message_from(response),
151
+ response,
152
+ :test => response["test"],
153
+ :authorization => authorization_from(response, success)
154
+ )
155
+ end
156
+
157
+ def success_from(response)
158
+ (
159
+ response["successful"] &&
160
+ response["response"] &&
161
+ (response["response"]["successful"] || response["response"]["token"])
162
+ )
163
+ end
164
+
165
+ def authorization_from(response, success)
166
+ if success
167
+ (response["response"]["id"] || response["response"]["token"])
168
+ else
169
+ nil
170
+ end
171
+ end
172
+
173
+ def message_from(response)
174
+ if !response["errors"].empty?
175
+ response["errors"].join(", ")
176
+ elsif response["response"]["message"]
177
+ response["response"]["message"]
178
+ else
179
+ "Unknown Error"
180
+ end
181
+ end
182
+
183
+ # Parse the returned JSON, if parse errors are raised then return a detailed error.
184
+ def parse(response)
185
+ begin
186
+ JSON.parse(response)
187
+ rescue JSON::ParserError
188
+ msg = 'Invalid JSON response received from Fat Zebra. Please contact support@fatzebra.com.au if you continue to receive this message.'
189
+ msg += " (The raw response returned by the API was #{response.inspect})"
190
+ {
191
+ "successful" => false,
192
+ "response" => {},
193
+ "errors" => [msg]
194
+ }
195
+ end
196
+ end
197
+
198
+ # Build the URL based on the AM mode and the URI
199
+ def get_url(uri)
200
+ base = test? ? self.test_url : self.live_url
201
+ base + "/" + uri
202
+ end
203
+
204
+ # Builds the auth and U-A headers for the request
205
+ def headers
206
+ {
207
+ "Authorization" => "Basic " + Base64.strict_encode64(@options[:username].to_s + ":" + @options[:token].to_s).strip,
208
+ "User-Agent" => "Fat Zebra v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
209
+ }
210
+ end
211
+ end
212
+ end
213
+ end