tomriley-active_merchant 1.4.2.3

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 (278) hide show
  1. data/CHANGELOG +442 -0
  2. data/CONTRIBUTERS +102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +134 -0
  5. data/Rakefile +153 -0
  6. data/active_merchant.gemspec +15 -0
  7. data/gem-public_cert.pem +20 -0
  8. data/init.rb +4 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +57 -0
  11. data/lib/active_merchant/billing/check.rb +68 -0
  12. data/lib/active_merchant/billing/credit_card.rb +159 -0
  13. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  14. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  15. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  16. data/lib/active_merchant/billing/expiry_date.rb +28 -0
  17. data/lib/active_merchant/billing/gateway.rb +158 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +646 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +702 -0
  20. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +233 -0
  21. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -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/eway.rb +272 -0
  30. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  31. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  32. data/lib/active_merchant/billing/gateways/linkpoint.rb +396 -0
  33. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  34. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  35. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +214 -0
  36. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  37. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  38. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  39. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  40. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  41. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  42. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  43. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  44. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  45. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  46. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  47. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  48. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  49. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +325 -0
  50. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  51. data/lib/active_merchant/billing/gateways/paypal.rb +108 -0
  52. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  53. data/lib/active_merchant/billing/gateways/paypal_express.rb +130 -0
  54. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  55. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  56. data/lib/active_merchant/billing/gateways/protx.rb +349 -0
  57. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/psl_card.rb +306 -0
  59. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  60. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  61. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  62. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +110 -0
  63. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  64. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  65. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  66. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  67. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  68. data/lib/active_merchant/billing/gateways/skip_jack.rb +442 -0
  69. data/lib/active_merchant/billing/gateways/smart_ps.rb +254 -0
  70. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  71. data/lib/active_merchant/billing/gateways/transax.rb +26 -0
  72. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  73. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  74. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  75. data/lib/active_merchant/billing/gateways/viaklix.rb +165 -0
  76. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  77. data/lib/active_merchant/billing/gateways.rb +3 -0
  78. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  79. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  80. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  81. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  82. data/lib/active_merchant/billing/integrations/bogus.rb +22 -0
  83. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
  84. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
  85. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  86. data/lib/active_merchant/billing/integrations/chronopay.rb +22 -0
  87. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  88. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  89. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
  90. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  91. data/lib/active_merchant/billing/integrations/gestpay.rb +26 -0
  92. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  93. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  94. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  95. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  96. data/lib/active_merchant/billing/integrations/hi_trust.rb +26 -0
  97. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  98. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  99. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  100. data/lib/active_merchant/billing/integrations/nochex.rb +87 -0
  101. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  102. data/lib/active_merchant/billing/integrations/paypal/helper.rb +118 -0
  103. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  104. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  105. data/lib/active_merchant/billing/integrations/paypal.rb +40 -0
  106. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  107. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  108. data/lib/active_merchant/billing/integrations/quickpay.rb +18 -0
  109. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  110. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  111. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  112. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  113. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  114. data/lib/active_merchant/billing/integrations.rb +22 -0
  115. data/lib/active_merchant/billing/response.rb +32 -0
  116. data/lib/active_merchant/lib/connection.rb +170 -0
  117. data/lib/active_merchant/lib/country.rb +319 -0
  118. data/lib/active_merchant/lib/error.rb +4 -0
  119. data/lib/active_merchant/lib/post_data.rb +22 -0
  120. data/lib/active_merchant/lib/posts_data.rb +47 -0
  121. data/lib/active_merchant/lib/requires_parameters.rb +16 -0
  122. data/lib/active_merchant/lib/utils.rb +18 -0
  123. data/lib/active_merchant/lib/validateable.rb +76 -0
  124. data/lib/active_merchant.rb +60 -0
  125. data/lib/certs/cacert.pem +7815 -0
  126. data/lib/support/gateway_support.rb +58 -0
  127. data/script/destroy +14 -0
  128. data/script/generate +14 -0
  129. data/test/fixtures.yml +330 -0
  130. data/test/remote/gateways/remote_authorize_net_cim_test.rb +459 -0
  131. data/test/remote/gateways/remote_authorize_net_test.rb +145 -0
  132. data/test/remote/gateways/remote_beanstream_interac_test.rb +53 -0
  133. data/test/remote/gateways/remote_beanstream_test.rb +150 -0
  134. data/test/remote/gateways/remote_braintree_test.rb +154 -0
  135. data/test/remote/gateways/remote_card_stream_test.rb +148 -0
  136. data/test/remote/gateways/remote_cyber_source_test.rb +144 -0
  137. data/test/remote/gateways/remote_data_cash_test.rb +357 -0
  138. data/test/remote/gateways/remote_efsnet_test.rb +81 -0
  139. data/test/remote/gateways/remote_eway_test.rb +74 -0
  140. data/test/remote/gateways/remote_exact_test.rb +60 -0
  141. data/test/remote/gateways/remote_instapay_test.rb +61 -0
  142. data/test/remote/gateways/remote_linkpoint_test.rb +112 -0
  143. data/test/remote/gateways/remote_merchant_e_solutions_test.rb +173 -0
  144. data/test/remote/gateways/remote_modern_payments_cim_test.rb +58 -0
  145. data/test/remote/gateways/remote_modern_payments_test.rb +43 -0
  146. data/test/remote/gateways/remote_moneris_test.rb +82 -0
  147. data/test/remote/gateways/remote_net_registry_test.rb +85 -0
  148. data/test/remote/gateways/remote_netbilling_test.rb +70 -0
  149. data/test/remote/gateways/remote_pay_junction_test.rb +143 -0
  150. data/test/remote/gateways/remote_pay_secure_test.rb +39 -0
  151. data/test/remote/gateways/remote_payflow_express_test.rb +50 -0
  152. data/test/remote/gateways/remote_payflow_test.rb +237 -0
  153. data/test/remote/gateways/remote_payflow_uk_test.rb +173 -0
  154. data/test/remote/gateways/remote_payment_express_test.rb +136 -0
  155. data/test/remote/gateways/remote_paypal_express_test.rb +49 -0
  156. data/test/remote/gateways/remote_paypal_test.rb +167 -0
  157. data/test/remote/gateways/remote_plugnpay_test.rb +72 -0
  158. data/test/remote/gateways/remote_protx_test.rb +219 -0
  159. data/test/remote/gateways/remote_psigate_test.rb +50 -0
  160. data/test/remote/gateways/remote_psl_card_test.rb +125 -0
  161. data/test/remote/gateways/remote_quickpay_test.rb +190 -0
  162. data/test/remote/gateways/remote_realex_test.rb +224 -0
  163. data/test/remote/gateways/remote_sage_bankcard_test.rb +109 -0
  164. data/test/remote/gateways/remote_sage_test.rb +87 -0
  165. data/test/remote/gateways/remote_sage_virtual_check_test.rb +62 -0
  166. data/test/remote/gateways/remote_secure_pay_au_test.rb +40 -0
  167. data/test/remote/gateways/remote_secure_pay_tech_test.rb +37 -0
  168. data/test/remote/gateways/remote_secure_pay_test.rb +28 -0
  169. data/test/remote/gateways/remote_skipjack_test.rb +105 -0
  170. data/test/remote/gateways/remote_trans_first_test.rb +34 -0
  171. data/test/remote/gateways/remote_transax_test.rb +112 -0
  172. data/test/remote/gateways/remote_trust_commerce_test.rb +152 -0
  173. data/test/remote/gateways/remote_usa_epay_test.rb +46 -0
  174. data/test/remote/gateways/remote_verifi_test.rb +107 -0
  175. data/test/remote/gateways/remote_viaklix_test.rb +43 -0
  176. data/test/remote/gateways/remote_wirecard_test.rb +111 -0
  177. data/test/remote/integrations/remote_gestpay_integration_test.rb +37 -0
  178. data/test/remote/integrations/remote_paypal_integration_test.rb +26 -0
  179. data/test/test_helper.rb +182 -0
  180. data/test/unit/avs_result_test.rb +59 -0
  181. data/test/unit/base_test.rb +55 -0
  182. data/test/unit/check_test.rb +88 -0
  183. data/test/unit/connection_test.rb +129 -0
  184. data/test/unit/country_code_test.rb +33 -0
  185. data/test/unit/country_test.rb +64 -0
  186. data/test/unit/credit_card_formatting_test.rb +19 -0
  187. data/test/unit/credit_card_methods_test.rb +170 -0
  188. data/test/unit/credit_card_test.rb +318 -0
  189. data/test/unit/cvv_result_test.rb +33 -0
  190. data/test/unit/expiry_date_test.rb +21 -0
  191. data/test/unit/gateways/authorize_net_cim_test.rb +638 -0
  192. data/test/unit/gateways/authorize_net_test.rb +290 -0
  193. data/test/unit/gateways/beanstream_interac_test.rb +51 -0
  194. data/test/unit/gateways/beanstream_test.rb +108 -0
  195. data/test/unit/gateways/bogus_test.rb +46 -0
  196. data/test/unit/gateways/braintree_test.rb +126 -0
  197. data/test/unit/gateways/card_stream_test.rb +90 -0
  198. data/test/unit/gateways/cyber_source_test.rb +188 -0
  199. data/test/unit/gateways/data_cash_test.rb +133 -0
  200. data/test/unit/gateways/efsnet_test.rb +123 -0
  201. data/test/unit/gateways/eway_test.rb +118 -0
  202. data/test/unit/gateways/exact_test.rb +156 -0
  203. data/test/unit/gateways/gateway_test.rb +48 -0
  204. data/test/unit/gateways/instapay_test.rb +102 -0
  205. data/test/unit/gateways/linkpoint_test.rb +167 -0
  206. data/test/unit/gateways/merchant_e_solutions_test.rb +169 -0
  207. data/test/unit/gateways/modern_payments_cim_test.rb +171 -0
  208. data/test/unit/gateways/moneris_test.rb +158 -0
  209. data/test/unit/gateways/net_registry_test.rb +416 -0
  210. data/test/unit/gateways/netbilling_test.rb +54 -0
  211. data/test/unit/gateways/pay_junction_test.rb +123 -0
  212. data/test/unit/gateways/pay_secure_test.rb +71 -0
  213. data/test/unit/gateways/payflow_express_test.rb +173 -0
  214. data/test/unit/gateways/payflow_express_uk_test.rb +86 -0
  215. data/test/unit/gateways/payflow_test.rb +305 -0
  216. data/test/unit/gateways/payflow_uk_test.rb +30 -0
  217. data/test/unit/gateways/payment_express_test.rb +195 -0
  218. data/test/unit/gateways/paypal_express_test.rb +382 -0
  219. data/test/unit/gateways/paypal_test.rb +520 -0
  220. data/test/unit/gateways/plugnpay_test.rb +86 -0
  221. data/test/unit/gateways/protx_test.rb +139 -0
  222. data/test/unit/gateways/psigate_test.rb +169 -0
  223. data/test/unit/gateways/psl_card_test.rb +64 -0
  224. data/test/unit/gateways/quickpay_test.rb +112 -0
  225. data/test/unit/gateways/realex_test.rb +151 -0
  226. data/test/unit/gateways/sage_bankcard_test.rb +162 -0
  227. data/test/unit/gateways/sage_virtual_check_test.rb +71 -0
  228. data/test/unit/gateways/secure_pay_au_test.rb +207 -0
  229. data/test/unit/gateways/secure_pay_tech_test.rb +44 -0
  230. data/test/unit/gateways/secure_pay_test.rb +87 -0
  231. data/test/unit/gateways/skip_jack_test.rb +133 -0
  232. data/test/unit/gateways/trans_first_test.rb +112 -0
  233. data/test/unit/gateways/trust_commerce_test.rb +90 -0
  234. data/test/unit/gateways/usa_epay_test.rb +128 -0
  235. data/test/unit/gateways/verifi_test.rb +96 -0
  236. data/test/unit/gateways/viaklix_test.rb +78 -0
  237. data/test/unit/gateways/wirecard_test.rb +250 -0
  238. data/test/unit/generators/test_gateway_generator.rb +46 -0
  239. data/test/unit/generators/test_generator_helper.rb +20 -0
  240. data/test/unit/generators/test_integration_generator.rb +53 -0
  241. data/test/unit/integrations/action_view_helper_test.rb +50 -0
  242. data/test/unit/integrations/bogus_module_test.rb +20 -0
  243. data/test/unit/integrations/chronopay_module_test.rb +13 -0
  244. data/test/unit/integrations/gestpay_module_test.rb +14 -0
  245. data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
  246. data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
  247. data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
  248. data/test/unit/integrations/helpers/hi_trust_helper_test.rb +16 -0
  249. data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
  250. data/test/unit/integrations/helpers/paypal_helper_test.rb +162 -0
  251. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  252. data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
  253. data/test/unit/integrations/hi_trust_module_test.rb +13 -0
  254. data/test/unit/integrations/nochex_module_test.rb +13 -0
  255. data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
  256. data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
  257. data/test/unit/integrations/notifications/hi_trust_notification_test.rb +59 -0
  258. data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
  259. data/test/unit/integrations/notifications/notification_test.rb +54 -0
  260. data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
  261. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  262. data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
  263. data/test/unit/integrations/paypal_module_test.rb +28 -0
  264. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  265. data/test/unit/integrations/returns/chronopay_return_test.rb +11 -0
  266. data/test/unit/integrations/returns/gestpay_return_test.rb +10 -0
  267. data/test/unit/integrations/returns/hi_trust_return_test.rb +24 -0
  268. data/test/unit/integrations/returns/nochex_return_test.rb +10 -0
  269. data/test/unit/integrations/returns/paypal_return_test.rb +10 -0
  270. data/test/unit/integrations/returns/return_test.rb +11 -0
  271. data/test/unit/integrations/returns/two_checkout_return_test.rb +24 -0
  272. data/test/unit/integrations/two_checkout_module_test.rb +13 -0
  273. data/test/unit/post_data_test.rb +55 -0
  274. data/test/unit/posts_data_test.rb +48 -0
  275. data/test/unit/response_test.rb +28 -0
  276. data/test/unit/utils_test.rb +7 -0
  277. data/test/unit/validateable_test.rb +60 -0
  278. metadata +364 -0
