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,207 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class HdfcGateway < Gateway
6
+ self.display_name = "HDFC"
7
+ self.homepage_url = "http://www.hdfcbank.com/sme/sme-details/merchant-services/guzh6m0i"
8
+
9
+ self.test_url = "https://securepgtest.fssnet.co.in/pgway/servlet/"
10
+ self.live_url = "https://securepg.fssnet.co.in/pgway/servlet/"
11
+
12
+ self.supported_countries = ["IN"]
13
+ self.default_currency = "INR"
14
+ self.money_format = :dollars
15
+ self.supported_cardtypes = [:visa, :master, :discover, :diners_club]
16
+
17
+ def initialize(options={})
18
+ requires!(options, :login, :password)
19
+ super
20
+ end
21
+
22
+ def purchase(amount, payment_method, options={})
23
+ post = {}
24
+ add_invoice(post, amount, options)
25
+ add_payment_method(post, payment_method)
26
+ add_customer_data(post, options)
27
+
28
+ commit("purchase", post)
29
+ end
30
+
31
+ def authorize(amount, payment_method, options={})
32
+ post = {}
33
+ add_invoice(post, amount, options)
34
+ add_payment_method(post, payment_method)
35
+ add_customer_data(post, options)
36
+
37
+ commit("authorize", post)
38
+ end
39
+
40
+ def capture(amount, authorization, options={})
41
+ post = {}
42
+ add_invoice(post, amount, options)
43
+ add_reference(post, authorization)
44
+ add_customer_data(post, options)
45
+
46
+ commit("capture", post)
47
+ end
48
+
49
+ def refund(amount, authorization, options={})
50
+ post = {}
51
+ add_invoice(post, amount, options)
52
+ add_reference(post, authorization)
53
+ add_customer_data(post, options)
54
+
55
+ commit("refund", post)
56
+ end
57
+
58
+ private
59
+
60
+ CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
61
+ CURRENCY_CODES["AED"] = "784"
62
+ CURRENCY_CODES["AUD"] = "036"
63
+ CURRENCY_CODES["CAD"] = "124"
64
+ CURRENCY_CODES["EUR"] = "978"
65
+ CURRENCY_CODES["GBP"] = "826"
66
+ CURRENCY_CODES["INR"] = "356"
67
+ CURRENCY_CODES["OMR"] = "512"
68
+ CURRENCY_CODES["QAR"] = "634"
69
+ CURRENCY_CODES["SGD"] = "702"
70
+ CURRENCY_CODES["USD"] = "840"
71
+
72
+ def add_invoice(post, amount, options)
73
+ post[:amt] = amount(amount)
74
+ post[:currencycode] = CURRENCY_CODES[options[:currency] || currency(amount)]
75
+ post[:trackid] = escape(options[:order_id], 40) if options[:order_id]
76
+ post[:udf1] = escape(options[:description]) if options[:description]
77
+ post[:eci] = options[:eci] if options[:eci]
78
+ end
79
+
80
+ def add_customer_data(post, options)
81
+ post[:udf2] = escape(options[:email]) if options[:email]
82
+ if address = (options[:billing_address] || options[:address])
83
+ post[:udf3] = escape(address[:phone]) if address[:phone]
84
+ post[:udf4] = escape(<<EOA)
85
+ #{address[:name]}
86
+ #{address[:company]}
87
+ #{address[:address1]}
88
+ #{address[:address2]}
89
+ #{address[:city]} #{address[:state]} #{address[:zip]}
90
+ #{address[:country]}
91
+ EOA
92
+ end
93
+ end
94
+
95
+ def add_payment_method(post, payment_method)
96
+ post[:member] = escape(payment_method.name, 30)
97
+ post[:card] = escape(payment_method.number)
98
+ post[:cvv2] = escape(payment_method.verification_value)
99
+ post[:expyear] = format(payment_method.year, :four_digits)
100
+ post[:expmonth] = format(payment_method.month, :two_digits)
101
+ end
102
+
103
+ def add_reference(post, authorization)
104
+ tranid, member = split_authorization(authorization)
105
+ post[:transid] = tranid
106
+ post[:member] = member
107
+ end
108
+
109
+ def parse(xml)
110
+ response = {}
111
+
112
+ doc = Nokogiri::XML.fragment(fix_xml(xml))
113
+ doc.children.each do |node|
114
+ if node.text?
115
+ next
116
+ elsif (node.elements.size == 0)
117
+ response[node.name.downcase.to_sym] = node.text
118
+ else
119
+ node.elements.each do |childnode|
120
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
121
+ response[name.to_sym] = childnode.text
122
+ end
123
+ end
124
+ end
125
+
126
+ response
127
+ end
128
+
129
+ def fix_xml(xml)
130
+ xml.gsub(/&(?!(?:amp|quot|apos|lt|gt);)/, "&amp;")
131
+ end
132
+
133
+ ACTIONS = {
134
+ "purchase" => "1",
135
+ "refund" => "2",
136
+ "authorize" => "4",
137
+ "capture" => "5",
138
+ }
139
+
140
+ def commit(action, post)
141
+ post[:id] = @options[:login]
142
+ post[:password] = @options[:password]
143
+ post[:action] = ACTIONS[action] if ACTIONS[action]
144
+
145
+ raw = parse(ssl_post(url(action), build_request(post)))
146
+
147
+ succeeded = success_from(raw[:result])
148
+ Response.new(
149
+ succeeded,
150
+ message_from(succeeded, raw),
151
+ raw,
152
+ :authorization => authorization_from(post, raw),
153
+ :test => test?
154
+ )
155
+ end
156
+
157
+ def build_request(post)
158
+ xml = Builder::XmlMarkup.new :indent => 2
159
+ xml.instruct!
160
+ post.each do |field, value|
161
+ xml.tag!(field, value)
162
+ end
163
+ xml.target!
164
+ end
165
+
166
+ def url(action)
167
+ endpoint = "TranPortalXMLServlet"
168
+ (test? ? test_url : live_url) + endpoint
169
+ end
170
+
171
+ def success_from(result)
172
+ case result
173
+ when "CAPTURED", "APPROVED", "NOT ENROLLED", "ENROLLED"
174
+ true
175
+ else
176
+ false
177
+ end
178
+ end
179
+
180
+ def message_from(succeeded, response)
181
+ if succeeded
182
+ "Succeeded"
183
+ else
184
+ (response[:error_text] || response[:result] || "Unable to read error message").split("-").last
185
+ end
186
+ end
187
+
188
+ def authorization_from(request, response)
189
+ [response[:tranid], request[:member]].join("|")
190
+ end
191
+
192
+ def split_authorization(authorization)
193
+ tranid, member = authorization.split("|")
194
+ [tranid, member]
195
+ end
196
+
197
+ def escape(string, max_length=250)
198
+ return "" unless string
199
+ if max_length
200
+ string = string[0...max_length]
201
+ end
202
+ string.gsub(/[^A-Za-z0-9 \-_@\.\n]/, '')
203
+ end
204
+ end
205
+ end
206
+ end
207
+
@@ -0,0 +1,287 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class HpsGateway < Gateway
6
+ self.live_url = 'https://posgateway.secureexchange.net/Hps.Exchange.PosGateway/PosGatewayService.asmx?wsdl'
7
+ self.test_url = 'https://posgateway.cert.secureexchange.net/Hps.Exchange.PosGateway/PosGatewayService.asmx?wsdl'
8
+
9
+ self.supported_countries = ['US']
10
+ self.default_currency = 'USD'
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jbc, :diners_club]
12
+
13
+ self.homepage_url = 'http://developer.heartlandpaymentsystems.com/SecureSubmit/'
14
+ self.display_name = 'Heartland Payment Systems'
15
+
16
+ self.money_format = :dollars
17
+
18
+ def initialize(options={})
19
+ requires!(options, :secret_api_key)
20
+ super
21
+ end
22
+
23
+ def authorize(money, card_or_token, options={})
24
+ commit('CreditAuth') do |xml|
25
+ add_amount(xml, money)
26
+ add_allow_dup(xml)
27
+ add_customer_data(xml, card_or_token, options)
28
+ add_details(xml, options)
29
+ add_payment(xml, card_or_token, options)
30
+ end
31
+ end
32
+
33
+ def capture(money, transaction_id, options={})
34
+ commit('CreditAddToBatch') do |xml|
35
+ add_amount(xml, money)
36
+ add_reference(xml, transaction_id)
37
+ end
38
+ end
39
+
40
+ def purchase(money, card_or_token, options={})
41
+ commit('CreditSale') do |xml|
42
+ add_amount(xml, money)
43
+ add_allow_dup(xml)
44
+ add_customer_data(xml, card_or_token,options)
45
+ add_details(xml, options)
46
+ add_payment(xml, card_or_token, options)
47
+ end
48
+ end
49
+
50
+ def refund(money, transaction_id, options={})
51
+ commit('CreditReturn') do |xml|
52
+ add_amount(xml, money)
53
+ add_allow_dup(xml)
54
+ add_reference(xml, transaction_id)
55
+ add_customer_data(xml, transaction_id,options)
56
+ add_details(xml, options)
57
+ end
58
+ end
59
+
60
+ def verify(card_or_token, options={})
61
+ commit('CreditAccountVerify') do |xml|
62
+ add_customer_data(xml, card_or_token, options)
63
+ add_payment(xml, card_or_token, options)
64
+ end
65
+ end
66
+
67
+ def void(transaction_id, options={})
68
+ commit('CreditVoid') do |xml|
69
+ add_reference(xml, transaction_id)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def add_reference(xml, transaction_id)
76
+ xml.hps :GatewayTxnId, transaction_id
77
+ end
78
+
79
+ def add_amount(xml, money)
80
+ xml.hps :Amt, amount(money) if money
81
+ end
82
+
83
+ def add_customer_data(xml, credit_card, options)
84
+ xml.hps :CardHolderData do
85
+ if credit_card.respond_to?(:number)
86
+ xml.hps :CardHolderFirstName, credit_card.first_name if credit_card.first_name
87
+ xml.hps :CardHolderLastName, credit_card.last_name if credit_card.last_name
88
+ end
89
+
90
+ xml.hps :CardHolderEmail, options[:email] if options[:email]
91
+ xml.hps :CardHolderPhone, options[:phone] if options[:phone]
92
+
93
+ if(billing_address = (options[:billing_address] || options[:address]))
94
+ xml.hps :CardHolderAddr, billing_address[:address1] if billing_address[:address1]
95
+ xml.hps :CardHolderCity, billing_address[:city] if billing_address[:city]
96
+ xml.hps :CardHolderState, billing_address[:state] if billing_address[:state]
97
+ xml.hps :CardHolderZip, billing_address[:zip] if billing_address[:zip]
98
+ end
99
+ end
100
+ end
101
+
102
+ def add_payment(xml, card_or_token, options)
103
+ xml.hps :CardData do
104
+ if card_or_token.respond_to?(:number)
105
+ if card_or_token.track_data
106
+ xml.tag!("hps:TrackData", 'method'=>'swipe') do
107
+ xml.text! card_or_token.track_data
108
+ end
109
+ if options[:encryption_type]
110
+ xml.hps :EncryptionData do
111
+ xml.hps :Version, options[:encryption_type]
112
+ if options[:encryption_type] == '02'
113
+ xml.hps :EncryptedTrackNumber, options[:encrypted_track_number]
114
+ xml.hps :KTB, options[:ktb]
115
+ end
116
+ end
117
+ end
118
+ else
119
+ xml.hps :ManualEntry do
120
+ xml.hps :CardNbr, card_or_token.number
121
+ xml.hps :ExpMonth, card_or_token.month
122
+ xml.hps :ExpYear, card_or_token.year
123
+ xml.hps :CVV2, card_or_token.verification_value if card_or_token.verification_value
124
+ xml.hps :CardPresent, 'N'
125
+ xml.hps :ReaderPresent, 'N'
126
+ end
127
+ end
128
+ else
129
+ xml.hps :TokenData do
130
+ xml.hps :TokenValue, card_or_token
131
+ end
132
+ end
133
+ xml.hps :TokenRequest, (options[:store] ? 'Y' : 'N')
134
+ end
135
+ end
136
+
137
+ def add_details(xml, options)
138
+ xml.hps :AdditionalTxnFields do
139
+ xml.hps :Description, options[:description] if options[:description]
140
+ xml.hps :InvoiceNbr, options[:order_id] if options[:order_id]
141
+ xml.hps :CustomerID, options[:customer_id] if options[:customer_id]
142
+ end
143
+ end
144
+
145
+ def add_allow_dup(xml)
146
+ xml.hps :AllowDup, 'Y'
147
+ end
148
+
149
+ def build_request(action)
150
+ xml = Builder::XmlMarkup.new(encoding: 'UTF-8')
151
+ xml.instruct!(:xml, encoding: 'UTF-8')
152
+ xml.SOAP :Envelope, {
153
+ 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/',
154
+ 'xmlns:hps' => 'http://Hps.Exchange.PosGateway' } do
155
+ xml.SOAP :Body do
156
+ xml.hps :PosRequest do
157
+ xml.hps 'Ver1.0'.to_sym do
158
+ xml.hps :Header do
159
+ xml.hps :SecretAPIKey, @options[:secret_api_key]
160
+ xml.hps :DeveloperID, @options[:developer_id] if @options[:developer_id]
161
+ xml.hps :VersionNbr, @options[:version_number] if @options[:version_number]
162
+ xml.hps :SiteTrace, @options[:site_trace] if @options[:site_trace]
163
+ end
164
+ xml.hps :Transaction do
165
+ xml.hps action.to_sym do
166
+ if %w(CreditVoid CreditAddToBatch).include?(action)
167
+ yield(xml)
168
+ else
169
+ xml.hps :Block1 do
170
+ yield(xml)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ xml.target!
180
+ end
181
+
182
+ def parse(raw)
183
+ response = {}
184
+
185
+ doc = Nokogiri::XML(raw)
186
+ doc.remove_namespaces!
187
+ if(header = doc.xpath("//Header").first)
188
+ header.elements.each do |node|
189
+ if (node.elements.size == 0)
190
+ response[node.name] = node.text
191
+ else
192
+ node.elements.each do |childnode|
193
+ response[childnode.name] = childnode.text
194
+ end
195
+ end
196
+ end
197
+ end
198
+ if(transaction = doc.xpath("//Transaction/*[1]").first)
199
+ transaction.elements.each do |node|
200
+ response[node.name] = node.text
201
+ end
202
+ end
203
+ if(fault = doc.xpath("//Fault/Reason/Text").first)
204
+ response["Fault"] = fault.text
205
+ end
206
+
207
+ response
208
+ end
209
+
210
+ def commit(action, &request)
211
+ data = build_request(action, &request)
212
+
213
+ response = begin
214
+ parse(ssl_post((test? ? test_url : live_url), data, 'Content-type' => 'text/xml'))
215
+ rescue ResponseError => e
216
+ parse(e.response.body)
217
+ end
218
+
219
+ ActiveMerchant::Billing::Response.new(
220
+ successful?(response),
221
+ message_from(response),
222
+ response,
223
+ test: test?,
224
+ authorization: authorization_from(response),
225
+ avs_result: {
226
+ code: response['AVSRsltCode'],
227
+ message: response['AVSRsltText']
228
+ },
229
+ cvv_result: response['CVVRsltCode']
230
+ )
231
+ end
232
+
233
+ def successful?(response)
234
+ (
235
+ (response["GatewayRspCode"] == "0") &&
236
+ ((response["RspCode"] || "00") == "00" || response["RspCode"] == "85")
237
+ )
238
+ end
239
+
240
+ def message_from(response)
241
+ if(response["Fault"])
242
+ response["Fault"]
243
+ elsif(response["GatewayRspCode"] == "0")
244
+ if(response["RspCode"] != "00" && response["RspCode"] != "85")
245
+ issuer_message(response["RspCode"])
246
+ else
247
+ response['GatewayRspMsg']
248
+ end
249
+ else
250
+ (GATEWAY_MESSAGES[response["GatewayRspCode"]] || response["GatewayRspMsg"])
251
+ end
252
+ end
253
+
254
+ def authorization_from(response)
255
+ response['GatewayTxnId']
256
+ end
257
+
258
+ def test?
259
+ (@options[:secret_api_key] && @options[:secret_api_key].include?('_cert_'))
260
+ end
261
+
262
+ ISSUER_MESSAGES = {
263
+ "13" => "Must be greater than or equal 0.",
264
+ "14" => "The card number is incorrect.",
265
+ "54" => "The card has expired.",
266
+ "55" => "The 4-digit pin is invalid.",
267
+ "75" => "Maximum number of pin retries exceeded.",
268
+ "80" => "Card expiration date is invalid.",
269
+ "86" => "Can't verify card pin number."
270
+ }
271
+ def issuer_message(code)
272
+ return "The card was declined." if %w(02 03 04 05 41 43 44 51 56 61 62 63 65 78).include?(code)
273
+ return "An error occurred while processing the card." if %w(06 07 12 15 19 12 52 53 57 58 76 77 91 96 EC).include?(code)
274
+ return "The card's security code is incorrect." if %w(EB N7).include?(code)
275
+ ISSUER_MESSAGES[code]
276
+ end
277
+
278
+ GATEWAY_MESSAGES = {
279
+ "-2" => "Authentication error. Please double check your service configuration.",
280
+ "12" => "Invalid CPC data.",
281
+ "13" => "Invalid card data.",
282
+ "14" => "The card number is not a valid credit card number.",
283
+ "30" => "Gateway timed out."
284
+ }
285
+ end
286
+ end
287
+ end