active_accountability_merchant 1.97.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +2948 -0
  3. data/CONTRIBUTORS +568 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +246 -0
  6. data/lib/active_merchant.rb +63 -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 +96 -0
  10. data/lib/active_merchant/billing/base.rb +61 -0
  11. data/lib/active_merchant/billing/check.rb +80 -0
  12. data/lib/active_merchant/billing/compatibility.rb +117 -0
  13. data/lib/active_merchant/billing/credit_card.rb +406 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +23 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +343 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +330 -0
  18. data/lib/active_merchant/billing/gateways.rb +14 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +503 -0
  20. data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net.rb +1055 -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 +980 -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/bambora_apac.rb +226 -0
  27. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  28. data/lib/active_merchant/billing/gateways/banwire.rb +116 -0
  29. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +384 -0
  30. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  31. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  32. data/lib/active_merchant/billing/gateways/beanstream.rb +217 -0
  33. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +473 -0
  34. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +57 -0
  35. data/lib/active_merchant/billing/gateways/blue_pay.rb +522 -0
  36. data/lib/active_merchant/billing/gateways/blue_snap.rb +522 -0
  37. data/lib/active_merchant/billing/gateways/bogus.rb +186 -0
  38. data/lib/active_merchant/billing/gateways/borgun.rb +220 -0
  39. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  40. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  41. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +22 -0
  42. data/lib/active_merchant/billing/gateways/braintree_blue.rb +740 -0
  43. data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
  44. data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
  45. data/lib/active_merchant/billing/gateways/cams.rb +230 -0
  46. data/lib/active_merchant/billing/gateways/card_connect.rb +316 -0
  47. data/lib/active_merchant/billing/gateways/card_save.rb +22 -0
  48. data/lib/active_merchant/billing/gateways/card_stream.rb +367 -0
  49. data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
  50. data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
  51. data/lib/active_merchant/billing/gateways/cashnet.rb +219 -0
  52. data/lib/active_merchant/billing/gateways/cc5.rb +198 -0
  53. data/lib/active_merchant/billing/gateways/cecabank.rb +249 -0
  54. data/lib/active_merchant/billing/gateways/cenpos.rb +327 -0
  55. data/lib/active_merchant/billing/gateways/checkout.rb +214 -0
  56. data/lib/active_merchant/billing/gateways/checkout_v2.rb +270 -0
  57. data/lib/active_merchant/billing/gateways/citrus_pay.rb +22 -0
  58. data/lib/active_merchant/billing/gateways/clearhaus.rb +220 -0
  59. data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
  60. data/lib/active_merchant/billing/gateways/conekta.rb +228 -0
  61. data/lib/active_merchant/billing/gateways/creditcall.rb +271 -0
  62. data/lib/active_merchant/billing/gateways/credorax.rb +382 -0
  63. data/lib/active_merchant/billing/gateways/ct_payment.rb +268 -0
  64. data/lib/active_merchant/billing/gateways/culqi.rb +277 -0
  65. data/lib/active_merchant/billing/gateways/cyber_source.rb +828 -0
  66. data/lib/active_merchant/billing/gateways/d_local.rb +226 -0
  67. data/lib/active_merchant/billing/gateways/data_cash.rb +305 -0
  68. data/lib/active_merchant/billing/gateways/decidir.rb +233 -0
  69. data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
  70. data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
  71. data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
  72. data/lib/active_merchant/billing/gateways/efsnet.rb +215 -0
  73. data/lib/active_merchant/billing/gateways/elavon.rb +320 -0
  74. data/lib/active_merchant/billing/gateways/element.rb +356 -0
  75. data/lib/active_merchant/billing/gateways/epay.rb +285 -0
  76. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  77. data/lib/active_merchant/billing/gateways/eway.rb +226 -0
  78. data/lib/active_merchant/billing/gateways/eway_managed.rb +290 -0
  79. data/lib/active_merchant/billing/gateways/eway_rapid.rb +563 -0
  80. data/lib/active_merchant/billing/gateways/exact.rb +224 -0
  81. data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
  82. data/lib/active_merchant/billing/gateways/fat_zebra.rb +218 -0
  83. data/lib/active_merchant/billing/gateways/federated_canada.rb +159 -0
  84. data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
  85. data/lib/active_merchant/billing/gateways/first_giving.rb +142 -0
  86. data/lib/active_merchant/billing/gateways/first_pay.rb +182 -0
  87. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +451 -0
  88. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +485 -0
  89. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  90. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  91. data/lib/active_merchant/billing/gateways/forte.rb +270 -0
  92. data/lib/active_merchant/billing/gateways/garanti.rb +259 -0
  93. data/lib/active_merchant/billing/gateways/global_collect.rb +336 -0
  94. data/lib/active_merchant/billing/gateways/global_transport.rb +194 -0
  95. data/lib/active_merchant/billing/gateways/hdfc.rb +206 -0
  96. data/lib/active_merchant/billing/gateways/hps.rb +350 -0
  97. data/lib/active_merchant/billing/gateways/iats_payments.rb +290 -0
  98. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  99. data/lib/active_merchant/billing/gateways/inspire.rb +218 -0
  100. data/lib/active_merchant/billing/gateways/instapay.rb +162 -0
  101. data/lib/active_merchant/billing/gateways/ipp.rb +176 -0
  102. data/lib/active_merchant/billing/gateways/iridium.rb +468 -0
  103. data/lib/active_merchant/billing/gateways/itransact.rb +447 -0
  104. data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
  105. data/lib/active_merchant/billing/gateways/jetpay.rb +402 -0
  106. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
  107. data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
  108. data/lib/active_merchant/billing/gateways/kushki.rb +219 -0
  109. data/lib/active_merchant/billing/gateways/latitude19.rb +411 -0
  110. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  111. data/lib/active_merchant/billing/gateways/litle.rb +507 -0
  112. data/lib/active_merchant/billing/gateways/mastercard.rb +267 -0
  113. data/lib/active_merchant/billing/gateways/maxipago.rb +220 -0
  114. data/lib/active_merchant/billing/gateways/mercado_pago.rb +277 -0
  115. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +194 -0
  116. data/lib/active_merchant/billing/gateways/merchant_one.rb +113 -0
  117. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  118. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  119. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +286 -0
  120. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +210 -0
  121. data/lib/active_merchant/billing/gateways/mercury.rb +356 -0
  122. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  123. data/lib/active_merchant/billing/gateways/micropayment.rb +183 -0
  124. data/lib/active_merchant/billing/gateways/migs.rb +332 -0
  125. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  126. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  127. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +217 -0
  128. data/lib/active_merchant/billing/gateways/monei.rb +338 -0
  129. data/lib/active_merchant/billing/gateways/moneris.rb +377 -0
  130. data/lib/active_merchant/billing/gateways/moneris_us.rb +352 -0
  131. data/lib/active_merchant/billing/gateways/money_movers.rb +151 -0
  132. data/lib/active_merchant/billing/gateways/mundipagg.rb +293 -0
  133. data/lib/active_merchant/billing/gateways/nab_transact.rb +301 -0
  134. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +165 -0
  135. data/lib/active_merchant/billing/gateways/net_registry.rb +199 -0
  136. data/lib/active_merchant/billing/gateways/netaxept.rb +180 -0
  137. data/lib/active_merchant/billing/gateways/netbanx.rb +294 -0
  138. data/lib/active_merchant/billing/gateways/netbilling.rb +232 -0
  139. data/lib/active_merchant/billing/gateways/netpay.rb +222 -0
  140. data/lib/active_merchant/billing/gateways/network_merchants.rb +241 -0
  141. data/lib/active_merchant/billing/gateways/nmi.rb +324 -0
  142. data/lib/active_merchant/billing/gateways/ogone.rb +478 -0
  143. data/lib/active_merchant/billing/gateways/omise.rb +324 -0
  144. data/lib/active_merchant/billing/gateways/openpay.rb +228 -0
  145. data/lib/active_merchant/billing/gateways/opp.rb +388 -0
  146. data/lib/active_merchant/billing/gateways/optimal_payment.rb +332 -0
  147. data/lib/active_merchant/billing/gateways/orbital.rb +1006 -0
  148. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  149. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +206 -0
  150. data/lib/active_merchant/billing/gateways/pagarme.rb +246 -0
  151. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  152. data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
  153. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +280 -0
  154. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  155. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  156. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +188 -0
  157. data/lib/active_merchant/billing/gateways/pay_secure.rb +111 -0
  158. data/lib/active_merchant/billing/gateways/paybox_direct.rb +200 -0
  159. data/lib/active_merchant/billing/gateways/payeezy.rb +410 -0
  160. data/lib/active_merchant/billing/gateways/payex.rb +410 -0
  161. data/lib/active_merchant/billing/gateways/payflow.rb +383 -0
  162. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +235 -0
  163. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +43 -0
  164. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  165. data/lib/active_merchant/billing/gateways/payflow_express.rb +220 -0
  166. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +14 -0
  167. data/lib/active_merchant/billing/gateways/payflow_uk.rb +20 -0
  168. data/lib/active_merchant/billing/gateways/payment_express.rb +369 -0
  169. data/lib/active_merchant/billing/gateways/paymentez.rb +300 -0
  170. data/lib/active_merchant/billing/gateways/paymill.rb +371 -0
  171. data/lib/active_merchant/billing/gateways/paypal.rb +128 -0
  172. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +717 -0
  173. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  174. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  175. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  176. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  177. data/lib/active_merchant/billing/gateways/paypal_express.rb +269 -0
  178. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  179. data/lib/active_merchant/billing/gateways/payscout.rb +160 -0
  180. data/lib/active_merchant/billing/gateways/paystation.rb +207 -0
  181. data/lib/active_merchant/billing/gateways/payu_in.rb +248 -0
  182. data/lib/active_merchant/billing/gateways/payu_latam.rb +449 -0
  183. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  184. data/lib/active_merchant/billing/gateways/pin.rb +234 -0
  185. data/lib/active_merchant/billing/gateways/plugnpay.rb +284 -0
  186. data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
  187. data/lib/active_merchant/billing/gateways/psigate.rb +227 -0
  188. data/lib/active_merchant/billing/gateways/psl_card.rb +296 -0
  189. data/lib/active_merchant/billing/gateways/qbms.rb +303 -0
  190. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  191. data/lib/active_merchant/billing/gateways/quickbooks.rb +290 -0
  192. data/lib/active_merchant/billing/gateways/quickpay.rb +25 -0
  193. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
  194. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +301 -0
  195. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
  196. data/lib/active_merchant/billing/gateways/qvalent.rb +289 -0
  197. data/lib/active_merchant/billing/gateways/realex.rb +374 -0
  198. data/lib/active_merchant/billing/gateways/redsys.rb +534 -0
  199. data/lib/active_merchant/billing/gateways/s5.rb +246 -0
  200. data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
  201. data/lib/active_merchant/billing/gateways/sage.rb +448 -0
  202. data/lib/active_merchant/billing/gateways/sage_pay.rb +434 -0
  203. data/lib/active_merchant/billing/gateways/sallie_mae.rb +142 -0
  204. data/lib/active_merchant/billing/gateways/secure_net.rb +267 -0
  205. data/lib/active_merchant/billing/gateways/secure_pay.rb +200 -0
  206. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +292 -0
  207. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +104 -0
  208. data/lib/active_merchant/billing/gateways/securion_pay.rb +264 -0
  209. data/lib/active_merchant/billing/gateways/skip_jack.rb +450 -0
  210. data/lib/active_merchant/billing/gateways/smart_ps.rb +280 -0
  211. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  212. data/lib/active_merchant/billing/gateways/spreedly_core.rb +306 -0
  213. data/lib/active_merchant/billing/gateways/stripe.rb +790 -0
  214. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +267 -0
  215. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +152 -0
  216. data/lib/active_merchant/billing/gateways/telr.rb +274 -0
  217. data/lib/active_merchant/billing/gateways/tns.rb +22 -0
  218. data/lib/active_merchant/billing/gateways/trans_first.rb +239 -0
  219. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +608 -0
  220. data/lib/active_merchant/billing/gateways/transact_pro.rb +224 -0
  221. data/lib/active_merchant/billing/gateways/transax.rb +22 -0
  222. data/lib/active_merchant/billing/gateways/transnational.rb +9 -0
  223. data/lib/active_merchant/billing/gateways/trexle.rb +218 -0
  224. data/lib/active_merchant/billing/gateways/trust_commerce.rb +490 -0
  225. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  226. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1620 -0
  227. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +355 -0
  228. data/lib/active_merchant/billing/gateways/vanco.rb +294 -0
  229. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  230. data/lib/active_merchant/billing/gateways/viaklix.rb +176 -0
  231. data/lib/active_merchant/billing/gateways/visanet_peru.rb +245 -0
  232. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  233. data/lib/active_merchant/billing/gateways/wepay.rb +237 -0
  234. data/lib/active_merchant/billing/gateways/wirecard.rb +432 -0
  235. data/lib/active_merchant/billing/gateways/world_net.rb +344 -0
  236. data/lib/active_merchant/billing/gateways/worldpay.rb +634 -0
  237. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +215 -0
  238. data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
  239. data/lib/active_merchant/billing/model.rb +30 -0
  240. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -0
  241. data/lib/active_merchant/billing/payment_token.rb +21 -0
  242. data/lib/active_merchant/billing/rails.rb +3 -0
  243. data/lib/active_merchant/billing/response.rb +92 -0
  244. data/lib/active_merchant/connection.rb +195 -0
  245. data/lib/active_merchant/country.rb +336 -0
  246. data/lib/active_merchant/empty.rb +20 -0
  247. data/lib/active_merchant/errors.rb +35 -0
  248. data/lib/active_merchant/net_http_ssl_connection.rb +10 -0
  249. data/lib/active_merchant/network_connection_retries.rb +80 -0
  250. data/lib/active_merchant/post_data.rb +25 -0
  251. data/lib/active_merchant/posts_data.rb +92 -0
  252. data/lib/active_merchant/version.rb +3 -0
  253. data/lib/activemerchant.rb +1 -0
  254. data/lib/certs/cacert.pem +3988 -0
  255. data/lib/support/gateway_support.rb +69 -0
  256. data/lib/support/outbound_hosts.rb +28 -0
  257. data/lib/support/ssl_verify.rb +92 -0
  258. data/lib/support/ssl_version.rb +87 -0
  259. metadata +435 -0