@@ -0,0 +1,646 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # For more information on the Authorize.Net Gateway please visit their {Integration Center}[http://developer.authorize.net/]
4
+ #
5
+ # The login and password are not the username and password you use to
6
+ # login to the Authorize.Net Merchant Interface. Instead, you will
7
+ # use the API Login ID as the login and Transaction Key as the
8
+ # password.
9
+ #
10
+ # ==== How to Get Your API Login ID and Transaction Key
11
+ #
12
+ # 1. Log into the Merchant Interface
13
+ # 2. Select Settings from the Main Menu
14
+ # 3. Click on API Login ID and Transaction Key in the Security section
15
+ # 4. Type in the answer to the secret question configured on setup
16
+ # 5. Click Submit
17
+ #
18
+ # ==== Automated Recurring Billing (ARB)
19
+ #
20
+ # Automated Recurring Billing (ARB) is an optional service for submitting and managing recurring, or subscription-based, transactions.
21
+ #
22
+ # To use recurring, update_recurring, and cancel_recurring ARB must be enabled for your account.
23
+ #
24
+ # Information about ARB is available on the {Authorize.Net website}[http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/].
25
+ # Information about the ARB API is available at the {Authorize.Net Integration Center}[http://developer.authorize.net/]
26
+ class AuthorizeNetGateway < Gateway
27
+ API_VERSION = '3.1'
28
+
29
+ class_inheritable_accessor :test_url, :live_url, :arb_test_url, :arb_live_url
30
+
31
+ self.test_url = "https://test.authorize.net/gateway/transact.dll"
32
+ self.live_url = "https://secure.authorize.net/gateway/transact.dll"
33
+
34
+ self.arb_test_url = 'https://apitest.authorize.net/xml/v1/request.api'
35
+ self.arb_live_url = 'https://api.authorize.net/xml/v1/request.api'
36
+
37
+ class_inheritable_accessor :duplicate_window
38
+
39
+ APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
40
+
41
+ RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
42
+ AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
43
+
44
+ self.supported_countries = ['US']
45
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
46
+ self.homepage_url = 'http://www.authorize.net/'
47
+ self.display_name = 'Authorize.Net'
48
+
49
+ CARD_CODE_ERRORS = %w( N S )
50
+ AVS_ERRORS = %w( A E N R W Z )
51
+
52
+ AUTHORIZE_NET_ARB_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'
53
+
54
+ RECURRING_ACTIONS = {
55
+ :create => 'ARBCreateSubscription',
56
+ :update => 'ARBUpdateSubscription',
57
+ :cancel => 'ARBCancelSubscription'
58
+ }
59
+
60
+ # Creates a new AuthorizeNetGateway
61
+ #
62
+ # The gateway requires that a valid login and password be passed
63
+ # in the +options+ hash.
64
+ #
65
+ # ==== Options
66
+ #
67
+ # * <tt>:login</tt> -- The Authorize.Net API Login ID (REQUIRED)
68
+ # * <tt>:password</tt> -- The Authorize.Net Transaction Key. (REQUIRED)
69
+ # * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
70
+ # Otherwise, perform transactions against the production server.
71
+ def initialize(options = {})
72
+ requires!(options, :login, :password)
73
+ @options = options
74
+ super
75
+ end
76
+
77
+ # Performs an authorization, which reserves the funds on the customer's credit card, but does not
78
+ # charge the card.
79
+ #
80
+ # ==== Parameters
81
+ #
82
+ # * <tt>money</tt> -- The amount to be authorized. Either an Integer value in cents or a Money object.
83
+ # * <tt>creditcard</tt> -- The CreditCard details for the transaction.
84
+ # * <tt>options</tt> -- A hash of optional parameters.
85
+ def authorize(money, creditcard, options = {})
86
+ post = {}
87
+ add_invoice(post, options)
88
+ add_creditcard(post, creditcard)
89
+ add_address(post, options)
90
+ add_customer_data(post, options)
91
+ add_duplicate_window(post)
92
+
93
+ commit('AUTH_ONLY', money, post)
94
+ end
95
+
96
+ # Perform a purchase, which is essentially an authorization and capture in a single operation.
97
+ #
98
+ # ==== Parameters
99
+ #
100
+ # * <tt>money</tt> -- The amount to be purchased. Either an Integer value in cents or a Money object.
101
+ # * <tt>creditcard</tt> -- The CreditCard details for the transaction.
102
+ # * <tt>options</tt> -- A hash of optional parameters.
103
+ def purchase(money, creditcard, options = {})
104
+ post = {}
105
+ add_invoice(post, options)
106
+ add_creditcard(post, creditcard)
107
+ add_address(post, options)
108
+ add_customer_data(post, options)
109
+ add_duplicate_window(post)
110
+
111
+ commit('AUTH_CAPTURE', money, post)
112
+ end
113
+
114
+ # Captures the funds from an authorized transaction.
115
+ #
116
+ # ==== Parameters
117
+ #
118
+ # * <tt>money</tt> -- The amount to be captured. Either an Integer value in cents or a Money object.
119
+ # * <tt>authorization</tt> -- The authorization returned from the previous authorize request.
120
+ def capture(money, authorization, options = {})
121
+ post = {:trans_id => authorization}
122
+ add_customer_data(post, options)
123
+ commit('PRIOR_AUTH_CAPTURE', money, post)
124
+ end
125
+
126
+ # Void a previous transaction
127
+ #
128
+ # ==== Parameters
129
+ #
130
+ # * <tt>authorization</tt> - The authorization returned from the previous authorize request.
131
+ def void(authorization, options = {})
132
+ post = {:trans_id => authorization}
133
+ commit('VOID', nil, post)
134
+ end
135
+
136
+ # Credit an account.
137
+ #
138
+ # This transaction is also referred to as a Refund and indicates to the gateway that
139
+ # money should flow from the merchant to the customer.
140
+ #
141
+ # ==== Parameters
142
+ #
143
+ # * <tt>money</tt> -- The amount to be credited to the customer. Either an Integer value in cents or a Money object.
144
+ # * <tt>identification</tt> -- The ID of the original transaction against which the credit is being issued.
145
+ # * <tt>options</tt> -- A hash of parameters.
146
+ #
147
+ # ==== Options
148
+ #
149
+ # * <tt>:card_number</tt> -- The credit card number the credit is being issued to. (REQUIRED)
150
+ def credit(money, identification, options = {})
151
+ requires!(options, :card_number)
152
+
153
+ post = { :trans_id => identification,
154
+ :card_num => options[:card_number]
155
+ }
156
+ add_invoice(post, options)
157
+
158
+ commit('CREDIT', money, post)
159
+ end
160
+
161
+ # Create a recurring payment.
162
+ #
163
+ # This transaction creates a new Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled.
164
+ #
165
+ # ==== Parameters
166
+ #
167
+ # * <tt>money</tt> -- The amount to be charged to the customer at each interval. Either an Integer value in cents or
168
+ # a Money object.
169
+ # * <tt>creditcard</tt> -- The CreditCard details for the transaction.
170
+ # * <tt>options</tt> -- A hash of parameters.
171
+ #
172
+ # ==== Options
173
+ #
174
+ # * <tt>:interval</tt> -- A hash containing information about the interval of time between payments. Must
175
+ # contain the keys <tt>:length</tt> and <tt>:unit</tt>. <tt>:unit</tt> can be either <tt>:months</tt> or <tt>:days</tt>.
176
+ # If <tt>:unit</tt> is <tt>:months</tt> then <tt>:interval</tt> must be an integer between 1 and 12 inclusive.
177
+ # If <tt>:unit</tt> is <tt>:days</tt> then <tt>:interval</tt> must be an integer between 7 and 365 inclusive.
178
+ # For example, to charge the customer once every three months the hash would be
179
+ # +{ :unit => :months, :interval => 3 }+ (REQUIRED)
180
+ # * <tt>:duration</tt> -- A hash containing keys for the <tt>:start_date</tt> the subscription begins (also the date the
181
+ # initial billing occurs) and the total number of billing <tt>:occurences</tt> or payments for the subscription. (REQUIRED)
182
+ def recurring(money, creditcard, options={})
183
+ requires!(options, :interval, :duration, :billing_address)
184
+ requires!(options[:interval], :length, [:unit, :days, :months])
185
+ requires!(options[:duration], :start_date, :occurrences)
186
+ requires!(options[:billing_address], :first_name, :last_name)
187
+
188
+ options[:credit_card] = creditcard
189
+ options[:amount] = money
190
+
191
+ request = build_recurring_request(:create, options)
192
+ recurring_commit(:create, request)
193
+ end
194
+
195
+ # Update a recurring payment's details.
196
+ #
197
+ # This transaction updates an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled
198
+ # and the subscription must have already been created previously by calling +recurring()+. The ability to change certain
199
+ # details about a recurring payment is dependent on transaction history and cannot be determined until after calling
200
+ # +update_recurring()+. See the ARB XML Guide for such conditions.
201
+ #
202
+ # ==== Parameters
203
+ #
204
+ # * <tt>options</tt> -- A hash of parameters.
205
+ #
206
+ # ==== Options
207
+ #
208
+ # * <tt>:subscription_id</tt> -- A string containing the <tt>:subscription_id</tt> of the recurring payment already in place
209
+ # for a given credit card. (REQUIRED)
210
+ def update_recurring(options={})
211
+ requires!(options, :subscription_id)
212
+ request = build_recurring_request(:update, options)
213
+ recurring_commit(:update, request)
214
+ end
215
+
216
+ # Cancel a recurring payment.
217
+ #
218
+ # This transaction cancels an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled
219
+ # and the subscription must have already been created previously by calling recurring()
220
+ #
221
+ # ==== Parameters
222
+ #
223
+ # * <tt>subscription_id</tt> -- A string containing the +subscription_id+ of the recurring payment already in place
224
+ # for a given credit card. (REQUIRED)
225
+ def cancel_recurring(subscription_id)
226
+ request = build_recurring_request(:cancel, :subscription_id => subscription_id)
227
+ recurring_commit(:cancel, request)
228
+ end
229
+
230
+ private
231
+
232
+ def commit(action, money, parameters)
233
+ parameters[:amount] = amount(money) unless action == 'VOID'
234
+
235
+ # Only activate the test_request when the :test option is passed in
236
+ parameters[:test_request] = @options[:test] ? 'TRUE' : 'FALSE'
237
+
238
+ url = test? ? self.test_url : self.live_url
239
+ data = ssl_post url, post_data(action, parameters)
240
+
241
+ response = parse(data)
242
+
243
+ message = message_from(response)
244
+
245
+ # Return the response. The authorization can be taken out of the transaction_id
246
+ # Test Mode on/off is something we have to parse from the response text.
247
+ # It usually looks something like this
248
+ #
249
+ # (TESTMODE) Successful Sale
250
+ test_mode = test? || message =~ /TESTMODE/
251
+
252
+ Response.new(success?(response), message, response,
253
+ :test => test_mode,
254
+ :authorization => response[:transaction_id],
255
+ :fraud_review => fraud_review?(response),
256
+ :avs_result => { :code => response[:avs_result_code] },
257
+ :cvv_result => response[:card_code]
258
+ )
259
+ end
260
+
261
+ def success?(response)
262
+ response[:response_code] == APPROVED
263
+ end
264
+
265
+ def fraud_review?(response)
266
+ response[:response_code] == FRAUD_REVIEW
267
+ end
268
+
269
+ def parse(body)
270
+ fields = split(body)
271
+
272
+ results = {
273
+ :response_code => fields[RESPONSE_CODE].to_i,
274
+ :response_reason_code => fields[RESPONSE_REASON_CODE],
275
+ :response_reason_text => fields[RESPONSE_REASON_TEXT],
276
+ :avs_result_code => fields[AVS_RESULT_CODE],
277
+ :transaction_id => fields[TRANSACTION_ID],
278
+ :card_code => fields[CARD_CODE_RESPONSE_CODE]
279
+ }
280
+ results
281
+ end
282
+
283
+ def post_data(action, parameters = {})
284
+ post = {}
285
+
286
+ post[:version] = API_VERSION
287
+ post[:login] = @options[:login]
288
+ post[:tran_key] = @options[:password]
289
+ post[:relay_response] = "FALSE"
290
+ post[:type] = action
291
+ post[:delim_data] = "TRUE"
292
+ post[:delim_char] = ","
293
+ post[:encap_char] = "$"
294
+
295
+ request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
296
+ request
297
+ end
298
+
299
+ def add_invoice(post, options)
300
+ post[:invoice_num] = options[:order_id]
301
+ post[:description] = options[:description]
302
+ end
303
+
304
+ def add_creditcard(post, creditcard)
305
+ post[:card_num] = creditcard.number
306
+ post[:card_code] = creditcard.verification_value if creditcard.verification_value?
307
+ post[:exp_date] = expdate(creditcard)
308
+ post[:first_name] = creditcard.first_name
309
+ post[:last_name] = creditcard.last_name
310
+ end
311
+
312
+ def add_customer_data(post, options)
313
+ if options.has_key? :email
314
+ post[:email] = options[:email]
315
+ post[:email_customer] = false
316
+ end
317
+
318
+ if options.has_key? :customer
319
+ post[:cust_id] = options[:customer]
320
+ end
321
+
322
+ if options.has_key? :ip
323
+ post[:customer_ip] = options[:ip]
324
+ end
325
+ end
326
+
327
+ # x_duplicate_window won't be sent by default, because sending it changes the response.
328
+ # "If this field is present in the request with or without a value, an enhanced duplicate transaction response will be sent."
329
+ # (as of 2008-12-30) http://www.authorize.net/support/AIM_guide_SCC.pdf
330
+ def add_duplicate_window(post)
331
+ unless duplicate_window.nil?
332
+ post[:duplicate_window] = duplicate_window
333
+ end
334
+ end
335
+
336
+ def add_address(post, options)
337
+
338
+ if address = options[:billing_address] || options[:address]
339
+ post[:address] = address[:address1].to_s
340
+ post[:company] = address[:company].to_s
341
+ post[:phone] = address[:phone].to_s
342
+ post[:zip] = address[:zip].to_s
343
+ post[:city] = address[:city].to_s
344
+ post[:country] = address[:country].to_s
345
+ post[:state] = address[:state].blank? ? 'n/a' : address[:state]
346
+ end
347
+ end
348
+
349
+ # Make a ruby type out of the response string
350
+ def normalize(field)
351
+ case field
352
+ when "true" then true
353
+ when "false" then false
354
+ when "" then nil
355
+ when "null" then nil
356
+ else field
357
+ end
358
+ end
359
+
360
+ def message_from(results)
361
+ if results[:response_code] == DECLINED
362
+ return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
363
+ return AVSResult.messages[ results[:avs_result_code] ] if AVS_ERRORS.include?(results[:avs_result_code])
364
+ end
365
+
366
+ return results[:response_reason_text].nil? ? '' : results[:response_reason_text][0..-2]
367
+ end
368
+
369
+ def expdate(creditcard)
370
+ year = sprintf("%.4i", creditcard.year)
371
+ month = sprintf("%.2i", creditcard.month)
372
+
373
+ "#{month}#{year[-2..-1]}"
374
+ end
375
+
376
+ def split(response)
377
+ response[1..-2].split(/\$,\$/)
378
+ end
379
+
380
+ # ARB
381
+
382
+ # Builds recurring billing request
383
+ def build_recurring_request(action, options = {})
384
+ unless RECURRING_ACTIONS.include?(action)
385
+ raise StandardError, "Invalid Automated Recurring Billing Action: #{action}"
386
+ end
387
+
388
+ xml = Builder::XmlMarkup.new(:indent => 2)
389
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
390
+ xml.tag!("#{RECURRING_ACTIONS[action]}Request", :xmlns => AUTHORIZE_NET_ARB_NAMESPACE) do
391
+ add_arb_merchant_authentication(xml)
392
+ # Merchant-assigned reference ID for the request
393
+ xml.tag!('refId', options[:ref_id]) if options[:ref_id]
394
+ send("build_arb_#{action}_subscription_request", xml, options)
395
+ end
396
+ end
397
+
398
+ # Contains the merchant’s payment gateway account authentication information
399
+ def add_arb_merchant_authentication(xml)
400
+ xml.tag!('merchantAuthentication') do
401
+ xml.tag!('name', @options[:login])
402
+ xml.tag!('transactionKey', @options[:password])
403
+ end
404
+ end
405
+
406
+ # Builds body for ARBCreateSubscriptionRequest
407
+ def build_arb_create_subscription_request(xml, options)
408
+ # Subscription
409
+ add_arb_subscription(xml, options)
410
+
411
+ xml.target!
412
+ end
413
+
414
+ # Builds body for ARBUpdateSubscriptionRequest
415
+ def build_arb_update_subscription_request(xml, options)
416
+ xml.tag!('subscriptionId', options[:subscription_id])
417
+ # Adds Subscription
418
+ add_arb_subscription(xml, options)
419
+
420
+ xml.target!
421
+ end
422
+
423
+ # Builds body for ARBCancelSubscriptionRequest
424
+ def build_arb_cancel_subscription_request(xml, options)
425
+ xml.tag!('subscriptionId', options[:subscription_id])
426
+
427
+ xml.target!
428
+ end
429
+
430
+ # Adds subscription information
431
+ def add_arb_subscription(xml, options)
432
+ xml.tag!('subscription') do
433
+ # Merchant-assigned name for the subscription (optional)
434
+ xml.tag!('name', options[:subscription_name]) if options[:subscription_name]
435
+ # Contains information about the payment schedule
436
+ add_arb_payment_schedule(xml, options)
437
+ # The amount to be billed to the customer
438
+ # for each payment in the subscription
439
+ xml.tag!('amount', amount(options[:amount])) if options[:amount]
440
+ if trial = options[:trial]
441
+ # The amount to be charged for each payment during a trial period (conditional)
442
+ xml.tag!('trialAmount', amount(trial[:amount])) if trial[:amount]
443
+ end
444
+ # Contains either the customer’s credit card
445
+ # or bank account payment information
446
+ add_arb_payment(xml, options)
447
+ # Contains order information (optional)
448
+ add_arb_order(xml, options)
449
+ # Contains information about the customer
450
+ add_arb_customer(xml, options)
451
+ # Contains the customer's billing address information
452
+ add_arb_address(xml, 'billTo', options[:billing_address])
453
+ # Contains the customer's shipping address information (optional)
454
+ add_arb_address(xml, 'shipTo', options[:shipping_address])
455
+ end
456
+ end
457
+
458
+ # Adds information about the interval of time between payments
459
+ def add_arb_interval(xml, options)
460
+ interval = options[:interval]
461
+ return unless interval
462
+ xml.tag!('interval') do
463
+ # The measurement of time, in association with the Interval Unit,
464
+ # that is used to define the frequency of the billing occurrences
465
+ xml.tag!('length', interval[:length])
466
+ # The unit of time, in association with the Interval Length,
467
+ # between each billing occurrence
468
+ xml.tag!('unit', interval[:unit].to_s)
469
+ end
470
+ end
471
+
472
+ # Adds information about the subscription duration
473
+ def add_arb_duration(xml, options)
474
+ duration = options[:duration]
475
+ return unless duration
476
+ # The date the subscription begins
477
+ # (also the date the initial billing occurs)
478
+ xml.tag!('startDate', duration[:start_date]) if duration[:start_date]
479
+ # Number of billing occurrences or payments for the subscription
480
+ xml.tag!('totalOccurrences', duration[:occurrences]) if duration[:occurrences]
481
+ end
482
+
483
+ def add_arb_payment_schedule(xml, options)
484
+ return unless options[:interval] || options[:duration]
485
+ xml.tag!('paymentSchedule') do
486
+ # Contains information about the interval of time between payments
487
+ add_arb_interval(xml, options)
488
+ add_arb_duration(xml, options)
489
+ if trial = options[:trial]
490
+ # Number of billing occurrences or payments in the trial period (optional)
491
+ xml.tag!('trialOccurrences', trial[:occurrences]) if trial[:occurrences]
492
+ end
493
+ end
494
+ end
495
+
496
+ # Adds customer's credit card or bank account payment information
497
+ def add_arb_payment(xml, options)
498
+ return unless options[:credit_card] || options[:bank_account]
499
+ xml.tag!('payment') do
500
+ # Contains the customer’s credit card information
501
+ add_arb_credit_card(xml, options)
502
+ # Contains the customer’s bank account information
503
+ add_arb_bank_account(xml, options)
504
+ end
505
+ end
506
+
507
+ # Adds customer’s credit card information
508
+ # Note: This element should only be included
509
+ # when the payment method is credit card.
510
+ def add_arb_credit_card(xml, options)
511
+ credit_card = options[:credit_card]
512
+ return unless credit_card
513
+ xml.tag!('creditCard') do
514
+ # The credit card number used for payment of the subscription
515
+ xml.tag!('cardNumber', credit_card.number)
516
+ # The expiration date of the credit card used for the subscription
517
+ xml.tag!('expirationDate', arb_expdate(credit_card))
518
+ end
519
+ end
520
+
521
+ # Adds customer’s bank account information
522
+ # Note: This element should only be included
523
+ # when the payment method is bank account.
524
+ def add_arb_bank_account(xml, options)
525
+ bank_account = options[:bank_account]
526
+ return unless bank_account
527
+ xml.tag!('bankAccount') do
528
+ # The type of bank account used for payment of the subscription
529
+ xml.tag!('accountType', bank_account[:account_type])
530
+ # The routing number of the customer’s bank
531
+ xml.tag!('routingNumber', bank_account[:routing_number])
532
+ # The bank account number used for payment of the subscription
533
+ xml.tag!('accountNumber', bank_account[:account_number])
534
+ # The full name of the individual associated
535
+ # with the bank account number
536
+ xml.tag!('nameOfAccount', bank_account[:name_of_account])
537
+ # The full name of the individual associated
538
+ # with the bank account number (optional)
539
+ xml.tag!('bankName', bank_account[:bank_name]) if bank_account[:bank_name]
540
+ # The type of electronic check transaction used for the subscription
541
+ xml.tag!('echeckType', bank_account[:echeck_type])
542
+ end
543
+ end
544
+
545
+ # Adds order information (optional)
546
+ def add_arb_order(xml, options)
547
+ order = options[:order]
548
+ return unless order
549
+ xml.tag!('order') do
550
+ # Merchant-assigned invoice number for the subscription (optional)
551
+ xml.tag!('invoiceNumber', order[:invoice_number])
552
+ # Description of the subscription (optional)
553
+ xml.tag!('description', order[:description])
554
+ end
555
+ end
556
+
557
+ # Adds information about the customer
558
+ def add_arb_customer(xml, options)
559
+ customer = options[:customer]
560
+ return unless customer
561
+ xml.tag!('customer') do
562
+ xml.tag!('type', customer[:type]) if customer[:type]
563
+ xml.tag!('id', customer[:id]) if customer[:id]
564
+ xml.tag!('email', customer[:email]) if customer[:email]
565
+ xml.tag!('phoneNumber', customer[:phone_number]) if customer[:phone_number]
566
+ xml.tag!('faxNumber', customer[:fax_number]) if customer[:fax_number]
567
+ add_arb_drivers_license(xml, options)
568
+ xml.tag!('taxId', customer[:tax_id]) if customer[:tax_id]
569
+ end
570
+ end
571
+
572
+ # Adds the customer's driver's license information (conditional)
573
+ def add_arb_drivers_license(xml, options)
574
+ return unless customer = options[:customer]
575
+ return unless drivers_license = customer[:drivers_license]
576
+ xml.tag!('driversLicense') do
577
+ # The customer's driver's license number
578
+ xml.tag!('number', drivers_license[:number])
579
+ # The customer's driver's license state
580
+ xml.tag!('state', drivers_license[:state])
581
+ # The customer's driver's license date of birth
582
+ xml.tag!('dateOfBirth', drivers_license[:date_of_birth])
583
+ end
584
+ end
585
+
586
+ # Adds address information
587
+ def add_arb_address(xml, container_name, address)
588
+ return if address.blank?
589
+ xml.tag!(container_name) do
590
+ xml.tag!('firstName', address[:first_name])
591
+ xml.tag!('lastName', address[:last_name])
592
+ xml.tag!('company', address[:company])
593
+ xml.tag!('address', address[:address1])
594
+ xml.tag!('city', address[:city])
595
+ xml.tag!('state', address[:state])
596
+ xml.tag!('zip', address[:zip])
597
+ xml.tag!('country', address[:country])
598
+ end
599
+ end
600
+
601
+ def arb_expdate(credit_card)
602
+ sprintf('%04d-%02d', credit_card.year, credit_card.month)
603
+ end
604
+
605
+ def recurring_commit(action, request)
606
+ url = test? ? arb_test_url : arb_live_url
607
+ xml = ssl_post(url, request, "Content-Type" => "text/xml")
608
+
609
+ response = recurring_parse(action, xml)
610
+
611
+ message = response[:message] || response[:text]
612
+ test_mode = test? || message =~ /Test Mode/
613
+ success = response[:result_code] == 'Ok'
614
+
615
+ Response.new(success, message, response,
616
+ :test => test_mode,
617
+ :authorization => response[:subscription_id]
618
+ )
619
+ end
620
+
621
+ def recurring_parse(action, xml)
622
+ response = {}
623
+ xml = REXML::Document.new(xml)
624
+ root = REXML::XPath.first(xml, "//#{RECURRING_ACTIONS[action]}Response") ||
625
+ REXML::XPath.first(xml, "//ErrorResponse")
626
+ if root
627
+ root.elements.to_a.each do |node|
628
+ recurring_parse_element(response, node)
629
+ end
630
+ end
631
+
632
+ response
633
+ end
634
+
635
+ def recurring_parse_element(response, node)
636
+ if node.has_elements?
637
+ node.elements.each{|e| recurring_parse_element(response, e) }
638
+ else
639
+ response[node.name.underscore.to_sym] = node.text
640
+ end
641
+ end
642
+ end
643
+
644
+ AuthorizedNetGateway = AuthorizeNetGateway
645
+ end
646
+ end