ghazel-activemerchant 1.4.2

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 (296) hide show
  1. data/CHANGELOG +473 -0
  2. data/CONTRIBUTORS +126 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +135 -0
  5. data/Rakefile +153 -0
  6. data/gem-public_cert.pem +20 -0
  7. data/init.rb +3 -0
  8. data/lib/active_merchant.rb +60 -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 +34 -0
  17. data/lib/active_merchant/billing/gateway.rb +158 -0
  18. data/lib/active_merchant/billing/gateways.rb +3 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net.rb +657 -0
  20. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
  21. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  22. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +233 -0
  23. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  24. data/lib/active_merchant/billing/gateways/bogus.rb +98 -0
  25. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  26. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  27. data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
  28. data/lib/active_merchant/billing/gateways/data_cash.rb +595 -0
  29. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  30. data/lib/active_merchant/billing/gateways/elavon.rb +106 -0
  31. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  32. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  33. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  34. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  35. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  36. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  37. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  38. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  39. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  40. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +214 -0
  41. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  42. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  43. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  44. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  45. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  46. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  47. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  48. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  49. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  50. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  51. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  52. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  53. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  54. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  55. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  56. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  57. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  58. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  59. data/lib/active_merchant/billing/gateways/paypal_express.rb +130 -0
  60. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  61. data/lib/active_merchant/billing/gateways/paypal_express_recurring.rb +310 -0
  62. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  63. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  64. data/lib/active_merchant/billing/gateways/psl_card.rb +306 -0
  65. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  66. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  67. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  68. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  69. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  70. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  71. data/lib/active_merchant/billing/gateways/sage_pay.rb +308 -0
  72. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  73. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  74. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  75. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  76. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  77. data/lib/active_merchant/billing/gateways/smart_ps.rb +254 -0
  78. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  79. data/lib/active_merchant/billing/gateways/transax.rb +26 -0
  80. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  81. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  82. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  83. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  84. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  85. data/lib/active_merchant/billing/integrations.rb +22 -0
  86. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  87. data/lib/active_merchant/billing/integrations/bogus.rb +22 -0
  88. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  89. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  90. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  91. data/lib/active_merchant/billing/integrations/chronopay.rb +22 -0
  92. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
  93. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
  94. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  95. data/lib/active_merchant/billing/integrations/gestpay.rb +26 -0
  96. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  97. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  98. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
  99. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  100. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  101. data/lib/active_merchant/billing/integrations/hi_trust.rb +26 -0
  102. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  103. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  104. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  105. data/lib/active_merchant/billing/integrations/nochex.rb +87 -0
  106. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  107. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  108. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  109. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  110. data/lib/active_merchant/billing/integrations/paypal.rb +40 -0
  111. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  112. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  113. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  114. data/lib/active_merchant/billing/integrations/quickpay.rb +18 -0
  115. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  116. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  117. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  118. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  119. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  120. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  121. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  122. data/lib/active_merchant/billing/response.rb +32 -0
  123. data/lib/active_merchant/lib/connection.rb +170 -0
  124. data/lib/active_merchant/lib/country.rb +319 -0
  125. data/lib/active_merchant/lib/error.rb +4 -0
  126. data/lib/active_merchant/lib/post_data.rb +22 -0
  127. data/lib/active_merchant/lib/posts_data.rb +47 -0
  128. data/lib/active_merchant/lib/requires_parameters.rb +16 -0
  129. data/lib/active_merchant/lib/utils.rb +18 -0
  130. data/lib/active_merchant/lib/validateable.rb +76 -0
  131. data/lib/certs/cacert.pem +7815 -0
  132. data/lib/support/gateway_support.rb +58 -0
  133. data/script/destroy +14 -0
  134. data/script/generate +14 -0
  135. data/test/fixtures.yml +355 -0
  136. data/test/remote/gateways/remote_authorize_net_cim_test.rb +460 -0
  137. data/test/remote/gateways/remote_authorize_net_test.rb +145 -0
  138. data/test/remote/gateways/remote_beanstream_interac_test.rb +53 -0
  139. data/test/remote/gateways/remote_beanstream_test.rb +150 -0
  140. data/test/remote/gateways/remote_braintree_test.rb +154 -0
  141. data/test/remote/gateways/remote_card_stream_test.rb +148 -0
  142. data/test/remote/gateways/remote_cyber_source_test.rb +144 -0
  143. data/test/remote/gateways/remote_data_cash_test.rb +357 -0
  144. data/test/remote/gateways/remote_efsnet_test.rb +81 -0
  145. data/test/remote/gateways/remote_elavon_test.rb +66 -0
  146. data/test/remote/gateways/remote_eway_test.rb +74 -0
  147. data/test/remote/gateways/remote_exact_test.rb +60 -0
  148. data/test/remote/gateways/remote_first_pay_test.rb +87 -0
  149. data/test/remote/gateways/remote_instapay_test.rb +61 -0
  150. data/test/remote/gateways/remote_jetpay_test.rb +103 -0
  151. data/test/remote/gateways/remote_linkpoint_test.rb +121 -0
  152. data/test/remote/gateways/remote_merchant_e_solutions_test.rb +173 -0
  153. data/test/remote/gateways/remote_merchant_ware_test.rb +113 -0
  154. data/test/remote/gateways/remote_modern_payments_cim_test.rb +58 -0
  155. data/test/remote/gateways/remote_modern_payments_test.rb +43 -0
  156. data/test/remote/gateways/remote_moneris_test.rb +82 -0
  157. data/test/remote/gateways/remote_net_registry_test.rb +85 -0
  158. data/test/remote/gateways/remote_netbilling_test.rb +70 -0
  159. data/test/remote/gateways/remote_ogone_test.rb +115 -0
  160. data/test/remote/gateways/remote_pay_junction_test.rb +143 -0
  161. data/test/remote/gateways/remote_pay_secure_test.rb +39 -0
  162. data/test/remote/gateways/remote_payflow_express_test.rb +50 -0
  163. data/test/remote/gateways/remote_payflow_test.rb +237 -0
  164. data/test/remote/gateways/remote_payflow_uk_test.rb +173 -0
  165. data/test/remote/gateways/remote_payment_express_test.rb +136 -0
  166. data/test/remote/gateways/remote_paypal_express_test.rb +49 -0
  167. data/test/remote/gateways/remote_paypal_test.rb +191 -0
  168. data/test/remote/gateways/remote_plugnpay_test.rb +72 -0
  169. data/test/remote/gateways/remote_psigate_test.rb +50 -0
  170. data/test/remote/gateways/remote_psl_card_test.rb +125 -0
  171. data/test/remote/gateways/remote_quickpay_test.rb +190 -0
  172. data/test/remote/gateways/remote_realex_test.rb +224 -0
  173. data/test/remote/gateways/remote_sage_bankcard_test.rb +109 -0
  174. data/test/remote/gateways/remote_sage_pay_test.rb +219 -0
  175. data/test/remote/gateways/remote_sage_test.rb +87 -0
  176. data/test/remote/gateways/remote_sage_virtual_check_test.rb +62 -0
  177. data/test/remote/gateways/remote_sallie_mae_test.rb +51 -0
  178. data/test/remote/gateways/remote_secure_pay_au_test.rb +40 -0
  179. data/test/remote/gateways/remote_secure_pay_tech_test.rb +37 -0
  180. data/test/remote/gateways/remote_secure_pay_test.rb +28 -0
  181. data/test/remote/gateways/remote_skipjack_test.rb +105 -0
  182. data/test/remote/gateways/remote_trans_first_test.rb +34 -0
  183. data/test/remote/gateways/remote_transax_test.rb +112 -0
  184. data/test/remote/gateways/remote_trust_commerce_test.rb +152 -0
  185. data/test/remote/gateways/remote_usa_epay_test.rb +46 -0
  186. data/test/remote/gateways/remote_verifi_test.rb +107 -0
  187. data/test/remote/gateways/remote_viaklix_test.rb +43 -0
  188. data/test/remote/gateways/remote_wirecard_test.rb +111 -0
  189. data/test/remote/integrations/remote_gestpay_integration_test.rb +37 -0
  190. data/test/remote/integrations/remote_paypal_integration_test.rb +26 -0
  191. data/test/test_helper.rb +182 -0
  192. data/test/unit/avs_result_test.rb +59 -0
  193. data/test/unit/base_test.rb +55 -0
  194. data/test/unit/check_test.rb +88 -0
  195. data/test/unit/connection_test.rb +129 -0
  196. data/test/unit/country_code_test.rb +33 -0
  197. data/test/unit/country_test.rb +64 -0
  198. data/test/unit/credit_card_formatting_test.rb +19 -0
  199. data/test/unit/credit_card_methods_test.rb +179 -0
  200. data/test/unit/credit_card_test.rb +318 -0
  201. data/test/unit/cvv_result_test.rb +33 -0
  202. data/test/unit/expiry_date_test.rb +32 -0
  203. data/test/unit/gateways/authorize_net_cim_test.rb +676 -0
  204. data/test/unit/gateways/authorize_net_test.rb +290 -0
  205. data/test/unit/gateways/beanstream_interac_test.rb +51 -0
  206. data/test/unit/gateways/beanstream_test.rb +108 -0
  207. data/test/unit/gateways/bogus_test.rb +46 -0
  208. data/test/unit/gateways/braintree_test.rb +126 -0
  209. data/test/unit/gateways/card_stream_test.rb +90 -0
  210. data/test/unit/gateways/cyber_source_test.rb +188 -0
  211. data/test/unit/gateways/data_cash_test.rb +133 -0
  212. data/test/unit/gateways/efsnet_test.rb +123 -0
  213. data/test/unit/gateways/elavon_test.rb +139 -0
  214. data/test/unit/gateways/eway_test.rb +118 -0
  215. data/test/unit/gateways/exact_test.rb +156 -0
  216. data/test/unit/gateways/first_pay_test.rb +125 -0
  217. data/test/unit/gateways/gateway_test.rb +48 -0
  218. data/test/unit/gateways/instapay_test.rb +102 -0
  219. data/test/unit/gateways/jetpay_test.rb +185 -0
  220. data/test/unit/gateways/linkpoint_test.rb +184 -0
  221. data/test/unit/gateways/merchant_e_solutions_test.rb +169 -0
  222. data/test/unit/gateways/merchant_ware_test.rb +188 -0
  223. data/test/unit/gateways/modern_payments_cim_test.rb +171 -0
  224. data/test/unit/gateways/moneris_test.rb +158 -0
  225. data/test/unit/gateways/net_registry_test.rb +416 -0
  226. data/test/unit/gateways/netbilling_test.rb +54 -0
  227. data/test/unit/gateways/ogone_test.rb +319 -0
  228. data/test/unit/gateways/pay_junction_test.rb +123 -0
  229. data/test/unit/gateways/pay_secure_test.rb +71 -0
  230. data/test/unit/gateways/payflow_express_test.rb +173 -0
  231. data/test/unit/gateways/payflow_express_uk_test.rb +86 -0
  232. data/test/unit/gateways/payflow_test.rb +305 -0
  233. data/test/unit/gateways/payflow_uk_test.rb +30 -0
  234. data/test/unit/gateways/payment_express_test.rb +195 -0
  235. data/test/unit/gateways/paypal_express_test.rb +382 -0
  236. data/test/unit/gateways/paypal_test.rb +569 -0
  237. data/test/unit/gateways/plugnpay_test.rb +86 -0
  238. data/test/unit/gateways/psigate_test.rb +169 -0
  239. data/test/unit/gateways/psl_card_test.rb +64 -0
  240. data/test/unit/gateways/quickpay_test.rb +112 -0
  241. data/test/unit/gateways/realex_test.rb +151 -0
  242. data/test/unit/gateways/sage_bankcard_test.rb +196 -0
  243. data/test/unit/gateways/sage_pay_test.rb +139 -0
  244. data/test/unit/gateways/sage_virtual_check_test.rb +71 -0
  245. data/test/unit/gateways/sallie_mae_test.rb +53 -0
  246. data/test/unit/gateways/secure_pay_au_test.rb +207 -0
  247. data/test/unit/gateways/secure_pay_tech_test.rb +44 -0
  248. data/test/unit/gateways/secure_pay_test.rb +87 -0
  249. data/test/unit/gateways/skip_jack_test.rb +213 -0
  250. data/test/unit/gateways/trans_first_test.rb +112 -0
  251. data/test/unit/gateways/trust_commerce_test.rb +90 -0
  252. data/test/unit/gateways/usa_epay_test.rb +128 -0
  253. data/test/unit/gateways/verifi_test.rb +96 -0
  254. data/test/unit/gateways/viaklix_test.rb +78 -0
  255. data/test/unit/gateways/wirecard_test.rb +250 -0
  256. data/test/unit/generators/test_gateway_generator.rb +46 -0
  257. data/test/unit/generators/test_generator_helper.rb +20 -0
  258. data/test/unit/generators/test_integration_generator.rb +53 -0
  259. data/test/unit/integrations/action_view_helper_test.rb +50 -0
  260. data/test/unit/integrations/bogus_module_test.rb +20 -0
  261. data/test/unit/integrations/chronopay_module_test.rb +13 -0
  262. data/test/unit/integrations/gestpay_module_test.rb +14 -0
  263. data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
  264. data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
  265. data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
  266. data/test/unit/integrations/helpers/hi_trust_helper_test.rb +16 -0
  267. data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
  268. data/test/unit/integrations/helpers/paypal_helper_test.rb +171 -0
  269. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  270. data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
  271. data/test/unit/integrations/hi_trust_module_test.rb +13 -0
  272. data/test/unit/integrations/nochex_module_test.rb +13 -0
  273. data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
  274. data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
  275. data/test/unit/integrations/notifications/hi_trust_notification_test.rb +59 -0
  276. data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
  277. data/test/unit/integrations/notifications/notification_test.rb +54 -0
  278. data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
  279. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  280. data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
  281. data/test/unit/integrations/paypal_module_test.rb +28 -0
  282. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  283. data/test/unit/integrations/returns/chronopay_return_test.rb +11 -0
  284. data/test/unit/integrations/returns/gestpay_return_test.rb +10 -0
  285. data/test/unit/integrations/returns/hi_trust_return_test.rb +24 -0
  286. data/test/unit/integrations/returns/nochex_return_test.rb +10 -0
  287. data/test/unit/integrations/returns/paypal_return_test.rb +10 -0
  288. data/test/unit/integrations/returns/return_test.rb +11 -0
  289. data/test/unit/integrations/returns/two_checkout_return_test.rb +24 -0
  290. data/test/unit/integrations/two_checkout_module_test.rb +13 -0
  291. data/test/unit/post_data_test.rb +55 -0
  292. data/test/unit/posts_data_test.rb +48 -0
  293. data/test/unit/response_test.rb +28 -0
  294. data/test/unit/utils_test.rb +7 -0
  295. data/test/unit/validateable_test.rb +60 -0
  296. metadata +368 -0
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/paypal'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # The PayPal gateway for PayPal Website Payments Pro Canada only supports Visa and MasterCard
6
+ class PaypalCaGateway < PaypalGateway
7
+ self.supported_cardtypes = [:visa, :master, :american_express]
8
+ self.supported_countries = ['CA']
9
+ self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_wp-pro-overview-outside'
10
+ self.display_name = 'PayPal Website Payments Pro (CA)'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,130 @@
1
+ require File.dirname(__FILE__) + '/paypal/paypal_common_api'
2
+ require File.dirname(__FILE__) + '/paypal/paypal_express_response'
3
+ require File.dirname(__FILE__) + '/paypal_express_common'
4
+
5
+ module ActiveMerchant #:nodoc:
6
+ module Billing #:nodoc:
7
+ class PaypalExpressGateway < Gateway
8
+ include PaypalCommonAPI
9
+ include PaypalExpressCommon
10
+
11
+ self.test_redirect_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='
12
+ self.supported_countries = ['US']
13
+ self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
14
+ self.display_name = 'PayPal Express Checkout'
15
+
16
+ def setup_authorization(money, options = {})
17
+ requires!(options, :return_url, :cancel_return_url)
18
+
19
+ commit 'SetExpressCheckout', build_setup_request('Authorization', money, options)
20
+ end
21
+
22
+ def setup_purchase(money, options = {})
23
+ requires!(options, :return_url, :cancel_return_url)
24
+
25
+ commit 'SetExpressCheckout', build_setup_request('Sale', money, options)
26
+ end
27
+
28
+ def details_for(token)
29
+ commit 'GetExpressCheckoutDetails', build_get_details_request(token)
30
+ end
31
+
32
+ def authorize(money, options = {})
33
+ requires!(options, :token, :payer_id)
34
+
35
+ commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Authorization', money, options)
36
+ end
37
+
38
+ def purchase(money, options = {})
39
+ requires!(options, :token, :payer_id)
40
+
41
+ commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
42
+ end
43
+
44
+ private
45
+ def build_get_details_request(token)
46
+ xml = Builder::XmlMarkup.new :indent => 2
47
+ xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
48
+ xml.tag! 'GetExpressCheckoutDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
49
+ xml.tag! 'n2:Version', API_VERSION
50
+ xml.tag! 'Token', token
51
+ end
52
+ end
53
+
54
+ xml.target!
55
+ end
56
+
57
+ def build_sale_or_authorization_request(action, money, options)
58
+ currency_code = options[:currency] || currency(money)
59
+
60
+ xml = Builder::XmlMarkup.new :indent => 2
61
+ xml.tag! 'DoExpressCheckoutPaymentReq', 'xmlns' => PAYPAL_NAMESPACE do
62
+ xml.tag! 'DoExpressCheckoutPaymentRequest', 'xmlns:n2' => EBAY_NAMESPACE do
63
+ xml.tag! 'n2:Version', API_VERSION
64
+ xml.tag! 'n2:DoExpressCheckoutPaymentRequestDetails' do
65
+ xml.tag! 'n2:PaymentAction', action
66
+ xml.tag! 'n2:Token', options[:token]
67
+ xml.tag! 'n2:PayerID', options[:payer_id]
68
+ xml.tag! 'n2:PaymentDetails' do
69
+ xml.tag! 'n2:OrderTotal', amount(money), 'currencyID' => currency_code
70
+
71
+ # All of the values must be included together and add up to the order total
72
+ if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
73
+ xml.tag! 'n2:ItemTotal', amount(options[:subtotal]), 'currencyID' => currency_code
74
+ xml.tag! 'n2:ShippingTotal', amount(options[:shipping]),'currencyID' => currency_code
75
+ xml.tag! 'n2:HandlingTotal', amount(options[:handling]),'currencyID' => currency_code
76
+ xml.tag! 'n2:TaxTotal', amount(options[:tax]), 'currencyID' => currency_code
77
+ end
78
+
79
+ xml.tag! 'n2:NotifyURL', options[:notify_url]
80
+ xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ xml.target!
87
+ end
88
+
89
+ def build_setup_request(action, money, options)
90
+ xml = Builder::XmlMarkup.new :indent => 2
91
+ xml.tag! 'SetExpressCheckoutReq', 'xmlns' => PAYPAL_NAMESPACE do
92
+ xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
93
+ xml.tag! 'n2:Version', API_VERSION
94
+ xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
95
+ xml.tag! 'n2:PaymentAction', action
96
+ xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? amount(100) : amount(money), 'currencyID' => options[:currency] || currency(money)
97
+ if options[:max_amount]
98
+ xml.tag! 'n2:MaxAmount', amount(options[:max_amount]), 'currencyID' => options[:currency] || currency(options[:max_amount])
99
+ end
100
+ add_address(xml, 'n2:Address', options[:shipping_address] || options[:address])
101
+ xml.tag! 'n2:AddressOverride', options[:address_override] ? '1' : '0'
102
+ xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
103
+ xml.tag! 'n2:ReturnURL', options[:return_url]
104
+ xml.tag! 'n2:CancelURL', options[:cancel_return_url]
105
+ xml.tag! 'n2:IPAddress', options[:ip]
106
+ xml.tag! 'n2:OrderDescription', options[:description]
107
+ xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
108
+ xml.tag! 'n2:InvoiceID', options[:order_id]
109
+
110
+ # Customization of the payment page
111
+ xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
112
+ xml.tag! 'n2:cpp-image-header', options[:header_image] unless options[:header_image].blank?
113
+ xml.tag! 'n2:cpp-header-back-color', options[:header_background_color] unless options[:header_background_color].blank?
114
+ xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
115
+ xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
116
+
117
+ xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
118
+ end
119
+ end
120
+ end
121
+
122
+ xml.target!
123
+ end
124
+
125
+ def build_response(success, message, response, options = {})
126
+ PaypalExpressResponse.new(success, message, response, options)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module PaypalExpressCommon
4
+ def self.included(base)
5
+ base.cattr_accessor :test_redirect_url
6
+ base.cattr_accessor :live_redirect_url
7
+ base.live_redirect_url = 'https://www.paypal.com/cgibin/webscr?cmd=_express-checkout&token='
8
+ end
9
+
10
+ def redirect_url
11
+ test? ? test_redirect_url : live_redirect_url
12
+ end
13
+
14
+ def redirect_url_for(token, options = {})
15
+ options = {:review => true}.update(options)
16
+ options[:review] ? "#{redirect_url}#{token}" : "#{redirect_url}#{token}&useraction=commit"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,310 @@
1
+ require File.dirname(__FILE__) + '/paypal/paypal_common_api'
2
+ require File.dirname(__FILE__) + '/paypal/paypal_express_response'
3
+ require File.dirname(__FILE__) + '/paypal_express_common'
4
+
5
+ module ActiveMerchant #:nodoc:
6
+ module Billing #:nodoc:
7
+ class PaypalExpressRecurringGateway < Gateway
8
+ include PaypalCommonAPI
9
+ include PaypalExpressCommon
10
+
11
+ LIVE_REDIRECT_URL = 'https://www.paypal.com/cgi-bin/webscr?cmd=_customer-billing-agreement&token='
12
+ TEST_REDIRECT_URL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_customer-billing-agreement&token='
13
+
14
+ def redirect_url
15
+ test? ? TEST_REDIRECT_URL : LIVE_REDIRECT_URL
16
+ end
17
+
18
+ def redirect_url_for(token)
19
+ "#{redirect_url}#{token}"
20
+ end
21
+
22
+ ## def setup_agreement(options = {})
23
+ ## requires!(options, :description, :return_url, :cancel_return_url)
24
+ ##
25
+ ## commit 'SetCustomerBillingAgreement', build_setup_request(options)
26
+ ## end
27
+
28
+ def get_agreement(token)
29
+ commit 'GetBillingAgreementCustomerDetails', build_get_agreement_request(token)
30
+ end
31
+
32
+ # self.test_redirect_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='
33
+ # self.supported_countries = ['US']
34
+ # self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
35
+ # self.display_name = 'PayPal Express Checkout Recurring'
36
+ # API_VERSION = 50.0
37
+
38
+ def setup_agreement(options = {})
39
+ requires!(options, :description, :return_url, :cancel_return_url)
40
+
41
+ commit 'SetExpressCheckout', build_setup_request('Authorization', options)
42
+ end
43
+
44
+ def details_for(token)
45
+ commit 'GetExpressCheckoutDetails', build_get_details_request(token)
46
+ end
47
+
48
+ def create_profile(token, options = {})
49
+ requires!(options, :description, :start_date, :frequency, :amount)
50
+
51
+ commit 'CreateRecurringPaymentsProfile', build_create_profile_request(token, options)
52
+ end
53
+
54
+ def get_profile_details(profile_id)
55
+ commit 'GetRecurringPaymentsProfileDetails', build_get_profile_details_request(profile_id)
56
+ end
57
+
58
+ def update_profile(profile_id, options = {})
59
+ commit 'UpdateRecurringPaymentsProfile', build_change_profile_request(profile_id, options)
60
+ end
61
+
62
+ def cancel_profile(profile_id, options = {})
63
+ commit 'ManageRecurringPaymentsProfileStatus', build_manage_profile_request(profile_id, 'Cancel', options)
64
+ end
65
+
66
+ def suspend_profile(profile_id, options = {})
67
+ commit 'ManageRecurringPaymentsProfileStatus', build_manage_profile_request(profile_id, 'Suspend', options)
68
+ end
69
+
70
+ def reactivate_profile(profile_id, options = {})
71
+ commit 'ManageRecurringPaymentsProfileStatus', build_manage_profile_request(profile_id, 'Reactivate', options)
72
+ end
73
+
74
+ def bill_outstanding_amount(profile_id, options = {})
75
+ commit 'BillOutstandingAmount', build_bill_outstanding_amount(profile_id, options)
76
+ end
77
+
78
+ private
79
+
80
+ ## def build_setup_request(options)
81
+ ## xml = Builder::XmlMarkup.new :indent => 2
82
+ ## xml.tag! 'SetCustomerBillingAgreementReq', 'xmlns' => PAYPAL_NAMESPACE do
83
+ ## xml.tag! 'SetCustomerBillingAgreementRequest', 'xmlns:n2' => EBAY_NAMESPACE do
84
+ ## xml.tag! 'n2:Version', API_VERSION
85
+ ## xml.tag! 'n2:SetCustomerBillingAgreementRequestDetails' do
86
+ ## xml.tag! 'n2:BillingAgreementDetails' do
87
+ ## xml.tag! 'n2:BillingType', 'RecurringPayments'
88
+ ## xml.tag! 'n2:BillingAgreementDescription', options[:description]
89
+ ## end
90
+ ## xml.tag! 'n2:ReturnURL', options[:return_url]
91
+ ## xml.tag! 'n2:CancelURL', options[:cancel_return_url]
92
+ ## end
93
+ ## end
94
+ ## end
95
+ ##
96
+ ## xml.target!
97
+ ## end
98
+
99
+ def build_get_agreement_request(token)
100
+ xml = Builder::XmlMarkup.new :indent => 2
101
+ xml.tag! 'GetBillingAgreementCustomerDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
102
+ xml.tag! 'GetBillingAgreementCustomerDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
103
+ xml.tag! 'n2:Version', API_VERSION
104
+ xml.tag! 'Token', token
105
+ end
106
+ end
107
+
108
+ xml.target!
109
+ end
110
+
111
+ def build_setup_request(action, options)
112
+ xml = Builder::XmlMarkup.new :indent => 2
113
+ xml.tag! 'SetExpressCheckoutReq', 'xmlns' => PAYPAL_NAMESPACE do
114
+ xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
115
+ xml.tag! 'n2:Version', API_VERSION
116
+ xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
117
+ xml.tag! 'n2:PaymentAction', action
118
+ xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
119
+ xml.tag! 'n2:ReturnURL', options[:return_url]
120
+ xml.tag! 'n2:CancelURL', options[:cancel_return_url]
121
+ xml.tag! 'n2:BillingAgreementDetails' do
122
+ xml.tag! 'n2:BillingType', 'RecurringPayments'
123
+ xml.tag! 'n2:BillingAgreementDescription', options[:description]
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ xml.target!
130
+ end
131
+
132
+ def build_get_details_request(token)
133
+ xml = Builder::XmlMarkup.new :indent => 2
134
+ xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
135
+ xml.tag! 'GetExpressCheckoutDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
136
+ xml.tag! 'n2:Version', API_VERSION
137
+ xml.tag! 'Token', token
138
+ end
139
+ end
140
+
141
+ xml.target!
142
+ end
143
+
144
+ def build_create_profile_request(token, options)
145
+ xml = Builder::XmlMarkup.new :indent => 2
146
+ xml.tag! 'CreateRecurringPaymentsProfileReq', 'xmlns' => PAYPAL_NAMESPACE do
147
+ xml.tag! 'CreateRecurringPaymentsProfileRequest', 'xmlns:n2' => EBAY_NAMESPACE do
148
+ xml.tag! 'n2:Version', API_VERSION
149
+ xml.tag! 'n2:CreateRecurringPaymentsProfileRequestDetails' do
150
+ xml.tag! 'Token', token unless token.blank?
151
+ if options[:credit_card]
152
+ add_credit_card(xml, options[:credit_card], (options[:billing_address] || options[:address]), options)
153
+ end
154
+ xml.tag! 'n2:RecurringPaymentsProfileDetails' do
155
+ xml.tag! 'n2:BillingStartDate', (options[:start_date].is_a?(Date) ? options[:start_date].to_time : options[:start_date]).utc.iso8601
156
+ xml.tag! 'n2:ProfileReference', options[:reference] unless options[:reference].blank?
157
+ xml.tag! 'n2:SubscriberName', options[:subscriber_name] unless options[:subscriber_name].blank?
158
+ add_address(xml, 'n2:SubscriberShippingAddress', (options[:shipping_address] || options[:address])) if options[:shipping_address] || options[:address]
159
+ end
160
+ xml.tag! 'n2:ScheduleDetails' do
161
+ xml.tag! 'n2:Description', options[:description]
162
+ xml.tag! 'n2:PaymentPeriod' do
163
+ xml.tag! 'n2:BillingPeriod', options[:period] || 'Month'
164
+ xml.tag! 'n2:BillingFrequency', options[:frequency]
165
+ xml.tag! 'n2:TotalBillingCycles', options[:cycles] unless options[:cycles].blank?
166
+ xml.tag! 'n2:Amount', amount(options[:amount]), 'currencyID' => options[:currency] || 'USD'
167
+ xml.tag! 'n2:TaxAmount', amount(options[:tax_amount] || 0), 'currencyID' => options[:currency] || 'USD'
168
+ end
169
+ if !options[:trialamount].blank?
170
+ xml.tag! 'n2:TrialPeriod' do
171
+ xml.tag! 'n2:BillingPeriod', options[:trialperiod] || 'Month'
172
+ xml.tag! 'n2:BillingFrequency', options[:trialfrequency]
173
+ xml.tag! 'n2:TotalBillingCycles', options[:trialcycles] || 1
174
+ xml.tag! 'n2:Amount', amount(options[:trialamount]), 'currencyID' => options[:currency] || 'USD'
175
+ end
176
+ end
177
+ if !options[:initial_amount].blank?
178
+ xml.tag! 'n2:ActivationDetails' do
179
+ xml.tag! 'n2:InitialAmount', amount(options[:initial_amount]), 'currencyID' => options[:currency] || 'USD'
180
+ xml.tag! 'n2:FailedInitialAmountAction', options[:continue_on_failure] ? 'ContinueOnFailure' : 'CancelOnFailure'
181
+ end
182
+ end
183
+ xml.tag! 'n2:MaxFailedPayments', options[:max_failed_payments] unless options[:max_failed_payments].blank?
184
+ xml.tag! 'n2:AutoBillOutstandingAmount', options[:auto_bill_outstanding] ? 'AddToNextBilling' : 'NoAutoBill'
185
+ end
186
+ end
187
+ end
188
+ end
189
+ xml.target!
190
+ end
191
+
192
+ def build_get_profile_details_request(profile_id)
193
+ xml = Builder::XmlMarkup.new :indent => 2
194
+ xml.tag! 'GetRecurringPaymentsProfileDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
195
+ xml.tag! 'GetRecurringPaymentsProfileDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
196
+ xml.tag! 'n2:Version', API_VERSION
197
+ xml.tag! 'ProfileID', profile_id
198
+ end
199
+ end
200
+
201
+ xml.target!
202
+ end
203
+
204
+ def build_change_profile_request(profile_id, options)
205
+ xml = Builder::XmlMarkup.new :indent => 2
206
+ xml.tag! 'UpdateRecurringPaymentsProfileReq', 'xmlns' => PAYPAL_NAMESPACE do
207
+ xml.tag! 'UpdateRecurringPaymentsProfileRequest', 'xmlns:n2' => EBAY_NAMESPACE do
208
+ xml.tag! 'n2:Version', API_VERSION
209
+ xml.tag! 'n2:UpdateRecurringPaymentsProfileRequestDetails' do
210
+ xml.tag! 'ProfileID', profile_id
211
+ if options[:credit_card]
212
+ add_credit_card(xml, options[:credit_card], options[:address], options)
213
+ end
214
+ xml.tag! 'n2:Note', options[:note] unless options[:note].blank?
215
+ xml.tag! 'n2:Description', options[:description] unless options[:description].blank?
216
+ xml.tag! 'n2:ProfileReference', options[:reference] unless options[:reference].blank?
217
+ xml.tag! 'n2:AdditionalBillingCycles', options[:additional_billing_cycles] unless options[:additional_billing_cycles].blank?
218
+ xml.tag! 'n2:MaxFailedPayments', options[:max_failed_payments] unless options[:max_failed_payments].blank?
219
+ xml.tag! 'n2:AutoBillOutstandingAmount', options[:auto_bill_outstanding] ? 'AddToNextBilling' : 'NoAutoBill'
220
+ if options.has_key?(:amount)
221
+ xml.tag! 'n2:Amount', amount(options[:amount]), 'currencyID' => options[:currency] || 'USD'
222
+ end
223
+ if options.has_key?(:tax_amount)
224
+ xml.tag! 'n2:TaxAmount', amount(options[:tax_amount] || 0), 'currencyID' => options[:currency] || 'USD'
225
+ end
226
+ if options.has_key?(:start_date)
227
+ xml.tag! 'n2:BillingStartDate', (options[:start_date].is_a?(Date) ? options[:start_date].to_time : options[:start_date]).utc.iso8601
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ xml.target!
234
+ end
235
+
236
+ def build_manage_profile_request(profile_id, action, options)
237
+ xml = Builder::XmlMarkup.new :indent => 2
238
+ xml.tag! 'ManageRecurringPaymentsProfileStatusReq', 'xmlns' => PAYPAL_NAMESPACE do
239
+ xml.tag! 'ManageRecurringPaymentsProfileStatusRequest', 'xmlns:n2' => EBAY_NAMESPACE do
240
+ xml.tag! 'n2:Version', API_VERSION
241
+ xml.tag! 'n2:ManageRecurringPaymentsProfileStatusRequestDetails' do
242
+ xml.tag! 'ProfileID', profile_id
243
+ xml.tag! 'n2:Action', action
244
+ xml.tag! 'n2:Note', options[:note] unless options[:note].blank?
245
+ end
246
+ end
247
+ end
248
+
249
+ xml.target!
250
+ end
251
+
252
+ def build_bill_outstanding_amount(profile_id, options)
253
+ xml = Builder::XmlMarkup.new :indent => 2
254
+ xml.tag! 'BillOutstandingAmountReq', 'xmlns' => PAYPAL_NAMESPACE do
255
+ xml.tag! 'BillOutstandingAmountRequest', 'xmlns:n2' => EBAY_NAMESPACE do
256
+ xml.tag! 'n2:Version', API_VERSION
257
+ xml.tag! 'ProfileID', profile_id
258
+ if options.has_key?(:amount)
259
+ xml.tag! 'n2:Amount', amount(options[:amount]), 'currencyID' => options[:currency] || 'USD'
260
+ end
261
+ xml.tag! 'n2:Note', options[:note] unless options[:note].blank?
262
+ end
263
+ end
264
+
265
+ xml.target!
266
+ end
267
+
268
+ def add_credit_card(xml, credit_card, address, options)
269
+ xml.tag! 'n2:CreditCard' do
270
+ xml.tag! 'n2:CreditCardType', credit_card_type(card_brand(credit_card))
271
+ xml.tag! 'n2:CreditCardNumber', credit_card.number
272
+ xml.tag! 'n2:ExpMonth', format(credit_card.month, :two_digits)
273
+ xml.tag! 'n2:ExpYear', format(credit_card.year, :four_digits)
274
+ xml.tag! 'n2:CVV2', credit_card.verification_value
275
+
276
+ if [ 'switch', 'solo' ].include?(card_brand(credit_card).to_s)
277
+ xml.tag! 'n2:StartMonth', format(credit_card.start_month, :two_digits) unless credit_card.start_month.blank?
278
+ xml.tag! 'n2:StartYear', format(credit_card.start_year, :four_digits) unless credit_card.start_year.blank?
279
+ xml.tag! 'n2:IssueNumber', format(credit_card.issue_number, :two_digits) unless credit_card.issue_number.blank?
280
+ end
281
+
282
+ xml.tag! 'n2:CardOwner' do
283
+ xml.tag! 'n2:PayerName' do
284
+ xml.tag! 'n2:FirstName', credit_card.first_name
285
+ xml.tag! 'n2:LastName', credit_card.last_name
286
+ end
287
+
288
+ xml.tag! 'n2:Payer', options[:email]
289
+ add_address(xml, 'n2:Address', address) if address
290
+ end
291
+ end
292
+ end
293
+
294
+ def credit_card_type(type)
295
+ case type
296
+ when 'visa' then 'Visa'
297
+ when 'master' then 'MasterCard'
298
+ when 'discover' then 'Discover'
299
+ when 'american_express' then 'Amex'
300
+ when 'switch' then 'Switch'
301
+ when 'solo' then 'Solo'
302
+ end
303
+ end
304
+
305
+ def build_response(success, message, response, options = {})
306
+ PaypalExpressResponse.new(success, message, response, options)
307
+ end
308
+ end
309
+ end
310
+ end