abtain_billing 1.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 (294) hide show
  1. data/CHANGELOG +473 -0
  2. data/CONTRIBUTORS +126 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +3 -0
  5. data/Rakefile +153 -0
  6. data/init.rb +3 -0
  7. data/lib/active_merchant.rb +60 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +57 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +159 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  15. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  16. data/lib/active_merchant/billing/gateway.rb +158 -0
  17. data/lib/active_merchant/billing/gateways.rb +3 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +657 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +813 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +233 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/bogus.rb +98 -0
  24. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  25. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  26. data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
  27. data/lib/active_merchant/billing/gateways/data_cash.rb +595 -0
  28. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  29. data/lib/active_merchant/billing/gateways/elavon.rb +106 -0
  30. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  31. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  32. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  33. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  34. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  35. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  36. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  37. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  38. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  39. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +214 -0
  40. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  41. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  43. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  44. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  45. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  46. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  47. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  48. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  49. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  50. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  51. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  52. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  53. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  54. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  55. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  56. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  57. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  58. data/lib/active_merchant/billing/gateways/paypal_express.rb +130 -0
  59. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  60. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  61. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  62. data/lib/active_merchant/billing/gateways/psl_card.rb +306 -0
  63. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  64. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  65. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  66. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  67. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  68. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  69. data/lib/active_merchant/billing/gateways/sage_pay.rb +308 -0
  70. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  71. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  72. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  73. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  74. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  75. data/lib/active_merchant/billing/gateways/smart_ps.rb +254 -0
  76. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  77. data/lib/active_merchant/billing/gateways/transax.rb +26 -0
  78. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  79. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  80. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  81. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  82. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  83. data/lib/active_merchant/billing/integrations.rb +22 -0
  84. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  85. data/lib/active_merchant/billing/integrations/bogus.rb +22 -0
  86. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  87. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  88. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  89. data/lib/active_merchant/billing/integrations/chronopay.rb +22 -0
  90. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
  91. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
  92. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  93. data/lib/active_merchant/billing/integrations/gestpay.rb +26 -0
  94. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  95. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  96. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
  97. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  98. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  99. data/lib/active_merchant/billing/integrations/hi_trust.rb +26 -0
  100. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  101. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  102. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  103. data/lib/active_merchant/billing/integrations/nochex.rb +87 -0
  104. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  105. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  106. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  107. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  108. data/lib/active_merchant/billing/integrations/paypal.rb +40 -0
  109. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  110. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  111. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  112. data/lib/active_merchant/billing/integrations/quickpay.rb +18 -0
  113. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  114. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  115. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  116. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  117. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  118. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  119. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  120. data/lib/active_merchant/billing/response.rb +32 -0
  121. data/lib/active_merchant/lib/connection.rb +170 -0
  122. data/lib/active_merchant/lib/country.rb +319 -0
  123. data/lib/active_merchant/lib/error.rb +4 -0
  124. data/lib/active_merchant/lib/post_data.rb +22 -0
  125. data/lib/active_merchant/lib/posts_data.rb +47 -0
  126. data/lib/active_merchant/lib/requires_parameters.rb +16 -0
  127. data/lib/active_merchant/lib/utils.rb +18 -0
  128. data/lib/active_merchant/lib/validateable.rb +76 -0
  129. data/lib/certs/cacert.pem +7815 -0
  130. data/lib/support/gateway_support.rb +58 -0
  131. data/script/destroy +14 -0
  132. data/script/generate +14 -0
  133. data/test/fixtures.yml +355 -0
  134. data/test/remote/gateways/remote_authorize_net_cim_test.rb +460 -0
  135. data/test/remote/gateways/remote_authorize_net_test.rb +145 -0
  136. data/test/remote/gateways/remote_beanstream_interac_test.rb +53 -0
  137. data/test/remote/gateways/remote_beanstream_test.rb +150 -0
  138. data/test/remote/gateways/remote_braintree_test.rb +154 -0
  139. data/test/remote/gateways/remote_card_stream_test.rb +148 -0
  140. data/test/remote/gateways/remote_cyber_source_test.rb +144 -0
  141. data/test/remote/gateways/remote_data_cash_test.rb +357 -0
  142. data/test/remote/gateways/remote_efsnet_test.rb +81 -0
  143. data/test/remote/gateways/remote_elavon_test.rb +66 -0
  144. data/test/remote/gateways/remote_eway_test.rb +74 -0
  145. data/test/remote/gateways/remote_exact_test.rb +60 -0
  146. data/test/remote/gateways/remote_first_pay_test.rb +87 -0
  147. data/test/remote/gateways/remote_instapay_test.rb +61 -0
  148. data/test/remote/gateways/remote_jetpay_test.rb +103 -0
  149. data/test/remote/gateways/remote_linkpoint_test.rb +121 -0
  150. data/test/remote/gateways/remote_merchant_e_solutions_test.rb +173 -0
  151. data/test/remote/gateways/remote_merchant_ware_test.rb +113 -0
  152. data/test/remote/gateways/remote_modern_payments_cim_test.rb +58 -0
  153. data/test/remote/gateways/remote_modern_payments_test.rb +43 -0
  154. data/test/remote/gateways/remote_moneris_test.rb +82 -0
  155. data/test/remote/gateways/remote_net_registry_test.rb +85 -0
  156. data/test/remote/gateways/remote_netbilling_test.rb +70 -0
  157. data/test/remote/gateways/remote_ogone_test.rb +115 -0
  158. data/test/remote/gateways/remote_pay_junction_test.rb +143 -0
  159. data/test/remote/gateways/remote_pay_secure_test.rb +39 -0
  160. data/test/remote/gateways/remote_payflow_express_test.rb +50 -0
  161. data/test/remote/gateways/remote_payflow_test.rb +237 -0
  162. data/test/remote/gateways/remote_payflow_uk_test.rb +173 -0
  163. data/test/remote/gateways/remote_payment_express_test.rb +136 -0
  164. data/test/remote/gateways/remote_paypal_express_test.rb +49 -0
  165. data/test/remote/gateways/remote_paypal_test.rb +191 -0
  166. data/test/remote/gateways/remote_plugnpay_test.rb +72 -0
  167. data/test/remote/gateways/remote_psigate_test.rb +50 -0
  168. data/test/remote/gateways/remote_psl_card_test.rb +125 -0
  169. data/test/remote/gateways/remote_quickpay_test.rb +190 -0
  170. data/test/remote/gateways/remote_realex_test.rb +224 -0
  171. data/test/remote/gateways/remote_sage_bankcard_test.rb +109 -0
  172. data/test/remote/gateways/remote_sage_pay_test.rb +219 -0
  173. data/test/remote/gateways/remote_sage_test.rb +87 -0
  174. data/test/remote/gateways/remote_sage_virtual_check_test.rb +62 -0
  175. data/test/remote/gateways/remote_sallie_mae_test.rb +51 -0
  176. data/test/remote/gateways/remote_secure_pay_au_test.rb +40 -0
  177. data/test/remote/gateways/remote_secure_pay_tech_test.rb +37 -0
  178. data/test/remote/gateways/remote_secure_pay_test.rb +28 -0
  179. data/test/remote/gateways/remote_skipjack_test.rb +105 -0
  180. data/test/remote/gateways/remote_trans_first_test.rb +34 -0
  181. data/test/remote/gateways/remote_transax_test.rb +112 -0
  182. data/test/remote/gateways/remote_trust_commerce_test.rb +152 -0
  183. data/test/remote/gateways/remote_usa_epay_test.rb +46 -0
  184. data/test/remote/gateways/remote_verifi_test.rb +107 -0
  185. data/test/remote/gateways/remote_viaklix_test.rb +43 -0
  186. data/test/remote/gateways/remote_wirecard_test.rb +111 -0
  187. data/test/remote/integrations/remote_gestpay_integration_test.rb +37 -0
  188. data/test/remote/integrations/remote_paypal_integration_test.rb +26 -0
  189. data/test/test_helper.rb +182 -0
  190. data/test/unit/avs_result_test.rb +59 -0
  191. data/test/unit/base_test.rb +55 -0
  192. data/test/unit/check_test.rb +88 -0
  193. data/test/unit/connection_test.rb +129 -0
  194. data/test/unit/country_code_test.rb +33 -0
  195. data/test/unit/country_test.rb +64 -0
  196. data/test/unit/credit_card_formatting_test.rb +19 -0
  197. data/test/unit/credit_card_methods_test.rb +179 -0
  198. data/test/unit/credit_card_test.rb +318 -0
  199. data/test/unit/cvv_result_test.rb +33 -0
  200. data/test/unit/expiry_date_test.rb +32 -0
  201. data/test/unit/gateways/authorize_net_cim_test.rb +676 -0
  202. data/test/unit/gateways/authorize_net_test.rb +290 -0
  203. data/test/unit/gateways/beanstream_interac_test.rb +51 -0
  204. data/test/unit/gateways/beanstream_test.rb +108 -0
  205. data/test/unit/gateways/bogus_test.rb +46 -0
  206. data/test/unit/gateways/braintree_test.rb +126 -0
  207. data/test/unit/gateways/card_stream_test.rb +90 -0
  208. data/test/unit/gateways/cyber_source_test.rb +188 -0
  209. data/test/unit/gateways/data_cash_test.rb +133 -0
  210. data/test/unit/gateways/efsnet_test.rb +123 -0
  211. data/test/unit/gateways/elavon_test.rb +139 -0
  212. data/test/unit/gateways/eway_test.rb +118 -0
  213. data/test/unit/gateways/exact_test.rb +156 -0
  214. data/test/unit/gateways/first_pay_test.rb +125 -0
  215. data/test/unit/gateways/gateway_test.rb +48 -0
  216. data/test/unit/gateways/instapay_test.rb +102 -0
  217. data/test/unit/gateways/jetpay_test.rb +185 -0
  218. data/test/unit/gateways/linkpoint_test.rb +184 -0
  219. data/test/unit/gateways/merchant_e_solutions_test.rb +169 -0
  220. data/test/unit/gateways/merchant_ware_test.rb +188 -0
  221. data/test/unit/gateways/modern_payments_cim_test.rb +171 -0
  222. data/test/unit/gateways/moneris_test.rb +158 -0
  223. data/test/unit/gateways/net_registry_test.rb +416 -0
  224. data/test/unit/gateways/netbilling_test.rb +54 -0
  225. data/test/unit/gateways/ogone_test.rb +319 -0
  226. data/test/unit/gateways/pay_junction_test.rb +123 -0
  227. data/test/unit/gateways/pay_secure_test.rb +71 -0
  228. data/test/unit/gateways/payflow_express_test.rb +173 -0
  229. data/test/unit/gateways/payflow_express_uk_test.rb +86 -0
  230. data/test/unit/gateways/payflow_test.rb +305 -0
  231. data/test/unit/gateways/payflow_uk_test.rb +30 -0
  232. data/test/unit/gateways/payment_express_test.rb +195 -0
  233. data/test/unit/gateways/paypal_express_test.rb +382 -0
  234. data/test/unit/gateways/paypal_test.rb +569 -0
  235. data/test/unit/gateways/plugnpay_test.rb +86 -0
  236. data/test/unit/gateways/psigate_test.rb +169 -0
  237. data/test/unit/gateways/psl_card_test.rb +64 -0
  238. data/test/unit/gateways/quickpay_test.rb +112 -0
  239. data/test/unit/gateways/realex_test.rb +151 -0
  240. data/test/unit/gateways/sage_bankcard_test.rb +196 -0
  241. data/test/unit/gateways/sage_pay_test.rb +139 -0
  242. data/test/unit/gateways/sage_virtual_check_test.rb +71 -0
  243. data/test/unit/gateways/sallie_mae_test.rb +53 -0
  244. data/test/unit/gateways/secure_pay_au_test.rb +207 -0
  245. data/test/unit/gateways/secure_pay_tech_test.rb +44 -0
  246. data/test/unit/gateways/secure_pay_test.rb +87 -0
  247. data/test/unit/gateways/skip_jack_test.rb +213 -0
  248. data/test/unit/gateways/trans_first_test.rb +112 -0
  249. data/test/unit/gateways/trust_commerce_test.rb +90 -0
  250. data/test/unit/gateways/usa_epay_test.rb +128 -0
  251. data/test/unit/gateways/verifi_test.rb +96 -0
  252. data/test/unit/gateways/viaklix_test.rb +78 -0
  253. data/test/unit/gateways/wirecard_test.rb +250 -0
  254. data/test/unit/generators/test_gateway_generator.rb +46 -0
  255. data/test/unit/generators/test_generator_helper.rb +20 -0
  256. data/test/unit/generators/test_integration_generator.rb +53 -0
  257. data/test/unit/integrations/action_view_helper_test.rb +50 -0
  258. data/test/unit/integrations/bogus_module_test.rb +20 -0
  259. data/test/unit/integrations/chronopay_module_test.rb +13 -0
  260. data/test/unit/integrations/gestpay_module_test.rb +14 -0
  261. data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
  262. data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
  263. data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
  264. data/test/unit/integrations/helpers/hi_trust_helper_test.rb +16 -0
  265. data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
  266. data/test/unit/integrations/helpers/paypal_helper_test.rb +171 -0
  267. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  268. data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
  269. data/test/unit/integrations/hi_trust_module_test.rb +13 -0
  270. data/test/unit/integrations/nochex_module_test.rb +13 -0
  271. data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
  272. data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
  273. data/test/unit/integrations/notifications/hi_trust_notification_test.rb +59 -0
  274. data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
  275. data/test/unit/integrations/notifications/notification_test.rb +54 -0
  276. data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
  277. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  278. data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
  279. data/test/unit/integrations/paypal_module_test.rb +28 -0
  280. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  281. data/test/unit/integrations/returns/chronopay_return_test.rb +11 -0
  282. data/test/unit/integrations/returns/gestpay_return_test.rb +10 -0
  283. data/test/unit/integrations/returns/hi_trust_return_test.rb +24 -0
  284. data/test/unit/integrations/returns/nochex_return_test.rb +10 -0
  285. data/test/unit/integrations/returns/paypal_return_test.rb +10 -0
  286. data/test/unit/integrations/returns/return_test.rb +11 -0
  287. data/test/unit/integrations/returns/two_checkout_return_test.rb +24 -0
  288. data/test/unit/integrations/two_checkout_module_test.rb +13 -0
  289. data/test/unit/post_data_test.rb +55 -0
  290. data/test/unit/posts_data_test.rb +48 -0
  291. data/test/unit/response_test.rb +28 -0
  292. data/test/unit/utils_test.rb +7 -0
  293. data/test/unit/validateable_test.rb +60 -0
  294. metadata +366 -0
