activemerchant-nsp 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (252) hide show
  1. data/CHANGELOG +952 -0
  2. data/CONTRIBUTORS +347 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +204 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant.rb +63 -0
  7. data/lib/active_merchant/billing.rb +9 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +56 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +274 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +143 -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 +176 -0
  17. data/lib/active_merchant/billing/gateways.rb +18 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +695 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +943 -0
  20. data/lib/active_merchant/billing/gateways/balanced.rb +462 -0
  21. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  22. data/lib/active_merchant/billing/gateways/beanstream.rb +167 -0
  23. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +389 -0
  24. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  25. data/lib/active_merchant/billing/gateways/blue_pay.rb +492 -0
  26. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  27. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  28. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  29. data/lib/active_merchant/billing/gateways/braintree_blue.rb +389 -0
  30. data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
  31. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  32. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  33. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  34. data/lib/active_merchant/billing/gateways/cyber_source.rb +576 -0
  35. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  36. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  37. data/lib/active_merchant/billing/gateways/elavon.rb +137 -0
  38. data/lib/active_merchant/billing/gateways/epay.rb +276 -0
  39. data/lib/active_merchant/billing/gateways/eway.rb +287 -0
  40. data/lib/active_merchant/billing/gateways/eway_managed.rb +265 -0
  41. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  42. data/lib/active_merchant/billing/gateways/fat_zebra.rb +152 -0
  43. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  44. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  45. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  46. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +252 -0
  47. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  48. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  49. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  50. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  51. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  52. data/lib/active_merchant/billing/gateways/iridium.rb +257 -0
  53. data/lib/active_merchant/billing/gateways/itransact.rb +450 -0
  54. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  55. data/lib/active_merchant/billing/gateways/linkpoint.rb +451 -0
  56. data/lib/active_merchant/billing/gateways/litle.rb +290 -0
  57. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +157 -0
  58. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  59. data/lib/active_merchant/billing/gateways/metrics_global.rb +323 -0
  60. data/lib/active_merchant/billing/gateways/migs.rb +263 -0
  61. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  62. data/lib/active_merchant/billing/gateways/modern_payments.rb +38 -0
  63. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  64. data/lib/active_merchant/billing/gateways/moneris.rb +250 -0
  65. data/lib/active_merchant/billing/gateways/moneris_us.rb +211 -0
  66. data/lib/active_merchant/billing/gateways/nab_transact.rb +257 -0
  67. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  68. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  69. data/lib/active_merchant/billing/gateways/netbilling.rb +196 -0
  70. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  71. data/lib/active_merchant/billing/gateways/ogone.rb +427 -0
  72. data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
  73. data/lib/active_merchant/billing/gateways/orbital.rb +351 -0
  74. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  75. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +266 -0
  76. data/lib/active_merchant/billing/gateways/pay_junction.rb +397 -0
  77. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  78. data/lib/active_merchant/billing/gateways/paybox_direct.rb +201 -0
  79. data/lib/active_merchant/billing/gateways/payflow.rb +268 -0
  80. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +212 -0
  81. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  82. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  83. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  84. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  85. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  86. data/lib/active_merchant/billing/gateways/payment_express.rb +282 -0
  87. data/lib/active_merchant/billing/gateways/paypal.rb +106 -0
  88. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +653 -0
  89. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  90. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +245 -0
  91. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  92. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +43 -0
  93. data/lib/active_merchant/billing/gateways/paypal_express.rb +178 -0
  94. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  95. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  96. data/lib/active_merchant/billing/gateways/payway.rb +214 -0
  97. data/lib/active_merchant/billing/gateways/plugnpay.rb +295 -0
  98. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  99. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  100. data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
  101. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  102. data/lib/active_merchant/billing/gateways/quickpay.rb +298 -0
  103. data/lib/active_merchant/billing/gateways/realex.rb +313 -0
  104. data/lib/active_merchant/billing/gateways/sage.rb +148 -0
  105. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  106. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +115 -0
  107. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  108. data/lib/active_merchant/billing/gateways/sage_pay.rb +322 -0
  109. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  110. data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
  111. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  112. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  113. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +284 -0
  114. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  115. data/lib/active_merchant/billing/gateways/skip_jack.rb +458 -0
  116. data/lib/active_merchant/billing/gateways/smart_ps.rb +273 -0
  117. data/lib/active_merchant/billing/gateways/stripe.rb +236 -0
  118. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  119. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  120. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  121. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  122. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1497 -0
  123. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
  124. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  125. data/lib/active_merchant/billing/gateways/viaklix.rb +194 -0
  126. data/lib/active_merchant/billing/gateways/vindicia.rb +359 -0
  127. data/lib/active_merchant/billing/gateways/wirecard.rb +313 -0
  128. data/lib/active_merchant/billing/gateways/worldpay.rb +271 -0
  129. data/lib/active_merchant/billing/integrations.rb +17 -0
  130. data/lib/active_merchant/billing/integrations/action_view_helper.rb +73 -0
  131. data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
  132. data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
  133. data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
  134. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  135. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  136. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  137. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  138. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  139. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  140. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  141. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  142. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  143. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  144. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  145. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  146. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  147. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  148. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  149. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  150. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  151. data/lib/active_merchant/billing/integrations/dotpay.rb +22 -0
  152. data/lib/active_merchant/billing/integrations/dotpay/helper.rb +77 -0
  153. data/lib/active_merchant/billing/integrations/dotpay/notification.rb +86 -0
  154. data/lib/active_merchant/billing/integrations/dotpay/return.rb +11 -0
  155. data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
  156. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
  157. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
  158. data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
  159. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  160. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  161. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  162. data/lib/active_merchant/billing/integrations/easy_pay.rb +30 -0
  163. data/lib/active_merchant/billing/integrations/easy_pay/common.rb +40 -0
  164. data/lib/active_merchant/billing/integrations/easy_pay/helper.rb +40 -0
  165. data/lib/active_merchant/billing/integrations/easy_pay/notification.rb +51 -0
  166. data/lib/active_merchant/billing/integrations/epay.rb +21 -0
  167. data/lib/active_merchant/billing/integrations/epay/helper.rb +55 -0
  168. data/lib/active_merchant/billing/integrations/epay/notification.rb +110 -0
  169. data/lib/active_merchant/billing/integrations/first_data.rb +38 -0
  170. data/lib/active_merchant/billing/integrations/first_data/helper.rb +63 -0
  171. data/lib/active_merchant/billing/integrations/first_data/notification.rb +56 -0
  172. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  173. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  174. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  175. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  176. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  177. data/lib/active_merchant/billing/integrations/helper.rb +117 -0
  178. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  179. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  180. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  181. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  182. data/lib/active_merchant/billing/integrations/maksuturva.rb +86 -0
  183. data/lib/active_merchant/billing/integrations/maksuturva/helper.rb +119 -0
  184. data/lib/active_merchant/billing/integrations/maksuturva/notification.rb +48 -0
  185. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  186. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  187. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  188. data/lib/active_merchant/billing/integrations/nelnet.rb +40 -0
  189. data/lib/active_merchant/billing/integrations/nelnet/helper.rb +34 -0
  190. data/lib/active_merchant/billing/integrations/nelnet/notification.rb +100 -0
  191. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  192. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  193. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  194. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  195. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  196. data/lib/active_merchant/billing/integrations/paxum.rb +44 -0
  197. data/lib/active_merchant/billing/integrations/paxum/common.rb +24 -0
  198. data/lib/active_merchant/billing/integrations/paxum/helper.rb +42 -0
  199. data/lib/active_merchant/billing/integrations/paxum/notification.rb +33 -0
  200. data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
  201. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
  202. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
  203. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  204. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  205. data/lib/active_merchant/billing/integrations/paypal/notification.rb +155 -0
  206. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  207. data/lib/active_merchant/billing/integrations/paypal_payments_advanced.rb +20 -0
  208. data/lib/active_merchant/billing/integrations/paypal_payments_advanced/helper.rb +15 -0
  209. data/lib/active_merchant/billing/integrations/pxpay.rb +31 -0
  210. data/lib/active_merchant/billing/integrations/pxpay/helper.rb +110 -0
  211. data/lib/active_merchant/billing/integrations/pxpay/notification.rb +157 -0
  212. data/lib/active_merchant/billing/integrations/pxpay/return.rb +25 -0
  213. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  214. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +71 -0
  215. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  216. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  217. data/lib/active_merchant/billing/integrations/robokassa.rb +49 -0
  218. data/lib/active_merchant/billing/integrations/robokassa/common.rb +19 -0
  219. data/lib/active_merchant/billing/integrations/robokassa/helper.rb +50 -0
  220. data/lib/active_merchant/billing/integrations/robokassa/notification.rb +55 -0
  221. data/lib/active_merchant/billing/integrations/robokassa/return.rb +17 -0
  222. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  223. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  224. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +129 -0
  225. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  226. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  227. data/lib/active_merchant/billing/integrations/two_checkout.rb +44 -0
  228. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +91 -0
  229. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +139 -0
  230. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  231. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  232. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  233. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  234. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  235. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  236. data/lib/active_merchant/billing/integrations/verkkomaksut.rb +20 -0
  237. data/lib/active_merchant/billing/integrations/verkkomaksut/helper.rb +87 -0
  238. data/lib/active_merchant/billing/integrations/verkkomaksut/notification.rb +59 -0
  239. data/lib/active_merchant/billing/integrations/web_pay.rb +45 -0
  240. data/lib/active_merchant/billing/integrations/web_pay/common.rb +50 -0
  241. data/lib/active_merchant/billing/integrations/web_pay/helper.rb +68 -0
  242. data/lib/active_merchant/billing/integrations/web_pay/notification.rb +51 -0
  243. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  244. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  245. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  246. data/lib/active_merchant/billing/response.rb +64 -0
  247. data/lib/active_merchant/version.rb +3 -0
  248. data/lib/activemerchant.rb +1 -0
  249. data/lib/support/gateway_support.rb +65 -0
  250. data/lib/support/outbound_hosts.rb +25 -0
  251. data/lib/support/ssl_verify.rb +93 -0
  252. metadata +482 -0