@@ -0,0 +1,1006 @@
1
+ require 'active_merchant/billing/gateways/orbital/orbital_soft_descriptors'
2
+ require 'rexml/document'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ # For more information on Orbital, visit the {integration center}[http://download.chasepaymentech.com]
7
+ #
8
+ # ==== Authentication Options
9
+ #
10
+ # The Orbital Gateway supports two methods of authenticating incoming requests:
11
+ # Source IP authentication and Connection Username/Password authentication
12
+ #
13
+ # In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs
14
+ # for which the client should be submitting transactions.
15
+ #
16
+ # This does allow Third Party Hosting service organizations presenting on behalf of other
17
+ # merchants to submit transactions. However, each time a new customer is added, the
18
+ # merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs
19
+ # or Chain IDs are affiliated with the hosting companies IPs or Connection Usernames.
20
+ #
21
+ # If the merchant expects to have more than one merchant account with the Orbital
22
+ # Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain
23
+ # level hierarchy within the Orbital Gateway. Each time a new merchant ID is added, as
24
+ # long as it is placed within the same Chain, it will simply work. Otherwise, the additional
25
+ # MIDs will need to be affiliated with the merchant IPs or Connection Usernames respectively.
26
+ # For example, we generally affiliate all Salem accounts [BIN 000001] with
27
+ # their Company Number [formerly called MA #] number so all MIDs or Divisions under that
28
+ # Company will automatically be affiliated.
29
+
30
+ class OrbitalGateway < Gateway
31
+ include Empty
32
+
33
+ API_VERSION = '7.7'
34
+
35
+ POST_HEADERS = {
36
+ 'MIME-Version' => '1.1',
37
+ 'Content-Type' => "application/PTI#{API_VERSION.gsub(/\./, '')}",
38
+ 'Content-transfer-encoding' => 'text',
39
+ 'Request-number' => '1',
40
+ 'Document-type' => 'Request',
41
+ 'Interface-Version' => 'Ruby|ActiveMerchant|Proprietary Gateway'
42
+ }
43
+
44
+ SUCCESS = '0'
45
+
46
+ APPROVED = [
47
+ '00', # Approved
48
+ '08', # Approved authorization, honor with ID
49
+ '11', # Approved authorization, VIP approval
50
+ '24', # Validated
51
+ '26', # Pre-noted
52
+ '27', # No reason to decline
53
+ '28', # Received and stored
54
+ '29', # Provided authorization
55
+ '31', # Request received
56
+ '32', # BIN alert
57
+ '34', # Approved for partial
58
+ '91', # Approved low fraud
59
+ '92', # Approved medium fraud
60
+ '93', # Approved high fraud
61
+ '94', # Approved fraud service unavailable
62
+ 'E7', # Stored
63
+ 'PA' # Partial approval
64
+ ]
65
+
66
+ class_attribute :secondary_test_url, :secondary_live_url
67
+
68
+ self.test_url = 'https://orbitalvar1.chasepaymentech.com/authorize'
69
+ self.secondary_test_url = 'https://orbitalvar2.chasepaymentech.com/authorize'
70
+
71
+ self.live_url = 'https://orbital1.chasepaymentech.com/authorize'
72
+ self.secondary_live_url = 'https://orbital2.chasepaymentech.com/authorize'
73
+
74
+ self.supported_countries = ['US', 'CA']
75
+ self.default_currency = 'CAD'
76
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
77
+
78
+ self.display_name = 'Orbital Paymentech'
79
+ self.homepage_url = 'http://chasepaymentech.com/'
80
+
81
+ self.money_format = :cents
82
+
83
+ AVS_SUPPORTED_COUNTRIES = ['US', 'CA', 'UK', 'GB']
84
+
85
+ CURRENCY_CODES = {
86
+ 'AUD' => '036',
87
+ 'BRL' => '986',
88
+ 'CAD' => '124',
89
+ 'CLP' => '152',
90
+ 'CZK' => '203',
91
+ 'DKK' => '208',
92
+ 'HKD' => '344',
93
+ 'ICK' => '352',
94
+ 'JPY' => '392',
95
+ 'MXN' => '484',
96
+ 'NZD' => '554',
97
+ 'NOK' => '578',
98
+ 'SGD' => '702',
99
+ 'SEK' => '752',
100
+ 'CHF' => '756',
101
+ 'GBP' => '826',
102
+ 'USD' => '840',
103
+ 'EUR' => '978'
104
+ }
105
+
106
+ CURRENCY_EXPONENTS = {
107
+ 'AUD' => '2',
108
+ 'BRL' => '2',
109
+ 'CAD' => '2',
110
+ 'CLP' => '2',
111
+ 'CZK' => '2',
112
+ 'DKK' => '2',
113
+ 'HKD' => '2',
114
+ 'ICK' => '2',
115
+ 'JPY' => '0',
116
+ 'MXN' => '2',
117
+ 'NZD' => '2',
118
+ 'NOK' => '2',
119
+ 'SGD' => '2',
120
+ 'SEK' => '2',
121
+ 'CHF' => '2',
122
+ 'GBP' => '2',
123
+ 'USD' => '2',
124
+ 'EUR' => '2'
125
+ }
126
+
127
+ # INDUSTRY TYPES
128
+ ECOMMERCE_TRANSACTION = 'EC'
129
+ RECURRING_PAYMENT_TRANSACTION = 'RC'
130
+ MAIL_ORDER_TELEPHONE_ORDER_TRANSACTION = 'MO'
131
+ INTERACTIVE_VOICE_RESPONSE = 'IV'
132
+ # INTERACTIVE_VOICE_RESPONSE = 'IN'
133
+
134
+ # Auth Only No Capture
135
+ AUTH_ONLY = 'A'
136
+ # AC - Auth and Capture = 'AC'
137
+ AUTH_AND_CAPTURE = 'AC'
138
+ # F - Force Auth No Capture and no online authorization = 'F'
139
+ FORCE_AUTH_ONLY = 'F'
140
+ # FR - Force Auth No Capture and no online authorization = 'FR'
141
+ # FC - Force Auth and Capture no online authorization = 'FC'
142
+ FORCE_AUTH_AND_CAPTURE = 'FC'
143
+ # Refund and Capture no online authorization
144
+ REFUND = 'R'
145
+
146
+ # Tax Inds
147
+ TAX_NOT_PROVIDED = 0
148
+ TAX_INCLUDED = 1
149
+ NON_TAXABLE_TRANSACTION = 2
150
+
151
+ # Customer Profile Actions
152
+ CREATE = 'C'
153
+ RETRIEVE = 'R'
154
+ UPDATE = 'U'
155
+ DELETE = 'D'
156
+
157
+ RECURRING = 'R'
158
+ DEFERRED = 'D'
159
+
160
+ # Status
161
+ # Profile Status Flag
162
+ # This field is used to set the status of a Customer Profile.
163
+ ACTIVE = 'A'
164
+ INACTIVE = 'I'
165
+ MANUAL_SUSPEND = 'MS'
166
+
167
+ # CustomerProfileOrderOverrideInd
168
+ # Defines if any Order Data can be pre-populated from
169
+ # the Customer Reference Number (CustomerRefNum)
170
+ NO_MAPPING_TO_ORDER_DATA = 'NO'
171
+ USE_CRN_FOR_ORDER_ID = 'OI'
172
+ USE_CRN_FOR_COMMENTS = 'OD'
173
+ USE_CRN_FOR_ORDER_ID_AND_COMMENTS = 'OA'
174
+
175
+ # CustomerProfileFromOrderInd
176
+ # Method to use to Generate the Customer Profile Number
177
+ # When Customer Profile Action Type = Create, defines
178
+ # what the Customer Profile Number will be:
179
+ AUTO_GENERATE = 'A' # Auto-Generate the CustomerRefNum
180
+ USE_CUSTOMER_REF_NUM = 'S' # Use CustomerRefNum field
181
+ USE_ORDER_ID = 'O' # Use OrderID field
182
+ USE_COMMENTS = 'D' # Use Comments field
183
+
184
+ SENSITIVE_FIELDS = [:account_num, :cc_account_num]
185
+
186
+ def initialize(options = {})
187
+ requires!(options, :merchant_id)
188
+ requires!(options, :login, :password) unless options[:ip_authentication]
189
+ super
190
+ @options[:merchant_id] = @options[:merchant_id].to_s
191
+ end
192
+
193
+ # A – Authorization request
194
+ def authorize(money, creditcard, options = {})
195
+ order = build_new_order_xml(AUTH_ONLY, money, creditcard, options) do |xml|
196
+ add_creditcard(xml, creditcard, options[:currency])
197
+ add_address(xml, creditcard, options)
198
+ if @options[:customer_profiles]
199
+ add_customer_data(xml, creditcard, options)
200
+ add_managed_billing(xml, options)
201
+ end
202
+ end
203
+ commit(order, :authorize, options[:trace_number])
204
+ end
205
+
206
+ def verify(creditcard, options = {})
207
+ MultiResponse.run(:use_first_response) do |r|
208
+ r.process { authorize(100, creditcard, options) }
209
+ r.process(:ignore_result) { void(r.authorization) }
210
+ end
211
+ end
212
+
213
+ # AC – Authorization and Capture
214
+ def purchase(money, creditcard, options = {})
215
+ order = build_new_order_xml(AUTH_AND_CAPTURE, money, creditcard, options) do |xml|
216
+ add_creditcard(xml, creditcard, options[:currency])
217
+ add_address(xml, creditcard, options)
218
+ if @options[:customer_profiles]
219
+ add_customer_data(xml, creditcard, options)
220
+ add_managed_billing(xml, options)
221
+ end
222
+ end
223
+ commit(order, :purchase, options[:trace_number])
224
+ end
225
+
226
+ # MFC - Mark For Capture
227
+ def capture(money, authorization, options = {})
228
+ commit(build_mark_for_capture_xml(money, authorization, options), :capture)
229
+ end
230
+
231
+ # R – Refund request
232
+ def refund(money, authorization, options = {})
233
+ order = build_new_order_xml(REFUND, money, nil, options.merge(:authorization => authorization)) do |xml|
234
+ add_refund(xml, options[:currency])
235
+ xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
236
+ end
237
+ commit(order, :refund, options[:trace_number])
238
+ end
239
+
240
+ def credit(money, authorization, options= {})
241
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
242
+ refund(money, authorization, options)
243
+ end
244
+
245
+ def void(authorization, options = {}, deprecated = {})
246
+ if(!options.kind_of?(Hash))
247
+ ActiveMerchant.deprecated('Calling the void method with an amount parameter is deprecated and will be removed in a future version.')
248
+ return void(options, deprecated.merge(:amount => authorization))
249
+ end
250
+
251
+ order = build_void_request_xml(authorization, options)
252
+ commit(order, :void, options[:trace_number])
253
+ end
254
+
255
+ # ==== Customer Profiles
256
+ # :customer_ref_num should be set unless you're happy with Orbital providing one
257
+ #
258
+ # :customer_profile_order_override_ind can be set to map
259
+ # the CustomerRefNum to OrderID or Comments. Defaults to 'NO' - no mapping
260
+ #
261
+ # 'NO' - No mapping to order data
262
+ # 'OI' - Use <CustomerRefNum> for <OrderID>
263
+ # 'OD' - Use <CustomerRefNum> for <Comments>
264
+ # 'OA' - Use <CustomerRefNum> for <OrderID> and <Comments>
265
+ #
266
+ # :order_default_description can be set optionally. 64 char max.
267
+ #
268
+ # :order_default_amount can be set optionally. integer as cents.
269
+ #
270
+ # :status defaults to Active
271
+ #
272
+ # 'A' - Active
273
+ # 'I' - Inactive
274
+ # 'MS' - Manual Suspend
275
+
276
+ def add_customer_profile(creditcard, options = {})
277
+ options[:customer_profile_action] = CREATE
278
+ order = build_customer_request_xml(creditcard, options)
279
+ commit(order, :add_customer_profile)
280
+ end
281
+
282
+ def update_customer_profile(creditcard, options = {})
283
+ options[:customer_profile_action] = UPDATE
284
+ order = build_customer_request_xml(creditcard, options)
285
+ commit(order, :update_customer_profile)
286
+ end
287
+
288
+ def retrieve_customer_profile(customer_ref_num)
289
+ options = {:customer_profile_action => RETRIEVE, :customer_ref_num => customer_ref_num}
290
+ order = build_customer_request_xml(nil, options)
291
+ commit(order, :retrieve_customer_profile)
292
+ end
293
+
294
+ def delete_customer_profile(customer_ref_num)
295
+ options = {:customer_profile_action => DELETE, :customer_ref_num => customer_ref_num}
296
+ order = build_customer_request_xml(nil, options)
297
+ commit(order, :delete_customer_profile)
298
+ end
299
+
300
+ def supports_scrubbing?
301
+ true
302
+ end
303
+
304
+ def scrub(transcript)
305
+ transcript.
306
+ gsub(%r((<OrbitalConnectionUsername>).+(</OrbitalConnectionUsername>)), '\1[FILTERED]\2').
307
+ gsub(%r((<OrbitalConnectionPassword>).+(</OrbitalConnectionPassword>)), '\1[FILTERED]\2').
308
+ gsub(%r((<AccountNum>).+(</AccountNum>)), '\1[FILTERED]\2').
309
+ gsub(%r((<CCAccountNum>).+(</CCAccountNum>)), '\1[FILTERED]\2').
310
+ gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
311
+ gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
312
+ gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2')
313
+ end
314
+
315
+ private
316
+
317
+ def authorization_string(*args)
318
+ args.compact.join(';')
319
+ end
320
+
321
+ def split_authorization(authorization)
322
+ authorization.split(';')
323
+ end
324
+
325
+ def add_customer_data(xml, creditcard, options)
326
+ if options[:profile_txn]
327
+ xml.tag! :CustomerRefNum, options[:customer_ref_num]
328
+ else
329
+ if options[:customer_ref_num]
330
+ if creditcard
331
+ xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM
332
+ end
333
+ xml.tag! :CustomerRefNum, options[:customer_ref_num]
334
+ else
335
+ xml.tag! :CustomerProfileFromOrderInd, AUTO_GENERATE
336
+ end
337
+ xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
338
+ end
339
+ end
340
+
341
+ def add_soft_descriptors(xml, soft_desc)
342
+ xml.tag! :SDMerchantName, soft_desc.merchant_name if soft_desc.merchant_name
343
+ xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
344
+ xml.tag! :SDMerchantCity, soft_desc.merchant_city if soft_desc.merchant_city
345
+ xml.tag! :SDMerchantPhone, soft_desc.merchant_phone if soft_desc.merchant_phone
346
+ xml.tag! :SDMerchantURL, soft_desc.merchant_url if soft_desc.merchant_url
347
+ xml.tag! :SDMerchantEmail, soft_desc.merchant_email if soft_desc.merchant_email
348
+ end
349
+
350
+ def add_soft_descriptors_from_hash(xml, soft_desc)
351
+ xml.tag! :SDMerchantName, soft_desc[:merchant_name] || nil
352
+ xml.tag! :SDProductDescription, soft_desc[:product_description] || nil
353
+ xml.tag! :SDMerchantCity, soft_desc[:merchant_city] || nil
354
+ xml.tag! :SDMerchantPhone, soft_desc[:merchant_phone] || nil
355
+ xml.tag! :SDMerchantURL, soft_desc[:merchant_url] || nil
356
+ xml.tag! :SDMerchantEmail, soft_desc[:merchant_email] || nil
357
+ end
358
+
359
+ def add_level_2_tax(xml, options={})
360
+ if (level_2 = options[:level_2_data])
361
+ xml.tag! :TaxInd, level_2[:tax_indicator] if [TAX_NOT_PROVIDED, TAX_INCLUDED, NON_TAXABLE_TRANSACTION].include?(level_2[:tax_indicator].to_i)
362
+ xml.tag! :Tax, level_2[:tax].to_i if level_2[:tax]
363
+ end
364
+ end
365
+
366
+ def add_level_2_advice_addendum(xml, options={})
367
+ if (level_2 = options[:level_2_data])
368
+ xml.tag! :AMEXTranAdvAddn1, byte_limit(level_2[:advice_addendum_1], 40) if level_2[:advice_addendum_1]
369
+ xml.tag! :AMEXTranAdvAddn2, byte_limit(level_2[:advice_addendum_2], 40) if level_2[:advice_addendum_2]
370
+ xml.tag! :AMEXTranAdvAddn3, byte_limit(level_2[:advice_addendum_3], 40) if level_2[:advice_addendum_3]
371
+ xml.tag! :AMEXTranAdvAddn4, byte_limit(level_2[:advice_addendum_4], 40) if level_2[:advice_addendum_4]
372
+ end
373
+ end
374
+
375
+ def add_level_2_purchase(xml, options={})
376
+ if (level_2 = options[:level_2_data])
377
+ xml.tag! :PCOrderNum, byte_limit(level_2[:purchase_order], 17) if level_2[:purchase_order]
378
+ xml.tag! :PCDestZip, byte_limit(format_address_field(level_2[:zip]), 10) if level_2[:zip]
379
+ xml.tag! :PCDestName, byte_limit(format_address_field(level_2[:name]), 30) if level_2[:name]
380
+ xml.tag! :PCDestAddress1, byte_limit(format_address_field(level_2[:address1]), 30) if level_2[:address1]
381
+ xml.tag! :PCDestAddress2, byte_limit(format_address_field(level_2[:address2]), 30) if level_2[:address2]
382
+ xml.tag! :PCDestCity, byte_limit(format_address_field(level_2[:city]), 20) if level_2[:city]
383
+ xml.tag! :PCDestState, byte_limit(format_address_field(level_2[:state]), 2) if level_2[:state]
384
+ end
385
+ end
386
+
387
+ def add_address(xml, creditcard, options)
388
+ if(address = (options[:billing_address] || options[:address]))
389
+ avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
390
+
391
+ if avs_supported
392
+ xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
393
+ xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
394
+ xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
395
+ xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
396
+ xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
397
+ xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
398
+ end
399
+
400
+ xml.tag! :AVSname, (creditcard&.name ? creditcard.name[0..29] : nil)
401
+ xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '')
402
+
403
+ # Needs to come after AVScountryCode
404
+ add_destination_address(xml, address) if avs_supported
405
+ end
406
+ end
407
+
408
+ def add_destination_address(xml, address)
409
+ if address[:dest_zip]
410
+ avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:dest_country].to_s)
411
+
412
+ xml.tag! :AVSDestzip, byte_limit(format_address_field(address[:dest_zip]), 10)
413
+ xml.tag! :AVSDestaddress1, byte_limit(format_address_field(address[:dest_address1]), 30)
414
+ xml.tag! :AVSDestaddress2, byte_limit(format_address_field(address[:dest_address2]), 30)
415
+ xml.tag! :AVSDestcity, byte_limit(format_address_field(address[:dest_city]), 20)
416
+ xml.tag! :AVSDeststate, byte_limit(format_address_field(address[:dest_state]), 2)
417
+ xml.tag! :AVSDestphoneNum, (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
418
+
419
+ xml.tag! :AVSDestname, byte_limit(address[:dest_name], 30)
420
+ xml.tag! :AVSDestcountryCode, (avs_supported ? address[:dest_country] : '')
421
+ end
422
+ end
423
+
424
+ # For Profile requests
425
+ def add_customer_address(xml, options)
426
+ if(address = (options[:billing_address] || options[:address]))
427
+ avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
428
+
429
+ xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
430
+ xml.tag! :CustomerAddress2, byte_limit(format_address_field(address[:address2]), 30)
431
+ xml.tag! :CustomerCity, byte_limit(format_address_field(address[:city]), 20)
432
+ xml.tag! :CustomerState, byte_limit(format_address_field(address[:state]), 2)
433
+ xml.tag! :CustomerZIP, byte_limit(format_address_field(address[:zip]), 10)
434
+ xml.tag! :CustomerEmail, byte_limit(address[:email], 50) if address[:email]
435
+ xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
436
+ xml.tag! :CustomerCountryCode, (avs_supported ? address[:country] : '')
437
+ end
438
+ end
439
+
440
+ def add_creditcard(xml, creditcard, currency=nil)
441
+ unless creditcard.nil?
442
+ xml.tag! :AccountNum, creditcard.number
443
+ xml.tag! :Exp, expiry_date(creditcard)
444
+ end
445
+
446
+ xml.tag! :CurrencyCode, currency_code(currency)
447
+ xml.tag! :CurrencyExponent, currency_exponents(currency)
448
+
449
+ # If you are trying to collect a Card Verification Number
450
+ # (CardSecVal) for a Visa or Discover transaction, pass one of these values:
451
+ # 1 Value is Present
452
+ # 2 Value on card but illegible
453
+ # 9 Cardholder states data not available
454
+ # If the transaction is not a Visa or Discover transaction:
455
+ # Null-fill this attribute OR
456
+ # Do not submit the attribute at all.
457
+ # - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
458
+ unless creditcard.nil?
459
+ if creditcard.verification_value?
460
+ if %w( visa discover ).include?(creditcard.brand)
461
+ xml.tag! :CardSecValInd, '1'
462
+ end
463
+ xml.tag! :CardSecVal, creditcard.verification_value
464
+ end
465
+ end
466
+ end
467
+
468
+ def add_eci(xml, creditcard, three_d_secure)
469
+ eci = if three_d_secure
470
+ three_d_secure[:eci]
471
+ elsif creditcard.is_a?(NetworkTokenizationCreditCard)
472
+ creditcard.eci
473
+ end
474
+
475
+ xml.tag!(:AuthenticationECIInd, eci) if eci
476
+ end
477
+
478
+ def add_xid(xml, creditcard, three_d_secure)
479
+ xid = if three_d_secure && creditcard.brand == 'visa'
480
+ three_d_secure[:xid]
481
+ elsif creditcard.is_a?(NetworkTokenizationCreditCard)
482
+ creditcard.transaction_id
483
+ end
484
+
485
+ xml.tag!(:XID, xid) if xid
486
+ end
487
+
488
+ def add_cavv(xml, creditcard, three_d_secure)
489
+ return unless three_d_secure && creditcard.brand == 'visa'
490
+
491
+ xml.tag!(:CAVV, three_d_secure[:cavv])
492
+ end
493
+
494
+ def add_aav(xml, creditcard, three_d_secure)
495
+ return unless three_d_secure && creditcard.brand == 'master'
496
+
497
+ xml.tag!(:AAV, three_d_secure[:cavv])
498
+ end
499
+
500
+ def add_dpanind(xml, creditcard)
501
+ return unless creditcard.is_a?(NetworkTokenizationCreditCard)
502
+
503
+ xml.tag! :DPANInd, 'Y'
504
+ end
505
+
506
+ def add_digital_token_cryptogram(xml, creditcard)
507
+ return unless creditcard.is_a?(NetworkTokenizationCreditCard)
508
+
509
+ xml.tag! :DigitalTokenCryptogram, creditcard.payment_cryptogram
510
+ end
511
+
512
+ def add_aevv(xml, creditcard, three_d_secure)
513
+ return unless three_d_secure && creditcard.brand == 'american_express'
514
+
515
+ xml.tag!(:AEVV, three_d_secure[:cavv])
516
+ end
517
+
518
+ def add_pymt_brand_program_code(xml, creditcard, three_d_secure)
519
+ return unless three_d_secure && creditcard.brand == 'american_express'
520
+
521
+ xml.tag!(:PymtBrandProgramCode, 'ASK')
522
+ end
523
+
524
+ def add_refund(xml, currency=nil)
525
+ xml.tag! :AccountNum, nil
526
+
527
+ xml.tag! :CurrencyCode, currency_code(currency)
528
+ xml.tag! :CurrencyExponent, currency_exponents(currency)
529
+ end
530
+
531
+ def add_managed_billing(xml, options)
532
+ if mb = options[:managed_billing]
533
+ ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE
534
+
535
+ # default to recurring (R). Other option is deferred (D).
536
+ xml.tag! :MBType, mb[:type] || RECURRING
537
+ # default to Customer Reference Number
538
+ xml.tag! :MBOrderIdGenerationMethod, mb[:order_id_generation_method] || 'IO'
539
+ # By default use MBRecurringEndDate, set to N.
540
+ # MMDDYYYY
541
+ xml.tag! :MBRecurringStartDate, mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
542
+ # MMDDYYYY
543
+ xml.tag! :MBRecurringEndDate, mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
544
+ # By default listen to any value set in MBRecurringEndDate.
545
+ xml.tag! :MBRecurringNoEndDateFlag, mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
546
+ xml.tag! :MBRecurringMaxBillings, mb[:max_billings] if mb[:max_billings]
547
+ xml.tag! :MBRecurringFrequency, mb[:frequency] if mb[:frequency]
548
+ xml.tag! :MBDeferredBillDate, mb[:deferred_bill_date] if mb[:deferred_bill_date]
549
+ xml.tag! :MBMicroPaymentMaxDollarValue, mb[:max_dollar_value] if mb[:max_dollar_value]
550
+ xml.tag! :MBMicroPaymentMaxBillingDays, mb[:max_billing_days] if mb[:max_billing_days]
551
+ xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions] if mb[:max_transactions]
552
+ end
553
+ end
554
+
555
+ def add_stored_credentials(xml, parameters)
556
+ return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)
557
+ if msg_type = get_msg_type(parameters)
558
+ xml.tag! :MITMsgType, msg_type
559
+ end
560
+ xml.tag! :MITStoredCredentialInd, 'Y'
561
+ if parameters[:mit_submitted_transaction_id]
562
+ xml.tag! :MITSubmittedTransactionID, parameters[:mit_submitted_transaction_id]
563
+ elsif parameters.dig(:stored_credential, :network_transaction_id) && parameters.dig(:stored_credential, :initiator) == 'merchant'
564
+ xml.tag! :MITSubmittedTransactionID, parameters[:stored_credential][:network_transaction_id]
565
+ end
566
+ end
567
+
568
+ def get_msg_type(parameters)
569
+ return parameters[:mit_msg_type] if parameters[:mit_msg_type]
570
+ return 'CSTO' if parameters[:stored_credential][:initial_transaction]
571
+ return unless parameters[:stored_credential][:initiator] && parameters[:stored_credential][:reason_type]
572
+ initiator = case parameters[:stored_credential][:initiator]
573
+ when 'customer' then 'C'
574
+ when 'merchant' then 'M'
575
+ end
576
+ reason = case parameters[:stored_credential][:reason_type]
577
+ when 'recurring' then 'REC'
578
+ when 'installment' then 'INS'
579
+ when 'unscheduled' then 'USE'
580
+ end
581
+
582
+ "#{initiator}#{reason}"
583
+ end
584
+
585
+ def parse(body)
586
+ response = {}
587
+ xml = REXML::Document.new(body)
588
+ root = REXML::XPath.first(xml, '//Response') ||
589
+ REXML::XPath.first(xml, '//ErrorResponse')
590
+ if root
591
+ root.elements.to_a.each do |node|
592
+ recurring_parse_element(response, node)
593
+ end
594
+ end
595
+
596
+ response.delete_if { |k, _| SENSITIVE_FIELDS.include?(k) }
597
+ end
598
+
599
+ def recurring_parse_element(response, node)
600
+ if node.has_elements?
601
+ node.elements.each { |e| recurring_parse_element(response, e) }
602
+ else
603
+ response[node.name.underscore.to_sym] = node.text
604
+ end
605
+ end
606
+
607
+ def commit(order, message_type, trace_number=nil)
608
+ headers = POST_HEADERS.merge('Content-length' => order.size.to_s)
609
+ if @options[:retry_logic] && trace_number
610
+ headers['Trace-number'] = trace_number.to_s
611
+ headers['Merchant-Id'] = @options[:merchant_id]
612
+ end
613
+ request = ->(url) { parse(ssl_post(url, order, headers)) }
614
+
615
+ # Failover URL will be attempted in the event of a connection error
616
+ response = begin
617
+ request.call(remote_url)
618
+ rescue ConnectionError
619
+ request.call(remote_url(:secondary))
620
+ end
621
+
622
+ Response.new(success?(response, message_type), message_from(response), response,
623
+ {
624
+ :authorization => authorization_string(response[:tx_ref_num], response[:order_id]),
625
+ :test => self.test?,
626
+ :avs_result => OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
627
+ :cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
628
+ }
629
+ )
630
+ end
631
+
632
+ def remote_url(url=:primary)
633
+ if url == :primary
634
+ (self.test? ? self.test_url : self.live_url)
635
+ else
636
+ (self.test? ? self.secondary_test_url : self.secondary_live_url)
637
+ end
638
+ end
639
+
640
+ def success?(response, message_type)
641
+ if [:refund, :void].include?(message_type)
642
+ response[:proc_status] == SUCCESS
643
+ elsif response[:customer_profile_action]
644
+ response[:profile_proc_status] == SUCCESS
645
+ else
646
+ response[:proc_status] == SUCCESS &&
647
+ APPROVED.include?(response[:resp_code])
648
+ end
649
+ end
650
+
651
+ def message_from(response)
652
+ response[:resp_msg] || response[:status_msg] || response[:customer_profile_message]
653
+ end
654
+
655
+ def ip_authentication?
656
+ @options[:ip_authentication] == true
657
+ end
658
+
659
+ def build_new_order_xml(action, money, creditcard, parameters = {})
660
+ requires!(parameters, :order_id)
661
+ xml = xml_envelope
662
+ xml.tag! :Request do
663
+ xml.tag! :NewOrder do
664
+ add_xml_credentials(xml)
665
+ # EC - Ecommerce transaction
666
+ # RC - Recurring Payment transaction
667
+ # MO - Mail Order Telephone Order transaction
668
+ # IV - Interactive Voice Response
669
+ # IN - Interactive Voice Response
670
+ xml.tag! :IndustryType, parameters[:industry_type] || ECOMMERCE_TRANSACTION
671
+ # A - Auth Only No Capture
672
+ # AC - Auth and Capture
673
+ # F - Force Auth No Capture and no online authorization
674
+ # FR - Force Auth No Capture and no online authorization
675
+ # FC - Force Auth and Capture no online authorization
676
+ # R - Refund and Capture no online authorization
677
+ xml.tag! :MessageType, action
678
+ add_bin_merchant_and_terminal(xml, parameters)
679
+
680
+ yield xml if block_given?
681
+
682
+ three_d_secure = parameters[:three_d_secure]
683
+
684
+ add_eci(xml, creditcard, three_d_secure)
685
+ add_cavv(xml, creditcard, three_d_secure)
686
+ add_xid(xml, creditcard, three_d_secure)
687
+
688
+ xml.tag! :OrderID, format_order_id(parameters[:order_id])
689
+ xml.tag! :Amount, amount(money)
690
+ xml.tag! :Comments, parameters[:comments] if parameters[:comments]
691
+
692
+ add_level_2_tax(xml, parameters)
693
+ add_level_2_advice_addendum(xml, parameters)
694
+
695
+ add_aav(xml, creditcard, three_d_secure)
696
+ # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
697
+
698
+ add_dpanind(xml, creditcard)
699
+ add_aevv(xml, creditcard, three_d_secure)
700
+ add_digital_token_cryptogram(xml, creditcard)
701
+
702
+ if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
703
+ add_soft_descriptors(xml, parameters[:soft_descriptors])
704
+ elsif parameters[:soft_descriptors].is_a?(Hash)
705
+ add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors])
706
+ end
707
+
708
+ set_recurring_ind(xml, parameters)
709
+
710
+ # Append Transaction Reference Number at the end for Refund transactions
711
+ if action == REFUND
712
+ tx_ref_num, _ = split_authorization(parameters[:authorization])
713
+ xml.tag! :TxRefNum, tx_ref_num
714
+ end
715
+
716
+ add_level_2_purchase(xml, parameters)
717
+ add_stored_credentials(xml, parameters)
718
+ add_pymt_brand_program_code(xml, creditcard, three_d_secure)
719
+ end
720
+ end
721
+ xml.target!
722
+ end
723
+
724
+ # For Canadian transactions on PNS Tampa on New Order
725
+ # RF - First Recurring Transaction
726
+ # RS - Subsequent Recurring Transactions
727
+ def set_recurring_ind(xml, parameters)
728
+ if parameters[:recurring_ind]
729
+ raise 'RecurringInd must be set to either "RF" or "RS"' unless %w(RF RS).include?(parameters[:recurring_ind])
730
+ xml.tag! :RecurringInd, parameters[:recurring_ind]
731
+ end
732
+ end
733
+
734
+ def build_mark_for_capture_xml(money, authorization, parameters = {})
735
+ tx_ref_num, order_id = split_authorization(authorization)
736
+ xml = xml_envelope
737
+ xml.tag! :Request do
738
+ xml.tag! :MarkForCapture do
739
+ add_xml_credentials(xml)
740
+ xml.tag! :OrderID, format_order_id(order_id)
741
+ xml.tag! :Amount, amount(money)
742
+ add_level_2_tax(xml, parameters)
743
+ add_bin_merchant_and_terminal(xml, parameters)
744
+ xml.tag! :TxRefNum, tx_ref_num
745
+ add_level_2_purchase(xml, parameters)
746
+ add_level_2_advice_addendum(xml, parameters)
747
+ end
748
+ end
749
+ xml.target!
750
+ end
751
+
752
+ def build_void_request_xml(authorization, parameters = {})
753
+ tx_ref_num, order_id = split_authorization(authorization)
754
+ xml = xml_envelope
755
+ xml.tag! :Request do
756
+ xml.tag! :Reversal do
757
+ add_xml_credentials(xml)
758
+ xml.tag! :TxRefNum, tx_ref_num
759
+ xml.tag! :TxRefIdx, parameters[:transaction_index]
760
+ xml.tag! :AdjustedAmt, parameters[:amount] # setting adjusted amount to nil will void entire amount
761
+ xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
762
+ add_bin_merchant_and_terminal(xml, parameters)
763
+ xml.tag! :ReversalRetryNumber, parameters[:reversal_retry_number] if parameters[:reversal_retry_number]
764
+ xml.tag! :OnlineReversalInd, parameters[:online_reversal_ind] if parameters[:online_reversal_ind]
765
+ end
766
+ end
767
+ xml.target!
768
+ end
769
+
770
+ def currency_code(currency)
771
+ CURRENCY_CODES[(currency || self.default_currency)].to_s
772
+ end
773
+
774
+ def currency_exponents(currency)
775
+ CURRENCY_EXPONENTS[(currency || self.default_currency)].to_s
776
+ end
777
+
778
+ def expiry_date(credit_card)
779
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
780
+ end
781
+
782
+ def bin
783
+ @options[:bin] || (salem_mid? ? '000001' : '000002')
784
+ end
785
+
786
+ def xml_envelope
787
+ xml = Builder::XmlMarkup.new(:indent => 2)
788
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
789
+ xml
790
+ end
791
+
792
+ def add_xml_credentials(xml)
793
+ unless ip_authentication?
794
+ xml.tag! :OrbitalConnectionUsername, @options[:login]
795
+ xml.tag! :OrbitalConnectionPassword, @options[:password]
796
+ end
797
+ end
798
+
799
+ def add_bin_merchant_and_terminal(xml, parameters)
800
+ xml.tag! :BIN, bin
801
+ xml.tag! :MerchantID, @options[:merchant_id]
802
+ xml.tag! :TerminalID, parameters[:terminal_id] || '001'
803
+ end
804
+
805
+ def salem_mid?
806
+ @options[:merchant_id].length == 6
807
+ end
808
+
809
+ # The valid characters include:
810
+ #
811
+ # 1. all letters and digits
812
+ # 2. - , $ @ & and a space character, though the space character cannot be the leading character
813
+ # 3. PINless Debit transactions can only use uppercase and lowercase alpha (A-Z, a-z) and numeric (0-9)
814
+ def format_order_id(order_id)
815
+ illegal_characters = /[^,$@&\- \w]/
816
+ order_id = order_id.to_s.gsub(/\./, '-')
817
+ order_id.gsub!(illegal_characters, '')
818
+ order_id.lstrip!
819
+ order_id[0...22]
820
+ end
821
+
822
+ # Address-related fields cannot contain % | ^ \ /
823
+ # Returns the value with these characters removed, or nil
824
+ def format_address_field(value)
825
+ value.gsub(/[%\|\^\\\/]/, '') if value.respond_to?(:gsub)
826
+ end
827
+
828
+ # Field lengths should be limited by byte count instead of character count
829
+ # Returns the truncated value or nil
830
+ def byte_limit(value, byte_length)
831
+ limited_value = ''
832
+
833
+ value.to_s.each_char do |c|
834
+ break if((limited_value.bytesize + c.bytesize) > byte_length)
835
+ limited_value << c
836
+ end
837
+
838
+ limited_value
839
+ end
840
+
841
+ def build_customer_request_xml(creditcard, options = {})
842
+ ActiveMerchant.deprecated 'Customer Profile support in Orbital is non-conformant to the ActiveMerchant API and will be removed in its current form in a future version. Please contact the ActiveMerchant maintainers if you have an interest in modifying it to conform to the store/unstore/update API.'
843
+ xml = xml_envelope
844
+ xml.tag! :Request do
845
+ xml.tag! :Profile do
846
+ xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
847
+ xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
848
+ xml.tag! :CustomerBin, bin
849
+ xml.tag! :CustomerMerchantID, @options[:merchant_id]
850
+ xml.tag! :CustomerName, creditcard.name if creditcard
851
+ xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
852
+
853
+ add_customer_address(xml, options)
854
+
855
+ xml.tag! :CustomerProfileAction, options[:customer_profile_action] # C, R, U, D
856
+ # NO No mapping to order data
857
+ # OI Use <CustomerRefNum> for <OrderID>
858
+ # OD Use <CustomerReferNum> for <Comments>
859
+ # OA Use <CustomerRefNum> for <OrderID> and <Comments>
860
+ xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
861
+
862
+ if options[:customer_profile_action] == CREATE
863
+ # A Auto-Generate the CustomerRefNum
864
+ # S Use CustomerRefNum field
865
+ # O Use OrderID field
866
+ # D Use Comments field
867
+ xml.tag! :CustomerProfileFromOrderInd, (options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE)
868
+ end
869
+
870
+ xml.tag! :OrderDefaultDescription, options[:order_default_description][0..63] if options[:order_default_description]
871
+ xml.tag! :OrderDefaultAmount, options[:order_default_amount] if options[:order_default_amount]
872
+
873
+ if [CREATE, UPDATE].include? options[:customer_profile_action]
874
+ xml.tag! :CustomerAccountType, 'CC' # Only credit card supported
875
+ xml.tag! :Status, options[:status] || ACTIVE # Active
876
+ end
877
+
878
+ xml.tag! :CCAccountNum, creditcard.number if creditcard
879
+ xml.tag! :CCExpireDate, creditcard.expiry_date.expiration.strftime('%m%y') if creditcard
880
+
881
+ # This has to come after CCExpireDate.
882
+ add_managed_billing(xml, options)
883
+ end
884
+ end
885
+ xml.target!
886
+ end
887
+
888
+ # Unfortunately, Orbital uses their own special codes for AVS responses
889
+ # that are different than the standard codes defined in
890
+ # <tt>ActiveMerchant::Billing::AVSResult</tt>.
891
+ #
892
+ # This class encapsulates the response codes shown on page 240 of their spec:
893
+ # http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
894
+ #
895
+ class AVSResult < ActiveMerchant::Billing::AVSResult
896
+ CODES = {
897
+ '1' => 'No address supplied',
898
+ '2' => 'Bill-to address did not pass Auth Host edit checks',
899
+ '3' => 'AVS not performed',
900
+ '4' => 'Issuer does not participate in AVS',
901
+ '5' => 'Edit-error - AVS data is invalid',
902
+ '6' => 'System unavailable or time-out',
903
+ '7' => 'Address information unavailable',
904
+ '8' => 'Transaction Ineligible for AVS',
905
+ '9' => 'Zip Match/Zip 4 Match/Locale match',
906
+ 'A' => 'Zip Match/Zip 4 Match/Locale no match',
907
+ 'B' => 'Zip Match/Zip 4 no Match/Locale match',
908
+ 'C' => 'Zip Match/Zip 4 no Match/Locale no match',
909
+ 'D' => 'Zip No Match/Zip 4 Match/Locale match',
910
+ 'E' => 'Zip No Match/Zip 4 Match/Locale no match',
911
+ 'F' => 'Zip No Match/Zip 4 No Match/Locale match',
912
+ 'G' => 'No match at all',
913
+ 'H' => 'Zip Match/Locale match',
914
+ 'J' => 'Issuer does not participate in Global AVS',
915
+ 'JA' => 'International street address and postal match',
916
+ 'JB' => 'International street address match. Postal code not verified',
917
+ 'JC' => 'International street address and postal code not verified',
918
+ 'JD' => 'International postal code match. Street address not verified',
919
+ 'M1' => 'Cardholder name matches',
920
+ 'M2' => 'Cardholder name, billing address, and postal code matches',
921
+ 'M3' => 'Cardholder name and billing code matches',
922
+ 'M4' => 'Cardholder name and billing address match',
923
+ 'M5' => 'Cardholder name incorrect, billing address and postal code match',
924
+ 'M6' => 'Cardholder name incorrect, billing postal code matches',
925
+ 'M7' => 'Cardholder name incorrect, billing address matches',
926
+ 'M8' => 'Cardholder name, billing address and postal code are all incorrect',
927
+ 'N3' => 'Address matches, ZIP not verified',
928
+ 'N4' => 'Address and ZIP code not verified due to incompatible formats',
929
+ 'N5' => 'Address and ZIP code match (International only)',
930
+ 'N6' => 'Address not verified (International only)',
931
+ 'N7' => 'ZIP matches, address not verified',
932
+ 'N8' => 'Address and ZIP code match (International only)',
933
+ 'N9' => 'Address and ZIP code match (UK only)',
934
+ 'R' => 'Issuer does not participate in AVS',
935
+ 'UK' => 'Unknown',
936
+ 'X' => 'Zip Match/Zip 4 Match/Address Match',
937
+ 'Z' => 'Zip Match/Locale no match',
938
+ }
939
+
940
+ # Map vendor's AVS result code to a postal match code
941
+ ORBITAL_POSTAL_MATCH_CODE = {
942
+ 'Y' => %w( 9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z ),
943
+ 'N' => %w( D E F G M8 ),
944
+ 'X' => %w( 4 J R ),
945
+ nil => %w( 1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK )
946
+ }.inject({}) do |map, (type, codes)|
947
+ codes.each { |code| map[code] = type }
948
+ map
949
+ end
950
+
951
+ # Map vendor's AVS result code to a street match code
952
+ ORBITAL_STREET_MATCH_CODE = {
953
+ 'Y' => %w( 9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X ),
954
+ 'N' => %w( A C E G M8 Z ),
955
+ 'X' => %w( 4 J R ),
956
+ nil => %w( 1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK )
957
+ }.inject({}) do |map, (type, codes)|
958
+ codes.each { |code| map[code] = type }
959
+ map
960
+ end
961
+
962
+ def self.messages
963
+ CODES
964
+ end
965
+
966
+ def initialize(code)
967
+ @code = (code.blank? ? nil : code.to_s.strip.upcase)
968
+ if @code
969
+ @message = CODES[@code]
970
+ @postal_match = ORBITAL_POSTAL_MATCH_CODE[@code]
971
+ @street_match = ORBITAL_STREET_MATCH_CODE[@code]
972
+ end
973
+ end
974
+ end
975
+
976
+ # Unfortunately, Orbital uses their own special codes for CVV responses
977
+ # that are different than the standard codes defined in
978
+ # <tt>ActiveMerchant::Billing::CVVResult</tt>.
979
+ #
980
+ # This class encapsulates the response codes shown on page 255 of their spec:
981
+ # http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
982
+ #
983
+ class CVVResult < ActiveMerchant::Billing::CVVResult
984
+ MESSAGES = {
985
+ 'M' => 'Match',
986
+ 'N' => 'No match',
987
+ 'P' => 'Not processed',
988
+ 'S' => 'Should have been present',
989
+ 'U' => 'Unsupported by issuer/Issuer unable to process request',
990
+ 'I' => 'Invalid',
991
+ 'Y' => 'Invalid',
992
+ '' => 'Not applicable'
993
+ }
994
+
995
+ def self.messages
996
+ MESSAGES
997
+ end
998
+
999
+ def initialize(code)
1000
+ @code = code.blank? ? '' : code.upcase
1001
+ @message = MESSAGES[@code]
1002
+ end
1003
+ end
1004
+ end
1005
+ end
1006
+ end