@@ -0,0 +1,452 @@
1
+ #!ruby19
2
+ # encoding: utf-8
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class SkipJackGateway < Gateway
7
+ API_VERSION = '?.?'
8
+
9
+ LIVE_HOST = "https://www.skipjackic.com"
10
+ TEST_HOST = "https://developer.skipjackic.com"
11
+
12
+ BASIC_PATH = "/scripts/evolvcc.dll"
13
+ ADVANCED_PATH = "/evolvcc/evolvcc.aspx"
14
+
15
+ ACTIONS = {
16
+ :authorization => 'AuthorizeAPI',
17
+ :change_status => 'SJAPI_TransactionChangeStatusRequest',
18
+ :get_status => 'SJAPI_TransactionStatusRequest'
19
+ }
20
+
21
+ SUCCESS_MESSAGE = 'The transaction was successful.'
22
+
23
+ MONETARY_CHANGE_STATUSES = ['AUTHORIZE', 'AUTHORIZE ADDITIONAL', 'CREDIT', 'SPLITSETTLE']
24
+
25
+ CARD_CODE_ERRORS = %w( N S "" )
26
+
27
+ CARD_CODE_MESSAGES = {
28
+ "M" => "Card verification number matched",
29
+ "N" => "Card verification number didn't match",
30
+ "P" => "Card verification number was not processed",
31
+ "S" => "Card verification number should be on card but was not indicated",
32
+ "U" => "Issuer was not certified for card verification",
33
+ "" => "Transaction failed because incorrect card verification number was entered or no number was entered"
34
+ }
35
+
36
+ AVS_ERRORS = %w( A B C E I N O P R W Z )
37
+
38
+ AVS_MESSAGES = {
39
+ "A" => "Street address matches billing information, zip/postal code does not",
40
+ "B" => "Street address match for international transaction. Postal code not verified due to incompatible formats",
41
+ "C" => "Street address and postal code not verified for internation transaction due to incompatible formats",
42
+ "D" => "Street address and postal code match for international transaction",
43
+ "E" => "Address verification service error",
44
+ "I" => "Address information not verified by international issuer",
45
+ "M" => "Street address and postal code match for international transaction",
46
+ "N" => "Neither street address nor zip/postal match billing information",
47
+ "O" => "Non-US issuer does not participate",
48
+ "P" => "Postal codes match for international transaction but street address not verified due to incompatible formats",
49
+ "P" => "Address verification not applicable for this transaction",
50
+ "R" => "Payment gateway was unavailable or timed out",
51
+ "S" => "Address verification service not supported by issuer",
52
+ "U" => "Address information is unavailable",
53
+ "W" => "9-digit zip/postal code matches billing information, street address does not",
54
+ "X" => "Street address and 9-digit zip/postal code matches billing information",
55
+ "Y" => "Street address and 5-digit zip/postal code matches billing information",
56
+ "Z" => "5-digit zip/postal code matches billing information, street address does not",
57
+ }
58
+
59
+ CHANGE_STATUS_ERROR_MESSAGES = {
60
+ '0' => 'Success',
61
+ '-1' => 'Invalid Command',
62
+ '-2' => 'Parameter Missing',
63
+ '-3' => 'Failed retrieving response',
64
+ '-4' => 'Invalid Status',
65
+ '-5' => 'Failed reading security flags',
66
+ '-6' => 'Developer serial number not found',
67
+ '-7' => 'Invalid Serial Number'
68
+ }
69
+
70
+ TRANSACTION_CURRENT_STATUS = {
71
+ '0' => 'Idle',
72
+ '1' => 'Authorized',
73
+ '2' => 'Denied',
74
+ '3' => 'Settled',
75
+ '4' => 'Credited',
76
+ '5' => 'Deleted',
77
+ '6' => 'Archived',
78
+ '7' => 'Pre-Authorized',
79
+ '8' => 'Split Settled'
80
+ }
81
+
82
+ TRANSACTION_PENDING_STATUS = {
83
+ '0' => 'Idle',
84
+ '1' => 'Pending Credit',
85
+ '2' => 'Pending Settlement',
86
+ '3' => 'Pending Authorization',
87
+ '4' => 'Pending Manual Settlement',
88
+ '5' => 'Pending Recurring'
89
+ }
90
+
91
+ RETURN_CODE_MESSAGES = {
92
+ '-1' => 'Data was not by received intact by Skipjack Transaction Network.',
93
+ '0' => 'Communication Failure. Error in Request and Response at IP level.',
94
+ '1' => 'Valid Data. Authorization request was valid.',
95
+ '-35' => 'Invalid credit card number. Retry with correct credit card number.',
96
+ '-37' => 'Merchant Processor Unavailable. Skipjack is unable to communicate with payment Processor. Retry',
97
+ '-39' => 'Length or value of HTML Serial. Number Invalid serial number. Check HTML Serial Number length and that it is a correct/valid number. Confirm you are sending to the correct environment (Development or Production)',
98
+ '-51' => 'The value or length for billing zip code is incorrect.',
99
+ '-52' => 'The value or length for shipping zip code is incorrect.',
100
+ '-53' => 'The value or length for credit card expiration month is incorrect.',
101
+ '-54' => 'The value or length of the month or year of the credit card account number was incorrect.',
102
+ '-55' => 'The value or length or billing street address is incorrect.',
103
+ '-56' => 'The value or length of the shipping address is incorrect.',
104
+ '-57' => 'The length of the transaction amount must be at least 3 digits long (excluding the decimal place).',
105
+ '-58' => 'Length or value in Merchant Name Merchant Name associated with Skipjack account is misconfigured or invalid',
106
+ '-59' => 'Length or value in Merchant Address Merchant Address associated with Skipjack account is misconfigured or invalid',
107
+ '-60' => 'Length or value in Merchant State Merchant State associated with Skipjack account is misconfigured or invalid',
108
+ '-61' => 'The value or length for shipping state/province is empty.',
109
+ '-62' => 'The value for length orderstring is empty.',
110
+ '-64' => 'The value for the phone number is incorrect.',
111
+ '-65' => 'The value or length for billing name is empty.',
112
+ '-66' => 'The value or length for billing e-mail is empty.',
113
+ '-67' => 'The value or length for billing street address is empty.',
114
+ '-68' => 'The value or length for billing city is empty.',
115
+ '-69' => 'The value or length for billing state is empty.',
116
+ '-70' => 'Empty zipcode Zip Code field is empty.',
117
+ '-71' => 'Empty ordernumber Ordernumber field is empty.',
118
+ '-72' => 'Empty accountnumber Accountnumber field is empty',
119
+ '-73' => 'Empty month Month field is empty.',
120
+ '-74' => 'Empty year Year field is empty.',
121
+ '-75' => 'Empty serialnumber Serialnumber field is empty.',
122
+ '-76' => 'Empty transactionamount Transaction amount field is empty.',
123
+ '-77' => 'Empty orderstring Orderstring field is empty.',
124
+ '-78' => 'Empty shiptophone Shiptophone field is empty.',
125
+ '-79' => 'The value or length for billing name is empty.',
126
+ '-80' => 'Length shipto name Error in the length or value of shiptophone.',
127
+ '-81' => 'Length or value of Customer location',
128
+ '-82' => 'The value or length for billing state is empty.',
129
+ '-83' => 'The value or length for shipping phone is empty.',
130
+ '-84' => 'There is already an existing pending transaction in the register sharing the posted Order Number.',
131
+ '-85' => 'Airline leg info invalid Airline leg field value is invalid or empty.',
132
+ '-86' => 'Airline ticket info invalid Airline ticket info field is invalid or empty',
133
+ '-87' => 'Point of Sale check routing number must be 9 numeric digits Point of Sale check routing number is invalid or empty.',
134
+ '-88' => 'Point of Sale check account number missing or invalid Point of Sale check account number is invalid or empty.',
135
+ '-89' => 'Point of Sale check MICR missing or invalid Point of Sale check MICR invalid or empty.',
136
+ '-90' => 'Point of Sale check number missing or invalid Point of Sale check number invalid or empty.',
137
+ '-91' => 'CVV2 Invalid or empty "Make CVV a required field feature" enabled (New feature 01 April 2006) in the Merchant Account Setup interface but no CVV code was sent in the transaction data.',
138
+ '-92' => 'Approval Code Invalid Approval Code Invalid. Approval Code is a 6 digit code.',
139
+ '-93' => 'Blind Credits Request Refused "Allow Blind Credits" option must be enabled on the Skipjack Merchant Account.',
140
+ '-94' => 'Blind Credits Failed',
141
+ '-95' => 'Voice Authorization Request Refused Voice Authorization option must be enabled on the Skipjack Merchant Account.',
142
+ '-96' => 'Voice Authorizations Failed',
143
+ '-97' => 'Fraud Rejection Violates Velocity Settling.',
144
+ '-98' => 'Invalid Discount Amount',
145
+ '-99' => 'POS PIN Debit Pin Block Debit-specific',
146
+ '-100' => 'POS PIN Debit Invalid Key Serial Number Debit-specific',
147
+ '-101' => 'Invalid Authentication Data Data for Verified by Visa/MC Secure Code is invalid.',
148
+ '-102' => 'Authentication Data Not Allowed',
149
+ '-103' => 'POS Check Invalid Birth Date POS check dateofbirth variable contains a birth date in an incorrect format. Use MM/DD/YYYY format for this variable.',
150
+ '-104' => 'POS Check Invalid Identification Type POS check identificationtype variable contains a identification type value which is invalid. Use the single digit value where Social Security Number=1, Drivers License=2 for this variable.',
151
+ '-105' => 'Invalid trackdata Track Data is in invalid format.',
152
+ '-106' => 'POS Check Invalid Account Type',
153
+ '-107' => 'POS PIN Debit Invalid Sequence Number',
154
+ '-108' => 'Invalid Transaction ID',
155
+ '-109' => 'Invalid From Account Type',
156
+ '-110' => 'Pos Error Invalid To Account Type',
157
+ '-112' => 'Pos Error Invalid Auth Option',
158
+ '-113' => 'Pos Error Transaction Failed',
159
+ '-114' => 'Pos Error Invalid Incoming Eci',
160
+ '-115' => 'POS Check Invalid Check Type',
161
+ '-116' => 'POS Check Invalid Lane Number POS Check lane or cash register number is invalid. Use a valid lane or cash register number that has been configured in the Skipjack Merchant Account.',
162
+ '-117' => 'POS Check Invalid Cashier Number'
163
+ }
164
+
165
+ self.supported_countries = ['US', 'CA']
166
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover, :diners_club]
167
+ self.homepage_url = 'http://www.skipjack.com/'
168
+ self.display_name = 'SkipJack'
169
+
170
+ # Creates a new SkipJackGateway
171
+ #
172
+ # The gateway requires that a valid login and password be passed
173
+ # in the +options+ hash.
174
+ #
175
+ # ==== Options
176
+ #
177
+ # * <tt>:login</tt> -- The SkipJack Merchant Serial Number.
178
+ # * <tt>:password</tt> -- The SkipJack Developer Serial Number.
179
+ # * <tt>:test => +true+ or +false+</tt> -- Use the test or live SkipJack url.
180
+ # * <tt>:advanced => +true+ or +false+</tt> -- Set to true if you're using an advanced processor
181
+ # See the SkipJack Integration Guide for details. (default: +false+)
182
+ def initialize(options = {})
183
+ requires!(options, :login, :password)
184
+ @options = options
185
+ super
186
+ end
187
+
188
+ def test?
189
+ @options[:test] || super
190
+ end
191
+
192
+ def authorize(money, creditcard, options = {})
193
+ requires!(options, :order_id, :email)
194
+ post = {}
195
+ add_invoice(post, options)
196
+ add_creditcard(post, creditcard)
197
+ add_address(post, options)
198
+ add_customer_data(post, options)
199
+ commit(:authorization, money, post)
200
+ end
201
+
202
+ def purchase(money, creditcard, options = {})
203
+ post = {}
204
+ authorization = authorize(money, creditcard, options)
205
+ if authorization.success?
206
+ capture(money, authorization.authorization)
207
+ else
208
+ authorization
209
+ end
210
+ end
211
+
212
+ # Captures the funds from an authorized transaction.
213
+ #
214
+ # ==== Parameters
215
+ #
216
+ # * <tt>money</tt> -- The amount to be capture as an Integer in cents.
217
+ # * <tt>authorization</tt> -- The authorization returned from the previous authorize request.
218
+ # * <tt>options</tt> -- A hash of optional parameters.
219
+ #
220
+ # ==== Options
221
+ #
222
+ # * <tt>:force_settlement</tt> -- Force the settlement to occur as soon as possible. This option is not supported by other gateways. See the SkipJack API reference for more details
223
+ def capture(money, authorization, options = {})
224
+ post = { }
225
+ add_status_action(post, 'SETTLE')
226
+ add_forced_settlement(post, options)
227
+ add_transaction_id(post, authorization)
228
+ commit(:change_status, money, post)
229
+ end
230
+
231
+ def void(authorization, options = {})
232
+ post = {}
233
+ add_status_action(post, 'DELETE')
234
+ add_forced_settlement(post, options)
235
+ add_transaction_id(post, authorization)
236
+ commit(:change_status, nil, post)
237
+ end
238
+
239
+ def credit(money, identification, options = {})
240
+ post = {}
241
+ add_status_action(post, 'CREDIT')
242
+ add_forced_settlement(post, options)
243
+ add_transaction_id(post, identification)
244
+ commit(:change_status, money, post)
245
+ end
246
+
247
+ def status(order_id)
248
+ commit(:get_status, nil, :szOrderNumber => order_id)
249
+ end
250
+
251
+ private
252
+
253
+ def advanced?
254
+ @options[:advanced]
255
+ end
256
+
257
+ def add_forced_settlement(post, options)
258
+ post[:szForceSettlement] = options[:force_settlment] ? 1 : 0
259
+ end
260
+
261
+ def add_status_action(post, action)
262
+ post[:szDesiredStatus] = action
263
+ end
264
+
265
+ def commit(action, money, parameters)
266
+ response = parse( ssl_post( url_for(action), post_data(action, money, parameters) ), action )
267
+
268
+ # Pass along the original transaction id in the case an update transaction
269
+ Response.new(response[:success], message_from(response, action), response,
270
+ :test => test?,
271
+ :authorization => response[:szTransactionFileName] || parameters[:szTransactionId],
272
+ :avs_result => { :code => response[:szAVSResponseCode] },
273
+ :cvv_result => response[:szCVV2ResponseCode]
274
+ )
275
+ end
276
+
277
+ def url_for(action)
278
+ result = test? ? TEST_HOST : LIVE_HOST
279
+ result += advanced? && action == :authorization ? ADVANCED_PATH : BASIC_PATH
280
+ result += "?#{ACTIONS[action]}"
281
+ end
282
+
283
+ def add_credentials(params, action)
284
+ if action == :authorization
285
+ params[:SerialNumber] = @options[:login]
286
+ params[:DeveloperSerialNumber] = @options[:password]
287
+ else
288
+ params[:szSerialNumber] = @options[:login]
289
+ params[:szDeveloperSerialNumber] = @options[:password]
290
+ end
291
+ end
292
+
293
+ def add_amount(params, action, money)
294
+ if action == :authorization
295
+ params[:TransactionAmount] = amount(money)
296
+ else
297
+ params[:szAmount] = amount(money) if MONETARY_CHANGE_STATUSES.include?(params[:szDesiredStatus])
298
+ end
299
+ end
300
+
301
+ def parse(body, action)
302
+ case action
303
+ when :authorization
304
+ parse_authorization_response(body)
305
+ when :get_status
306
+ parse_status_response(body, [ :SerialNumber, :TransactionAmount, :TransactionStatusCode, :TransactionStatusMessage, :OrderNumber, :TransactionDateTime, :TransactionID, :ApprovalCode, :BatchNumber ])
307
+ else
308
+ parse_status_response(body, [ :SerialNumber, :TransactionAmount, :DesiredStatus, :StatusResponse, :StatusResponseMessage, :OrderNumber, :AuditID ])
309
+ end
310
+ end
311
+
312
+ def split_lines(body)
313
+ body.split(/[\r\n]+/)
314
+ end
315
+
316
+ def split_line(line)
317
+ line.split(/","/).collect { |key| key.sub(/"*([^"]*)"*/, '\1').strip; }
318
+ end
319
+
320
+ def authorize_response_map(body)
321
+ lines = split_lines(body)
322
+ keys, values = split_line(lines[0]), split_line(lines[1])
323
+ Hash[*(keys.zip(values).flatten)].symbolize_keys
324
+ end
325
+
326
+ def parse_authorization_response(body)
327
+ result = authorize_response_map(body)
328
+ result[:success] = (result[:szIsApproved] == '1')
329
+ result
330
+ end
331
+
332
+ def parse_status_response(body, response_keys)
333
+ lines = split_lines(body)
334
+
335
+ keys = [ :szSerialNumber, :szErrorCode, :szNumberRecords]
336
+ values = split_line(lines[0])[0..2]
337
+
338
+ result = Hash[*(keys.zip(values).flatten)]
339
+
340
+ result[:szErrorMessage] = ''
341
+ result[:success] = (result[:szErrorCode] == '0')
342
+
343
+ if result[:success]
344
+ lines[1..-1].each do |line|
345
+ values = split_line(line)
346
+ response_keys.each_with_index do |key, index|
347
+ result[key] = values[index]
348
+ end
349
+ end
350
+ else
351
+ result[:szErrorMessage] = lines[1]
352
+ end
353
+ result
354
+ end
355
+
356
+ def post_data(action, money, params = {})
357
+ add_credentials(params, action)
358
+ add_amount(params, action, money)
359
+ params.collect { |key, value| "#{key.to_s}=#{CGI.escape(value.to_s)}" }.join("&")
360
+ end
361
+
362
+ def add_transaction_id(post, transaction_id)
363
+ post[:szTransactionId] = transaction_id
364
+ end
365
+
366
+ def add_invoice(post, options)
367
+ post[:OrderNumber] = sanitize_order_id(options[:order_id])
368
+ post[:CustomerCode] = options[:customer].to_s.slice(0, 17)
369
+ post[:InvoiceNumber] = options[:invoice]
370
+ post[:OrderDescription] = options[:description]
371
+
372
+ if order_items = options[:items]
373
+ post[:OrderString] = order_items.collect { |item| "#{item[:sku]}~#{item[:description].tr('~','-')}~#{item[:declared_value]}~#{item[:quantity]}~#{item[:taxable]}~~~~~~~~#{item[:tax_rate]}~||"}.join
374
+ else
375
+ post[:OrderString] = '1~None~0.00~0~N~||'
376
+ end
377
+ end
378
+
379
+ def add_creditcard(post, creditcard)
380
+ post[:AccountNumber] = creditcard.number
381
+ post[:Month] = creditcard.month
382
+ post[:Year] = creditcard.year
383
+ post[:CVV2] = creditcard.verification_value if creditcard.verification_value?
384
+ post[:SJName] = creditcard.name
385
+ end
386
+
387
+ def add_customer_data(post, options)
388
+ post[:Email] = options[:email]
389
+ end
390
+
391
+ def add_address(post, options)
392
+ if address = options[:billing_address] || options[:address]
393
+ post[:StreetAddress] = address[:address1]
394
+ post[:StreetAddress2] = address[:address2]
395
+ post[:City] = address[:city]
396
+ post[:State] = address[:state]
397
+ post[:ZipCode] = address[:zip]
398
+ post[:Country] = address[:country]
399
+ post[:Phone] = address[:phone]
400
+ post[:Fax] = address[:fax]
401
+ end
402
+
403
+ if address = options[:shipping_address]
404
+ post[:ShipToName] = address[:name]
405
+ post[:ShipToStreetAddress] = address[:address1]
406
+ post[:ShipToStreetAddress2] = address[:address2]
407
+ post[:ShipToCity] = address[:city]
408
+ post[:ShipToState] = address[:state]
409
+ post[:ShipToZipCode] = address[:zip]
410
+ post[:ShipToCountry] = address[:country]
411
+ post[:ShipToPhone] = address[:phone]
412
+ post[:ShipToFax] = address[:fax]
413
+ end
414
+
415
+ # The phone number for the shipping address is required
416
+ # Use the billing address phone number if a shipping address
417
+ # phone number wasn't provided
418
+ post[:ShipToPhone] = post[:Phone] if post[:ShipToPhone].blank?
419
+ end
420
+
421
+ def message_from(response, action)
422
+ case action
423
+ when :authorization
424
+ message_from_authorization(response)
425
+ when :get_status
426
+ message_from_status(response)
427
+ else
428
+ message_from_status(response)
429
+ end
430
+ end
431
+
432
+ def message_from_authorization(response)
433
+ if response[:success]
434
+ return SUCCESS_MESSAGE
435
+ else
436
+ return CARD_CODE_MESSAGES[response[:szCVV2ResponseCode]] if CARD_CODE_ERRORS.include?(response[:szCVV2ResponseCode])
437
+ return AVS_MESSAGES[response[:szAVSResponseMessage]] if AVS_ERRORS.include?(response[:szAVSResponseCode])
438
+ return RETURN_CODE_MESSAGES[response[:szReturnCode]] if response[:szReturnCode] != '1'
439
+ return response[:szAuthorizationDeclinedMessage]
440
+ end
441
+ end
442
+
443
+ def message_from_status(response)
444
+ response[:success] ? SUCCESS_MESSAGE : response[:szErrorMessage]
445
+ end
446
+
447
+ def sanitize_order_id(value)
448
+ value.to_s.gsub(/[^\w.]/, '')
449
+ end
450
+ end
451
+ end
452
+ end
@@ -0,0 +1,254 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'check.rb')
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class SmartPs < Gateway #:nodoc:
6
+
7
+ ##
8
+ # This is the base gateway for processors who use the smartPS processing system
9
+
10
+ def initialize(options = {})
11
+ requires!(options, :login, :password)
12
+ @options = options
13
+ super
14
+ end
15
+
16
+ # Pass :store => true in the options to store the
17
+ # payment info at the gateway and get a generated
18
+ # customer_vault_id in the response.
19
+ # Pass :store => some_number_or_string to specify the
20
+ # customer_vault_id the gateway should use (make sure it's
21
+ # unique).
22
+ def authorize(money, creditcard, options = {})
23
+ post = {}
24
+ add_invoice(post, options)
25
+ add_payment_source(post, creditcard,options)
26
+ add_address(post, options[:billing_address]||options[:address])
27
+ add_address(post, options[:shipping_address],"shipping")
28
+ add_customer_data(post, options)
29
+
30
+ commit('auth', money, post)
31
+ end
32
+
33
+ def purchase(money, payment_source, options = {})
34
+ post = {}
35
+ add_invoice(post, options)
36
+ add_payment_source(post, payment_source, options)
37
+ add_address(post, options)
38
+ add_address(post, options[:shipping_address],"shipping")
39
+ add_customer_data(post, options)
40
+
41
+ commit('sale', money, post)
42
+ end
43
+
44
+ def capture(money, authorization, options = {})
45
+ post ={}
46
+ post[:transactionid] = authorization
47
+ commit('capture', money, post)
48
+ end
49
+
50
+ def void(authorization, options = {})
51
+ post ={}
52
+ post[:transactionid] = authorization
53
+ commit('void', nil, post)
54
+ end
55
+
56
+ def credit(money, payment_source, options = {})
57
+ post = {}
58
+ add_invoice(post, options)
59
+ add_payment_source(post, payment_source, options)
60
+ add_address(post, options)
61
+ add_customer_data(post, options)
62
+ add_sku(post,options)
63
+
64
+ commit('credit', money, post)
65
+ end
66
+
67
+ def refund(auth, options = {})
68
+ post = {}
69
+ add_transaction(post, auth)
70
+ commit('refund', options.delete(:amount), post)
71
+ end
72
+
73
+
74
+ # Update the values (such as CC expiration) stored at
75
+ # the gateway. The CC number must be supplied in the
76
+ # CreditCard object.
77
+ def update(vault_id, creditcard, options = {})
78
+ post = {}
79
+ post[:customer_vault] = "update_customer"
80
+ add_customer_vault_id(post, vault_id)
81
+ add_creditcard(post, creditcard, options)
82
+ add_address(post, options)
83
+ add_customer_data(post, options)
84
+
85
+ commit(nil, nil, post)
86
+ end
87
+
88
+ # Amend an existing transaction
89
+ def amend(auth, options = {})
90
+ post = {}
91
+ add_invoice(post, options)
92
+ add_transaction(post, auth)
93
+ commit('update', nil, post)
94
+ end
95
+
96
+
97
+ def delete(vault_id)
98
+ post = {}
99
+ post[:customer_vault] = "delete_customer"
100
+ add_customer_vault_id(post, vault_id)
101
+ commit(nil, nil, post)
102
+ end
103
+
104
+ # To match the other stored-value gateways, like TrustCommerce,
105
+ # store and unstore need to be defined
106
+ def store(payment_source, options = {})
107
+ post = {}
108
+ billing_id = options.delete(:billing_id).to_s || true
109
+ add_payment_source(post, payment_source, :store => billing_id)
110
+ add_address(post, options[:billing_address] || options[:address])
111
+ add_customer_data(post, options)
112
+ commit(nil, nil, post)
113
+ end
114
+
115
+ alias_method :unstore, :delete
116
+
117
+ private
118
+ def add_customer_data(post, options)
119
+ if options.has_key? :email
120
+ post[:email] = options[:email]
121
+ end
122
+
123
+ if options.has_key? :ip
124
+ post[:ipaddress] = options[:ip]
125
+ end
126
+ end
127
+
128
+ def add_address(post, address,prefix="")
129
+ prefix +="_" unless prefix.blank?
130
+ unless address.blank? or address.values.blank?
131
+ post[prefix+"address1"] = address[:address1].to_s
132
+ post[prefix+"address2"] = address[:address2].to_s unless address[:address2].blank?
133
+ post[prefix+"company"] = address[:company].to_s
134
+ post[prefix+"phone"] = address[:phone].to_s
135
+ post[prefix+"zip"] = address[:zip].to_s
136
+ post[prefix+"city"] = address[:city].to_s
137
+ post[prefix+"country"] = address[:country].to_s
138
+ post[prefix+"state"] = address[:state].blank? ? 'n/a' : address[:state]
139
+ end
140
+ end
141
+
142
+ def add_invoice(post, options)
143
+ post[:orderid] = options[:order_id].to_s.gsub(/[^\w.]/, '')
144
+ end
145
+
146
+ def add_payment_source(params, source, options={})
147
+ case determine_funding_source(source)
148
+ when :vault then add_customer_vault_id(params, source)
149
+ when :credit_card then add_creditcard(params, source, options)
150
+ when :check then add_check(params, source, options)
151
+ end
152
+ end
153
+
154
+ def add_customer_vault_id(params, vault_id)
155
+ params[:customer_vault_id] = vault_id
156
+ end
157
+
158
+ def add_creditcard(post, creditcard, options)
159
+ if options[:store]
160
+ post[:customer_vault] = "add_customer"
161
+ post[:customer_vault_id] = options[:store] unless options[:store] == true
162
+ end
163
+ post[:ccnumber] = creditcard.number
164
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
165
+ post[:ccexp] = expdate(creditcard)
166
+ post[:firstname] = creditcard.first_name
167
+ post[:lastname] = creditcard.last_name
168
+ end
169
+
170
+ def add_check(post, check, options)
171
+ if options[:store]
172
+ post[:customer_vault] = "add_customer"
173
+ post[:customer_vault_id] = options[:store] unless options[:store] == true
174
+ end
175
+
176
+ post[:payment] = 'check' # Set transaction to ACH
177
+ post[:checkname] = check.name # The name on the customer's Checking Account
178
+ post[:checkaba] = check.routing_number # The customer's bank routing number
179
+ post[:checkaccount] = check.account_number # The customer's account number
180
+ post[:account_holder_type] = check.account_holder_type # The customer's type of ACH account
181
+ post[:account_type] = check.account_type # The customer's type of ACH account
182
+ end
183
+
184
+ def add_sku(post,options)
185
+ post["product_sku_#"] = options[:sku] || options["product_sku_#"]
186
+ end
187
+
188
+ def add_transaction(post, auth)
189
+ post[:transactionid] = auth
190
+ end
191
+
192
+ def parse(body)
193
+ results = {}
194
+ body.split(/&/).each do |pair|
195
+ key,val = pair.split(/=/)
196
+ results[key] = val
197
+ end
198
+
199
+ results
200
+ end
201
+
202
+ def commit(action, money, parameters)
203
+ parameters[:amount] = amount(money) if money
204
+ response = parse( ssl_post(api_url, post_data(action,parameters)) )
205
+ Response.new(response["response"] == "1", message_from(response), response,
206
+ :authorization => response["transactionid"],
207
+ :test => test?,
208
+ :cvv_result => response["cvvresponse"],
209
+ :avs_result => { :code => response["avsresponse"] }
210
+ )
211
+
212
+ end
213
+
214
+ def expdate(creditcard)
215
+ year = sprintf("%.04i", creditcard.year.to_i)
216
+ month = sprintf("%.02i", creditcard.month.to_i)
217
+
218
+ "#{month}#{year[-2..-1]}"
219
+ end
220
+
221
+
222
+ def message_from(response)
223
+ case response["responsetext"]
224
+ when "SUCCESS", "Approved", nil # This is dubious, but responses from UPDATE are nil.
225
+ "This transaction has been approved"
226
+ when "DECLINE"
227
+ "This transaction has been declined"
228
+ else
229
+ response["responsetext"]
230
+ end
231
+ end
232
+
233
+ def post_data(action, parameters = {})
234
+ post = {}
235
+ post[:username] = @options[:login]
236
+ post[:password] = @options[:password]
237
+ post[:type] = action if action
238
+
239
+ request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
240
+ request
241
+ end
242
+
243
+ def determine_funding_source(source)
244
+ case
245
+ when source.is_a?(String) then :vault
246
+ when CreditCard.card_companies.keys.include?(card_brand(source)) then :credit_card
247
+ when card_brand(source) == 'check' then :check
248
+ else raise ArgumentError, "Unsupported funding source provided"
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+