@@ -0,0 +1,212 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module PayflowCommonAPI
4
+ def self.included(base)
5
+ base.default_currency = 'USD'
6
+
7
+ base.class_attribute :partner
8
+
9
+ # Set the default partner to PayPal
10
+ base.partner = 'PayPal'
11
+
12
+ base.supported_countries = ['US', 'CA', 'SG', 'AU']
13
+
14
+ base.class_attribute :timeout
15
+ base.timeout = 60
16
+
17
+ base.test_url = 'https://pilot-payflowpro.paypal.com'
18
+ base.live_url = 'https://payflowpro.paypal.com'
19
+
20
+ # Enable safe retry of failed connections
21
+ # Payflow is safe to retry because retried transactions use the same
22
+ # X-VPS-Request-ID header. If a transaction is detected as a duplicate
23
+ # only the original transaction data will be used by Payflow, and the
24
+ # subsequent Responses will have a :duplicate parameter set in the params
25
+ # hash.
26
+ base.retry_safe = true
27
+ end
28
+
29
+ XMLNS = 'http://www.paypal.com/XMLPay'
30
+
31
+ CARD_MAPPING = {
32
+ :visa => 'Visa',
33
+ :master => 'MasterCard',
34
+ :discover => 'Discover',
35
+ :american_express => 'Amex',
36
+ :jcb => 'JCB',
37
+ :diners_club => 'DinersClub',
38
+ :switch => 'Switch',
39
+ :solo => 'Solo'
40
+ }
41
+
42
+ TRANSACTIONS = {
43
+ :purchase => "Sale",
44
+ :authorization => "Authorization",
45
+ :capture => "Capture",
46
+ :void => "Void",
47
+ :credit => "Credit"
48
+ }
49
+
50
+ CVV_CODE = {
51
+ 'Match' => 'M',
52
+ 'No Match' => 'N',
53
+ 'Service Not Available' => 'U',
54
+ 'Service not Requested' => 'P'
55
+ }
56
+
57
+ def initialize(options = {})
58
+ requires!(options, :login, :password)
59
+
60
+ @options = options
61
+ @options[:partner] = partner if @options[:partner].blank?
62
+ super
63
+ end
64
+
65
+ def test?
66
+ @options[:test] || super
67
+ end
68
+
69
+ def capture(money, authorization, options = {})
70
+ request = build_reference_request(:capture, money, authorization, options)
71
+ commit(request, options)
72
+ end
73
+
74
+ def void(authorization, options = {})
75
+ request = build_reference_request(:void, nil, authorization, options)
76
+ commit(request, options)
77
+ end
78
+
79
+ private
80
+ def build_request(body, options = {})
81
+ xml = Builder::XmlMarkup.new
82
+ xml.instruct!
83
+ xml.tag! 'XMLPayRequest', 'Timeout' => timeout.to_s, 'version' => "2.1", "xmlns" => XMLNS do
84
+ xml.tag! 'RequestData' do
85
+ xml.tag! 'Vendor', @options[:login]
86
+ xml.tag! 'Partner', @options[:partner]
87
+ if options[:request_type] == :recurring
88
+ xml << body
89
+ else
90
+ xml.tag! 'Transactions' do
91
+ xml.tag! 'Transaction', 'CustRef' => options[:customer] do
92
+ xml.tag! 'Verbosity', 'MEDIUM'
93
+ xml << body
94
+ end
95
+ end
96
+ end
97
+ end
98
+ xml.tag! 'RequestAuth' do
99
+ xml.tag! 'UserPass' do
100
+ xml.tag! 'User', !@options[:user].blank? ? @options[:user] : @options[:login]
101
+ xml.tag! 'Password', @options[:password]
102
+ end
103
+ end
104
+ end
105
+ xml.target!
106
+ end
107
+
108
+ def build_reference_request(action, money, authorization, options)
109
+ xml = Builder::XmlMarkup.new
110
+ xml.tag! TRANSACTIONS[action] do
111
+ xml.tag! 'PNRef', authorization
112
+
113
+ unless money.nil?
114
+ xml.tag! 'Invoice' do
115
+ xml.tag!('TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money))
116
+ xml.tag!('Description', options[:description]) unless options[:description].blank?
117
+ xml.tag!('Comment', options[:comment]) unless options[:comment].blank?
118
+ xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].blank?
119
+ end
120
+ end
121
+ end
122
+
123
+ xml.target!
124
+ end
125
+
126
+ def add_address(xml, tag, address, options)
127
+ return if address.nil?
128
+ xml.tag! tag do
129
+ xml.tag! 'Name', address[:name] unless address[:name].blank?
130
+ xml.tag! 'EMail', options[:email] unless options[:email].blank?
131
+ xml.tag! 'Phone', address[:phone] unless address[:phone].blank?
132
+ xml.tag! 'CustCode', options[:customer] if !options[:customer].blank? && tag == 'BillTo'
133
+ xml.tag! 'PONum', options[:po_number] if !options[:po_number].blank? && tag == 'BillTo'
134
+
135
+ xml.tag! 'Address' do
136
+ xml.tag! 'Street', address[:address1] unless address[:address1].blank?
137
+ xml.tag! 'City', address[:city] unless address[:city].blank?
138
+ xml.tag! 'State', address[:state].blank? ? "N/A" : address[:state]
139
+ xml.tag! 'Country', address[:country] unless address[:country].blank?
140
+ xml.tag! 'Zip', address[:zip] unless address[:zip].blank?
141
+ end
142
+ end
143
+ end
144
+
145
+ def parse(data)
146
+ response = {}
147
+ xml = REXML::Document.new(data)
148
+ root = REXML::XPath.first(xml, "//ResponseData")
149
+
150
+ # REXML::XPath in Ruby 1.8.6 is now unable to match nodes based on their attributes
151
+ tx_result = REXML::XPath.first(root, "//TransactionResult")
152
+
153
+ if tx_result && tx_result.attributes['Duplicate'] == "true"
154
+ response[:duplicate] = true
155
+ end
156
+
157
+ root.elements.to_a.each do |node|
158
+ parse_element(response, node)
159
+ end
160
+
161
+ response
162
+ end
163
+
164
+ def parse_element(response, node)
165
+ node_name = node.name.underscore.to_sym
166
+ case
167
+ when node_name == :rp_payment_result
168
+ # Since we'll have multiple history items, we can't just flatten everything
169
+ # down as we do everywhere else. RPPaymentResult elements are not contained
170
+ # in an RPPaymentResults element so we'll come here multiple times
171
+ response[node_name] ||= []
172
+ response[node_name] << ( payment_result_response = {} )
173
+ node.elements.each{ |e| parse_element(payment_result_response, e) }
174
+ when node.has_elements?
175
+ node.elements.each{|e| parse_element(response, e) }
176
+ when node_name.to_s =~ /amt$/
177
+ # *Amt elements don't put the value in the #text - instead they use a Currency attribute
178
+ response[node_name] = node.attributes['Currency']
179
+ when node_name == :ext_data
180
+ response[node.attributes['Name'].underscore.to_sym] = node.attributes['Value']
181
+ else
182
+ response[node_name] = node.text
183
+ end
184
+ end
185
+
186
+ def build_headers(content_length)
187
+ {
188
+ "Content-Type" => "text/xml",
189
+ "Content-Length" => content_length.to_s,
190
+ "X-VPS-Client-Timeout" => timeout.to_s,
191
+ "X-VPS-VIT-Integration-Product" => "ActiveMerchant",
192
+ "X-VPS-VIT-Runtime-Version" => RUBY_VERSION,
193
+ "X-VPS-Request-ID" => Utils.generate_unique_id
194
+ }
195
+ end
196
+
197
+ def commit(request_body, options = {})
198
+ request = build_request(request_body, options)
199
+ headers = build_headers(request.size)
200
+
201
+ response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers))
202
+
203
+ build_response(response[:result] == "0", response[:message], response,
204
+ :test => test?,
205
+ :authorization => response[:pn_ref] || response[:rp_ref],
206
+ :cvv_result => CVV_CODE[response[:cv_result]],
207
+ :avs_result => { :code => response[:avs_result] }
208
+ )
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PayflowExpressResponse < Response
4
+ def email
5
+ @params['e_mail']
6
+ end
7
+
8
+ def full_name
9
+ "#{@params['name']} #{@params['lastname']}"
10
+ end
11
+
12
+ def token
13
+ @params['token']
14
+ end
15
+
16
+ def payer_id
17
+ @params['payer_id']
18
+ end
19
+
20
+ # Really the shipping country, but it is all the information provided
21
+ def payer_country
22
+ address['country']
23
+ end
24
+
25
+ def address
26
+ { 'name' => full_name,
27
+ 'company' => nil,
28
+ 'address1' => @params['street'],
29
+ 'address2' => @params['shiptostreet2'] || @params['street2'],
30
+ 'city' => @params['city'],
31
+ 'state' => @params['state'],
32
+ 'country' => @params['country'],
33
+ 'zip' => @params['zip'],
34
+ 'phone' => nil
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PayflowResponse < Response
4
+ def profile_id
5
+ @params['profile_id']
6
+ end
7
+
8
+ def payment_history
9
+ @payment_history ||= @params['rp_payment_result'].collect{ |result| result.stringify_keys } rescue []
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,224 @@
1
+ require File.dirname(__FILE__) + '/payflow/payflow_common_api'
2
+ require File.dirname(__FILE__) + '/payflow/payflow_express_response'
3
+ require File.dirname(__FILE__) + '/paypal_express_common'
4
+
5
+ module ActiveMerchant #:nodoc:
6
+ module Billing #:nodoc:
7
+ # ==General Parameters
8
+ # The following parameters are supported for #setup_authorization, #setup_purchase, #authorize and #purchase transactions. I've read
9
+ # in the docs that they recommend you pass the exact same parameters to both setup and authorize/purchase.
10
+ #
11
+ # This information was gleaned from a mix of:
12
+ # * PayFlow documentation
13
+ # * for key value pairs: {Express Checkout for Payflow Pro (PDF)}[https://cms.paypal.com/cms_content/US/en_US/files/developer/PFP_ExpressCheckout_PP.pdf]
14
+ # * XMLPay: {Payflow Pro XMLPay Developer's Guide (PDF)}[https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_PayflowPro_XMLPay_Guide.pdf]
15
+ # * previous ActiveMerchant code
16
+ # * trial & error
17
+ #
18
+ # The following parameters are currently supported.
19
+ # [<tt>:ip</tt>] (opt) Customer IP Address
20
+ # [<tt>:order_id</tt>] (opt) An order or invoice number. This will be passed through to the Payflow backend at manager.paypal.com, and show up as "Supplier Reference #"
21
+ # [<tt>:description</tt>] (opt) Order description, shown to buyer (after redirected to PayPal). If Order Line Items are used (see below), then the description is suppressed. This will not be passed through to the Payflow backend.
22
+ # [<tt>:billing_address</tt>] (opt) See ActiveMerchant::Billing::Gateway for details
23
+ # [<tt>:shipping_address</tt>] (opt) See ActiveMerchant::Billing::Gateway for details
24
+ # [<tt>:currency</tt>] (req) Currency of transaction, will be set to USD by default for PayFlow Express if not specified
25
+ # [<tt>:email</tt>] (opt) Email of buyer; used to pre-fill PayPal login screen
26
+ # [<tt>:payer_id</tt>] (opt) Unique PayPal buyer account identification number, as returned by details_for request
27
+ # [<tt>:token</tt>] (req for #authorize & #purchase) Token returned by setup transaction
28
+ # [<tt>:no_shipping</tt>] (opt) Boolean for whether or not to display shipping address to buyer
29
+ # [<tt>:address_override</tt>] (opt) Boolean. If true, display shipping address passed by parameters, rather than shipping address on file with PayPal
30
+ # [<tt>:allow_note</tt>] (opt) Boolean for permitting buyer to add note during checkout. Note contents can be retrieved with details_for transaction
31
+ # [<tt>:return_url</tt>] (req) URL to which the buyer’s browser is returned after choosing to pay.
32
+ # [<tt>:cancel_return_url</tt>] (req) URL to which the buyer is returned if the buyer cancels the order.
33
+ # [<tt>:notify_url</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
34
+ # [<tt>:comment</tt>] (opt) Comment field which will be reported to Payflow backend (at manager.paypal.com) as Comment1
35
+ # [<tt>:comment2</tt>] (opt) Comment field which will be reported to Payflow backend (at manager.paypal.com) as Comment2
36
+ # [<tt>:discount</tt>] (opt) Total discounts in cents
37
+ #
38
+ # ==Line Items
39
+ # Support for order line items is available, but has to be enabled on the PayFlow backend. This is what I was told by Todd Sieber at Technical Support:
40
+ #
41
+ # <em>You will need to call Payflow Support at 1-888-883-9770, choose option #2. Request that they update your account in "Pandora" under Product Settings >> PayPal Mark and update the Features Bitmap to 1111111111111112. This is 15 ones and a two.</em>
42
+ #
43
+ # See here[https://www.x.com/message/206214#206214] for the forum discussion (requires login to {x.com}[https://x.com]
44
+ #
45
+ # [<tt>:items</tt>] (opt) Array of Order Line Items hashes. These are shown to the buyer after redirect to PayPal.
46
+ #
47
+ #
48
+ #
49
+ # The following keys are supported for line items:
50
+ # [<tt>:name</tt>] Name of line item
51
+ # [<tt>:description</tt>] Description of line item
52
+ # [<tt>:amount</tt>] Line Item Amount in Cents (as Integer)
53
+ # [<tt>:quantity</tt>] Line Item Quantity (default to 1 if left blank)
54
+ #
55
+ # ====Customization of Payment Page
56
+ # [<tt>:page_style</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
57
+ # [<tt>:header_image</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
58
+ # [<tt>:background_color</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
59
+ # ====Additional options for old Checkout Experience, being phased out in 2010 and 2011
60
+ # [<tt>:header_background_color</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
61
+ # [<tt>:header_border_color</tt>] (opt) Your URL for receiving Instant Payment Notification (IPN) about this transaction.
62
+
63
+
64
+ class PayflowExpressGateway < Gateway
65
+ include PayflowCommonAPI
66
+ include PaypalExpressCommon
67
+
68
+ self.test_redirect_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'
69
+ self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
70
+ self.display_name = 'PayPal Express Checkout'
71
+
72
+ def authorize(money, options = {})
73
+ requires!(options, :token, :payer_id)
74
+ request = build_sale_or_authorization_request('Authorization', money, options)
75
+ commit(request, options)
76
+ end
77
+
78
+ def purchase(money, options = {})
79
+ requires!(options, :token, :payer_id)
80
+ request = build_sale_or_authorization_request('Sale', money, options)
81
+ commit(request, options)
82
+ end
83
+
84
+ def refund(money, identification, options = {})
85
+ request = build_reference_request(:credit, money, identification, options)
86
+ commit(request, options)
87
+ end
88
+
89
+ def credit(money, identification, options = {})
90
+ deprecated CREDIT_DEPRECATION_MESSAGE
91
+ refund(money, identification, options)
92
+ end
93
+
94
+ def setup_authorization(money, options = {})
95
+ requires!(options, :return_url, :cancel_return_url)
96
+
97
+ request = build_setup_express_sale_or_authorization_request('Authorization', money, options)
98
+ commit(request, options)
99
+ end
100
+
101
+ def setup_purchase(money, options = {})
102
+ requires!(options, :return_url, :cancel_return_url)
103
+
104
+ request = build_setup_express_sale_or_authorization_request('Sale', money, options)
105
+ commit(request, options)
106
+ end
107
+
108
+ def details_for(token)
109
+ request = build_get_express_details_request(token)
110
+ commit(request, options)
111
+ end
112
+
113
+ private
114
+ def build_get_express_details_request(token)
115
+ xml = Builder::XmlMarkup.new :indent => 2
116
+ xml.tag! 'GetExpressCheckout' do
117
+ xml.tag! 'Authorization' do
118
+ xml.tag! 'PayData' do
119
+ xml.tag! 'Tender' do
120
+ xml.tag! 'PayPal' do
121
+ xml.tag! 'Token', token
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ xml.target!
128
+ end
129
+
130
+ def build_setup_express_sale_or_authorization_request(action, money, options = {})
131
+ xml = Builder::XmlMarkup.new :indent => 2
132
+ xml.tag! 'SetExpressCheckout' do
133
+ xml.tag! action do
134
+ add_pay_data xml, money, options
135
+ end
136
+ end
137
+ xml.target!
138
+ end
139
+
140
+ def build_sale_or_authorization_request(action, money, options)
141
+ xml = Builder::XmlMarkup.new :indent => 2
142
+ xml.tag! 'DoExpressCheckout' do
143
+ xml.tag! action do
144
+ add_pay_data xml, money, options
145
+ end
146
+ end
147
+ xml.target!
148
+ end
149
+
150
+ def add_pay_data(xml, money, options)
151
+ xml.tag! 'PayData' do
152
+ xml.tag! 'Invoice' do
153
+ xml.tag! 'CustIP', options[:ip] unless options[:ip].blank?
154
+ xml.tag! 'InvNum', options[:order_id] unless options[:order_id].blank?
155
+ # Description field will be shown to buyer, unless line items are also being supplied (then only line items are shown).
156
+ xml.tag! 'Description', options[:description] unless options[:description].blank?
157
+ # Comment, Comment2 should make it to the backend at manager.paypal.com, as with Payflow credit card transactions
158
+ # but that doesn't seem to work (yet?). See: https://www.x.com/thread/51908?tstart=0
159
+ xml.tag! 'Comment', options[:comment] unless options[:comment].nil?
160
+ xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].nil?
161
+
162
+ billing_address = options[:billing_address] || options[:address]
163
+ add_address(xml, 'BillTo', billing_address, options) if billing_address
164
+ add_address(xml, 'ShipTo', options[:shipping_address], options) if options[:shipping_address]
165
+
166
+ # Note: To get order line-items to show up with Payflow Express, this feature has to be enabled on the backend.
167
+ # Call Support at 888 883 9770, press 2. Then request that they update your account in "Pandora" under Product Settings >> PayPal
168
+ # Mark and update the Features Bitmap to 1111111111111112. This is 15 ones and a two.
169
+ # See here for the forum discussion: https://www.x.com/message/206214#206214
170
+ items = options[:items] || []
171
+ items.each_with_index do |item, index|
172
+ xml.tag! 'ExtData', 'Name' => "L_DESC#{index}", 'Value' => item[:description]
173
+ xml.tag! 'ExtData', 'Name' => "L_COST#{index}", 'Value' => amount(item[:amount])
174
+ xml.tag! 'ExtData', 'Name' => "L_QTY#{index}", 'Value' => item[:quantity] || '1'
175
+ xml.tag! 'ExtData', 'Name' => "L_NAME#{index}", 'Value' => item[:name]
176
+ # Note: An ItemURL is supported in Paypal Express (different API), but not PayFlow Express, as far as I can tell.
177
+ # L_URLn nor L_ITEMURLn seem to work
178
+ end
179
+ if items.any?
180
+ xml.tag! 'ExtData', 'Name' => 'CURRENCY', 'Value' => options[:currency] || currency(money)
181
+ xml.tag! 'ExtData', 'Name' => "ITEMAMT", 'Value' => amount(options[:subtotal] || money)
182
+ end
183
+ xml.tag! 'DiscountAmt', amount(options[:discount]) if options[:discount]
184
+ xml.tag! 'TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money)
185
+
186
+ end
187
+
188
+ xml.tag! 'Tender' do
189
+ add_paypal_details(xml, options)
190
+ end
191
+ end
192
+ end
193
+
194
+ def add_paypal_details(xml, options)
195
+ xml.tag! 'PayPal' do
196
+ xml.tag! 'EMail', options[:email] unless options[:email].blank?
197
+ xml.tag! 'ReturnURL', options[:return_url] unless options[:return_url].blank?
198
+ xml.tag! 'CancelURL', options[:cancel_return_url] unless options[:cancel_return_url].blank?
199
+ xml.tag! 'NotifyURL', options[:notify_url] unless options[:notify_url].blank?
200
+ xml.tag! 'PayerID', options[:payer_id] unless options[:payer_id].blank?
201
+ xml.tag! 'Token', options[:token] unless options[:token].blank?
202
+ xml.tag! 'NoShipping', options[:no_shipping] ? '1' : '0'
203
+ xml.tag! 'AddressOverride', options[:address_override] ? '1' : '0'
204
+ xml.tag! 'ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
205
+
206
+ # Customization of the payment page
207
+ xml.tag! 'PageStyle', options[:page_style] unless options[:page_style].blank?
208
+ xml.tag! 'HeaderImage', options[:header_image] unless options[:header_image].blank?
209
+ xml.tag! 'PayflowColor', options[:background_color] unless options[:background_color].blank?
210
+ # Note: HeaderImage and PayflowColor apply to both the new (as of 2010) and the old checkout experience
211
+ # HeaderBackColor and HeaderBorderColor apply only to the old checkout experience which is being phased out.
212
+ xml.tag! 'HeaderBackColor', options[:header_background_color] unless options[:header_background_color].blank?
213
+ xml.tag! 'HeaderBorderColor', options[:header_border_color] unless options[:header_border_color].blank?
214
+ xml.tag! 'ExtData', 'Name' => 'ALLOWNOTE', 'Value' => options[:allow_note]
215
+ end
216
+ end
217
+
218
+ def build_response(success, message, response, options = {})
219
+ PayflowExpressResponse.new(success, message, response, options)
220
+ end
221
+ end
222
+ end
223
+ end
224
+