WP eCommerce - Version 3.10.0

Version Description

  • Enhancement: Added updated PayPal gateways. We now support Digital Goods and Pro Hosted, and have updated the Express Checkout gateway. We now recommend all existing users of the 2.0 Express Checkout gateway update to the 3.0 version.
Download this release

Release Info

Developer JustinSainton
Plugin Icon 128x128 WP eCommerce
Version 3.10.0
Comparing to
See all releases

Code changes from version 3.9.5 to 3.10.0

Files changed (187) hide show
  1. package.json +1 -1
  2. phpunit.xml +0 -14
  3. readme.md +1 -1
  4. readme.txt +6 -2
  5. wp-shopping-cart.php +1 -1
  6. wpsc-components/merchant-core-v2/helpers/admin.php +1 -3
  7. wpsc-components/merchant-core-v3/classes/http.php +1 -1
  8. wpsc-components/merchant-core-v3/classes/payment-gateway.php +191 -40
  9. wpsc-components/merchant-core-v3/gateways/dg.css +0 -0
  10. wpsc-components/merchant-core-v3/gateways/dg.js +65 -15
  11. wpsc-components/merchant-core-v3/gateways/dgs.js +62 -0
  12. wpsc-components/merchant-core-v3/gateways/manual.php +0 -0
  13. wpsc-components/merchant-core-v3/gateways/paypal-digital-goods.php +680 -542
  14. wpsc-components/merchant-core-v3/gateways/paypal-express-checkout.php +977 -659
  15. wpsc-components/merchant-core-v3/gateways/paypal-pro.php +65 -74
  16. wpsc-components/merchant-core-v3/gateways/php-merchant/README.md +0 -0
  17. wpsc-components/merchant-core-v3/gateways/php-merchant/common/exception.php +0 -0
  18. wpsc-components/merchant-core-v3/gateways/php-merchant/common/helpers.php +0 -0
  19. wpsc-components/merchant-core-v3/gateways/php-merchant/common/http-curl.php +0 -0
  20. wpsc-components/merchant-core-v3/gateways/php-merchant/common/http.php +0 -0
  21. wpsc-components/merchant-core-v3/gateways/php-merchant/common/php-merchant.php +0 -0
  22. wpsc-components/merchant-core-v3/gateways/php-merchant/common/response.php +0 -0
  23. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-digital-goods.php +22 -19
  24. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-express-checkout-response.php +0 -0
  25. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-express-checkout.php +73 -34
  26. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-ipn.php +0 -0
  27. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-pro-response.php +0 -0
  28. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-pro.php +53 -16
  29. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-response.php +0 -0
  30. wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal.php +0 -0
  31. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/http-curl.php +0 -0
  32. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/php-merchant.php +0 -0
  33. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/test-accounts.php +0 -0
  34. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal-express-checkout.php +0 -0
  35. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal-ipn.php +0 -0
  36. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal.php +0 -0
  37. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/index.php +0 -0
  38. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/http-curl.php +0 -0
  39. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x1.php +0 -0
  40. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x2.php +0 -0
  41. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x3.php +0 -0
  42. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x4.php +0 -0
  43. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x1.php +0 -0
  44. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x2.php +0 -0
  45. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x3.php +0 -0
  46. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x4.php +0 -0
  47. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x5.php +0 -0
  48. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x6.php +0 -0
  49. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-express-checkout.php +0 -0
  50. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-pro-cert-x1.php +0 -0
  51. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-pro-cert-x2.php +0 -0
  52. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE +0 -0
  53. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/LICENSE +0 -0
  54. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/README +0 -0
  55. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/VERSION +0 -0
  56. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/authentication.php +0 -0
  57. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/autorun.php +0 -0
  58. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/browser.php +0 -0
  59. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/collector.php +0 -0
  60. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/compatibility.php +0 -0
  61. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/cookies.php +0 -0
  62. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/default_reporter.php +0 -0
  63. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/detached.php +0 -0
  64. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/authentication_documentation.html +0 -0
  65. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/browser_documentation.html +0 -0
  66. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/docs.css +0 -0
  67. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/expectation_documentation.html +0 -0
  68. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/form_testing_documentation.html +0 -0
  69. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/group_test_documentation.html +0 -0
  70. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/index.html +0 -0
  71. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/mock_objects_documentation.html +0 -0
  72. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/overview.html +0 -0
  73. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/partial_mocks_documentation.html +0 -0
  74. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/reporter_documentation.html +0 -0
  75. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/unit_test_documentation.html +0 -0
  76. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/web_tester_documentation.html +0 -0
  77. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/authentication_documentation.html +0 -0
  78. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/browser_documentation.html +0 -0
  79. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/docs.css +0 -0
  80. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/expectation_documentation.html +0 -0
  81. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/form_testing_documentation.html +0 -0
  82. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/group_test_documentation.html +0 -0
  83. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/index.html +0 -0
  84. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/mock_objects_documentation.html +0 -0
  85. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/overview.html +0 -0
  86. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/partial_mocks_documentation.html +0 -0
  87. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/reporter_documentation.html +0 -0
  88. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/unit_test_documentation.html +0 -0
  89. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/web_tester_documentation.html +0 -0
  90. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/dumper.php +0 -0
  91. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/eclipse.php +0 -0
  92. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/encoding.php +0 -0
  93. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/errors.php +0 -0
  94. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/exceptions.php +0 -0
  95. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/expectation.php +0 -0
  96. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/pear_test_case.php +0 -0
  97. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/testdox.php +0 -0
  98. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/testdox/test.php +0 -0
  99. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/form.php +0 -0
  100. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/frames.php +0 -0
  101. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/http.php +0 -0
  102. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/invoker.php +0 -0
  103. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/mock_objects.php +0 -0
  104. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/page.php +0 -0
  105. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/php_parser.php +0 -0
  106. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reflection_php4.php +0 -0
  107. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reflection_php5.php +0 -0
  108. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/remote.php +0 -0
  109. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reporter.php +0 -0
  110. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/scorer.php +0 -0
  111. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/selector.php +0 -0
  112. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/shell_tester.php +0 -0
  113. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/simpletest.php +0 -0
  114. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/socket.php +0 -0
  115. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/tag.php +0 -0
  116. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/acceptance_test.php +0 -0
  117. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/adapter_test.php +0 -0
  118. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/all_tests.php +0 -0
  119. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/authentication_test.php +0 -0
  120. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/autorun_test.php +0 -0
  121. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/bad_test_suite.php +0 -0
  122. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/browser_test.php +0 -0
  123. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/collector_test.php +0 -0
  124. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/command_line_test.php +0 -0
  125. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/compatibility_test.php +0 -0
  126. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/cookies_test.php +0 -0
  127. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/detached_test.php +0 -0
  128. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/dumper_test.php +0 -0
  129. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/eclipse_test.php +0 -0
  130. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/encoding_test.php +0 -0
  131. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/errors_test.php +0 -0
  132. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/exceptions_test.php +0 -0
  133. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/expectation_test.php +0 -0
  134. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/form_test.php +0 -0
  135. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/frames_test.php +0 -0
  136. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/http_test.php +0 -0
  137. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/interfaces_test.php +0 -0
  138. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/interfaces_test_php5_1.php +0 -0
  139. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/live_test.php +0 -0
  140. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/mock_objects_test.php +0 -0
  141. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/page_test.php +0 -0
  142. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/parse_error_test.php +0 -0
  143. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/parsing_test.php +0 -0
  144. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/php_parser_test.php +0 -0
  145. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/reflection_php4_test.php +0 -0
  146. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/reflection_php5_test.php +0 -0
  147. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/remote_test.php +0 -0
  148. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/shell_test.php +0 -0
  149. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/shell_tester_test.php +0 -0
  150. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/simpletest_test.php +0 -0
  151. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/site/file.html +0 -0
  152. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/socket_test.php +0 -0
  153. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/collector/collectable.1 +0 -0
  154. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/collector/collectable.2 +0 -0
  155. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/empty_test_file.php +0 -0
  156. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/failing_test.php +0 -0
  157. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/latin1_sample +0 -0
  158. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/passing_test.php +0 -0
  159. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/spl_examples.php +0 -0
  160. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/supplementary_upload_sample.txt +0 -0
  161. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/test1.php +0 -0
  162. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/upload_sample.txt +0 -0
  163. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/tag_test.php +0 -0
  164. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/test_with_parse_error.php +0 -0
  165. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/unit_tester_test.php +0 -0
  166. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/unit_tests.php +0 -0
  167. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/url_test.php +0 -0
  168. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/user_agent_test.php +0 -0
  169. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/visual_test.php +0 -0
  170. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/web_tester_test.php +0 -0
  171. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/xml_test.php +0 -0
  172. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test_case.php +0 -0
  173. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/tidy_parser.php +0 -0
  174. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/unit_tester.php +0 -0
  175. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/url.php +0 -0
  176. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/user_agent.php +0 -0
  177. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/varlog.php +0 -0
  178. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/web_tester.php +0 -0
  179. wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/xml.php +0 -0
  180. wpsc-components/merchant-core-v3/gateways/pro.css +23 -0
  181. wpsc-components/merchant-core-v3/gateways/pro.js +27 -15
  182. wpsc-components/merchant-core-v3/helpers/admin.php +0 -0
  183. wpsc-components/merchant-core-v3/helpers/checkout.php +4 -2
  184. wpsc-components/merchant-core-v3/helpers/common.php +12 -1
  185. wpsc-components/merchant-core-v3/helpers/payment-gateway.php +0 -0
  186. wpsc-components/merchant-core-v3/merchant-core-v3.php +3 -1
  187. wpsc-core/wpsc-constants.php +3 -3
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "wp-e-commerce",
3
- "version": "3.9.5",
4
  "private": true,
5
  "devDependencies": {
6
  "grunt": "~0.4.5",
1
  {
2
  "name": "wp-e-commerce",
3
+ "version": "3.10.0",
4
  "private": true,
5
  "devDependencies": {
6
  "grunt": "~0.4.5",
phpunit.xml DELETED
@@ -1,14 +0,0 @@
1
- <phpunit
2
- bootstrap="tests/bootstrap.php"
3
- backupGlobals="false"
4
- colors="true"
5
- convertErrorsToExceptions="true"
6
- convertNoticesToExceptions="false"
7
- convertWarningsToExceptions="false"
8
- >
9
- <testsuites>
10
- <testsuite>
11
- <directory prefix="test-" suffix=".php">./tests/</directory>
12
- </testsuite>
13
- </testsuites>
14
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.md CHANGED
@@ -15,7 +15,7 @@ If you're looking for general user support, please submit your support request o
15
  Development status
16
  -------------------------
17
 
18
- * The latest stable version is [3.9.5](http://wordpress.org/extend/plugins/wp-e-commerce).
19
  * Active development version: 4.0-dev (branch [master](https://github.com/wp-e-commerce/WP-e-Commerce))
20
  * [Roadmap for 4.0](https://github.com/wp-e-commerce/wp-e-commerce/wiki/Roadmap)
21
  * [4.0 tickets](https://github.com/wp-e-commerce/WP-e-Commerce/milestones/4.0)
15
  Development status
16
  -------------------------
17
 
18
+ * The latest stable version is [3.10.0](http://wordpress.org/extend/plugins/wp-e-commerce).
19
  * Active development version: 4.0-dev (branch [master](https://github.com/wp-e-commerce/WP-e-Commerce))
20
  * [Roadmap for 4.0](https://github.com/wp-e-commerce/wp-e-commerce/wiki/Roadmap)
21
  * [4.0 tickets](https://github.com/wp-e-commerce/WP-e-Commerce/milestones/4.0)
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: JustinSainton, mufasa
3
  Donate link: https://wpecommerce.org
4
  Tags: e-commerce, wp-e-commerce, shop, cart, paypal, authorize, stock control, ecommerce, shipping, tax
5
- Requires at least: 4.0
6
  Tested up to: 4.3
7
- Stable tag: 3.9.5
8
 
9
  WP eCommerce is a free, powerful plugin that empowers you to sell anything online, quickly and easily.
10
 
@@ -36,6 +36,10 @@ After upgrading from earlier versions look for link "Update Store". This will up
36
 
37
  == Changelog ==
38
 
 
 
 
 
39
  = 3.9.5 =
40
 
41
  * Fix: 4.3 Compatibility w/ WP_Widget constructors.
2
  Contributors: JustinSainton, mufasa
3
  Donate link: https://wpecommerce.org
4
  Tags: e-commerce, wp-e-commerce, shop, cart, paypal, authorize, stock control, ecommerce, shipping, tax
5
+ Requires at least: 4.1
6
  Tested up to: 4.3
7
+ Stable tag: 3.10.0
8
 
9
  WP eCommerce is a free, powerful plugin that empowers you to sell anything online, quickly and easily.
10
 
36
 
37
  == Changelog ==
38
 
39
+ = 3.10.0 =
40
+
41
+ * Enhancement: Added updated PayPal gateways. We now support Digital Goods and Pro Hosted, and have updated the Express Checkout gateway. We now recommend all existing users of the 2.0 Express Checkout gateway update to the 3.0 version.
42
+
43
  = 3.9.5 =
44
 
45
  * Fix: 4.3 Compatibility w/ WP_Widget constructors.
wp-shopping-cart.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WP eCommerce
4
  * Plugin URI: http://wpecommerce.org/
5
  * Description: A plugin that provides a WordPress Shopping Cart. See also: <a href="http://wpecommerce.org" target="_blank">WPeCommerce.org</a> | <a href="https://wordpress.org/support/plugin/wp-e-commerce/" target="_blank">Support Forum</a> | <a href="http://docs.wpecommerce.org/" target="_blank">Documentation</a>
6
- * Version: 3.9.5
7
  * Author: WP eCommerce
8
  * Author URI: http://wpecommerce.org/
9
  **/
3
  * Plugin Name: WP eCommerce
4
  * Plugin URI: http://wpecommerce.org/
5
  * Description: A plugin that provides a WordPress Shopping Cart. See also: <a href="http://wpecommerce.org" target="_blank">WPeCommerce.org</a> | <a href="https://wordpress.org/support/plugin/wp-e-commerce/" target="_blank">Support Forum</a> | <a href="http://docs.wpecommerce.org/" target="_blank">Documentation</a>
6
+ * Version: 3.10.0
7
  * Author: WP eCommerce
8
  * Author URI: http://wpecommerce.org/
9
  **/
wpsc-components/merchant-core-v2/helpers/admin.php CHANGED
@@ -40,9 +40,7 @@ add_filter(
40
  function wpsc_filter_deprecated_v2_gateways( $gateways ) {
41
 
42
  $deprecated_gateways = array(
43
- 'manual',
44
- 'paypal-pro',
45
- 'paypal-express-checkout'
46
  );
47
 
48
  // Loops through available gateways, checks if available gateway is both inactive and deprecated, and removes it.
40
  function wpsc_filter_deprecated_v2_gateways( $gateways ) {
41
 
42
  $deprecated_gateways = array(
43
+ 'wpsc_merchant_paypal_express'
 
 
44
  );
45
 
46
  // Loops through available gateways, checks if available gateway is both inactive and deprecated, and removes it.
wpsc-components/merchant-core-v3/classes/http.php CHANGED
@@ -16,7 +16,7 @@ class WPSC_Payment_Gateway_HTTP extends PHP_Merchant_HTTP {
16
  $args = array_merge( $defaults, $args );
17
  $args['body'] = $fields;
18
 
19
- $response = wp_remote_request( $url, $args );
20
 
21
  if ( is_wp_error( $response ) )
22
  throw new PHP_Merchant_Exception( PHPME_HTTP_REQUEST_FAILED, $response->get_error_message() );
16
  $args = array_merge( $defaults, $args );
17
  $args['body'] = $fields;
18
 
19
+ $response = wp_safe_remote_request( $url, $args );
20
 
21
  if ( is_wp_error( $response ) )
22
  throw new PHP_Merchant_Exception( PHPME_HTTP_REQUEST_FAILED, $response->get_error_message() );
wpsc-components/merchant-core-v3/classes/payment-gateway.php CHANGED
@@ -55,37 +55,54 @@ final class WPSC_Payment_Gateways {
55
  * @since 3.9
56
  */
57
  public static function &get( $gateway, $meta = false ) {
58
- if ( empty( self::$instances[$gateway] ) ) {
59
- if ( ! $meta )
60
- $meta = self::$gateways[$gateway];
 
 
 
 
 
 
 
 
61
  require_once( $meta['path'] );
 
62
  $class_name = $meta['class'];
 
63
  $options = array(
64
  'http_client' => new WPSC_Payment_Gateway_HTTP(),
65
  );
 
66
  if ( ! class_exists( $class_name ) ) {
67
  $error = new WP_Error( 'wpsc_invalid_payment_gateway', sprintf( __( 'Invalid payment gateway: Class %s does not exist.', 'wpsc' ), $class_name ) );
68
  return $error;
69
  }
70
 
71
- self::$instances[$gateway] = new $class_name( $options );
72
  }
73
 
74
- return self::$instances[$gateway];
75
  }
76
 
77
  public static function init() {
 
78
  add_action( 'wpsc_submit_gateway_options', array( 'WPSC_Payment_Gateway_Setting', 'action_update_payment_gateway_settings' ) );
79
 
80
- if ( ! defined( 'WPSC_PAYMENT_GATEWAY_DEBUG' ) || WPSC_PAYMENT_GATEWAY_DEBUG == false )
81
- add_action( 'wp_loaded', array( 'WPSC_Payment_Gateways', 'action_save_payment_gateway_cache' ), 99 );
82
- else
83
  WPSC_Payment_Gateways::flush_cache();
 
84
 
85
  WPSC_Payment_Gateways::register_dir( WPSC_MERCHANT_V3_PATH . '/gateways' );
86
 
87
- if ( isset( $_REQUEST['payment_gateway'] ) && isset( $_REQUEST['payment_gateway_callback'] ) && self::is_registered( $_REQUEST['payment_gateway'] ) )
 
 
 
88
  add_action( 'init', array( 'WPSC_Payment_Gateways', 'action_process_callbacks' ) );
 
89
  }
90
 
91
  public static function action_process_callbacks() {
@@ -93,8 +110,9 @@ final class WPSC_Payment_Gateways {
93
  $function_name = "callback_{$_REQUEST['payment_gateway_callback']}";
94
  $callback = array( $gateway, $function_name );
95
 
96
- if ( is_callable( $callback ) )
97
  $gateway->$function_name();
 
98
  }
99
 
100
  /**
@@ -107,7 +125,7 @@ final class WPSC_Payment_Gateways {
107
  * @return bool True if it's already registered.
108
  */
109
  public static function is_registered( $gateway ) {
110
- return ! empty( self::$gateways[$gateway] );
111
  }
112
 
113
  /**
@@ -149,19 +167,22 @@ final class WPSC_Payment_Gateways {
149
  // scan files in dir
150
  $files = scandir( $dir );
151
 
152
- if ( in_array( $main_file, $files ) )
153
  return self::register_file( $dir . $main_file );
 
154
 
155
  foreach ( $files as $file ) {
156
  $path = $dir . $file;
157
 
158
- if ( pathinfo( $path, PATHINFO_EXTENSION ) != 'php' || in_array( $file, array( '.', '..' ) ) || is_dir( $path ) )
159
  continue;
 
160
 
161
  $return = self::register_file( $path );
162
 
163
- if ( is_wp_error( $return ) )
164
  return $return;
 
165
  }
166
  }
167
 
@@ -188,20 +209,35 @@ final class WPSC_Payment_Gateways {
188
  * a valid class. Otherwise, a WP_Error object is returned.
189
  */
190
  public static function register_file( $file ) {
191
- if ( empty( self::$payment_gateway_cache ) )
 
192
  self::$payment_gateway_cache = get_option( 'wpsc_payment_gateway_cache', array() );
 
 
193
  $filename = basename( $file, '.php' );
194
 
195
  // payment gateway already exists in cache
196
- if ( isset( self::$payment_gateway_cache[$filename] ) ) {
197
- self::$gateways[$filename] = self::$payment_gateway_cache[$filename];
198
- return true;
199
  }
200
 
201
  // if payment gateway is not in cache, load metadata
202
  $classname = ucwords( str_replace( '-', ' ', $filename ) );
203
  $classname = 'WPSC_Payment_Gateway_' . str_replace( ' ', '_', $classname );
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  $meta = array(
206
  'class' => $classname,
207
  'path' => $file,
@@ -210,17 +246,25 @@ final class WPSC_Payment_Gateways {
210
 
211
  $gateway = self::get( $filename, $meta );
212
 
213
- if ( is_wp_error( $gateway ) )
214
  return $gateway;
 
215
 
216
- $meta['name'] = $gateway->get_title();
217
  $meta['image'] = $gateway->get_image_url();
218
- $meta['mark'] = $gateway->get_mark_html();
219
- self::$gateways[$filename] = $meta;
 
220
 
221
  return true;
222
  }
223
 
 
 
 
 
 
 
224
  /**
225
  * Updates the payment gateway cache when it's changed.
226
  *
@@ -233,13 +277,14 @@ final class WPSC_Payment_Gateways {
233
  * @return void
234
  */
235
  public static function action_save_payment_gateway_cache() {
236
- if ( self::$payment_gateway_cache != self::$gateways )
237
  update_option( 'wpsc_payment_gateway_cache', self::$gateways );
 
238
  }
239
 
240
  /**
241
- * Flush the payment gateways cache.
242
- *
243
  * @access public
244
  * @static
245
  * @since 3.9
@@ -278,6 +323,15 @@ final class WPSC_Payment_Gateways {
278
  return array_keys( self::$gateways );
279
  }
280
 
 
 
 
 
 
 
 
 
 
281
  public static function get_active_gateways() {
282
  if ( empty( self::$active_gateways ) ) {
283
  $selected_gateways = get_option( 'custom_gateway_options', array() );
@@ -288,6 +342,83 @@ final class WPSC_Payment_Gateways {
288
  return apply_filters( 'wpsc_get_active_gateways', array_values( self::$active_gateways ) );
289
  }
290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  /**
292
  * No instantiation for this class
293
  *
@@ -346,20 +477,22 @@ abstract class WPSC_Payment_Gateway {
346
  */
347
  public function setup_form() {
348
  $checkout_field_types = array(
349
- 'billing' => __( 'Billing Fields', 'wpsc' ),
350
  'shipping' => __( 'Shipping Fields', 'wpsc' ),
351
  );
352
 
353
  $fields = array(
354
- 'firstname' => __( 'First Name', 'wpsc' ),
355
- 'lastname' => __( 'Last Name', 'wpsc' ),
356
- 'address' => __( 'Address', 'wpsc' ),
357
- 'city' => __( 'City', 'wpsc' ),
358
- 'state' => __( 'State', 'wpsc' ),
359
- 'country' => __( 'Country', 'wpsc' ),
360
  'postcode' => __( 'Postal Code', 'wpsc' ),
361
  );
 
362
  $checkout_form = WPSC_Checkout_Form::get();
 
363
  foreach ( $checkout_field_types as $field_type => $title ): ?>
364
  <tr>
365
  <td colspan="2">
@@ -448,7 +581,7 @@ abstract class WPSC_Payment_Gateway {
448
  }
449
 
450
  public function get_shopping_cart_payment_url() {
451
- return _wpsc_maybe_activate_theme_engine_v2() ? wpsc_get_checkout_url( 'payment' ) : get_option( 'shopping_cart_url' );
452
  }
453
 
454
  public function get_products_page_url() {
@@ -479,14 +612,29 @@ abstract class WPSC_Payment_Gateway {
479
  }
480
 
481
  /**
482
- * Payment gateway constructor. Should use WPSC_Payment_Gateways::get( $gateway_name ) instead.
 
 
483
  *
484
  * @access public
485
  * @return WPSC_Payment_Gateway
486
  */
487
  public function __construct() {
 
488
  $this->setting = new WPSC_Payment_Gateway_Setting( get_class( $this ) );
489
  }
 
 
 
 
 
 
 
 
 
 
 
 
490
  }
491
 
492
  class WPSC_Payment_Gateway_Setting {
@@ -562,8 +710,9 @@ class WPSC_Payment_Gateway_Setting {
562
  * @return void
563
  */
564
  private function lazy_load() {
565
- if ( is_null( $this->settings ) )
566
  $this->settings = get_option( $this->option_name, array() );
 
567
  }
568
 
569
  /**
@@ -575,7 +724,7 @@ class WPSC_Payment_Gateway_Setting {
575
  */
576
  public function get( $setting, $default = false ) {
577
  $this->lazy_load();
578
- return isset( $this->settings[$setting] ) ? $this->settings[$setting] : $default;
579
  }
580
 
581
  /**
@@ -589,9 +738,10 @@ class WPSC_Payment_Gateway_Setting {
589
  */
590
  public function set( $setting, $value, $defer = false ) {
591
  $this->lazy_load();
592
- $this->unsaved_settings[$setting] = $value;
593
- if ( ! $defer )
594
  $this->save();
 
595
  }
596
 
597
  /**
@@ -607,8 +757,9 @@ class WPSC_Payment_Gateway_Setting {
607
  public function merge( $settings, $defer = false ) {
608
  $this->lazy_load();
609
  $this->unsaved_settings = array_merge( $this->unsaved_settings, $settings );
610
- if ( ! $defer )
611
  $this->save();
 
612
  }
613
 
614
  /**
@@ -636,4 +787,4 @@ class WPSC_Payment_Gateway_Setting {
636
  }
637
  }
638
 
639
- WPSC_Payment_Gateways::init();
55
  * @since 3.9
56
  */
57
  public static function &get( $gateway, $meta = false ) {
58
+
59
+ if ( empty( self::$instances[ $gateway ] ) ) {
60
+
61
+ if ( ! $meta ) {
62
+ $meta = self::$gateways[ $gateway ];
63
+ }
64
+
65
+ if ( ! file_exists( $meta['path'] ) ) {
66
+ WPSC_Payment_Gateways::flush_cache();
67
+ }
68
+
69
  require_once( $meta['path'] );
70
+
71
  $class_name = $meta['class'];
72
+
73
  $options = array(
74
  'http_client' => new WPSC_Payment_Gateway_HTTP(),
75
  );
76
+
77
  if ( ! class_exists( $class_name ) ) {
78
  $error = new WP_Error( 'wpsc_invalid_payment_gateway', sprintf( __( 'Invalid payment gateway: Class %s does not exist.', 'wpsc' ), $class_name ) );
79
  return $error;
80
  }
81
 
82
+ self::$instances[ $gateway ] = new $class_name( $options );
83
  }
84
 
85
+ return self::$instances[ $gateway ];
86
  }
87
 
88
  public static function init() {
89
+
90
  add_action( 'wpsc_submit_gateway_options', array( 'WPSC_Payment_Gateway_Setting', 'action_update_payment_gateway_settings' ) );
91
 
92
+ if ( ! defined( 'WPSC_PAYMENT_GATEWAY_DEBUG' ) || WPSC_PAYMENT_GATEWAY_DEBUG == false ) {
93
+ add_action( 'init', array( 'WPSC_Payment_Gateways', 'action_save_payment_gateway_cache' ), 99 );
94
+ } else {
95
  WPSC_Payment_Gateways::flush_cache();
96
+ }
97
 
98
  WPSC_Payment_Gateways::register_dir( WPSC_MERCHANT_V3_PATH . '/gateways' );
99
 
100
+ // Call the Active Gateways init function
101
+ self::initialize_gateways();
102
+
103
+ if ( isset( $_REQUEST['payment_gateway'] ) && isset( $_REQUEST['payment_gateway_callback'] ) ) {
104
  add_action( 'init', array( 'WPSC_Payment_Gateways', 'action_process_callbacks' ) );
105
+ }
106
  }
107
 
108
  public static function action_process_callbacks() {
110
  $function_name = "callback_{$_REQUEST['payment_gateway_callback']}";
111
  $callback = array( $gateway, $function_name );
112
 
113
+ if ( is_callable( $callback ) ) {
114
  $gateway->$function_name();
115
+ }
116
  }
117
 
118
  /**
125
  * @return bool True if it's already registered.
126
  */
127
  public static function is_registered( $gateway ) {
128
+ return ! empty( self::$gateways[ $gateway ] );
129
  }
130
 
131
  /**
167
  // scan files in dir
168
  $files = scandir( $dir );
169
 
170
+ if ( in_array( $main_file, $files ) ) {
171
  return self::register_file( $dir . $main_file );
172
+ }
173
 
174
  foreach ( $files as $file ) {
175
  $path = $dir . $file;
176
 
177
+ if ( pathinfo( $path, PATHINFO_EXTENSION ) != 'php' || in_array( $file, array( '.', '..' ) ) || is_dir( $path ) ) {
178
  continue;
179
+ }
180
 
181
  $return = self::register_file( $path );
182
 
183
+ if ( is_wp_error( $return ) ) {
184
  return $return;
185
+ }
186
  }
187
  }
188
 
209
  * a valid class. Otherwise, a WP_Error object is returned.
210
  */
211
  public static function register_file( $file ) {
212
+
213
+ if ( empty( self::$payment_gateway_cache ) ) {
214
  self::$payment_gateway_cache = get_option( 'wpsc_payment_gateway_cache', array() );
215
+ }
216
+
217
  $filename = basename( $file, '.php' );
218
 
219
  // payment gateway already exists in cache
220
+ if ( isset( self::$payment_gateway_cache[ $filename ] ) ) {
221
+ self::$gateways[ $filename ] = self::$payment_gateway_cache[ $filename ];
 
222
  }
223
 
224
  // if payment gateway is not in cache, load metadata
225
  $classname = ucwords( str_replace( '-', ' ', $filename ) );
226
  $classname = 'WPSC_Payment_Gateway_' . str_replace( ' ', '_', $classname );
227
 
228
+ if ( file_exists( $file ) ) {
229
+ require_once $file;
230
+ }
231
+
232
+ if ( is_callable( array( $classname, 'load' ) ) && ! call_user_func( array( $classname, 'load' ) ) ) {
233
+
234
+ self::unregister_file( $filename );
235
+
236
+ $error = new WP_Error( 'wpsc-payment', __( 'Error' ) );
237
+
238
+ return $error;
239
+ }
240
+
241
  $meta = array(
242
  'class' => $classname,
243
  'path' => $file,
246
 
247
  $gateway = self::get( $filename, $meta );
248
 
249
+ if ( is_wp_error( $gateway ) ) {
250
  return $gateway;
251
+ }
252
 
253
+ $meta['name'] = $gateway->get_title();
254
  $meta['image'] = $gateway->get_image_url();
255
+ $meta['mark'] = $gateway->get_mark_html();
256
+
257
+ self::$gateways[ $filename ] = $meta;
258
 
259
  return true;
260
  }
261
 
262
+ public static function unregister_file( $filename ) {
263
+ if ( isset( self::$gateways[ $filename ] ) ) {
264
+ unset( self::$gateways[ $filename ] );
265
+ }
266
+ }
267
+
268
  /**
269
  * Updates the payment gateway cache when it's changed.
270
  *
277
  * @return void
278
  */
279
  public static function action_save_payment_gateway_cache() {
280
+ if ( self::$payment_gateway_cache != self::$gateways ) {
281
  update_option( 'wpsc_payment_gateway_cache', self::$gateways );
282
+ }
283
  }
284
 
285
  /**
286
+ * Flush the payment gateways cache.
287
+ *
288
  * @access public
289
  * @static
290
  * @since 3.9
323
  return array_keys( self::$gateways );
324
  }
325
 
326
+ /**
327
+ *
328
+ * Return an array containing active gateway names.
329
+ *
330
+ * @access public
331
+ * @since 3.9
332
+ *
333
+ * @return array
334
+ */
335
  public static function get_active_gateways() {
336
  if ( empty( self::$active_gateways ) ) {
337
  $selected_gateways = get_option( 'custom_gateway_options', array() );
342
  return apply_filters( 'wpsc_get_active_gateways', array_values( self::$active_gateways ) );
343
  }
344
 
345
+ /**
346
+ * Initialize the Active Gateways
347
+ *
348
+ * @access public
349
+ * @since 4.0
350
+ *
351
+ * @return void
352
+ */
353
+ public static function initialize_gateways() {
354
+ $active_gateways = self::get_active_gateways();
355
+
356
+ foreach( $active_gateways as $gateway_id ) {
357
+ $gateway = self::get( $gateway_id );
358
+ $gateway->init();
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Returns all known currencies without fractions.
364
+ *
365
+ * Our internal list has not been updated in some time, so returning a filterable list
366
+ * for ever-changing economies and currencies should prove helpful.
367
+ *
368
+ * @link http://www.currency-iso.org/dam/downloads/table_a1.xml
369
+ *
370
+ * @since 4.0
371
+ *
372
+ * @return array Currency ISO codes that do not use fractions.
373
+ */
374
+ public static function currencies_without_fractions() {
375
+
376
+ $currencies = array(
377
+ 'JPY',
378
+ 'HUF',
379
+ 'VND',
380
+ 'BYR',
381
+ 'XOF',
382
+ 'BIF',
383
+ 'XAF',
384
+ 'CLP',
385
+ 'KMF',
386
+ 'DJF',
387
+ 'XPF',
388
+ 'GNF',
389
+ 'ISK',
390
+ 'GNF',
391
+ 'KRW',
392
+ 'PYG',
393
+ 'RWF',
394
+ 'UGX',
395
+ 'UYI',
396
+ 'VUV',
397
+ );
398
+
399
+ return (array) apply_filters( 'wpsc_currencies_without_fractions', $currencies );
400
+ }
401
+
402
+ /**
403
+ * Gets an array of countries in the EU.
404
+ *
405
+ * MC (monaco) and IM (Isle of Man, part of UK) also use VAT.
406
+ *
407
+ * @since 4.0
408
+ * @param $type Type of countries to retrieve. Blank for EU member countries. eu_vat for EU VAT countries.
409
+ * @return string[]
410
+ */
411
+ public function get_european_union_countries( $type = '' ) {
412
+ $countries = array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HU', 'HR', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
413
+
414
+ if ( 'eu_vat' === $type ) {
415
+ $countries[] = 'MC';
416
+ $countries[] = 'IM';
417
+ }
418
+
419
+ return $countries;
420
+ }
421
+
422
  /**
423
  * No instantiation for this class
424
  *
477
  */
478
  public function setup_form() {
479
  $checkout_field_types = array(
480
+ 'billing' => __( 'Billing Fields' , 'wpsc' ),
481
  'shipping' => __( 'Shipping Fields', 'wpsc' ),
482
  );
483
 
484
  $fields = array(
485
+ 'firstname' => __( 'First Name' , 'wpsc' ),
486
+ 'lastname' => __( 'Last Name' , 'wpsc' ),
487
+ 'address' => __( 'Address' , 'wpsc' ),
488
+ 'city' => __( 'City' , 'wpsc' ),
489
+ 'state' => __( 'State' , 'wpsc' ),
490
+ 'country' => __( 'Country' , 'wpsc' ),
491
  'postcode' => __( 'Postal Code', 'wpsc' ),
492
  );
493
+
494
  $checkout_form = WPSC_Checkout_Form::get();
495
+
496
  foreach ( $checkout_field_types as $field_type => $title ): ?>
497
  <tr>
498
  <td colspan="2">
581
  }
582
 
583
  public function get_shopping_cart_payment_url() {
584
+ return _wpsc_maybe_activate_theme_engine_v2() ? wpsc_get_checkout_url( 'shipping-and-billing' ) : get_option( 'shopping_cart_url' );
585
  }
586
 
587
  public function get_products_page_url() {
612
  }
613
 
614
  /**
615
+ * Payment gateway constructor.
616
+ *
617
+ * Use WPSC_Payment_Gateways::get( $gateway_name ) instead.
618
  *
619
  * @access public
620
  * @return WPSC_Payment_Gateway
621
  */
622
  public function __construct() {
623
+
624
  $this->setting = new WPSC_Payment_Gateway_Setting( get_class( $this ) );
625
  }
626
+
627
+ /**
628
+ * Gateway initialization function.
629
+ *
630
+ * You should use this function for hooks with actions and filters that are required by the gateway.
631
+ *
632
+ * @access public
633
+ * @since 4.0
634
+ *
635
+ * @return void
636
+ */
637
+ public function init() {}
638
  }
639
 
640
  class WPSC_Payment_Gateway_Setting {
710
  * @return void
711
  */
712
  private function lazy_load() {
713
+ if ( is_null( $this->settings ) ) {
714
  $this->settings = get_option( $this->option_name, array() );
715
+ }
716
  }
717
 
718
  /**
724
  */
725
  public function get( $setting, $default = false ) {
726
  $this->lazy_load();
727
+ return isset( $this->settings[ $setting ] ) ? $this->settings[ $setting ] : $default;
728
  }
729
 
730
  /**
738
  */
739
  public function set( $setting, $value, $defer = false ) {
740
  $this->lazy_load();
741
+ $this->unsaved_settings[ $setting ] = $value;
742
+ if ( ! $defer ) {
743
  $this->save();
744
+ }
745
  }
746
 
747
  /**
757
  public function merge( $settings, $defer = false ) {
758
  $this->lazy_load();
759
  $this->unsaved_settings = array_merge( $this->unsaved_settings, $settings );
760
+ if ( ! $defer ) {
761
  $this->save();
762
+ }
763
  }
764
 
765
  /**
787
  }
788
  }
789
 
790
+ WPSC_Payment_Gateways::init();
wpsc-components/merchant-core-v3/gateways/dg.css CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/dg.js CHANGED
@@ -2,27 +2,77 @@
2
  * PayPal for Digital Goods script
3
  */
4
  (function($) {
5
- $(window).load(function() {
6
- // Declare variables/doom elements
7
- var $checkout_btn = $( '.wpsc-checkout-form-button' ),
 
 
 
 
 
8
  $rd_btn = $( 'input[value="paypal-digital-goods"]' ),
9
- $inputs = $( 'input[type="radio"]' ),
10
- $form = $( '#wpsc-checkout-form' );
11
 
12
  // Change the id of the checkout button
13
  $checkout_btn.attr( 'id', 'submitBtn' );
14
 
15
- // Gateway selection changed
16
- $inputs.on( 'change', function() {
17
  if ( $rd_btn.is( ':checked' ) ) {
18
- // Starts the DG Flow
19
- var dg = new PAYPAL.apps.DGFlow( {
20
- trigger: 'submitBtn'
21
- } );
22
- } else {
23
- $form.attr( 'target', '' );
24
  }
25
- } );
26
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  } )( jQuery );
2
  * PayPal for Digital Goods script
3
  */
4
  (function($) {
5
+ var utils = {
6
+ isValidPPURL: function( url ) {
7
+ return url.substring( 0, 4 ) === 'http';
8
+ }
9
+ };
10
+ $( window ).load( function() {
11
+ // Declare DOM elements
12
+ var $checkout_btn = $( '.wpsc-checkout-form-button, .wpsc_buy_button' ),
13
  $rd_btn = $( 'input[value="paypal-digital-goods"]' ),
14
+ $form = $( '#wpsc-checkout-form, .wpsc_checkout_forms' );
 
15
 
16
  // Change the id of the checkout button
17
  $checkout_btn.attr( 'id', 'submitBtn' );
18
 
19
+ // Disable Form submission if DG is selected
20
+ $form.on ( 'submit', function() {
21
  if ( $rd_btn.is( ':checked' ) ) {
22
+ return false;
 
 
 
 
 
23
  }
24
+ } );
25
+
26
+ // Inserts the Spinner
27
+ if ( dg_loc && dg_loc.spinner_url ) {
28
+ $checkout_btn.after( '<img src="' + dg_loc.spinner_url + '" class="dg-spinner" alt="spinner" />' );
29
+ var $spinner = $( '.dg-spinner' );
30
+ // Add some basic styling
31
+ $spinner.css({
32
+ 'vertical-align': 'middle',
33
+ 'padding-left': '15px'
34
+ });
35
+ $checkout_btn.css( 'vertical-align', 'middle' );
36
+ // Hide the Spinner
37
+ $spinner.hide();
38
+ } else {
39
+ $spinner = $( '' ); // Avoids exceptions if the dg_loc is not loaded
40
+ }
41
+
42
+ // Submit button Click handler
43
+ $checkout_btn.on( 'click', function() {
44
+ // If DG is selected
45
+ if ( $rd_btn.is( ':checked' ) ) {
46
+ // Disable Submit button
47
+ $checkout_btn.val( dg_loc.loading ).prop( 'disabled', true );
48
 
49
+ // Show the Spinner
50
+ $spinner.show();
51
+
52
+ // Submit the FORM with AJAX
53
+ $.ajax({
54
+ url: '',
55
+ type: 'post',
56
+ data: $form.serialize() + '&custom_gateway=paypal-digital-goods',
57
+ success: function( url ) {
58
+ // Start the DG flow
59
+ var dg = new PAYPAL.apps.DGFlow({
60
+ trigger: null
61
+ });
62
+
63
+ if ( utils.isValidPPURL( url ) ) {
64
+ dg.startFlow( url );
65
+ } else {
66
+ if ( window.console ) {
67
+ console.info( url );
68
+ }
69
+ }
70
+ // Hide the Spinner
71
+ $spinner.hide();
72
+ }
73
+ });
74
+ return false;
75
+ }
76
+ } );
77
+ } );
78
  } )( jQuery );
wpsc-components/merchant-core-v3/gateways/dgs.js ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*globals jQuery, dg_loc */
2
+
3
+ /*
4
+ * PayPal for Digital Goods script
5
+ */
6
+ (function($) {
7
+ var utils = {
8
+ isValidPPURL: function( url ) {
9
+ return url.substring( 0, 4 ) === 'http';
10
+ }
11
+ };
12
+ $( window ).load( function() {
13
+ // Declare DOM elements
14
+ var $checkout_btn = $( '#pp-ecs-dg' ), $spinner = $( '' ); // Avoids exceptions if the dg_loc is not loaded;
15
+
16
+ // Inserts the Spinner
17
+ if ( window.dg_loc && window.dg_loc.spinner_url ) {
18
+ $checkout_btn.after( '<img src="' + dg_loc.spinner_url + '" class="dg-spinner" alt="spinner" />' );
19
+ $spinner = $( '.dg-spinner' );
20
+ // Add some basic styling
21
+ $spinner.css( {
22
+ 'vertical-align': 'middle',
23
+ 'padding-left': '15px'
24
+ } );
25
+ $checkout_btn.css( 'vertical-align', 'middle' );
26
+ // Hide the Spinner
27
+ $spinner.hide();
28
+ }
29
+
30
+ // Submit button Click handler
31
+ $checkout_btn.on( 'click', function() {
32
+ // Disable Submit button
33
+ $checkout_btn.val( window.dg_loc.loading ).prop( 'disabled', true );
34
+
35
+ // Show the Spinner
36
+ $spinner.show();
37
+
38
+ // Submit the FORM with AJAX
39
+ $.ajax({
40
+ url: $checkout_btn.attr( 'href' ),
41
+ type: 'get',
42
+ success: function( url ) {
43
+ // Start the DG flow
44
+ var dg = new window.PAYPAL.apps.DGFlow({
45
+ trigger: null
46
+ });
47
+
48
+ if ( utils.isValidPPURL( url ) ) {
49
+ dg.startFlow( url );
50
+ } else {
51
+ if ( window.console ) {
52
+ window.console.info( url );
53
+ }
54
+ }
55
+ // Hide the Spinner
56
+ $spinner.hide();
57
+ }
58
+ });
59
+ return false;
60
+ } );
61
+ } );
62
+ } )( jQuery );
wpsc-components/merchant-core-v3/gateways/manual.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/paypal-digital-goods.php CHANGED
@@ -5,634 +5,772 @@ require_once( 'paypal-express-checkout.php' );
5
  * The PayPal Express Checkout Gateway class
6
  *
7
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- class WPSC_Payment_Gateway_Paypal_Digital_Goods extends WPSC_Payment_Gateway_Paypal_Express_Checkout
10
- {
11
- const SANDBOX_URL = 'https://www.sandbox.paypal.com/incontext?token=';
12
- const LIVE_URL = 'https://www.paypal.com/incontext?token=';
13
- public $gateway;
14
-
15
- /**
16
- * Constructor of PayPal Express Checkout Gateway
17
- *
18
- * @param array $options
19
- * @return void
20
- *
21
- * @since 3.9
22
- */
23
- public function __construct( $options ) {
24
-
25
- require_once( 'php-merchant/gateways/paypal-digital-goods.php' );
26
  $this->gateway = new PHP_Merchant_Paypal_Digital_Goods( $options );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- // Now that the gateway is created, call parent constructor
29
- parent::__construct( $options );
 
 
 
 
30
 
31
- $this->title = __( 'PayPal ExpressCheckout for Digital Goods', 'wpsc' );
 
 
32
 
33
- $this->gateway->set_options( array(
34
- 'api_username' => $this->setting->get( 'api_username' ),
35
- 'api_password' => $this->setting->get( 'api_password' ),
36
- 'api_signature' => $this->setting->get( 'api_signature' ),
37
- 'cancel_url' => $this->get_cancel_url(),
38
- 'currency' => $this->get_currency_code(),
39
- 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
40
- 'address_override' => 1,
41
- 'solution_type' => 'mark',
42
- 'cart_logo' => $this->setting->get( 'cart_logo' ),
43
- 'cart_border' => $this->setting->get( 'cart_border' ),
44
- ) );
45
 
46
- add_action( 'wp_enqueue_scripts', array( $this, 'dg_script' ) );
 
 
 
 
47
 
48
- add_filter( 'wpsc_purchase_log_gateway_data', array( get_parent_class( $this ), 'filter_purchase_log_gateway_data' ), 10, 2 );
 
 
 
 
 
 
 
 
 
49
 
50
- add_filter(
51
- 'wpsc_payment_method_form_fields',
52
- array( $this, 'filter_unselect_default' ), 100 , 1
53
- );
54
  }
55
 
56
  /**
57
- * WordPress Enqueue for the Dgital Goods Script and CSS file
58
- *
59
- * @return void
60
- *
61
- * @since 3.9
62
- */
63
- public function dg_script() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  if ( wpsc_is_checkout() ) {
65
  wp_enqueue_script( 'dg-script', 'https://www.paypalobjects.com/js/external/dg.js' );
66
  wp_enqueue_script( 'dg-script-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/dg.js', array( 'jquery' ) );
 
67
  }
68
- }
69
-
70
-
71
- /**
72
- * No payment gateway is selected by default
73
- *
74
- * @access public
75
- * @since 3.9
76
- *
77
- * @param array $fields
78
- *
79
- * @return array
80
- */
81
- public function filter_unselect_default( $fields ) {
82
- foreach ( $fields as $i=>$field ) {
83
- $fields[ $i ][ 'checked' ] = false;
84
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  return $fields;
87
- }
88
-
89
- /**
90
- * Return the PayPal return URL
91
- *
92
- * @return string
93
- *
94
- * @since 3.9
95
- */
96
- protected function get_return_url() {
97
- $redirect = add_query_arg( array(
98
- 'sessionid' => $this->purchase_log->get( 'sessionid' ),
99
- 'payment_gateway' => 'paypal-digital-goods',
100
- 'payment_gateway_callback' => 'return_url_redirect',
101
- ),
102
- get_option( 'transact_url' )
103
- );
104
- return apply_filters( 'wpsc_paypal_digital_goods_return_url_redirect', $redirect, $this );
105
- }
106
-
107
- /**
108
- * PayPal Lightbox Form redirection for the Return URL
109
- *
110
- * @return void
111
- *
112
- * @since 3.9
113
- */
114
- public function callback_return_url_redirect() {
115
- // Session id
116
- if ( ! isset( $_GET['sessionid'] ) ) {
117
- return;
118
- } else {
119
- $sessionid = $_GET['sessionid'];
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
- // Page Styles
123
- wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
124
-
125
- // Return a redirection page
126
  ?>
127
  <html>
128
- <head>
129
- <title><?php _e( 'Processing...', 'wpsc' ); ?></title>
130
- <?php wp_print_styles( 'ppdg-iframe' ); ?>
131
- </head>
132
- <body>
133
- <div id="left_frame">
134
- <div id="right_frame">
135
- <p id="message">
136
- <?php _e( 'Processing Order', 'wpsc'); ?>
137
- <?php $location = esc_js( $this->get_original_return_url( $sessionid ) ); ?>
138
- </p>
139
- <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
140
- <div id="right_bottom">
141
- <div id="left_bottom">
142
- </div>
143
- </div>
144
- </div>
145
- </div>
146
- <script type="text/javascript">
147
- setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
148
- </script>
149
- </body>
 
150
  </html>
151
  <?php
152
- exit();
153
- }
154
-
155
- /**
156
- * Return the original (real) Return URL
157
- *
158
- * @param integer $session_id
159
- *
160
- * @return string
161
- *
162
- * @since 3.9
163
- */
164
- protected function get_original_return_url( $session_id ) {
165
- $location = add_query_arg( array(
166
- 'sessionid' => $session_id,
167
- 'token' => $_REQUEST['token'],
168
- 'PayerID' => $_REQUEST['PayerID'],
169
- 'payment_gateway' => 'paypal-digital-goods',
170
- 'payment_gateway_callback' => 'confirm_transaction',
 
 
 
 
171
  ),
172
- get_option( 'transact_url' )
173
- );
174
- return apply_filters( 'wpsc_paypal_digital_goods_return_url', $location );
175
- }
176
-
177
- /**
178
- * Return the Cancel URL
179
- *
180
- * @return string
181
- *
182
- * @since 3.9
183
- */
184
- protected function get_cancel_url() {
185
- $redirect = add_query_arg( array(
186
- 'payment_gateway' => 'paypal-digital-goods',
187
- 'payment_gateway_callback' => 'cancel_url_redirect',
188
- ),
189
- get_option( 'transact_url' )
190
- );
191
- return apply_filters( 'wpsc_paypal_digital_goods_cancel_url_redirect', $redirect );
192
- }
193
-
194
- /**
195
- * PayPal Lightbox Form redirection for the Cancel URL
196
- *
197
- * @return void
198
- *
199
- * @since 3.9
200
- */
201
- public function callback_cancel_url_redirect() {
202
- // Page Styles
203
- wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
204
-
205
- // Return a redirection page
 
 
 
 
206
  ?>
207
- <html>
208
- <head>
209
- <title><?php _e( 'Processing...', 'wpsc' ); ?></title>
210
- <?php wp_print_styles( 'ppdg-iframe' ); ?>
211
- </head>
212
- <body>
213
- <div id="left_frame">
214
- <div id="right_frame">
215
- <p id="message">
216
- <?php _e( 'Cancelling Order', 'ppdg'); ?>
217
- <?php $location = html_entity_decode( $this->get_original_cancel_url() ); ?>
218
- </p>
219
- <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
220
- <div id="right_bottom">
221
- <div id="left_bottom">
222
- </div>
223
- </div>
224
- </div>
225
- </div>
226
- <script type="text/javascript">
227
- setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
228
- </script>
229
- </body>
230
  </html>
231
  <?php
232
- exit();
233
- }
234
-
235
- /**
236
- * Return the original (real) Cancel URL
237
- *
238
- * @param integer $session_id
239
- *
240
- * @return string
241
- *
242
- * @since 3.9
243
- */
244
- protected function get_original_cancel_url() {
245
- return apply_filters( 'wpsc_paypal_digital_goods_cancel_url', $this->get_shopping_cart_payment_url() );
246
- }
247
-
248
- /**
249
- * Return the notify URL
250
- *
251
- * @return string
252
- *
253
- * @since 3.9
254
- */
255
- protected function get_notify_url() {
256
- $location = add_query_arg( array(
257
- 'payment_gateway' => 'paypal-digital-goods',
258
- 'payment_gateway_callback' => 'ipn',
259
- ), home_url( 'index.php' ) );
260
-
261
- return apply_filters( 'wpsc_paypal_express_checkout_notify_url', $location );
262
- }
263
-
264
- /**
265
- * IPN Callback function
266
- *
267
- * @return void
268
- *
269
- * @since 3.9
270
- */
271
- public function callback_ipn() {
272
- $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
273
-
274
- if ( $ipn->is_verified() ) {
275
- $sessionid = $ipn->get( 'message_id' );
276
- $this->set_purchase_log_for_callbacks( $sessionid );
277
-
278
- if ( $ipn->is_payment_denied() ) {
279
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
280
- } elseif ( $ipn->is_payment_refunded() ) {
281
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUNDED );
282
- } elseif ( $ipn->is_payment_completed() ) {
283
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
284
- } elseif ( $ipn->is_payment_pending() ) {
285
- if ( $ipn->is_payment_refund_pending() )
286
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUND_PENDING );
287
- else
288
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
289
- }
290
-
291
- $this->purchase_log->save();
292
- transaction_results( $sessionid, false );
293
- }
294
-
295
- exit;
296
- }
297
-
298
- /**
299
- * Confirm Transaction Callback
300
- *
301
- * @return null
302
- *
303
- * @since 3.9
304
- */
305
- public function callback_confirm_transaction() {
306
-
307
- if ( ! isset( $_GET['sessionid'] ) || ! isset( $_GET['token'] ) || ! isset( $_GET['PayerID'] ) ) {
308
- return;
309
- }
310
-
311
- $this->set_purchase_log_for_callbacks();
312
-
313
- $this->callback_process_confirmed_payment();
314
- }
315
-
316
- /**
317
- * Process the transaction through the PayPal APIs
318
- *
319
- * @since 3.9
320
- */
321
- public function callback_process_confirmed_payment() {
322
- $args = array_map( 'urldecode', $_GET );
323
- extract( $args, EXTR_SKIP );
324
-
325
- if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
326
- return;
327
- }
328
-
329
- $this->set_purchase_log_for_callbacks();
330
-
331
- $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
332
- $options = array(
333
- 'token' => $token,
334
- 'payer_id' => $PayerID,
335
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
336
- 'invoice' => $this->purchase_log->get( 'sessionid' ) . '-' . $this->purchase_log->get( 'id' ),
337
- );
338
- $options += $this->checkout_data->get_gateway_data();
339
- $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
340
-
341
- if ( $this->setting->get( 'ipn', false ) ) {
342
- $options['notify_url'] = $this->get_notify_url();
343
- }
344
-
345
- // GetExpressCheckoutDetails
346
- $details = $this->gateway->get_details_for( $token );
347
- $this->log_payer_details( $details );
348
-
349
- $response = $this->gateway->purchase( $options );
350
- $this->log_protection_status( $response );
351
- $location = remove_query_arg( 'payment_gateway_callback' );
352
-
353
- if ( $response->has_errors() ) {
354
- wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
355
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
356
- } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
357
- $location = remove_query_arg( 'payment_gateway' );
358
-
359
- if ( $response->is_payment_completed() ) {
360
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
361
- } else {
362
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
363
- }
364
-
365
- $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
366
- ->set( 'date', time() )
367
- ->save();
368
- } else {
369
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
370
- }
371
-
372
- wp_redirect( esc_url_raw( $location ) );
373
- exit;
374
-
375
- }
376
-
377
- /**
378
- * PayPal Lightbox Form redirection for the Error Page
379
- *
380
- * @return void
381
- *
382
- * @since 3.9
383
- */
384
- public function callback_display_paypal_error_redirect() {
385
- // Redirect Location
386
- $location = esc_url_raw( add_query_arg( array(
387
- 'payment_gateway' => 'paypal-digital-goods',
388
- 'payment_gateway_callback' => 'display_paypal_error',
389
- ), base64_decode( $_GET['return_url'] ) ) );
390
-
391
- // Page Styles
392
- wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
393
-
394
- // Return a redirection page
395
  ?>
396
  <html>
397
- <head>
398
- <title><?php __( 'Processing...', 'wpsc' ); ?></title>
399
- <?php wp_print_styles( 'ppdg-iframe' ); ?>
400
- </head>
401
- <body>
402
- <div id="left_frame">
403
- <div id="right_frame">
404
- <p id="message">
405
- <?php _e( 'Processing Order', 'wpsc'); ?>
406
- </p>
407
- <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
408
- <div id="right_bottom">
409
- <div id="left_bottom">
410
- </div>
411
- </div>
412
- </div>
413
- </div>
414
- <script type="text/javascript">
415
- setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
416
- </script>
417
- </body>
418
  </html>
419
  <?php
420
- exit();
421
 
422
 
423
- }
424
 
425
- public function callback_display_paypal_error() {
426
- add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_paypal_error_page' ) );
427
- }
428
 
429
- public function callback_display_generic_error() {
430
- add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_generic_error_page' ) );
431
- }
432
 
433
- /**
434
- * Error Page Template
435
- *
436
- * @since 3.9
437
- */
438
- public function filter_paypal_error_page() {
439
- $errors = wpsc_get_customer_meta( 'paypal_express_checkout_errors' );
440
- ob_start();
441
  ?>
442
  <p>
443
  <?php _e( 'Sorry, your transaction could not be processed by PayPal. Please contact the site administrator. The following errors are returned:', 'wpsc' ); ?>
444
  </p>
445
  <ul>
446
- <?php foreach ( $errors as $error ): ?>
447
- <li><?php echo esc_html( $error['details'] ) ?> (<?php echo esc_html( $error['code'] ); ?>)</li>
448
- <?php endforeach; ?>
449
  </ul>
450
  <p><a href="<?php echo esc_url( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
451
  <?php
452
- $output = apply_filters( 'wpsc_paypal_express_checkout_gateway_error_message', ob_get_clean(), $errors );
453
- return $output;
454
- }
455
-
456
- /**
457
- * Generic Error Page Template
458
- *
459
- * @since 3.9
460
- */
461
- public function filter_generic_error_page() {
462
- ob_start();
463
  ?>
464
  <p><?php _e( 'Sorry, but your transaction could not be processed by PayPal for some reason. Please contact the site administrator.', 'wpsc' ); ?></p>
465
  <p><a href="<?php echo esc_attr( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
466
  <?php
467
- $output = apply_filters( 'wpsc_paypal_express_checkout_generic_error_message', ob_get_clean() );
468
- return $output;
469
- }
470
-
471
- /**
472
- * Settings Form Template
473
- *
474
- * @since 3.9
475
- */
476
- public function setup_form() {
477
- $paypal_currency = $this->get_currency_code();
478
  ?>
479
  <!-- Account Credentials -->
480
  <tr>
481
- <td colspan="2">
482
- <h4><?php _e( 'Account Credentials', 'wpsc' ); ?></h4>
483
- </td>
484
  </tr>
485
  <tr>
486
- <td>
487
- <label for="wpsc-paypal-express-api-username"><?php _e( 'API Username', 'wpsc' ); ?></label>
488
- </td>
489
- <td>
490
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_username' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_username' ) ); ?>" id="wpsc-paypal-express-api-username" />
491
- </td>
492
  </tr>
493
  <tr>
494
- <td>
495
- <label for="wpsc-paypal-express-api-password"><?php _e( 'API Password', 'wpsc' ); ?></label>
496
- </td>
497
- <td>
498
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_password' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_password' ) ); ?>" id="wpsc-paypal-express-api-password" />
499
- </td>
500
  </tr>
501
  <tr>
502
- <td>
503
- <label for="wpsc-paypal-express-api-signature"><?php _e( 'API Signature', 'wpsc' ); ?></label>
504
- </td>
505
- <td>
506
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_signature' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_signature' ) ); ?>" id="wpsc-paypal-express-api-signature" />
507
- </td>
508
  </tr>
509
  <tr>
510
- <td>
511
- <label><?php _e( 'Sandbox Mode', 'wpsc' ); ?></label>
512
- </td>
513
- <td>
514
- <label><input <?php checked( $this->setting->get( 'sandbox_mode' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
515
- <label><input <?php checked( (bool) $this->setting->get( 'sandbox_mode' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
516
- </td>
517
  </tr>
518
  <tr>
519
- <td>
520
- <label><?php _e( 'IPN', 'wpsc' ); ?></label>
521
- </td>
522
- <td>
523
- <label><input <?php checked( $this->setting->get( 'ipn' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
524
- <label><input <?php checked( (bool) $this->setting->get( 'ipn' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
525
- </td>
526
  </tr>
527
 
528
  <!-- Cart Customization -->
529
  <tr>
530
- <td colspan="2">
531
- <label><h4><?php _e( 'Cart Customization', 'wpsc'); ?></h4></label>
532
- </td>
533
  </tr>
534
  <tr>
535
- <td>
536
- <label for="wpsc-paypal-express-cart-logo"><?php _e( 'Merchant Logo', 'wpsc' ); ?></label>
537
- </td>
538
- <td>
539
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_logo' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_logo' ) ); ?>" id="wpsc-paypal-express-cart-logo" />
540
- </td>
541
  </tr>
542
  <tr>
543
- <td>
544
- <label for="wpsc-paypal-express-cart-border"><?php _e( 'Cart Border Color', 'wpsc' ); ?></label>
545
- </td>
546
- <td>
547
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_border' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_border' ) ); ?>" id="wpsc-paypal-express-cart-border" />
548
- </td>
549
  </tr>
550
 
551
  <!-- Currency Conversion -->
552
  <?php if ( ! $this->is_currency_supported() ): ?>
553
  <tr>
554
- <td colspan="2">
555
- <h4><?php _e( 'Currency Conversion', 'wpsc' ); ?></h4>
556
- </td>
557
  </tr>
558
  <tr>
559
- <td colspan="2">
560
- <p><?php _e( 'Your base currency is currently not accepted by PayPal. As a result, before a payment request is sent to Paypal, WP eCommerce has to convert the amounts into one of Paypal supported currencies. Please select your preferred currency below.', 'wpsc' ); ?></p>
561
- </td>
562
  </tr>
563
  <tr>
564
- <td>
565
- <label for "wpsc-paypal-express-currency"><?php _e( 'Paypal Currency', 'wpsc' ); ?></label>
566
- </td>
567
- <td>
568
- <select name="<?php echo esc_attr( $this->setting->get_field_name( 'currency' ) ); ?>" id="wpsc-paypal-express-currency">
569
- <?php foreach ($this->gateway->get_supported_currencies() as $currency): ?>
570
- <option <?php selected( $currency, $paypal_currency ); ?> value="<?php echo esc_attr( $currency ); ?>"><?php echo esc_html( $currency ); ?></option>
571
- <?php endforeach ?>
572
- </select>
573
- </td>
574
  </tr>
575
  <?php endif ?>
576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  <!-- Error Logging -->
578
  <tr>
579
- <td colspan="2">
580
- <h4><?php _e( 'Error Logging', 'wpsc' ); ?></h4>
581
- </td>
582
  </tr>
583
  <tr>
584
- <td>
585
- <label><?php _e( 'Enable Debugging', 'wpsc' ); ?></label>
586
- </td>
587
- <td>
588
- <label><input <?php checked( $this->setting->get( 'debugging' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
589
- <label><input <?php checked( (bool) $this->setting->get( 'debugging' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
590
- </td>
591
  </tr>
592
  <?php
593
- }
594
-
595
- /**
596
- * Process the SetExpressCheckout API Call
597
- *
598
- * @param array $args
599
- * @return void
600
- *
601
- * @since 3.9
602
- */
603
- public function process( $args = array() ) {
604
- $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
605
- $options = array(
606
- 'return_url' => $this->get_return_url(),
607
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
608
- 'invoice' => $this->purchase_log->get( 'sessionid' ) . '-' . $this->purchase_log->get( 'id' ),
609
- 'address_override' => 1,
610
- );
611
- $options += $this->checkout_data->get_gateway_data();
612
- $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
613
-
614
- if ( $this->setting->get( 'ipn', false ) ) {
615
- $options['notify_url'] = $this->get_notify_url();
616
- }
617
-
618
- $response = $this->gateway->setup_purchase( $options );
619
-
620
- if ( $response->is_successful() ) {
621
- $url = ( $this->setting->get( 'sandbox_mode' ) ? self::SANDBOX_URL : self::LIVE_URL ) . $response->get( 'token' );
622
- } else {
623
- $this->log_error( $response );
624
- $url = add_query_arg( array(
625
- 'payment_gateway' => 'paypal-digital-goods',
626
- 'payment_gateway_callback' => 'display_paypal_error_redirect',
627
- 'return_url' => base64_encode( $this->get_return_url() ),
628
- ), $this->get_return_url() );
629
- }
630
-
631
- if( ! isset( $args['return_only'] ) || $args['return_only'] !== true ) {
632
- wp_redirect( $url );
633
- exit;
634
- }
635
-
636
- return $url;
637
- }
 
 
 
 
 
638
  }
5
  * The PayPal Express Checkout Gateway class
6
  *
7
  */
8
+ class WPSC_Payment_Gateway_Paypal_Digital_Goods extends WPSC_Payment_Gateway_Paypal_Express_Checkout {
9
+ const SANDBOX_URL = 'https://www.sandbox.paypal.com/incontext?token=';
10
+ const LIVE_URL = 'https://www.paypal.com/incontext?token=';
11
+ protected $gateway;
12
+
13
+ /**
14
+ * Constructor of PayPal Express Checkout Gateway
15
+ *
16
+ * @param array $options
17
+ *
18
+ * @since 3.9
19
+ */
20
+ public function __construct( $options ) {
21
+ require_once( 'php-merchant/gateways/paypal-digital-goods.php' );
22
+ // Now that the gateway is created, call parent constructor
23
+ parent::__construct( $options, true );
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  $this->gateway = new PHP_Merchant_Paypal_Digital_Goods( $options );
26
+ $this->title = __( 'PayPal Digital Goods for Express Checkout', 'wpsc' );
27
+
28
+ $this->gateway->set_options( array(
29
+ 'api_username' => $this->setting->get( 'api_username' ),
30
+ 'api_password' => $this->setting->get( 'api_password' ),
31
+ 'api_signature' => $this->setting->get( 'api_signature' ),
32
+ 'cancel_url' => $this->get_cancel_url(),
33
+ 'currency' => $this->get_currency_code(),
34
+ 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
35
+ 'address_override' => 1,
36
+ 'solution_type' => 'mark',
37
+ 'cart_logo' => $this->setting->get( 'cart_logo' ),
38
+ 'cart_border' => $this->setting->get( 'cart_border' ),
39
+ ) );
40
+
41
+ // Express Checkout for DG Button
42
+ add_action( 'wpsc_cart_item_table_form_actions_left', array( $this, 'add_ecs_button' ), 2, 2 );
43
+
44
+ // Filter Digital Goods option on checkout
45
+ add_filter( 'wpsc_payment_method_form_fields', array( &$this, 'dg_option_removal' ), 100 );
46
+ }
47
+
48
+ /**
49
+ * Toggles Digital Goods option based on whether or not shipping is being used on the given cart.
50
+ *
51
+ * @since 4.0
52
+ *
53
+ * @param array $fields Payment method form fields
54
+ *
55
+ * @return array $fields Modified payment method form fields
56
+ */
57
+ public function dg_option_removal( $fields ) {
58
+ if ( wpsc_uses_shipping() ) {
59
+ // Remove DG option
60
+ foreach( $fields as $index => $field ) {
61
+ if ( $field['value'] === 'paypal-digital-goods' ) {
62
+ unset( $fields[ $index] );
63
+ }
64
+ }
65
+ } else {
66
+ // Remove Normal option
67
+ foreach( $fields as $index => $field ) {
68
+ if ( $field['value'] === 'paypal-express-checkout' ) {
69
+ unset( $fields[ $index ] );
70
+ }
71
+ }
72
+ }
73
+ return $fields;
74
+ }
75
 
76
+ /**
77
+ * Insert the ExpessCheckout Shortcut Button
78
+ *
79
+ * @return void
80
+ */
81
+ public function add_ecs_button( $cart_table, $context ) {
82
 
83
+ if ( wpsc_uses_shipping() || ! wpsc_is_gateway_active( 'paypal-digital-goods' ) ) {
84
+ return;
85
+ }
86
 
87
+ if ( 'top' == $context ) {
88
+ return;
89
+ }
 
 
 
 
 
 
 
 
 
90
 
91
+ if ( _wpsc_get_current_controller_name() === 'cart' ) {
92
+ $url = $this->get_shortcut_url();
93
+ echo '<a id="pp-ecs-dg" href="'. esc_url ( $url ) .'"><img src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/checkout-logo-large.png" alt="' . __( 'Check out with PayPal', 'wpsc' ) . '" /></a>';
94
+ }
95
+ }
96
 
97
+ /**
98
+ * Return the ExpressCheckout Shortcut redirection URL
99
+ *
100
+ * @return void
101
+ */
102
+ public function get_shortcut_url() {
103
+ $location = add_query_arg( array(
104
+ 'payment_gateway' => 'paypal-digital-goods',
105
+ 'payment_gateway_callback' => 'shortcut_process',
106
+ ), home_url( 'index.php' ) );
107
 
108
+ return apply_filters( 'wpsc_paypal_digital_goods_shortcut_url', $location );
 
 
 
109
  }
110
 
111
  /**
112
+ * Sets the Review Callback for Review Order page.
113
+ *
114
+ * @param string $url
115
+ * @return string
116
+ */
117
+ public function review_order_callback( $url ) {
118
+ $args = array(
119
+ 'payment_gateway_callback' => 'review_transaction',
120
+ 'payment_gateway' => 'paypal-digital-goods',
121
+ );
122
+ $url = add_query_arg( $args, $url );
123
+
124
+ return $url;
125
+ }
126
+
127
+ /**
128
+ * Run the gateway hooks
129
+ *
130
+ * @access public
131
+ * @since 4.0
132
+ *
133
+ * @return void
134
+ */
135
+ public function init() {
136
+ // Disable default selection
137
+ add_filter(
138
+ 'wpsc_payment_method_form_fields',
139
+ array( 'WPSC_Payment_Gateway_Paypal_Digital_Goods', 'filter_unselect_default' ), 100 , 1
140
+ );
141
+
142
+ // Load DG scripts and styles
143
+ add_action( 'wp_enqueue_scripts', array( 'WPSC_Payment_Gateway_Paypal_Digital_Goods', 'dg_script' ) );
144
+ }
145
+
146
+ /**
147
+ * WordPress Enqueue for the Dgital Goods Script and CSS file
148
+ *
149
+ * @return void
150
+ *
151
+ * @since 3.9
152
+ */
153
+ public static function dg_script() {
154
+ $dg_loc = array(
155
+ 'spinner_url' => wpsc_get_ajax_spinner(),
156
+ 'loading' => __( 'Loading...', 'wpsc' ),
157
+ );
158
+ // Checkout Page
159
  if ( wpsc_is_checkout() ) {
160
  wp_enqueue_script( 'dg-script', 'https://www.paypalobjects.com/js/external/dg.js' );
161
  wp_enqueue_script( 'dg-script-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/dg.js', array( 'jquery' ) );
162
+ wp_localize_script( 'dg-script', 'dg_loc', $dg_loc );
163
  }
164
+ // Cart Page
165
+ if ( function_exists( 'wpsc_is_cart' ) && wpsc_is_cart() ) {
166
+ wp_enqueue_script( 'dg-script', 'https://www.paypalobjects.com/js/external/dg.js' );
167
+ wp_enqueue_script( 'dg-script-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/dgs.js', array( 'jquery' ) );
168
+ wp_localize_script( 'dg-script', 'dg_loc', $dg_loc );
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
+ }
171
+
172
+ /**
173
+ * No payment gateway is selected by default
174
+ *
175
+ * @access public
176
+ * @since 3.9
177
+ *
178
+ * @param array $fields
179
+ *
180
+ * @return array
181
+ */
182
+ public static function filter_unselect_default( $fields ) {
183
+ foreach ( $fields as $i => $field ) {
184
+ $fields[ $i ][ 'checked' ] = false;
185
+ }
186
 
187
  return $fields;
188
+ }
189
+
190
+ /**
191
+ * Return the PayPal return URL
192
+ *
193
+ * @return string
194
+ *
195
+ * @since 3.9
196
+ */
197
+ protected function get_return_url() {
198
+ $redirect = add_query_arg( array(
199
+ 'sessionid' => $this->purchase_log->get( 'sessionid' ),
200
+ 'payment_gateway' => 'paypal-digital-goods',
201
+ 'payment_gateway_callback' => 'return_url_redirect',
202
+ ),
203
+ get_option( 'transact_url' )
204
+ );
205
+ return apply_filters( 'wpsc_paypal_digital_goods_return_url_redirect', $redirect, $this );
206
+ }
207
+
208
+ /**
209
+ * PayPal Lightbox Form redirection for the Return URL
210
+ *
211
+ * @return void
212
+ *
213
+ * @since 3.9
214
+ */
215
+ public function callback_return_url_redirect() {
216
+ // Session id
217
+ if ( ! isset( $_GET['sessionid'] ) ) {
218
+ return;
219
+ } else {
220
+ $sessionid = $_GET['sessionid'];
221
+ }
222
+
223
+ // Page Styles
224
+ wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
225
+
226
+ // Apply any filters
227
+ if ( wpsc_get_customer_meta( 'ecs-' . $sessionid ) ) {
228
+ add_filter( 'wpsc_paypal_express_checkout_transact_url', array( &$this, 'review_order_url' ) );
229
+ add_filter( 'wpsc_paypal_express_checkout_return_url', array( &$this, 'review_order_callback' ) );
230
+
231
+ wpsc_delete_customer_meta( 'esc-' . $sessionid );
232
  }
233
 
234
+ // Return a redirection page
 
 
 
235
  ?>
236
  <html>
237
+ <head>
238
+ <title><?php _e( 'Processing...', 'wpsc' ); ?></title>
239
+ <?php wp_print_styles( 'ppdg-iframe' ); ?>
240
+ </head>
241
+ <body>
242
+ <div id="left_frame">
243
+ <div id="right_frame">
244
+ <p id="message">
245
+ <?php _e( 'Processing Order', 'wpsc'); ?>
246
+
247
+ </p>
248
+ <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
249
+ <div id="right_bottom">
250
+ <div id="left_bottom">
251
+ </div>
252
+ </div>
253
+ </div>
254
+ </div>
255
+ <script type="text/javascript">
256
+ <?php $location = $this->get_original_return_url( $sessionid ); ?>
257
+ setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
258
+ </script>
259
+ </body>
260
  </html>
261
  <?php
262
+ exit();
263
+ }
264
+
265
+ /**
266
+ * Return the original (real) Return URL
267
+ *
268
+ * @param integer $session_id
269
+ *
270
+ * @return string
271
+ *
272
+ * @since 3.9
273
+ */
274
+ protected function get_original_return_url( $session_id ) {
275
+ $transact_url = get_option( 'transact_url' );
276
+ $transact_url = apply_filters( 'wpsc_paypal_digital_goods_transact_url', $transact_url );
277
+ $transact_url = apply_filters( 'wpsc_paypal_express_checkout_transact_url', $transact_url );
278
+
279
+ $location = add_query_arg( array(
280
+ 'sessionid' => $session_id,
281
+ 'token' => $_REQUEST['token'],
282
+ 'PayerID' => $_REQUEST['PayerID'],
283
+ 'payment_gateway' => 'paypal-digital-goods',
284
+ 'payment_gateway_callback' => 'confirm_transaction',
285
  ),
286
+ $transact_url
287
+ );
288
+
289
+ $location = wp_validate_redirect( $location );
290
+ $location = apply_filters( 'wpsc_paypal_express_checkout_return_url', $location );
291
+
292
+ return apply_filters( 'wpsc_paypal_digital_goods_return_url', $location );
293
+ }
294
+
295
+ /**
296
+ * Return the Cancel URL
297
+ *
298
+ * @return string
299
+ *
300
+ * @since 3.9
301
+ */
302
+ protected function get_cancel_url() {
303
+ $redirect = add_query_arg( array(
304
+ 'payment_gateway' => 'paypal-digital-goods',
305
+ 'payment_gateway_callback' => 'cancel_url_redirect',
306
+ ),
307
+ get_option( 'transact_url' )
308
+ );
309
+ return apply_filters( 'wpsc_paypal_digital_goods_cancel_url_redirect', $redirect );
310
+ }
311
+
312
+ /**
313
+ * PayPal Lightbox Form redirection for the Cancel URL
314
+ *
315
+ * @return void
316
+ *
317
+ * @since 3.9
318
+ */
319
+ public function callback_cancel_url_redirect() {
320
+ // Page Styles
321
+ wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
322
+
323
+ // Return a redirection page
324
  ?>
325
+ <html>
326
+ <head>
327
+ <title><?php _e( 'Processing...', 'wpsc' ); ?></title>
328
+ <?php wp_print_styles( 'ppdg-iframe' ); ?>
329
+ </head>
330
+ <body>
331
+ <div id="left_frame">
332
+ <div id="right_frame">
333
+ <p id="message">
334
+ <?php _e( 'Cancelling Order', 'wpsc' ); ?>
335
+ </p>
336
+ <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
337
+ <div id="right_bottom">
338
+ <div id="left_bottom">
339
+ </div>
340
+ </div>
341
+ </div>
342
+ </div>
343
+ <script type="text/javascript">
344
+ <?php $location = $this->get_original_cancel_url() ; ?>
345
+ setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
346
+ </script>
347
+ </body>
348
  </html>
349
  <?php
350
+ exit();
351
+ }
352
+
353
+ /**
354
+ * Return the original (real) Cancel URL
355
+ *
356
+ * @return string
357
+ *
358
+ * @since 3.9
359
+ */
360
+ protected function get_original_cancel_url() {
361
+ return apply_filters( 'wpsc_paypal_digital_goods_cancel_url', $this->get_shopping_cart_payment_url() );
362
+ }
363
+
364
+ /**
365
+ * Return the notify URL
366
+ *
367
+ * @return string
368
+ *
369
+ * @since 3.9
370
+ */
371
+ protected function get_notify_url() {
372
+ $location = add_query_arg( array(
373
+ 'payment_gateway' => 'paypal-digital-goods',
374
+ 'payment_gateway_callback' => 'ipn',
375
+ ), home_url( 'index.php' ) );
376
+
377
+ return apply_filters( 'wpsc_paypal_express_checkout_notify_url', $location );
378
+ }
379
+
380
+ /**
381
+ * IPN Callback function
382
+ *
383
+ * @return void
384
+ *
385
+ * @since 3.9
386
+ */
387
+ public function callback_ipn() {
388
+ $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
389
+
390
+ if ( $ipn->is_verified() ) {
391
+ $sessionid = $ipn->get( 'message_id' );
392
+ $this->set_purchase_log_for_callbacks( $sessionid );
393
+
394
+ if ( $ipn->is_payment_denied() ) {
395
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
396
+ } elseif ( $ipn->is_payment_refunded() ) {
397
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUNDED );
398
+ } elseif ( $ipn->is_payment_completed() ) {
399
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
400
+ } elseif ( $ipn->is_payment_pending() ) {
401
+ if ( $ipn->is_payment_refund_pending() )
402
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUND_PENDING );
403
+ else
404
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
405
+ }
406
+
407
+ $this->purchase_log->save();
408
+ transaction_results( $sessionid, false );
409
+ }
410
+
411
+ exit;
412
+ }
413
+
414
+
415
+ /**
416
+ * Confirm Transaction Callback
417
+ *
418
+ * @return null
419
+ *
420
+ * @since 3.9
421
+ */
422
+ public function callback_confirm_transaction() {
423
+
424
+ if ( ! isset( $_GET['sessionid'] ) || ! isset( $_GET['token'] ) || ! isset( $_GET['PayerID'] ) ) {
425
+ return;
426
+ }
427
+
428
+ $this->set_purchase_log_for_callbacks();
429
+
430
+ $this->callback_process_confirmed_payment();
431
+ }
432
+
433
+ /**
434
+ * Process the transaction through the PayPal APIs
435
+ *
436
+ * @since 3.9
437
+ */
438
+ public function callback_process_confirmed_payment() {
439
+ $args = array_map( 'urldecode', $_GET );
440
+ extract( $args, EXTR_SKIP );
441
+
442
+ if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
443
+ return;
444
+ }
445
+
446
+ $this->set_purchase_log_for_callbacks();
447
+
448
+ $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
449
+ $options = array(
450
+ 'token' => $token,
451
+ 'payer_id' => $PayerID,
452
+ 'message_id' => $this->purchase_log->get( 'id' ),
453
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
454
+ );
455
+ $options += $this->checkout_data->get_gateway_data();
456
+ $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
457
+
458
+ if ( $this->setting->get( 'ipn', false ) ) {
459
+ $options['notify_url'] = $this->get_notify_url();
460
+ }
461
+
462
+ // GetExpressCheckoutDetails
463
+ $details = $this->gateway->get_details_for( $token );
464
+ $this->log_payer_details( $details );
465
+
466
+ $response = $this->gateway->purchase( $options );
467
+ $this->log_protection_status( $response );
468
+ $location = remove_query_arg( 'payment_gateway_callback' );
469
+
470
+ if ( $response->has_errors() ) {
471
+ wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
472
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
473
+ } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
474
+ $location = remove_query_arg( 'payment_gateway' );
475
+
476
+ if ( $response->is_payment_completed() ) {
477
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
478
+ } else {
479
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
480
+ }
481
+
482
+ $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
483
+ ->set( 'date', time() )
484
+ ->save();
485
+ } else {
486
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
487
+ }
488
+
489
+ wp_redirect( esc_url_raw( $location ) );
490
+ exit;
491
+
492
+ }
493
+
494
+ /**
495
+ * PayPal Lightbox Form redirection for the Error Page
496
+ *
497
+ * @return void
498
+ *
499
+ * @since 3.9
500
+ */
501
+ public function callback_display_paypal_error_redirect() {
502
+ // Redirect Location
503
+ $location = esc_url( add_query_arg( array(
504
+ 'payment_gateway' => 'paypal-digital-goods',
505
+ 'payment_gateway_callback' => 'display_paypal_error',
506
+ ), base64_decode( $_GET['return_url'] ) ) );
507
+
508
+ // Page Styles
509
+ wp_register_style( 'ppdg-iframe', plugins_url( 'dg.css', __FILE__ ) );
510
+
511
+ // Return a redirection page
 
512
  ?>
513
  <html>
514
+ <head>
515
+ <title><?php __( 'Processing...', 'wpsc' ); ?></title>
516
+ <?php wp_print_styles( 'ppdg-iframe' ); ?>
517
+ </head>
518
+ <body>
519
+ <div id="left_frame">
520
+ <div id="right_frame">
521
+ <p id="message">
522
+ <?php _e( 'Processing Order', 'wpsc'); ?>
523
+ </p>
524
+ <img src="https://www.paypal.com/en_US/i/icon/icon_animated_prog_42wx42h.gif" alt="Processing..." />
525
+ <div id="right_bottom">
526
+ <div id="left_bottom">
527
+ </div>
528
+ </div>
529
+ </div>
530
+ </div>
531
+ <script type="text/javascript">
532
+ setTimeout('if (window!=top) {top.location.replace("<?php echo $location; ?>");}else{location.replace("<?php echo $location; ?>");}', 1500);
533
+ </script>
534
+ </body>
535
  </html>
536
  <?php
537
+ exit();
538
 
539
 
540
+ }
541
 
542
+ public function callback_display_paypal_error() {
543
+ add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_paypal_error_page' ) );
544
+ }
545
 
546
+ public function callback_display_generic_error() {
547
+ add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_generic_error_page' ) );
548
+ }
549
 
550
+ /**
551
+ * Error Page Template
552
+ *
553
+ * @since 3.9
554
+ */
555
+ public function filter_paypal_error_page() {
556
+ $errors = wpsc_get_customer_meta( 'paypal_express_checkout_errors' );
557
+ ob_start();
558
  ?>
559
  <p>
560
  <?php _e( 'Sorry, your transaction could not be processed by PayPal. Please contact the site administrator. The following errors are returned:', 'wpsc' ); ?>
561
  </p>
562
  <ul>
563
+ <?php foreach ( $errors as $error ): ?>
564
+ <li><?php echo esc_html( $error['details'] ) ?> (<?php echo esc_html( $error['code'] ); ?>)</li>
565
+ <?php endforeach; ?>
566
  </ul>
567
  <p><a href="<?php echo esc_url( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
568
  <?php
569
+ $output = apply_filters( 'wpsc_paypal_express_checkout_gateway_error_message', ob_get_clean(), $errors );
570
+ return $output;
571
+ }
572
+
573
+ /**
574
+ * Generic Error Page Template
575
+ *
576
+ * @since 3.9
577
+ */
578
+ public function filter_generic_error_page() {
579
+ ob_start();
580
  ?>
581
  <p><?php _e( 'Sorry, but your transaction could not be processed by PayPal for some reason. Please contact the site administrator.', 'wpsc' ); ?></p>
582
  <p><a href="<?php echo esc_attr( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
583
  <?php
584
+ $output = apply_filters( 'wpsc_paypal_express_checkout_generic_error_message', ob_get_clean() );
585
+ return $output;
586
+ }
587
+
588
+ /**
589
+ * Settings Form Template
590
+ *
591
+ * @since 3.9
592
+ */
593
+ public function setup_form() {
594
+ $paypal_currency = $this->get_currency_code();
595
  ?>
596
  <!-- Account Credentials -->
597
  <tr>
598
+ <td colspan="2">
599
+ <h4><?php _e( 'Account Credentials', 'wpsc' ); ?></h4>
600
+ </td>
601
  </tr>
602
  <tr>
603
+ <td>
604
+ <label for="wpsc-paypal-express-api-username"><?php _e( 'API Username', 'wpsc' ); ?></label>
605
+ </td>
606
+ <td>
607
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_username' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_username' ) ); ?>" id="wpsc-paypal-express-api-username" />
608
+ </td>
609
  </tr>
610
  <tr>
611
+ <td>
612
+ <label for="wpsc-paypal-express-api-password"><?php _e( 'API Password', 'wpsc' ); ?></label>
613
+ </td>
614
+ <td>
615
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_password' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_password' ) ); ?>" id="wpsc-paypal-express-api-password" />
616
+ </td>
617
  </tr>
618
  <tr>
619
+ <td>
620
+ <label for="wpsc-paypal-express-api-signature"><?php _e( 'API Signature', 'wpsc' ); ?></label>
621
+ </td>
622
+ <td>
623
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_signature' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_signature' ) ); ?>" id="wpsc-paypal-express-api-signature" />
624
+ </td>
625
  </tr>
626
  <tr>
627
+ <td>
628
+ <label><?php _e( 'Sandbox Mode', 'wpsc' ); ?></label>
629
+ </td>
630
+ <td>
631
+ <label><input <?php checked( $this->setting->get( 'sandbox_mode' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
632
+ <label><input <?php checked( (bool) $this->setting->get( 'sandbox_mode' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
633
+ </td>
634
  </tr>
635
  <tr>
636
+ <td>
637
+ <label><?php _e( 'IPN', 'wpsc' ); ?></label>
638
+ </td>
639
+ <td>
640
+ <label><input <?php checked( $this->setting->get( 'ipn' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
641
+ <label><input <?php checked( (bool) $this->setting->get( 'ipn' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
642
+ </td>
643
  </tr>
644
 
645
  <!-- Cart Customization -->
646
  <tr>
647
+ <td colspan="2">
648
+ <label><h4><?php _e( 'Cart Customization', 'wpsc'); ?></h4></label>
649
+ </td>
650
  </tr>
651
  <tr>
652
+ <td>
653
+ <label for="wpsc-paypal-express-cart-logo"><?php _e( 'Merchant Logo', 'wpsc' ); ?></label>
654
+ </td>
655
+ <td>
656
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_logo' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_logo' ) ); ?>" id="wpsc-paypal-express-cart-logo" /><br><span class="small description"><?php _e( 'The image must be stored in a HTTPS Server. Limit the image to 190 pixels wide by 60 pixels high.', 'wpsc' ); ?></span>
657
+ </td>
658
  </tr>
659
  <tr>
660
+ <td>
661
+ <label for="wpsc-paypal-express-cart-border"><?php _e( 'Cart Border Color', 'wpsc' ); ?></label>
662
+ </td>
663
+ <td>
664
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_border' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_border' ) ); ?>" id="wpsc-paypal-express-cart-border" />
665
+ </td>
666
  </tr>
667
 
668
  <!-- Currency Conversion -->
669
  <?php if ( ! $this->is_currency_supported() ): ?>
670
  <tr>
671
+ <td colspan="2">
672
+ <h4><?php _e( 'Currency Conversion', 'wpsc' ); ?></h4>
673
+ </td>
674
  </tr>
675
  <tr>
676
+ <td colspan="2">
677
+ <p><?php _e( 'Your base currency is currently not accepted by PayPal. As a result, before a payment request is sent to Paypal, WP eCommerce has to convert the amounts into one of Paypal supported currencies. Please select your preferred currency below.', 'wpsc' ); ?></p>
678
+ </td>
679
  </tr>
680
  <tr>
681
+ <td>
682
+ <label for "wpsc-paypal-express-currency"><?php _e( 'Paypal Currency', 'wpsc' ); ?></label>
683
+ </td>
684
+ <td>
685
+ <select name="<?php echo esc_attr( $this->setting->get_field_name( 'currency' ) ); ?>" id="wpsc-paypal-express-currency">
686
+ <?php foreach ($this->gateway->get_supported_currencies() as $currency): ?>
687
+ <option <?php selected( $currency, $paypal_currency ); ?> value="<?php echo esc_attr( $currency ); ?>"><?php echo esc_html( $currency ); ?></option>
688
+ <?php endforeach ?>
689
+ </select>
690
+ </td>
691
  </tr>
692
  <?php endif ?>
693
 
694
+ <!-- Checkout Shortcut -->
695
+ <tr>
696
+ <td colspan="2">
697
+ <h4><?php _e( 'Express Checkout Shortcut', 'wpsc' ); ?></h4>
698
+ </td>
699
+ </tr>
700
+ <tr>
701
+ <td>
702
+ <label><?php _e( 'Enable Shortcut', 'wpsc' ); ?></label>
703
+ </td>
704
+ <td>
705
+ <label><input <?php checked( $this->setting->get( 'shortcut' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'shortcut' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
706
+ <label><input <?php checked( (bool) $this->setting->get( 'shortcut' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'shortcut' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
707
+ </td>
708
+ </tr>
709
+
710
  <!-- Error Logging -->
711
  <tr>
712
+ <td colspan="2">
713
+ <h4><?php _e( 'Error Logging', 'wpsc' ); ?></h4>
714
+ </td>
715
  </tr>
716
  <tr>
717
+ <td>
718
+ <label><?php _e( 'Enable Debugging', 'wpsc' ); ?></label>
719
+ </td>
720
+ <td>
721
+ <label><input <?php checked( $this->setting->get( 'debugging' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
722
+ <label><input <?php checked( (bool) $this->setting->get( 'debugging' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
723
+ </td>
724
  </tr>
725
  <?php
726
+ }
727
+
728
+ /**
729
+ * Process the SetExpressCheckout API Call
730
+ *
731
+ * @param array $args
732
+ * @return void
733
+ *
734
+ * @since 3.9
735
+ */
736
+ public function process( $args = array() ) {
737
+ $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
738
+
739
+ $options = array(
740
+ 'return_url' => $this->get_return_url(),
741
+ 'message_id' => $this->purchase_log->get( 'id' ),
742
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
743
+ 'address_override' => 1,
744
+ );
745
+ $options += $this->checkout_data->get_gateway_data();
746
+ $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
747
+
748
+ if ( $this->setting->get( 'ipn', false ) ) {
749
+ $options['notify_url'] = $this->get_notify_url();
750
+ }
751
+
752
+ $response = $this->gateway->setup_purchase( $options );
753
+
754
+ if ( $response->is_successful() ) {
755
+ $url = ( $this->setting->get( 'sandbox_mode' ) ? self::SANDBOX_URL : self::LIVE_URL ) . $response->get( 'token' );
756
+ } else {
757
+
758
+ // SetExpressCheckout Failure
759
+ $this->log_error( $response );
760
+ wpsc_update_customer_meta( 'paypal_digital_goods_errors', $response->get_errors() );
761
+
762
+ $url = add_query_arg( array(
763
+ 'payment_gateway' => 'paypal-digital-goods',
764
+ 'payment_gateway_callback' => 'display_paypal_error_redirect',
765
+ 'return_url' => base64_encode( $this->get_return_url() ),
766
+ ), $this->get_return_url() );
767
+ }
768
+
769
+ if( ! isset( $args['return_only'] ) || $args['return_only'] !== true ) {
770
+ echo( $url );
771
+ exit;
772
+ }
773
+
774
+ return $url;
775
+ }
776
  }
wpsc-components/merchant-core-v3/gateways/paypal-express-checkout.php CHANGED
@@ -5,709 +5,1027 @@
5
  */
6
 
7
  class WPSC_Payment_Gateway_Paypal_Express_Checkout extends WPSC_Payment_Gateway {
8
- public $sandbox_url = 'https://www.sandbox.paypal.com/webscr';
9
- public $live_url = 'https://www.paypal.com/cgi-bin/webscr';
10
- private $gateway;
11
-
12
- /**
13
- * Constructor of PayPal Express Checkout Gateway
14
- *
15
- * @param array $options
16
- * @return void
17
- *
18
- * @since 3.9
19
- */
20
- public function __construct( $options ) {
21
- parent::__construct();
22
- $this->title = __( 'PayPal Express Checkout 3.0', 'wpsc' );
23
-
24
- require_once( 'php-merchant/gateways/paypal-express-checkout.php' );
25
- $this->gateway = new PHP_Merchant_Paypal_Express_Checkout( $options );
26
- $this->gateway->set_options( array(
27
- 'api_username' => $this->setting->get( 'api_username' ),
28
- 'api_password' => $this->setting->get( 'api_password' ),
29
- 'api_signature' => $this->setting->get( 'api_signature' ),
30
- 'cancel_url' => $this->get_shopping_cart_payment_url(),
31
- 'currency' => $this->get_currency_code(),
32
- 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
33
- 'address_override' => 1,
34
- 'solution_type' => 'mark',
35
- 'cart_logo' => $this->setting->get( 'cart_logo' ),
36
- 'cart_border' => $this->setting->get( 'cart_border' ),
37
- ) );
38
-
39
- add_filter( 'wpsc_purchase_log_gateway_data', array( $this, 'filter_purchase_log_gateway_data' ), 10, 2 );
40
- add_filter(
41
- 'wpsc_payment_method_form_fields',
42
- array( $this, 'filter_unselect_default' ), 100 , 1
43
- );
44
- }
45
-
46
- /**
47
- * Returns the HTML of the logo of the payment gateway.
48
- *
49
- * @access public
50
- * @return string
51
- *
52
- * @since 3.9
53
- */
54
- public function get_mark_html() {
55
- $html = '<a href="https://www.paypal.com/webapps/mpp/paypal-popup" title="' . esc_attr__( 'How PayPal Works' ) . '" onclick="javascript:window.open(\'https://www.paypal.com/webapps/mpp/paypal-popup\',\'WIPaypal\',\'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700\'); return false;"><img src="https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg" border="0" alt="PayPal Logo"></a>';
56
-
57
- return apply_filters( 'wpsc_paypal-ec_mark_html', $html );
58
- }
59
-
60
- /**
61
- * No payment gateway is selected by default
62
- *
63
- * @access public
64
- * @param array $fields
65
- * @return array
66
- *
67
- * @since 3.9
68
- */
69
- public function filter_unselect_default( $fields ) {
70
- foreach ( $fields as $i=>$field ) {
71
- $fields[ $i ][ 'checked' ] = false;
72
- }
73
-
74
- return $fields;
75
- }
76
-
77
- /**
78
- * Returns the PayPal redirect URL
79
- *
80
- * @param array $data Arguments to encode with the URL
81
- * @return string
82
- *
83
- * @since 3.9
84
- */
85
- public function get_redirect_url( $data = array() ) {
86
-
87
- // Select either the Sandbox or the Live URL
88
- if ( $this->setting->get( 'sandbox_mode' ) ) {
89
- $url = $this->sandbox_url;
90
- } else {
91
- $url = $this->live_url;
92
- }
93
-
94
- // Common Vars
95
- $common = array(
96
- 'cmd' => '_express-checkout',
97
- 'useraction' => 'commit',
98
- );
99
-
100
- if ( wp_is_mobile() ) {
101
- $common['cmd'] = '_express-checkout-mobile';
102
- }
103
-
104
- // Merge the two arrays
105
- $data = array_merge( $data, $common );
106
-
107
- // Build the URL
108
- $url = add_query_arg( $data, $url );
109
-
110
- return esc_url( $url );
111
- }
112
-
113
- /**
114
- * Purchase Log Filter for Gateway Data
115
- *
116
- * @param array $gateway_data
117
- * @param array $data
118
- * @return array
119
- *
120
- * @since 3.9
121
- */
122
- public static function filter_purchase_log_gateway_data( $gateway_data, $data ) {
123
- // Because paypal express checkout API doesn't have full support for discount, we have to manually add an item here
124
- if ( isset( $gateway_data['discount'] ) && (float) $gateway_data['discount'] != 0 ) {
125
- $i =& $gateway_data['items'];
126
- $d =& $gateway_data['discount'];
127
- $s =& $gateway_data['subtotal'];
128
-
129
- // If discount amount is larger than or equal to the item total, we need to set item total to 0.01
130
- // because Paypal does not accept 0 item total.
131
- if ( $d >= $gateway_data['subtotal'] ) {
132
- $d = $s - 0.01;
133
-
134
- // if there's shipping, we'll take 0.01 from there
135
- if ( ! empty( $gateway_data['shipping'] ) ) {
136
- $gateway_data['shipping'] -= 0.01;
137
- } else {
138
- $gateway_data['amount'] = 0.01;
139
- }
140
- }
141
-
142
- $s -= $d;
143
-
144
- $i[] = array(
145
- 'name' => __( 'Discount', 'wpsc' ),
146
- 'amount' => - $d,
147
- 'quantity' => 1,
148
- );
149
- }
150
- return $gateway_data;
151
- }
152
-
153
- /**
154
- * Returns the URL of the Return Page after the PayPal Checkout
155
- *
156
- * @return string
157
- */
158
- protected function get_return_url() {
159
- $location = add_query_arg( array(
160
- 'sessionid' => $this->purchase_log->get( 'sessionid' ),
161
- 'payment_gateway' => 'paypal-express-checkout',
162
- 'payment_gateway_callback' => 'confirm_transaction',
163
- ),
164
- get_option( 'transact_url' )
165
- );
166
- return apply_filters( 'wpsc_paypal_express_checkout_return_url', $location, $this );
167
- }
168
-
169
- /**
170
- * Returns the URL of the IPN Page
171
- *
172
- * @return string
173
- */
174
- protected function get_notify_url() {
175
- $location = add_query_arg( array(
176
- 'payment_gateway' => 'paypal-express-checkout',
177
- 'payment_gateway_callback' => 'ipn',
178
- ), home_url( 'index.php' ) );
179
-
180
- return apply_filters( 'wpsc_paypal_express_checkout_notify_url', $location );
181
- }
182
-
183
- /**
184
- * Creates a new Purchase Log entry and set it to the current object
185
- *
186
- * @return null
187
- */
188
- protected function set_purchase_log_for_callbacks( $sessionid = false ) {
189
- // Define the sessionid if it's not passed
190
- if ( $sessionid === false ) {
191
- $sessionid = $_REQUEST['sessionid'];
192
- }
193
-
194
- // Create a new Purchase Log entry
195
- $purchase_log = new WPSC_Purchase_Log( $sessionid, 'sessionid' );
196
-
197
- if ( ! $purchase_log->exists() ) {
198
- return null;
199
- }
200
-
201
- // Set the Purchase Log for the gateway object
202
- $this->set_purchase_log( $purchase_log );
203
- }
204
-
205
- /**
206
- * IPN Callback function
207
- *
208
- * @return void
209
- */
210
- public function callback_ipn() {
211
- $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
212
-
213
- if ( $ipn->is_verified() ) {
214
- $sessionid = $ipn->get( 'invoice' );
215
- $this->set_purchase_log_for_callbacks( $sessionid );
216
-
217
- if ( $ipn->is_payment_denied() ) {
218
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
219
- } elseif ( $ipn->is_payment_refunded() ) {
220
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUNDED );
221
- } elseif ( $ipn->is_payment_completed() ) {
222
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
223
- } elseif ( $ipn->is_payment_pending() ) {
224
- if ( $ipn->is_payment_refund_pending() ) {
225
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUND_PENDING );
226
- } else {
227
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
228
- }
229
- }
230
-
231
- $this->purchase_log->save();
232
- transaction_results( $sessionid, false );
233
- }
234
-
235
- exit;
236
- }
237
-
238
- /**
239
- * Confirm Transaction Callback
240
- *
241
- * @return bool
242
- *
243
- * @since 3.9
244
- */
245
- public function callback_confirm_transaction() {
246
- if ( ! isset( $_REQUEST['sessionid'] ) || ! isset( $_REQUEST['token'] ) || ! isset( $_REQUEST['PayerID'] ) ) {
247
- return false;
248
- }
249
-
250
- // Set the Purchase Log
251
- $this->set_purchase_log_for_callbacks();
252
-
253
- // Display the Confirmation Page
254
- $this->do_transaction();
255
- }
256
-
257
- /**
258
- * Process the transaction through the PayPal APIs
259
- *
260
- * @since 3.9
261
- */
262
- public function do_transaction() {
263
- $args = array_map( 'urldecode', $_GET );
264
- extract( $args, EXTR_SKIP );
265
-
266
- if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
267
- return;
268
- }
269
-
270
- $this->set_purchase_log_for_callbacks();
271
-
272
- $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
273
- $options = array(
274
- 'token' => $token,
275
- 'payer_id' => $PayerID,
276
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
277
- 'invoice' => $this->purchase_log->get( 'id' ),
278
- );
279
- $options += $this->checkout_data->get_gateway_data();
280
- $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
281
-
282
- if ( $this->setting->get( 'ipn', false ) ) {
283
- $options['notify_url'] = $this->get_notify_url();
284
- }
285
-
286
- // GetExpressCheckoutDetails
287
- $details = $this->gateway->get_details_for( $token );
288
- $this->log_payer_details( $details );
289
-
290
- $response = $this->gateway->purchase( $options );
291
- $this->log_protection_status( $response );
292
- $location = remove_query_arg( 'payment_gateway_callback' );
293
-
294
- if ( $response->has_errors() ) {
295
- $errors = $response->get_params();
296
-
297
- if ( isset( $errors['L_ERRORCODE0'] ) && '10486' == $errors['L_ERRORCODE0'] ) {
298
- wp_redirect( $this->get_redirect_url( array( 'token' => $token ) ) );
299
- exit;
300
- }
301
-
302
- wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
303
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
304
-
305
- } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
306
- $location = remove_query_arg( 'payment_gateway' );
307
-
308
- if ( $response->is_payment_completed() ) {
309
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
310
- } else {
311
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
312
- }
313
-
314
- $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
315
- ->set( 'date', time() )
316
- ->save();
317
- } else {
318
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
319
- }
320
-
321
- wp_redirect( esc_url_raw( $location ) );
322
- exit;
323
- }
324
-
325
- public function callback_display_paypal_error() {
326
- add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_paypal_error_page' ) );
327
- }
328
-
329
- public function callback_display_generic_error() {
330
- add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_generic_error_page' ) );
331
- }
332
-
333
- /**
334
- * Records the Payer ID, Payer Status and Shipping Status to the Purchase
335
- * Log on GetExpressCheckout Call
336
- *
337
- * @return void
338
- */
339
- public function log_payer_details( $details ) {
340
- if ( isset( $details->get( 'payer' )->id ) && !empty( $details->get( 'payer' )->id ) ) {
341
- $payer_id = $details->get( 'payer' )->id;
342
- } else {
343
- $payer_id = 'not set';
344
- }
345
- if ( isset( $details->get( 'payer' )->status ) && !empty( $details->get( 'payer' )->status ) ) {
346
- $payer_status = $details->get( 'payer' )->status;
347
- } else {
348
- $payer_status = 'not set';
349
- }
350
- if ( isset( $details->get( 'payer' )->shipping_status ) && !empty( $details->get( 'payer' )->shipping_status ) ) {
351
- $payer_shipping_status = $details->get( 'payer' )->shipping_status;
352
- } else {
353
- $payer_shipping_status = 'not set';
354
- }
355
- $paypal_log = array(
356
- 'payer_id' => $payer_id,
357
- 'payer_status' => $payer_status,
358
- 'shipping_status' => $payer_shipping_status,
359
- 'protection' => null,
360
- );
361
-
362
- wpsc_update_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details' , $paypal_log );
363
- }
364
-
365
- /**
366
- * Records the Protection Eligibility status to the Purchase Log on
367
- * DoExpressCheckout Call
368
- *
369
- * @return void
370
- */
371
- public function log_protection_status( $response ) {
372
- $params = $response->get_params();
373
-
374
- $elg = $params['PAYMENTINFO_0_PROTECTIONELIGIBILITY'];
375
- $paypal_log = wpsc_get_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details', true );
376
- $paypal_log['protection'] = $elg;
377
- wpsc_update_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details' , $paypal_log );
378
- }
379
-
380
- public function callback_process_confirmed_payment() {
381
- $args = array_map( 'urldecode', $_GET );
382
- extract( $args, EXTR_SKIP );
383
-
384
- if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
385
- return;
386
- }
387
-
388
- $this->set_purchase_log_for_callbacks();
389
-
390
- $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
391
- $options = array(
392
- 'token' => $token,
393
- 'payer_id' => $PayerID,
394
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
395
- 'invoice' => $this->purchase_log->get( 'id' ),
396
- );
397
- $options += $this->checkout_data->get_gateway_data();
398
- $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
399
-
400
- if ( $this->setting->get( 'ipn', false ) ) {
401
- $options['notify_url'] = $this->get_notify_url();
402
- }
403
-
404
- // GetExpressCheckoutDetails
405
- $details = $this->gateway->get_details_for( $token );
406
- $this->log_payer_details( $details );
407
-
408
- $response = $this->gateway->purchase( $options );
409
- $this->log_protection_status( $response );
410
- $location = remove_query_arg( 'payment_gateway_callback' );
411
-
412
- if ( $response->has_errors() ) {
413
- wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
414
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
415
- } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
416
- $location = remove_query_arg( 'payment_gateway' );
417
-
418
- if ( $response->is_payment_completed() ) {
419
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
420
- } else {
421
- $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
422
- }
423
-
424
- $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
425
- ->set( 'date', time() )
426
- ->save();
427
- } else {
428
- $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
429
- }
430
-
431
- wp_redirect( esc_url_raw( $location ) );
432
- exit;
433
- }
434
-
435
- /**
436
- * Error Page Template
437
- *
438
- * @since 3.9
439
- */
440
- public function filter_paypal_error_page() {
441
- $errors = wpsc_get_customer_meta( 'paypal_express_checkout_errors' );
442
- ob_start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  ?>
444
- <p>
445
- <?php _e( 'Sorry, your transaction could not be processed by PayPal. Please contact the site administrator. The following errors are returned:' , 'wpsc' ); ?>
446
- </p>
447
- <ul>
448
- <?php foreach ( $errors as $error ): ?>
449
- <li><?php echo esc_html( $error['details'] ) ?> (<?php echo esc_html( $error['code'] ); ?>)</li>
450
- <?php endforeach; ?>
451
- </ul>
452
- <p><a href="<?php echo esc_url( $this->get_shopping_cart_payment_url() ); ?>"><?php ( 'Click here to go back to the checkout page.') ?></a></p>
453
  <?php
454
- $output = apply_filters( 'wpsc_paypal_express_checkout_gateway_error_message', ob_get_clean(), $errors );
455
- return $output;
456
- }
457
-
458
- /**
459
- * Generic Error Page Template
460
- *
461
- * @since 3.9
462
- */
463
- public function filter_generic_error_page() {
464
- ob_start();
465
  ?>
466
  <p><?php _e( 'Sorry, but your transaction could not be processed by PayPal for some reason. Please contact the site administrator.' , 'wpsc' ); ?></p>
467
  <p><a href="<?php echo esc_attr( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
468
  <?php
469
- $output = apply_filters( 'wpsc_paypal_express_checkout_generic_error_message', ob_get_clean() );
470
- return $output;
471
- }
472
-
473
- /**
474
- * Settings Form Template
475
- *
476
- * @since 3.9
477
- */
478
- public function setup_form() {
479
- $paypal_currency = $this->get_currency_code();
480
  ?>
481
 
482
  <!-- Account Credentials -->
483
  <tr>
484
- <td colspan="2">
485
- <h4><?php _e( 'Account Credentials', 'wpsc' ); ?></h4>
486
- </td>
487
  </tr>
488
  <tr>
489
- <td>
490
- <label for="wpsc-paypal-express-api-username"><?php _e( 'API Username', 'wpsc' ); ?></label>
491
- </td>
492
- <td>
493
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_username' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_username' ) ); ?>" id="wpsc-paypal-express-api-username" />
494
- </td>
495
  </tr>
496
  <tr>
497
- <td>
498
- <label for="wpsc-paypal-express-api-password"><?php _e( 'API Password', 'wpsc' ); ?></label>
499
- </td>
500
- <td>
501
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_password' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_password' ) ); ?>" id="wpsc-paypal-express-api-password" />
502
- </td>
503
  </tr>
504
  <tr>
505
- <td>
506
- <label for="wpsc-paypal-express-api-signature"><?php _e( 'API Signature', 'wpsc' ); ?></label>
507
- </td>
508
- <td>
509
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_signature' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_signature' ) ); ?>" id="wpsc-paypal-express-api-signature" />
510
- </td>
511
  </tr>
512
  <tr>
513
- <td>
514
- <label><?php _e( 'Sandbox Mode', 'wpsc' ); ?></label>
515
- </td>
516
- <td>
517
- <label><input <?php checked( $this->setting->get( 'sandbox_mode' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
518
- <label><input <?php checked( (bool) $this->setting->get( 'sandbox_mode' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
519
- </td>
520
  </tr>
521
  <tr>
522
- <td>
523
- <label><?php _e( 'IPN', 'wpsc' ); ?></label>
524
- </td>
525
- <td>
526
- <label><input <?php checked( $this->setting->get( 'ipn' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
527
- <label><input <?php checked( (bool) $this->setting->get( 'ipn' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
528
- </td>
529
  </tr>
530
 
531
  <!-- Cart Customization -->
532
  <tr>
533
- <td colspan="2">
534
- <label><h4><?php _e( 'Cart Customization', 'wpsc'); ?></h4></label>
535
- </td>
536
  </tr>
537
  <tr>
538
- <td>
539
- <label for="wpsc-paypal-express-cart-logo"><?php _e( 'Merchant Logo', 'wpsc' ); ?></label>
540
- </td>
541
- <td>
542
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_logo' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_logo' ) ); ?>" id="wpsc-paypal-express-cart-logo" />
543
- </td>
544
  </tr>
545
  <tr>
546
- <td>
547
- <label for="wpsc-paypal-express-cart-border"><?php _e( 'Cart Border Color', 'wpsc' ); ?></label>
548
- </td>
549
- <td>
550
- <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_border' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_border' ) ); ?>" id="wpsc-paypal-express-cart-border" />
551
- </td>
552
  </tr>
553
 
554
  <!-- Currency Conversion -->
555
  <?php if ( ! $this->is_currency_supported() ) : ?>
556
  <tr>
557
- <td colspan="2">
558
- <h4><?php _e( 'Currency Conversion', 'wpsc' ); ?></h4>
559
- </td>
560
  </tr>
561
  <tr>
562
- <td colspan="2">
563
- <p><?php _e( 'Your base currency is currently not accepted by PayPal. As a result, before a payment request is sent to PayPal, WP eCommerce has to convert the amounts into one of PayPal supported currencies. Please select your preferred currency below.', 'wpsc' ); ?></p>
564
- </td>
565
  </tr>
566
  <tr>
567
- <td>
568
- <label for "wpsc-paypal-express-currency"><?php _e( 'PayPal Currency', 'wpsc' ); ?></label>
569
- </td>
570
- <td>
571
- <select name="<?php echo esc_attr( $this->setting->get_field_name( 'currency' ) ); ?>" id="wpsc-paypal-express-currency">
572
- <?php foreach ( $this->gateway->get_supported_currencies() as $currency ) : ?>
573
- <option <?php selected( $currency, $paypal_currency ); ?> value="<?php echo esc_attr( $currency ); ?>"><?php echo esc_html( $currency ); ?></option>
574
- <?php endforeach ?>
575
- </select>
576
- </td>
577
  </tr>
578
  <?php endif ?>
579
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580
  <!-- Error Logging -->
581
  <tr>
582
- <td colspan="2">
583
- <h4><?php _e( 'Error Logging', 'wpsc' ); ?></h4>
584
- </td>
585
  </tr>
586
  <tr>
587
- <td>
588
- <label><?php _e( 'Enable Debugging', 'wpsc' ); ?></label>
589
- </td>
590
- <td>
591
- <label><input <?php checked( $this->setting->get( 'debugging' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
592
- <label><input <?php checked( (bool) $this->setting->get( 'debugging' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
593
- </td>
594
  </tr>
595
  <?php
596
- }
597
-
598
- /**
599
- * Check if the selected currency is supported by the gateway
600
- *
601
- * @return bool
602
- *
603
- * @since 3.9
604
- */
605
- protected function is_currency_supported() {
606
- return in_array( parent::get_currency_code(), $this->gateway->get_supported_currencies() );
607
- }
608
-
609
- /**
610
- * Return the Currency ISO code
611
- *
612
- * @return string
613
- *
614
- * @since 3.9
615
- */
616
- public function get_currency_code() {
617
- $code = parent::get_currency_code();
618
-
619
- if ( ! in_array( $code, $this->gateway->get_supported_currencies() ) ) {
620
- $code = $this->setting->get( 'currency', 'USD' );
621
- }
622
-
623
- return $code;
624
- }
625
-
626
- /**
627
- * Convert an amount (integer) to the supported currency
628
- * @param integer $amt
629
- *
630
- * @return integer
631
- *
632
- * @since 3.9
633
- */
634
- protected function convert( $amt ) {
635
- if ( $this->is_currency_supported() ) {
636
- return $amt;
637
- }
638
-
639
- return wpsc_convert_currency( $amt, parent::get_currency_code(), $this->get_currency_code() );
640
- }
641
-
642
- /**
643
- * Process the SetExpressCheckout API Call
644
- *
645
- * @return void
646
- *
647
- * @since 3.9
648
- */
649
- public function process() {
650
- $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
651
- $options = array(
652
- 'return_url' => $this->get_return_url(),
653
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
654
- 'invoice' => $this->purchase_log->get( 'id' ),
655
- 'address_override' => 1,
656
- );
657
-
658
- $options += $this->checkout_data->get_gateway_data();
659
- $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
660
-
661
- if ( $this->setting->get( 'ipn', false ) ) {
662
- $options['notify_url'] = $this->get_notify_url();
663
- }
664
-
665
- // SetExpressCheckout
666
- $response = $this->gateway->setup_purchase( $options );
667
-
668
- if ( $response->is_successful() ) {
669
- $params = $response->get_params();
670
- if ( $params['ACK'] == 'SuccessWithWarning' ) {
671
- $this->log_error( $response );
672
- }
673
- // Successful redirect
674
- $url = $this->get_redirect_url( array( 'token' => $response->get( 'token' ) ) );
675
- } else {
676
- // SetExpressCheckout Failure
677
- $this->log_error( $response );
678
- $url = add_query_arg( array(
679
- 'payment_gateway' => 'paypal-express-checkout',
680
- 'payment_gateway_callback' => 'display_paypal_error',
681
- ), $this->get_return_url() );
682
- }
683
-
684
- wp_redirect( $url );
685
- exit;
686
- }
687
-
688
- /**
689
- * Log an error message
690
- *
691
- * @param PHP_Merchant_Paypal_Express_Checkout_Response $response
692
- * @return void
693
- *
694
- * @since 3.9
695
- */
696
- public function log_error( $response ) {
697
- if ( $this->setting->get( 'debugging' ) ) {
698
- $log_data = array(
699
- 'post_title' => 'PayPal ExpressCheckout Operation Failure',
700
- 'post_content' => 'There was an error processing the payment. Find details in the log entry meta fields.',
701
- 'log_type' => 'error'
702
- );
703
-
704
- $log_meta = array(
705
- 'correlation_id' => $response->get( 'correlation_id' ),
706
- 'time' => $response->get( 'datetime' ),
707
- 'errors' => $response->get_errors(),
708
- );
709
-
710
- $log_entry = WPSC_Logging::insert_log( $log_data, $log_meta );
711
- }
712
- }
 
 
 
 
 
 
 
 
713
  }
5
  */
6
 
7
  class WPSC_Payment_Gateway_Paypal_Express_Checkout extends WPSC_Payment_Gateway {
8
+ public $sandbox_url = 'https://www.sandbox.paypal.com/webscr';
9
+ public $live_url = 'https://www.paypal.com/cgi-bin/webscr';
10
+ private $paypal_data;
11
+ protected $gateway;
12
+
13
+ /**
14
+ * Constructor of PayPal Express Checkout Gateway.
15
+ * The $child parameter should be set to true, if the constructor
16
+ * is called from a child class.
17
+ *
18
+ * @param array $options
19
+ * @param bool $child
20
+ *
21
+ * @since 3.9
22
+ */
23
+ public function __construct( $options, $child = false ) {
24
+ parent::__construct();
25
+
26
+ require_once( 'php-merchant/gateways/paypal-express-checkout.php' );
27
+ $this->gateway = new PHP_Merchant_Paypal_Express_Checkout( $options );
28
+
29
+ if ( ! $child ) {
30
+ $this->title = __( 'PayPal Express Checkout 3.0', 'wpsc' );
31
+ $this->gateway->set_options( array(
32
+ 'api_username' => $this->setting->get( 'api_username' ),
33
+ 'api_password' => $this->setting->get( 'api_password' ),
34
+ 'api_signature' => $this->setting->get( 'api_signature' ),
35
+ 'cancel_url' => $this->get_shopping_cart_payment_url(),
36
+ 'currency' => $this->get_currency_code(),
37
+ 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
38
+ 'address_override' => 1,
39
+ 'solution_type' => 'mark',
40
+ 'cart_logo' => $this->setting->get( 'cart_logo' ),
41
+ 'cart_border' => $this->setting->get( 'cart_border' ),
42
+ ) );
43
+
44
+ // Express Checkout Button
45
+ add_action( 'wpsc_cart_item_table_form_actions_left', array( $this, 'add_ecs_button' ), 2, 2 );
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Insert the ExpessCheckout Shortcut Button
51
+ *
52
+ * @return void
53
+ */
54
+ public function add_ecs_button( $cart_table, $context ) {
55
+
56
+ if ( ! wpsc_uses_shipping() && wpsc_is_gateway_active( 'paypal-digital-goods' ) || ! wpsc_is_gateway_active( 'paypal-express-checkout' ) ) {
57
+ return;
58
+ }
59
+
60
+ if ( 'top' == $context ) {
61
+ return;
62
+ }
63
+
64
+ if ( _wpsc_get_current_controller_name() === 'cart' ) {
65
+ $url = $this->get_shortcut_url();
66
+ echo '<a href="'. esc_url( $url ) .'"><img src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/checkout-logo-large.png" alt="' . __( 'Check out with PayPal', 'wpsc' ) . '" /></a>';
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Return the ExpressCheckout Shortcut redirection URL
72
+ *
73
+ * @return void
74
+ */
75
+ public function get_shortcut_url() {
76
+ $location = add_query_arg( array(
77
+ 'payment_gateway' => 'paypal-express-checkout',
78
+ 'payment_gateway_callback' => 'shortcut_process',
79
+ ), home_url( 'index.php' ) );
80
+
81
+ return apply_filters( 'wpsc_paypal_express_checkout_shortcut_url', $location );
82
+ }
83
+
84
+ /**
85
+ * ExpressCheckout Shortcut Callback
86
+ *
87
+ * @return int
88
+ */
89
+ public function callback_shortcut_process() {
90
+ if ( ! isset( $_GET['payment_gateway'] ) ) {
91
+ return;
92
+ }
93
+ $payment_gateway = $_GET['payment_gateway'];
94
+
95
+ global $wpsc_cart;
96
+ // Create a new PurchaseLog Object
97
+ $purchase_log = new WPSC_Purchase_Log();
98
+
99
+ // Create a Sessionid
100
+ $sessionid = ( mt_rand( 100, 999 ) . time() );
101
+ wpsc_update_customer_meta( 'checkout_session_id', $sessionid );
102
+ $purchase_log->set( array(
103
+ 'user_ID' => get_current_user_id(),
104
+ 'date' => time(),
105
+ 'plugin_version' => WPSC_VERSION,
106
+ 'statusno' => '0',
107
+ 'sessionid' => $sessionid,
108
+ ) );
109
+
110
+ if ( wpsc_is_tax_included() ) {
111
+ $tax = $wpsc_cart->calculate_total_tax();
112
+ $tax_percentage = $wpsc_cart->tax_percentage;
113
+ } else {
114
+ $tax = 0;
115
+ $tax_percentage = 0;
116
+ }
117
+ $purchase_log->set( array(
118
+ 'wpec_taxes_total' => $tax,
119
+ 'wpec_taxes_rate' => $tax_percentage,
120
+ ) );
121
+
122
+ // Save the purchase_log object to generate it's id
123
+ $purchase_log->save();
124
+ $purchase_log_id = $purchase_log->get( 'id' );
125
+
126
+ $wpsc_cart->log_id = $purchase_log_id;
127
+ wpsc_update_customer_meta( 'current_purchase_log_id', $purchase_log_id );
128
+
129
+ $purchase_log->set( array(
130
+ 'gateway' => $payment_gateway,
131
+ 'base_shipping' => $wpsc_cart->calculate_base_shipping(),
132
+ 'totalprice' => $wpsc_cart->calculate_total_price(),
133
+ ) );
134
+
135
+ $purchase_log->save();
136
+
137
+ $wpsc_cart->empty_db( $purchase_log_id );
138
+ $wpsc_cart->save_to_db( $purchase_log_id );
139
+ $wpsc_cart->submit_stock_claims( $purchase_log_id );
140
+
141
+ // Save an empty Form
142
+ $form = WPSC_Checkout_Form::get();
143
+ $fields = $form->get_fields();
144
+ WPSC_Checkout_Form_Data::save_form( $purchase_log, $fields );
145
+
146
+ // Return Customer to Review Order Page if there is Shipping
147
+ add_filter( 'wpsc_paypal_express_checkout_transact_url', array( &$this, 'review_order_url' ) );
148
+ add_filter( 'wpsc_paypal_express_checkout_return_url', array( &$this, 'review_order_callback' ) );
149
+
150
+ // Set a Temporary Option for EC Shortcut
151
+ wpsc_update_customer_meta( 'esc-' . $sessionid, true );
152
+
153
+ // Apply Checkout Actions
154
+ do_action( 'wpsc_submit_checkout', array(
155
+ 'purchase_log_id' => $purchase_log_id,
156
+ 'our_user_id' => get_current_user_id(),
157
+ ) );
158
+ do_action( 'wpsc_submit_checkout_gateway', $payment_gateway, $purchase_log );
159
+
160
+ return $sessionid;
161
+ }
162
+
163
+ /**
164
+ * Return Customer to Review Order Page if there are Shipping Costs.
165
+ *
166
+ * @param string $url
167
+ * @return string
168
+ */
169
+ public function review_order_url( $url ) {
170
+ if ( wpsc_uses_shipping() ) {
171
+ $url = wpsc_get_checkout_url( 'review-order' );
172
+ }
173
+
174
+ return $url;
175
+ }
176
+
177
+ /**
178
+ * Sets the Review Callback for Review Order page.
179
+ *
180
+ * @param string $url
181
+ * @return string
182
+ */
183
+ public function review_order_callback( $url ) {
184
+ $args = array(
185
+ 'payment_gateway_callback' => 'review_transaction',
186
+ 'payment_gateway' => 'paypal-express-checkout',
187
+ );
188
+ $url = add_query_arg( $args, $url );
189
+
190
+ return esc_url( $url );
191
+ }
192
+
193
+ /**
194
+ * Run the gateway hooks
195
+ *
196
+ * @access public
197
+ * @since 4.0
198
+ *
199
+ * @return void
200
+ */
201
+ public function init() {
202
+ add_filter(
203
+ 'wpsc_payment_method_form_fields',
204
+ array( 'WPSC_Payment_Gateway_Paypal_Express_Checkout', 'filter_unselect_default' ), 100 , 1
205
+ );
206
+ }
207
+
208
+ /**
209
+ * No payment gateway is selected by default
210
+ *
211
+ * @access public
212
+ * @param array $fields
213
+ * @return array
214
+ *
215
+ * @since 3.9
216
+ */
217
+ public static function filter_unselect_default( $fields ) {
218
+ foreach ( $fields as $i => $field ) {
219
+ $fields[ $i ][ 'checked' ] = false;
220
+ }
221
+
222
+ return $fields;
223
+ }
224
+
225
+ /**
226
+ * Returns the HTML of the logo of the payment gateway.
227
+ *
228
+ * @access public
229
+ * @return string
230
+ *
231
+ * @since 3.9
232
+ */
233
+ public function get_mark_html() {
234
+ $html = '<img src="https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg" border="0" alt="PayPal Logo">';
235
+
236
+ return apply_filters( 'wpsc_paypal-ec_mark_html', $html );
237
+ }
238
+
239
+ /**
240
+ * Returns the PayPal redirect URL
241
+ *
242
+ * @param array $data Arguments to encode with the URL
243
+ * @return string
244
+ *
245
+ * @since 3.9
246
+ */
247
+ public function get_redirect_url( $data = array() ) {
248
+
249
+ // Select either the Sandbox or the Live URL
250
+ if ( $this->setting->get( 'sandbox_mode' ) ) {
251
+ $url = $this->sandbox_url;
252
+ } else {
253
+ $url = $this->live_url;
254
+ }
255
+
256
+ // Common Vars
257
+ $common = array(
258
+ 'cmd' => '_express-checkout',
259
+ 'useraction' => 'commit',
260
+ );
261
+
262
+ if ( wp_is_mobile() ) {
263
+ $common['cmd'] = '_express-checkout-mobile';
264
+ }
265
+
266
+ // Merge the two arrays
267
+ $data = array_merge( $data, $common );
268
+
269
+ // Build the URL
270
+ $url = add_query_arg( $data, $url );
271
+
272
+ return $url;
273
+ }
274
+
275
+ /**
276
+ * Returns the URL of the Return Page after the PayPal Checkout
277
+ *
278
+ * @return string
279
+ */
280
+ protected function get_return_url() {
281
+ $transact_url = get_option( 'transact_url' );
282
+ $transact_url = apply_filters( 'wpsc_paypal_express_checkout_transact_url', $transact_url );
283
+
284
+ $location = add_query_arg( array(
285
+ 'sessionid' => $this->purchase_log->get( 'sessionid' ),
286
+ 'payment_gateway' => 'paypal-express-checkout',
287
+ 'payment_gateway_callback' => 'confirm_transaction',
288
+ ),
289
+ $transact_url
290
+ );
291
+ return apply_filters( 'wpsc_paypal_express_checkout_return_url', $location, $this );
292
+ }
293
+
294
+ /**
295
+ * Returns the URL of the IPN Page
296
+ *
297
+ * @return string
298
+ */
299
+ protected function get_notify_url() {
300
+ $location = add_query_arg( array(
301
+ 'payment_gateway' => 'paypal-express-checkout',
302
+ 'payment_gateway_callback' => 'ipn',
303
+ ), home_url( 'index.php' ) );
304
+
305
+ return apply_filters( 'wpsc_paypal_express_checkout_notify_url', $location );
306
+ }
307
+
308
+ /**
309
+ * Creates a new Purchase Log entry and set it to the current object
310
+ *
311
+ * @return null
312
+ */
313
+ protected function set_purchase_log_for_callbacks( $sessionid = false ) {
314
+ // Define the sessionid if it's not passed
315
+ if ( $sessionid === false ) {
316
+ $sessionid = $_REQUEST['sessionid'];
317
+ }
318
+
319
+ // Create a new Purchase Log entry
320
+ $purchase_log = new WPSC_Purchase_Log( $sessionid, 'sessionid' );
321
+
322
+ if ( ! $purchase_log->exists() ) {
323
+ return null;
324
+ }
325
+
326
+ // Set the Purchase Log for the gateway object
327
+ $this->set_purchase_log( $purchase_log );
328
+ }
329
+
330
+ /**
331
+ * IPN Callback function
332
+ *
333
+ * @return void
334
+ */
335
+ public function callback_ipn() {
336
+ $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
337
+
338
+ if ( $ipn->is_verified() ) {
339
+ $sessionid = $ipn->get( 'invoice' );
340
+ $this->set_purchase_log_for_callbacks( $sessionid );
341
+
342
+ if ( $ipn->is_payment_denied() ) {
343
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
344
+ } elseif ( $ipn->is_payment_refunded() ) {
345
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUNDED );
346
+ } elseif ( $ipn->is_payment_completed() ) {
347
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
348
+ } elseif ( $ipn->is_payment_pending() ) {
349
+ if ( $ipn->is_payment_refund_pending() ) {
350
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::REFUND_PENDING );
351
+ } else {
352
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
353
+ }
354
+ }
355
+
356
+ $this->purchase_log->save();
357
+ transaction_results( $sessionid, false );
358
+ }
359
+
360
+ exit;
361
+ }
362
+
363
+ /**
364
+ * Pull and Record PayPal Details
365
+ *
366
+ * @return void
367
+ */
368
+ public function pull_paypal_details() {
369
+ $this->set_purchase_log_for_callbacks();
370
+
371
+ // Pull the User Details from PayPal
372
+ $this->paypal_data = $paypal = $this->gateway->get_details_for( $_GET['token'] );
373
+ $payer = $paypal->get( 'payer' );
374
+ $address = $paypal->get( 'shipping_address' );
375
+
376
+ // PurchaseLog Update
377
+ if ( isset( $address['country_code'] ) ) {
378
+ $this->purchase_log->set( 'billing_country', $address['country_code'] );
379
+ $this->purchase_log->set( 'shipping_country', $address['country_code'] );
380
+ }
381
+ if ( isset( $address['state'] ) ) {
382
+ $this->purchase_log->set( 'billing_region', $address['state'] );
383
+ $this->purchase_log->set( 'shipping_region', $address['state'] );
384
+ }
385
+
386
+ // Save Checkout Form Fields
387
+ $form = WPSC_Checkout_Form::get();
388
+ $fields = $form->get_fields();
389
+ $_POST['wpsc_checkout_details'] = array();
390
+ foreach( $fields as $field ) {
391
+ $this->set_post_var( $field, $payer, $address );
392
+ }
393
+
394
+ // Save details to the Forms Table
395
+ WPSC_Checkout_Form_Data::save_form( $this->purchase_log, $fields );
396
+ }
397
+
398
+ /**
399
+ * To insert Data to the Form Table, we need to pass it
400
+ * to the global $_POST variable first
401
+ *
402
+ * @param object $payer
403
+ * @param object $field
404
+ * @param array $address
405
+ *
406
+ * @return void
407
+ */
408
+ private function set_post_var( $field, $payer, $address ) {
409
+ switch( $field->unique_name ) {
410
+ // Shipping Details
411
+ case 'shippingfirstname':
412
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['name'] );
413
+ break;
414
+ case 'shippinglastname':
415
+ $_POST['wpsc_checkout_details'][$field->id] = '';
416
+ break;
417
+ case 'shippingaddress':
418
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['street'] );
419
+ break;
420
+ case 'shippingcity':
421
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['city'] );
422
+ break;
423
+ case 'shippingstate':
424
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['state'] );
425
+ break;
426
+ case 'shippingcountry':
427
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['country_code'] );
428
+ break;
429
+ case 'shippingpostcode':
430
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $address['zip'] );
431
+ break;
432
+ // Billing Details
433
+ case 'billingfirstname':
434
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $payer->first_name );
435
+ break;
436
+ case 'billinglastname':
437
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $payer->last_name );
438
+ break;
439
+ case 'billingaddress':
440
+ case 'billingcity':
441
+ case 'billingstate':
442
+ case 'billingpostcode':
443
+ case 'billingphone':
444
+ $_POST['wpsc_checkout_details'][$field->id] = '';
445
+ break;
446
+ case 'billingcountry':
447
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $payer->country );
448
+ break;
449
+ case 'billingemail':
450
+ $_POST['wpsc_checkout_details'][$field->id] = $this->validate_var( $payer->email );
451
+ break;
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Verify that the variable isset and return it, otherwise return an empty
457
+ * string
458
+ *
459
+ * @param string $var
460
+ *
461
+ * @return string
462
+ */
463
+ private function validate_var( $var ) {
464
+ if ( isset( $var ) ) {
465
+ return $var;
466
+ }
467
+ return '';
468
+ }
469
+
470
+ /**
471
+ * Review Transaction Callback
472
+ *
473
+ * @return void
474
+ */
475
+ public function callback_review_transaction() {
476
+ // Pull Customer Details from PayPal
477
+ $this->pull_paypal_details();
478
+
479
+ // If no Shipping is required, confirm the Transaction
480
+ if ( !wpsc_uses_shipping() ) {
481
+ $this->callback_confirm_transaction();
482
+ }
483
+
484
+ // Display Customer Details
485
+ add_filter( 'wpsc_review_order_buyers_details', array( &$this, 'review_order_buyer_details' ) );
486
+ add_filter( 'wpsc_review_order_shipping_details', array( &$this, 'review_order_shipping_details' ) );
487
+ }
488
+
489
+ /**
490
+ * Display Customer Details from PayPal
491
+ *
492
+ * @param string $output
493
+ * @return string
494
+ */
495
+ public function review_order_buyer_details( $output ) {
496
+ $payer = $this->paypal_data->get( 'payer' );
497
+ $output .= '<ul>';
498
+ $output .= '<li><strong>' . __( 'Email:', 'wpsc' ) . ' </strong>' . $payer->email . '</li>';
499
+ $output .= '<li><strong>' . __( 'First Name:', 'wpsc' ) . ' </strong>' . $payer->first_name . '</li>';
500
+ $output .= '<li><strong>' . __( 'Last Name:', 'wpsc' ) . ' </strong>' . $payer->last_name . '</li>';
501
+ $output .= '</ul>';
502
+ return $output;
503
+ }
504
+
505
+ /**
506
+ * Display Shipping Details from PayPal
507
+ *
508
+ * @param string $output
509
+ * @return string
510
+ */
511
+ public function review_order_shipping_details( $output ) {
512
+ $address = $this->paypal_data->get( 'shipping_address' );
513
+ $output .= '<ul>';
514
+ $output .= '<li>' . $address[ 'name' ] . '</li>';
515
+ $output .= '<li>' . $address[ 'street' ] . '</li>';
516
+ $output .= '<li>' . $address[ 'city' ] . '</li>';
517
+ $output .= '<li>' . $address[ 'state' ] . '</li>';
518
+ $output .= '<li>' . $address[ 'zip' ] . '</li>';
519
+ $output .= '<li>' . $address[ 'country_code' ] . '</li>';
520
+ $output .= '</ul>';
521
+ return $output;
522
+ }
523
+
524
+ /**
525
+ * Confirm Transaction Callback
526
+ *
527
+ * @return bool
528
+ *
529
+ * @since 3.9
530
+ */
531
+ public function callback_confirm_transaction() {
532
+ if ( ! isset( $_REQUEST['sessionid'] ) || ! isset( $_REQUEST['token'] ) || ! isset( $_REQUEST['PayerID'] ) ) {
533
+ return false;
534
+ }
535
+
536
+ // Set the Purchase Log
537
+ $this->set_purchase_log_for_callbacks();
538
+
539
+ // Display the Confirmation Page
540
+ $this->do_transaction();
541
+
542
+ // Remove Shortcut option if it exists
543
+ $sessionid = $_REQUEST['sessionid'];
544
+ wpsc_delete_customer_meta( 'esc-' . $sessionid );
545
+ }
546
+
547
+ /**
548
+ * Process the transaction through the PayPal APIs
549
+ *
550
+ * @since 3.9
551
+ */
552
+ public function do_transaction() {
553
+ $args = array_map( 'urldecode', $_GET );
554
+ extract( $args, EXTR_SKIP );
555
+
556
+ if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
557
+ return;
558
+ }
559
+
560
+ $this->set_purchase_log_for_callbacks();
561
+
562
+ $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
563
+ $options = array(
564
+ 'token' => $token,
565
+ 'payer_id' => $PayerID,
566
+ 'message_id' => $this->purchase_log->get( 'id' ),
567
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
568
+ );
569
+ $options += $this->checkout_data->get_gateway_data();
570
+ $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
571
+
572
+ if ( $this->setting->get( 'ipn', false ) ) {
573
+ $options['notify_url'] = $this->get_notify_url();
574
+ }
575
+
576
+ // GetExpressCheckoutDetails
577
+ $details = $this->gateway->get_details_for( $token );
578
+ $this->log_payer_details( $details );
579
+
580
+ $response = $this->gateway->purchase( $options );
581
+ $this->log_protection_status( $response );
582
+ $location = remove_query_arg( 'payment_gateway_callback' );
583
+
584
+ if ( $response->has_errors() ) {
585
+ $errors = $response->get_params();
586
+
587
+ if ( isset( $errors['L_ERRORCODE0'] ) && '10486' == $errors['L_ERRORCODE0'] ) {
588
+ wp_redirect( $this->get_redirect_url( array( 'token' => $token ) ) );
589
+ exit;
590
+ }
591
+
592
+ wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
593
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
594
+
595
+ } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
596
+ $location = remove_query_arg( 'payment_gateway' );
597
+
598
+ if ( $response->is_payment_completed() ) {
599
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
600
+ } else {
601
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
602
+ }
603
+
604
+ $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
605
+ ->set( 'date', time() )
606
+ ->save();
607
+ } else {
608
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
609
+ }
610
+
611
+ wp_redirect( esc_url_raw( $location ) );
612
+ exit;
613
+ }
614
+
615
+ public function callback_display_paypal_error() {
616
+ add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_paypal_error_page' ) );
617
+ }
618
+
619
+ public function callback_display_generic_error() {
620
+ add_filter( 'wpsc_get_transaction_html_output', array( $this, 'filter_generic_error_page' ) );
621
+ }
622
+
623
+ /**
624
+ * Records the Payer ID, Payer Status and Shipping Status to the Purchase
625
+ * Log on GetExpressCheckout Call
626
+ *
627
+ * @return void
628
+ */
629
+ public function log_payer_details( $details ) {
630
+ if ( isset( $details->get( 'payer' )->id ) && !empty( $details->get( 'payer' )->id ) ) {
631
+ $payer_id = $details->get( 'payer' )->id;
632
+ } else {
633
+ $payer_id = 'not set';
634
+ }
635
+ if ( isset( $details->get( 'payer' )->status ) && !empty( $details->get( 'payer' )->status ) ) {
636
+ $payer_status = $details->get( 'payer' )->status;
637
+ } else {
638
+ $payer_status = 'not set';
639
+ }
640
+ if ( isset( $details->get( 'payer' )->shipping_status ) && !empty( $details->get( 'payer' )->shipping_status ) ) {
641
+ $payer_shipping_status = $details->get( 'payer' )->shipping_status;
642
+ } else {
643
+ $payer_shipping_status = 'not set';
644
+ }
645
+ $paypal_log = array(
646
+ 'payer_id' => $payer_id,
647
+ 'payer_status' => $payer_status,
648
+ 'shipping_status' => $payer_shipping_status,
649
+ 'protection' => null,
650
+ );
651
+
652
+ wpsc_update_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details' , $paypal_log );
653
+ }
654
+
655
+ /**
656
+ * Records the Protection Eligibility status to the Purchase Log on
657
+ * DoExpressCheckout Call
658
+ *
659
+ * @return void
660
+ */
661
+ public function log_protection_status( $response ) {
662
+ $params = $response->get_params();
663
+
664
+ if ( isset( $params['PAYMENTINFO_0_PROTECTIONELIGIBILITY'] ) ) {
665
+ $elg = $params['PAYMENTINFO_0_PROTECTIONELIGIBILITY'];
666
+ } else {
667
+ $elg = false;
668
+ }
669
+ $paypal_log = wpsc_get_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details', true );
670
+ $paypal_log['protection'] = $elg;
671
+ wpsc_update_purchase_meta( $this->purchase_log->get( 'id' ), 'paypal_ec_details' , $paypal_log );
672
+ }
673
+
674
+ public function callback_process_confirmed_payment() {
675
+ $args = array_map( 'urldecode', $_GET );
676
+ extract( $args, EXTR_SKIP );
677
+
678
+ if ( ! isset( $sessionid ) || ! isset( $token ) || ! isset( $PayerID ) ) {
679
+ return;
680
+ }
681
+
682
+ $this->set_purchase_log_for_callbacks();
683
+
684
+ $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
685
+ $options = array(
686
+ 'token' => $token,
687
+ 'payer_id' => $PayerID,
688
+ 'message_id' => $this->purchase_log->get( 'id' ),
689
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
690
+ );
691
+ $options += $this->checkout_data->get_gateway_data();
692
+ $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
693
+
694
+ if ( $this->setting->get( 'ipn', false ) ) {
695
+ $options['notify_url'] = $this->get_notify_url();
696
+ }
697
+
698
+ // GetExpressCheckoutDetails
699
+ $details = $this->gateway->get_details_for( $token );
700
+ $this->log_payer_details( $details );
701
+
702
+ $response = $this->gateway->purchase( $options );
703
+ $this->log_protection_status( $response );
704
+ $location = remove_query_arg( 'payment_gateway_callback' );
705
+
706
+ if ( $response->has_errors() ) {
707
+ wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
708
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_paypal_error' ) );
709
+ } elseif ( $response->is_payment_completed() || $response->is_payment_pending() ) {
710
+ $location = remove_query_arg( 'payment_gateway' );
711
+
712
+ if ( $response->is_payment_completed() ) {
713
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT );
714
+ } else {
715
+ $this->purchase_log->set( 'processed', WPSC_Purchase_Log::ORDER_RECEIVED );
716
+ }
717
+
718
+ $this->purchase_log->set( 'transactid', $response->get( 'transaction_id' ) )
719
+ ->set( 'date', time() )
720
+ ->save();
721
+ } else {
722
+ $location = add_query_arg( array( 'payment_gateway_callback' => 'display_generic_error' ) );
723
+ }
724
+
725
+ wp_redirect( esc_url_raw( $location ) );
726
+ exit;
727
+ }
728
+
729
+ /**
730
+ * Error Page Template
731
+ *
732
+ * @since 3.9
733
+ */
734
+ public function filter_paypal_error_page() {
735
+ $errors = wpsc_get_customer_meta( 'paypal_express_checkout_errors' );
736
+ ob_start();
737
  ?>
738
+ <p>
739
+ <?php _e( 'Sorry, your transaction could not be processed by PayPal. Please contact the site administrator. The following errors are returned:' , 'wpsc' ); ?>
740
+ </p>
741
+ <ul>
742
+ <?php foreach ( $errors as $error ): ?>
743
+ <li><?php echo esc_html( $error['details'] ) ?> (<?php echo esc_html( $error['code'] ); ?>)</li>
744
+ <?php endforeach; ?>
745
+ </ul>
746
+ <p><a href="<?php echo esc_url( $this->get_shopping_cart_payment_url() ); ?>"><?php ( 'Click here to go back to the checkout page.') ?></a></p>
747
  <?php
748
+ $output = apply_filters( 'wpsc_paypal_express_checkout_gateway_error_message', ob_get_clean(), $errors );
749
+ return $output;
750
+ }
751
+
752
+ /**
753
+ * Generic Error Page Template
754
+ *
755
+ * @since 3.9
756
+ */
757
+ public function filter_generic_error_page() {
758
+ ob_start();
759
  ?>
760
  <p><?php _e( 'Sorry, but your transaction could not be processed by PayPal for some reason. Please contact the site administrator.' , 'wpsc' ); ?></p>
761
  <p><a href="<?php echo esc_attr( $this->get_shopping_cart_payment_url() ); ?>"><?php _e( 'Click here to go back to the checkout page.', 'wpsc' ) ?></a></p>
762
  <?php
763
+ $output = apply_filters( 'wpsc_paypal_express_checkout_generic_error_message', ob_get_clean() );
764
+ return $output;
765
+ }
766
+
767
+ /**
768
+ * Settings Form Template
769
+ *
770
+ * @since 3.9
771
+ */
772
+ public function setup_form() {
773
+ $paypal_currency = $this->get_currency_code();
774
  ?>
775
 
776
  <!-- Account Credentials -->
777
  <tr>
778
+ <td colspan="2">
779
+ <h4><?php _e( 'Account Credentials', 'wpsc' ); ?></h4>
780
+ </td>
781
  </tr>
782
  <tr>
783
+ <td>
784
+ <label for="wpsc-paypal-express-api-username"><?php _e( 'API Username', 'wpsc' ); ?></label>
785
+ </td>
786
+ <td>
787
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_username' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_username' ) ); ?>" id="wpsc-paypal-express-api-username" />
788
+ </td>
789
  </tr>
790
  <tr>
791
+ <td>
792
+ <label for="wpsc-paypal-express-api-password"><?php _e( 'API Password', 'wpsc' ); ?></label>
793
+ </td>
794
+ <td>
795
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_password' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_password' ) ); ?>" id="wpsc-paypal-express-api-password" />
796
+ </td>
797
  </tr>
798
  <tr>
799
+ <td>
800
+ <label for="wpsc-paypal-express-api-signature"><?php _e( 'API Signature', 'wpsc' ); ?></label>
801
+ </td>
802
+ <td>
803
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'api_signature' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'api_signature' ) ); ?>" id="wpsc-paypal-express-api-signature" />
804
+ </td>
805
  </tr>
806
  <tr>
807
+ <td>
808
+ <label><?php _e( 'Sandbox Mode', 'wpsc' ); ?></label>
809
+ </td>
810
+ <td>
811
+ <label><input <?php checked( $this->setting->get( 'sandbox_mode' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
812
+ <label><input <?php checked( (bool) $this->setting->get( 'sandbox_mode' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
813
+ </td>
814
  </tr>
815
  <tr>
816
+ <td>
817
+ <label><?php _e( 'IPN', 'wpsc' ); ?></label>
818
+ </td>
819
+ <td>
820
+ <label><input <?php checked( $this->setting->get( 'ipn' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
821
+ <label><input <?php checked( (bool) $this->setting->get( 'ipn' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'ipn' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
822
+ </td>
823
  </tr>
824
 
825
  <!-- Cart Customization -->
826
  <tr>
827
+ <td colspan="2">
828
+ <label><h4><?php _e( 'Cart Customization', 'wpsc'); ?></h4></label>
829
+ </td>
830
  </tr>
831
  <tr>
832
+ <td>
833
+ <label for="wpsc-paypal-express-cart-logo"><?php _e( 'Merchant Logo', 'wpsc' ); ?></label>
834
+ </td>
835
+ <td>
836
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_logo' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_logo' ) ); ?>" id="wpsc-paypal-express-cart-logo" /><br><span class="small description"><?php _e( 'The image must be stored in a HTTPS Server. Limit the image to 190 pixels wide by 60 pixels high.', 'wpsc' ); ?></span>
837
+ </td>
838
  </tr>
839
  <tr>
840
+ <td>
841
+ <label for="wpsc-paypal-express-cart-border"><?php _e( 'Cart Border Color', 'wpsc' ); ?></label>
842
+ </td>
843
+ <td>
844
+ <input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'cart_border' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'cart_border' ) ); ?>" id="wpsc-paypal-express-cart-border" />
845
+ </td>
846
  </tr>
847
 
848
  <!-- Currency Conversion -->
849
  <?php if ( ! $this->is_currency_supported() ) : ?>
850
  <tr>
851
+ <td colspan="2">
852
+ <h4><?php _e( 'Currency Conversion', 'wpsc' ); ?></h4>
853
+ </td>
854
  </tr>
855
  <tr>
856
+ <td colspan="2">
857
+ <p><?php _e( 'Your base currency is currently not accepted by PayPal. As a result, before a payment request is sent to PayPal, WP eCommerce has to convert the amounts into one of PayPal supported currencies. Please select your preferred currency below.', 'wpsc' ); ?></p>
858
+ </td>
859
  </tr>
860
  <tr>
861
+ <td>
862
+ <label for "wpsc-paypal-express-currency"><?php _e( 'PayPal Currency', 'wpsc' ); ?></label>
863
+ </td>
864
+ <td>
865
+ <select name="<?php echo esc_attr( $this->setting->get_field_name( 'currency' ) ); ?>" id="wpsc-paypal-express-currency">
866
+ <?php foreach ( $this->gateway->get_supported_currencies() as $currency ) : ?>
867
+ <option <?php selected( $currency, $paypal_currency ); ?> value="<?php echo esc_attr( $currency ); ?>"><?php echo esc_html( $currency ); ?></option>
868
+ <?php endforeach ?>
869
+ </select>
870
+ </td>
871
  </tr>
872
  <?php endif ?>
873
 
874
+ <!-- Checkout Shortcut -->
875
+ <tr>
876
+ <td colspan="2">
877
+ <h4><?php _e( 'Express Checkout Shortcut', 'wpsc' ); ?></h4>
878
+ </td>
879
+ </tr>
880
+ <tr>
881
+ <td>
882
+ <label><?php _e( 'Enable Shortcut', 'wpsc' ); ?></label>
883
+ </td>
884
+ <td>
885
+ <label><input <?php checked( $this->setting->get( 'shortcut' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'shortcut' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
886
+ <label><input <?php checked( (bool) $this->setting->get( 'shortcut' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'shortcut' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
887
+ </td>
888
+ </tr>
889
+
890
  <!-- Error Logging -->
891
  <tr>
892
+ <td colspan="2">
893
+ <h4><?php _e( 'Error Logging', 'wpsc' ); ?></h4>
894
+ </td>
895
  </tr>
896
  <tr>
897
+ <td>
898
+ <label><?php _e( 'Enable Debugging', 'wpsc' ); ?></label>
899
+ </td>
900
+ <td>
901
+ <label><input <?php checked( $this->setting->get( 'debugging' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wpsc' ); ?></label>&nbsp;&nbsp;&nbsp;
902
+ <label><input <?php checked( (bool) $this->setting->get( 'debugging' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="0" /> <?php _e( 'No', 'wpsc' ); ?></label>
903
+ </td>
904
  </tr>
905
  <?php
906
+ }
907
+
908
+ /**
909
+ * Check if the selected currency is supported by the gateway
910
+ *
911
+ * @return bool
912
+ *
913
+ * @since 3.9
914
+ */
915
+ protected function is_currency_supported() {
916
+ return in_array( parent::get_currency_code(), $this->gateway->get_supported_currencies() );
917
+ }
918
+
919
+ /**
920
+ * Return the Currency ISO code
921
+ *
922
+ * @return string
923
+ *
924
+ * @since 3.9
925
+ */
926
+ public function get_currency_code() {
927
+ $code = parent::get_currency_code();
928
+
929
+ if ( ! in_array( $code, $this->gateway->get_supported_currencies() ) ) {
930
+ $code = $this->setting->get( 'currency', 'USD' );
931
+ }
932
+
933
+ return $code;
934
+ }
935
+
936
+ /**
937
+ * Convert an amount (integer) to the supported currency
938
+ * @param integer $amt
939
+ *
940
+ * @return integer
941
+ *
942
+ * @since 3.9
943
+ */
944
+ protected function convert( $amt ) {
945
+ if ( $this->is_currency_supported() ) {
946
+ return $amt;
947
+ }
948
+
949
+ return wpsc_convert_currency( $amt, parent::get_currency_code(), $this->get_currency_code() );
950
+ }
951
+
952
+ /**
953
+ * Process the SetExpressCheckout API Call
954
+ *
955
+ * @return void
956
+ *
957
+ * @since 3.9
958
+ */
959
+ public function process() {
960
+ $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
961
+ $options = array(
962
+ 'return_url' => $this->get_return_url(),
963
+ 'message_id' => $this->purchase_log->get( 'id' ),
964
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
965
+ 'address_override' => 1,
966
+ );
967
+
968
+ $options += $this->checkout_data->get_gateway_data();
969
+ $options += $this->purchase_log->get_gateway_data( parent::get_currency_code(), $this->get_currency_code() );
970
+
971
+ if ( $this->setting->get( 'ipn', false ) ) {
972
+ $options['notify_url'] = $this->get_notify_url();
973
+ }
974
+
975
+ // SetExpressCheckout
976
+ $response = $this->gateway->setup_purchase( $options );
977
+
978
+ if ( $response->is_successful() ) {
979
+ $params = $response->get_params();
980
+ if ( $params['ACK'] == 'SuccessWithWarning' ) {
981
+ $this->log_error( $response );
982
+ wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
983
+ }
984
+ // Successful redirect
985
+ $url = $this->get_redirect_url( array( 'token' => $response->get( 'token' ) ) );
986
+ } else {
987
+
988
+ // SetExpressCheckout Failure
989
+ $this->log_error( $response );
990
+ wpsc_update_customer_meta( 'paypal_express_checkout_errors', $response->get_errors() );
991
+
992
+ $url = add_query_arg( array(
993
+ 'payment_gateway' => 'paypal-express-checkout',
994
+ 'payment_gateway_callback' => 'display_paypal_error',
995
+ ), $this->get_return_url() );
996
+ }
997
+
998
+ wp_redirect( $url );
999
+ exit;
1000
+ }
1001
+
1002
+ /**
1003
+ * Log an error message
1004
+ *
1005
+ * @param PHP_Merchant_Paypal_Express_Checkout_Response $response
1006
+ * @return void
1007
+ *
1008
+ * @since 3.9
1009
+ */
1010
+ public function log_error( $response ) {
1011
+ if ( $this->setting->get( 'debugging' ) ) {
1012
+
1013
+ add_filter( 'wpsc_logging_post_type_args', 'WPSC_Logging::force_ui' );
1014
+ add_filter( 'wpsc_logging_taxonomy_args ', 'WPSC_Logging::force_ui' );
1015
+
1016
+ $log_data = array(
1017
+ 'post_title' => 'PayPal ExpressCheckout Operation Failure',
1018
+ 'post_content' => 'There was an error processing the payment. Find details in the log entry meta fields.',
1019
+ 'log_type' => 'error'
1020
+ );
1021
+
1022
+ $log_meta = array(
1023
+ 'correlation_id' => $response->get( 'correlation_id' ),
1024
+ 'time' => $response->get( 'datetime' ),
1025
+ 'errors' => $response->get_errors(),
1026
+ );
1027
+
1028
+ $log_entry = WPSC_Logging::insert_log( $log_data, $log_meta );
1029
+ }
1030
+ }
1031
  }
wpsc-components/merchant-core-v3/gateways/paypal-pro.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
 
2
  /**
3
  * The PayPal Pro Gateway class
4
  *
5
  */
6
-
7
  class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
8
  private $gateway;
9
 
@@ -25,23 +25,32 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
25
  $this->gateway = new PHP_Merchant_Paypal_Pro( $options );
26
 
27
  $this->gateway->set_options( array(
28
- 'api_username' => $this->setting->get( 'api_username' ),
29
- 'api_password' => $this->setting->get( 'api_password' ),
30
- 'api_signature' => $this->setting->get( 'api_signature' ),
31
- 'cancel_url' => $this->get_shopping_cart_payment_url(),
32
- 'currency' => $this->get_currency_code(),
33
- 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
34
  ) );
35
 
36
- // Load PayPal Pro JavaScript file
37
- add_action( 'wp_enqueue_scripts', array( $this, 'pro_script' ) );
38
 
39
- add_filter( 'wpsc_purchase_log_gateway_data', array( $this, 'filter_purchase_log_gateway_data' ), 10, 2 );
 
 
 
 
 
 
 
 
 
 
40
 
41
  // Unselect Default Payment Gateway
42
  add_filter(
43
  'wpsc_payment_method_form_fields',
44
- array( $this, 'filter_unselect_default' ), 101 , 1
45
  );
46
  }
47
 
@@ -54,7 +63,7 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
54
  *
55
  * @since 3.9
56
  */
57
- public function filter_unselect_default( $fields ) {
58
  foreach ( $fields as $i=>$field ) {
59
  $fields[ $i ][ 'checked' ] = false;
60
  }
@@ -62,20 +71,6 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
62
  return $fields;
63
  }
64
 
65
- /**
66
- * Returns the HTML of the logo of the payment gateway.
67
- *
68
- * @access public
69
- * @return string
70
- *
71
- * @since 3.9
72
- */
73
- public function get_mark_html() {
74
- $html = '<img src="' . WPSC_URL . '/images/cc.gif" border="0" alt="' . esc_attr__( 'Credit Card Icons' ) .'" />';
75
-
76
- return apply_filters( 'wpsc_paypal-pro_mark_html', $html );
77
- }
78
-
79
  /**
80
  * WordPress Enqueue for the Pro Script and CSS file
81
  *
@@ -83,51 +78,30 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
83
  *
84
  * @since 3.9
85
  */
86
- public function pro_script() {
87
  if ( wpsc_is_checkout() ) {
 
 
 
 
88
  wp_enqueue_script( 'pro-script-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/pro.js', array( 'jquery' ) );
89
- wp_enqueue_style( 'pro-syle-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/pro.css' );
 
90
  }
91
  }
92
 
93
  /**
94
- * Purchase Log Filter for Gateway Data
95
  *
96
- * @param array $gateway_data
97
- * @param array $data
98
- * @return array
99
  *
100
  * @since 3.9
101
  */
102
- public static function filter_purchase_log_gateway_data( $gateway_data, $data ) {
103
- // Because paypal express checkout API doesn't have full support for discount, we have to manually add an item here
104
- if ( isset( $gateway_data['discount'] ) && (float) $gateway_data['discount'] != 0 ) {
105
- $i =& $gateway_data['items'];
106
- $d =& $gateway_data['discount'];
107
- $s =& $gateway_data['subtotal'];
108
-
109
- // If discount amount is larger than or equal to the item total, we need to set item total to 0.01
110
- // because Paypal does not accept 0 item total.
111
- if ( $d >= $gateway_data['subtotal'] ) {
112
- $d = $s - 0.01;
113
-
114
- // if there's shipping, we'll take 0.01 from there
115
- if ( ! empty( $gateway_data['shipping'] ) ) {
116
- $gateway_data['shipping'] -= 0.01;
117
- } else {
118
- $gateway_data['amount'] = 0.01;
119
- }
120
- }
121
-
122
- $s -= $d;
123
 
124
- $i[] = array(
125
- 'name' => __( 'Discount', 'wpsc' ),
126
- 'amount' => - $d,
127
- 'quantity' => 1,
128
- );
129
- }
130
- return $gateway_data;
131
  }
132
 
133
  /**
@@ -195,11 +169,9 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
195
  */
196
  public function callback_ipn() {
197
  $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
198
-
199
  if ( $ipn->is_verified() ) {
200
  $sessionid = $ipn->get( 'invoice' );
201
- $this->set_purchase_log_for_callbacks( $sessionid );
202
-
203
  if ( $ipn->is_payment_denied() ) {
204
  $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
205
  } elseif ( $ipn->is_payment_refunded() ) {
@@ -260,8 +232,8 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
260
  $options = array(
261
  'tx' => $tx,
262
  'CSCMATCH' => $CSCMATCH,
263
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
264
- 'invoice' => $this->purchase_log->get( 'id' ),
265
  );
266
 
267
  $options += $this->checkout_data->get_gateway_data();
@@ -563,8 +535,8 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
563
  $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
564
  $options = array(
565
  'return_url' => $this->get_return_url(),
566
- 'message_id' => $this->purchase_log->get( 'sessionid' ),
567
- 'invoice' => $this->purchase_log->get( 'id' ),
568
  'address_override' => 1,
569
  'paymentaction' => 'sale',
570
  'template' => 'templateD',
@@ -578,30 +550,45 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
578
  $options['notify_url'] = $this->get_notify_url();
579
  }
580
 
 
 
 
 
 
581
  // BMCreateButton API call
582
  $response = $this->gateway->createButton( $options );
583
- $params = $response->get_params();
584
- $website_code = $params['WEBSITECODE'];
585
-
586
 
587
  if ( $response->is_successful() ) {
 
588
  $params = $response->get_params();
 
 
589
  // Log any warning
590
  if ( $params['ACK'] == 'SuccessWithWarning' ) {
591
  $this->log_error( $response );
 
 
592
  }
 
 
 
 
593
  } else {
 
594
  // Log errors and redirect user
595
  $this->log_error( $response );
 
 
596
  $url = add_query_arg( array(
597
- 'payment_gateway' => 'paypal-pro-checkout',
598
  'payment_gateway_callback' => 'display_paypal_error',
599
  ), $this->get_return_url() );
600
- }
601
 
602
- // Write the Button code
603
- echo( $website_code );
 
604
 
 
605
  exit;
606
  }
607
 
@@ -615,6 +602,10 @@ class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
615
  */
616
  public function log_error( $response ) {
617
  if ( $this->setting->get( 'debugging' ) ) {
 
 
 
 
618
  $log_data = array(
619
  'post_title' => 'PayPal Pro Operation Failure',
620
  'post_content' => 'There was an error processing the payment. Find details in the log entry meta fields.',
1
  <?php
2
+
3
  /**
4
  * The PayPal Pro Gateway class
5
  *
6
  */
 
7
  class WPSC_Payment_Gateway_Paypal_Pro extends WPSC_Payment_Gateway {
8
  private $gateway;
9
 
25
  $this->gateway = new PHP_Merchant_Paypal_Pro( $options );
26
 
27
  $this->gateway->set_options( array(
28
+ 'api_username' => $this->setting->get( 'api_username' ),
29
+ 'api_password' => $this->setting->get( 'api_password' ),
30
+ 'api_signature' => $this->setting->get( 'api_signature' ),
31
+ 'cancel_url' => $this->get_shopping_cart_payment_url(),
32
+ 'currency' => $this->get_currency_code(),
33
+ 'test' => (bool) $this->setting->get( 'sandbox_mode' ),
34
  ) );
35
 
36
+ }
 
37
 
38
+ /**
39
+ * Run the gateway hooks
40
+ *
41
+ * @access public
42
+ * @since 4.0
43
+ *
44
+ * @return void
45
+ */
46
+ public function init() {
47
+ // Load PayPal Pro JavaScript file
48
+ add_action( 'wp_enqueue_scripts', array( 'WPSC_Payment_Gateway_Paypal_Pro', 'pro_script' ) );
49
 
50
  // Unselect Default Payment Gateway
51
  add_filter(
52
  'wpsc_payment_method_form_fields',
53
+ array( 'WPSC_Payment_Gateway_Paypal_Pro', 'filter_unselect_default' ), 101 , 1
54
  );
55
  }
56
 
63
  *
64
  * @since 3.9
65
  */
66
+ public static function filter_unselect_default( $fields ) {
67
  foreach ( $fields as $i=>$field ) {
68
  $fields[ $i ][ 'checked' ] = false;
69
  }
71
  return $fields;
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  /**
75
  * WordPress Enqueue for the Pro Script and CSS file
76
  *
78
  *
79
  * @since 3.9
80
  */
81
+ public static function pro_script() {
82
  if ( wpsc_is_checkout() ) {
83
+ $pro_loc = array(
84
+ 'spinner_url' => wpsc_get_ajax_spinner(),
85
+ 'loading' => __( 'Loading...', 'wpsc' ),
86
+ );
87
  wp_enqueue_script( 'pro-script-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/pro.js', array( 'jquery' ) );
88
+ wp_enqueue_style( 'pro-style-internal', WPSC_URL . '/wpsc-components/merchant-core-v3/gateways/pro.css' );
89
+ wp_localize_script( 'pro-script-internal', 'pro_loc', $pro_loc );
90
  }
91
  }
92
 
93
  /**
94
+ * Returns the HTML of the logo of the payment gateway.
95
  *
96
+ * @access public
97
+ * @return string
 
98
  *
99
  * @since 3.9
100
  */
101
+ public function get_mark_html() {
102
+ $html = '<img src="' . WPSC_URL . '/images/cc.png" border="0" alt="' . esc_attr__( 'Credit Card Icons' ) .'" />';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ return apply_filters( 'wpsc_paypal-pro_mark_html', $html );
 
 
 
 
 
 
105
  }
106
 
107
  /**
169
  */
170
  public function callback_ipn() {
171
  $ipn = new PHP_Merchant_Paypal_IPN( false, (bool) $this->setting->get( 'sandbox_mode', false ) );
 
172
  if ( $ipn->is_verified() ) {
173
  $sessionid = $ipn->get( 'invoice' );
174
+ $this->set_purchase_log_for_callbacks( $sessionid, 'sessionid' );
 
175
  if ( $ipn->is_payment_denied() ) {
176
  $this->purchase_log->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
177
  } elseif ( $ipn->is_payment_refunded() ) {
232
  $options = array(
233
  'tx' => $tx,
234
  'CSCMATCH' => $CSCMATCH,
235
+ 'message_id' => $this->purchase_log->get( 'id' ),
236
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
237
  );
238
 
239
  $options += $this->checkout_data->get_gateway_data();
535
  $total = $this->convert( $this->purchase_log->get( 'totalprice' ) );
536
  $options = array(
537
  'return_url' => $this->get_return_url(),
538
+ 'message_id' => $this->purchase_log->get( 'id' ),
539
+ 'invoice' => $this->purchase_log->get( 'sessionid' ),
540
  'address_override' => 1,
541
  'paymentaction' => 'sale',
542
  'template' => 'templateD',
550
  $options['notify_url'] = $this->get_notify_url();
551
  }
552
 
553
+ // Detect Mobile Devices
554
+ if ( wp_is_mobile() ) {
555
+ $options['template'] = 'mobile-iframe';
556
+ }
557
+
558
  // BMCreateButton API call
559
  $response = $this->gateway->createButton( $options );
 
 
 
560
 
561
  if ( $response->is_successful() ) {
562
+
563
  $params = $response->get_params();
564
+ $website_code = $params['WEBSITECODE'];
565
+
566
  // Log any warning
567
  if ( $params['ACK'] == 'SuccessWithWarning' ) {
568
  $this->log_error( $response );
569
+ wpsc_update_customer_meta( 'paypal_pro_checkout_errors', $response->get_errors() );
570
+
571
  }
572
+
573
+ // Write the Button code
574
+ echo( $website_code );
575
+
576
  } else {
577
+
578
  // Log errors and redirect user
579
  $this->log_error( $response );
580
+ wpsc_update_customer_meta( 'paypal_pro_checkout_errors', $response->get_errors() );
581
+
582
  $url = add_query_arg( array(
583
+ 'payment_gateway' => 'paypal-pro',
584
  'payment_gateway_callback' => 'display_paypal_error',
585
  ), $this->get_return_url() );
 
586
 
587
+ // Redirect to the Error Page
588
+ wp_redirect( $url );
589
+ }
590
 
591
+ // Stop further execution
592
  exit;
593
  }
594
 
602
  */
603
  public function log_error( $response ) {
604
  if ( $this->setting->get( 'debugging' ) ) {
605
+
606
+ add_filter( 'wpsc_logging_post_type_args', 'WPSC_Logging::force_ui' );
607
+ add_filter( 'wpsc_logging_taxonomy_args ', 'WPSC_Logging::force_ui' );
608
+
609
  $log_data = array(
610
  'post_title' => 'PayPal Pro Operation Failure',
611
  'post_content' => 'There was an error processing the payment. Find details in the log entry meta fields.',
wpsc-components/merchant-core-v3/gateways/php-merchant/README.md CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/exception.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/helpers.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/http-curl.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/http.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/php-merchant.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/common/response.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-digital-goods.php CHANGED
@@ -3,19 +3,18 @@
3
  require_once( 'paypal-express-checkout.php' );
4
  require_once( 'paypal-express-checkout-response.php' );
5
 
6
- class PHP_Merchant_Paypal_Digital_Goods extends PHP_Merchant_Paypal_Express_Checkout
7
- {
8
  public function __construct( $options = array() ) {
9
  parent::__construct( $options );
10
  }
11
 
12
  /**
13
  * Creates and returns the payment component of a PayPal Digital Goods NVP API request.
14
- *
15
- * PayPal requires the category component for all items in a digital goods purchase to be set as Digital.
16
  * This function specifies that all goods are digital, then calls @see parent::add_payment() to create
17
  * the rest of the API request (which is the same as a vanilla Express Checkout request).
18
- *
19
  * @uses parent::add_payment() to create non digital goods components of the request.
20
  * @return Array An array of name value pairs for each element representing a payment in a PayPal Digital Goods NVP API request.
21
  */
@@ -27,51 +26,55 @@ class PHP_Merchant_Paypal_Digital_Goods extends PHP_Merchant_Paypal_Express_Chec
27
  $request += array( "L_PAYMENTREQUEST_0_ITEMCATEGORY{$i}" => 'Digital' );
28
  }
29
 
 
 
30
  return $request;
31
  }
32
 
33
  /**
34
  * For Digital Goods purchases, PayPal requires the PAYMENTREQUEST_n_ITEMAMT. This function sets the 'items' flag to required
35
- * then calls @see parent::setup_purchase() to initiate an Express Checkout payment.
36
- *
37
  * @uses self::requires() to flag 'items' as required
38
  * @uses parent::setup_purchase() to create and make the request.
39
- * @return PHP_Merchant_Paypal_Express_Checkout_Response An object containing the details of PayPal's response to the request.
40
  */
41
  public function setup_purchase( $options = array(), $action = 'Sale' ) {
 
42
  return parent::setup_purchase( $options, $action );
43
  }
44
 
45
  /**
46
  * For Digital Goods purchases, PayPal requires the PAYMENTREQUEST_n_ITEMAMT. This function sets the 'items' flag to required
47
- * then calls @see parent::setup_purchase() to complete the payment.
48
- *
49
  * @uses self::requires() to flag 'items' as required
50
  * @uses parent::setup_purchase() to create and make the request.
51
- * @return PHP_Merchant_Paypal_Express_Checkout_Response An object containing the details of PayPal's response to the request.
52
  */
53
  public function purchase( $options = array(), $action = 'Sale' ) {
 
54
  return parent::purchase( $options, $action );
55
  }
56
 
57
 
58
  /**
59
  * The Javascript to invoke the digital goods in context checkout process.
60
- *
61
- * No need to call this function manually, required scripts are automatically printed with @see print_buy_buttion().
62
- * If you do print this script manually, print it after the button in the DOM to ensure the
63
  * click event is properly hooked.
64
  */
65
  public function get_script( $args = array() ){
66
-
67
  if( empty( $args['element_id'] ) )
68
  $args['element_id'] = 'paypal-submit';
69
 
70
  $dg_script = '<script src ="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>'
71
- . '<script>'
72
- . 'var dg = new PAYPAL.apps.DGFlow({'
73
- . 'trigger: "' . $args['element_id'] . '"' // the ID of the HTML element which calls setExpressCheckout
74
- . '}); </script>';
75
 
76
  return $dg_script;
77
  }
3
  require_once( 'paypal-express-checkout.php' );
4
  require_once( 'paypal-express-checkout-response.php' );
5
 
6
+ class PHP_Merchant_Paypal_Digital_Goods extends PHP_Merchant_Paypal_Express_Checkout {
 
7
  public function __construct( $options = array() ) {
8
  parent::__construct( $options );
9
  }
10
 
11
  /**
12
  * Creates and returns the payment component of a PayPal Digital Goods NVP API request.
13
+ *
14
+ * PayPal requires the category component for all items in a digital goods purchase to be set as Digital.
15
  * This function specifies that all goods are digital, then calls @see parent::add_payment() to create
16
  * the rest of the API request (which is the same as a vanilla Express Checkout request).
17
+ *
18
  * @uses parent::add_payment() to create non digital goods components of the request.
19
  * @return Array An array of name value pairs for each element representing a payment in a PayPal Digital Goods NVP API request.
20
  */
26
  $request += array( "L_PAYMENTREQUEST_0_ITEMCATEGORY{$i}" => 'Digital' );
27
  }
28
 
29
+ $request['BUTTONSOURCE'] = 'WPeC_Cart_DG';
30
+
31
  return $request;
32
  }
33
 
34
  /**
35
  * For Digital Goods purchases, PayPal requires the PAYMENTREQUEST_n_ITEMAMT. This function sets the 'items' flag to required
36
+ * then calls @see parent::setup_purchase() to initiate an Express Checkout payment.
37
+ *
38
  * @uses self::requires() to flag 'items' as required
39
  * @uses parent::setup_purchase() to create and make the request.
40
+ * @return PHP_Merchant_Paypal_Express_Checkout_Response An object containing the details of PayPal's response to the request.
41
  */
42
  public function setup_purchase( $options = array(), $action = 'Sale' ) {
43
+ $options['no_shipping'] = true;
44
  return parent::setup_purchase( $options, $action );
45
  }
46
 
47
  /**
48
  * For Digital Goods purchases, PayPal requires the PAYMENTREQUEST_n_ITEMAMT. This function sets the 'items' flag to required
49
+ * then calls @see parent::setup_purchase() to complete the payment.
50
+ *
51
  * @uses self::requires() to flag 'items' as required
52
  * @uses parent::setup_purchase() to create and make the request.
53
+ * @return PHP_Merchant_Paypal_Express_Checkout_Response An object containing the details of PayPal's response to the request.
54
  */
55
  public function purchase( $options = array(), $action = 'Sale' ) {
56
+ $options['no_shipping'] = true;
57
  return parent::purchase( $options, $action );
58
  }
59
 
60
 
61
  /**
62
  * The Javascript to invoke the digital goods in context checkout process.
63
+ *
64
+ * No need to call this function manually, required scripts are automatically printed with @see print_buy_buttion().
65
+ * If you do print this script manually, print it after the button in the DOM to ensure the
66
  * click event is properly hooked.
67
  */
68
  public function get_script( $args = array() ){
69
+
70
  if( empty( $args['element_id'] ) )
71
  $args['element_id'] = 'paypal-submit';
72
 
73
  $dg_script = '<script src ="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>'
74
+ . '<script>'
75
+ . 'var dg = new PAYPAL.apps.DGFlow({'
76
+ . 'trigger: "' . $args['element_id'] . '"' // the ID of the HTML element which calls setExpressCheckout
77
+ . '}); </script>';
78
 
79
  return $dg_script;
80
  }
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-express-checkout-response.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-express-checkout.php CHANGED
@@ -2,8 +2,7 @@
2
  require_once( 'paypal.php' );
3
  require_once( 'paypal-express-checkout-response.php' );
4
 
5
- class PHP_Merchant_Paypal_Express_Checkout extends PHP_Merchant_Paypal
6
- {
7
  public function __construct( $options = array() ) {
8
  parent::__construct( $options );
9
  }
@@ -46,47 +45,87 @@ class PHP_Merchant_Paypal_Express_Checkout extends PHP_Merchant_Paypal
46
  'L_BILLINGAGREEMENTDESCRIPTION0' => 'billing_description',
47
  ) );
48
 
49
- $subtotal = 0;
 
 
50
 
51
  // Shopping Cart details
52
  $i = 0;
53
- foreach ( $this->options['items'] as $item ) {
54
- // Options Fields
55
- $item_optionals = array(
56
- 'description' => "L_PAYMENTREQUEST_0_DESC{$i}",
57
- 'tax' => "L_PAYMENTREQUEST_0_TAXAMT{$i}",
58
- 'url' => "L_PAYMENTREQUEST_0_ITEMURL{$i}",
59
- 'number' => "L_PAYMENTREQUEST_0_NUMBER{$i}",
60
- );
61
-
62
- // Format Amount Field
63
- $item['amount'] = $this->format( $item['amount'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- // Required Fields
66
- $request += phpme_map( $item, array(
67
- "L_PAYMENTREQUEST_0_NAME{$i}" => 'name',
68
- "L_PAYMENTREQUEST_0_AMT{$i}" => 'amount',
69
- "L_PAYMENTREQUEST_0_QTY{$i}" => 'quantity',
70
- ) );
71
 
72
- // No Shipping Field
73
- if ( isset( $this->options['no_shipping'] ) ) {
74
- $request["L_PAYMENTREQUEST_0_ITEMCATEGORY{$i}"] = 'DIGITAL';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
 
77
- foreach ( $item_optionals as $key => $param ) {
78
- if ( ! empty( $this->options['items'][$i][$key] ) )
79
- if ( $key == 'tax' ) {
80
- $request[$param] = $this->format( $this->options['items'][$i][$key] );
81
- } else {
82
- $request[$param] = $this->options['items'][$i][$key];
83
- }
84
  }
85
 
86
- $i ++;
 
 
 
 
 
87
  }
88
-
89
- return $request;
90
  }
91
 
92
  /**
@@ -170,7 +209,7 @@ class PHP_Merchant_Paypal_Express_Checkout extends PHP_Merchant_Paypal
170
  'COMPLETETYPE' => 'complete_type',
171
  ) );
172
 
173
- if ( ! empty( $this->options['shipping_address'] ) ) {
174
  $request += $this->add_address();
175
  }
176
 
2
  require_once( 'paypal.php' );
3
  require_once( 'paypal-express-checkout-response.php' );
4
 
5
+ class PHP_Merchant_Paypal_Express_Checkout extends PHP_Merchant_Paypal {
 
6
  public function __construct( $options = array() ) {
7
  parent::__construct( $options );
8
  }
45
  'L_BILLINGAGREEMENTDESCRIPTION0' => 'billing_description',
46
  ) );
47
 
48
+
49
+ // Apply a Discount if available
50
+ $this->add_discount();
51
 
52
  // Shopping Cart details
53
  $i = 0;
54
+ if ( is_array( $this->options['items'] ) ) {
55
+ foreach ( $this->options['items'] as $item ) {
56
+ // Options Fields
57
+ $item_optionals = array(
58
+ 'description' => "L_PAYMENTREQUEST_0_DESC{$i}",
59
+ 'tax' => "L_PAYMENTREQUEST_0_TAXAMT{$i}",
60
+ 'url' => "L_PAYMENTREQUEST_0_ITEMURL{$i}",
61
+ 'number' => "L_PAYMENTREQUEST_0_NUMBER{$i}",
62
+ );
63
+
64
+ // Format Amount Field
65
+ $item['amount'] = $this->format( $item['amount'] );
66
+
67
+ // Required Fields
68
+ $request += phpme_map( $item, array(
69
+ "L_PAYMENTREQUEST_0_NAME{$i}" => 'name',
70
+ "L_PAYMENTREQUEST_0_AMT{$i}" => 'amount',
71
+ "L_PAYMENTREQUEST_0_QTY{$i}" => 'quantity',
72
+ ) );
73
+
74
+ // No Shipping Field
75
+ if ( isset( $this->options['no_shipping'] ) ) {
76
+ $request["L_PAYMENTREQUEST_0_ITEMCATEGORY{$i}"] = 'DIGITAL';
77
+ }
78
+
79
+ foreach ( $item_optionals as $key => $param ) {
80
+ if ( ! empty( $this->options['items'][$i][$key] ) )
81
+ if ( $key == 'tax' ) {
82
+ $request[$param] = $this->format( $this->options['items'][$i][$key] );
83
+ } else {
84
+ $request[$param] = $this->options['items'][$i][$key];
85
+ }
86
+ }
87
+
88
+ $i ++;
89
+ }
90
+ }
91
 
92
+ return $request;
93
+ }
 
 
 
 
94
 
95
+ /**
96
+ * Add Discount for the Shopping Cart.
97
+ *
98
+ * Since PayPal doesn't have distinct support for discounts, we have to add the discount
99
+ * as a separate item with a negative value.
100
+ *
101
+ * @return void
102
+ */
103
+ protected function add_discount() {
104
+ // Verify if a discount is set
105
+ if ( isset( $this->options['discount'] ) && (float) $this->options['discount'] != 0 ) {
106
+ $discount = (float) $this->options['discount'];
107
+ $sub_total = (float) $this->options['subtotal'];
108
+
109
+ // If discount amount is larger than or equal to the item total, we need to set item total to 0.01
110
+ // because PayPal does not accept 0 item total.
111
+ if ( $discount >= $sub_total ) {
112
+ $discount = $sub_total - 0.01;
113
  }
114
 
115
+ // if there's shipping, we'll take 0.01 from there
116
+ if ( ! empty( $this->options['shipping'] ) ) {
117
+ $this->options['shipping'] -= 0.01;
118
+ } else {
119
+ $this->options['amount'] = 0.01;
 
 
120
  }
121
 
122
+ // Add the Discount as an Item
123
+ $this->options['items'][] = array(
124
+ 'name' => __( 'Discount', 'wpsc' ),
125
+ 'amount' => - $discount,
126
+ 'quantity' => '1',
127
+ );
128
  }
 
 
129
  }
130
 
131
  /**
209
  'COMPLETETYPE' => 'complete_type',
210
  ) );
211
 
212
+ if ( ! empty( $this->options['shipping_address'] ) && ! isset( $this->options['no_shipping'] ) ) {
213
  $request += $this->add_address();
214
  }
215
 
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-ipn.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-pro-response.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-pro.php CHANGED
@@ -44,17 +44,18 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
44
  'notify_url' => 'notify_url',
45
  ) );
46
 
47
- $subtotal = 0;
 
48
 
49
  // Shopping Cart details
50
  $i = 0;
51
  foreach ( $this->options['items'] as $item ) {
52
  // Options Fields
53
  $item_optionals = array(
54
- 'tax' => "tax{$i}",
55
  );
56
 
57
- // Format Amount Field
58
  $item['amount'] = $this->format( $item['amount'] );
59
 
60
  // Required Fields
@@ -79,6 +80,42 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
79
  return $request;
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * Add a shipping address to the PayPal request
84
  *
@@ -139,7 +176,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
139
  /**
140
  * Gateway implementation for BMCreateButton
141
  *
142
- * @param array $options
143
  * @return PHP_Merchant_Paypal_Pro_Response
144
  * @since 3.9
145
  */
@@ -151,14 +188,14 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
151
  $request['BUTTONCODE'] = 'TOKEN';
152
  $request['BUTTONTYPE'] = 'PAYMENT';
153
  $request['cmd'] = '_cart';
154
-
155
  $response_str = $this->commit( 'BMCreateButton', $request );
156
  return new PHP_Merchant_Paypal_Pro_Response( $response_str );
157
  }
158
 
159
  /**
160
  * Build the request array
161
- *
162
  * @param array $options
163
  * @return array
164
  * @since 3.9
@@ -180,7 +217,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
180
 
181
  if ( $action != false ) {
182
  $request += $this->add_payment( $action );
183
- $request['display'] = '1';
184
  }
185
 
186
  if ( ! empty( $this->options['shipping_address'] ) ) {
@@ -197,7 +234,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
197
 
198
  // Common Fields
199
  $request += phpme_map( $this->options, array(
200
- 'amount' => 'amount',
201
  'subtotal' => 'subtotal',
202
  'tax' => 'tax',
203
  'shipping' => 'shipping',
@@ -207,7 +244,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
207
  'vendor' => 'merchant_email',
208
  'invoice' => 'invoice',
209
  'currency' => 'currency',
210
- ) );
211
 
212
  $request = $this->add_sub( 'L_BUTTONVAR', $request );
213
 
@@ -223,7 +260,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
223
  * @since 3.9
224
  */
225
  function build_checkout_request( $action, $options = array() ) {
226
- $request = array();
227
 
228
  // Common Fields
229
  $request += phpme_map( $this->options, array(
@@ -247,9 +284,9 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
247
  'REFUNDADVICE' => 'refund_advice',
248
  ) );
249
  // BN Code
250
- $request['BUTTONSOURCE'] = 'WPECOM_ECM';
251
 
252
- return $request;
253
  }
254
 
255
  /**
@@ -260,7 +297,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
260
  * @return array
261
  * @since 3.9
262
  */
263
- private function add_sub( $sub, $arr ) {
264
  $request = array();
265
 
266
  $i = 0;
@@ -273,7 +310,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
273
  }
274
 
275
  /**
276
- * Gateway implementation for "purchase" operation
277
  *
278
  * @param array $options
279
  * @return PHP_Merchant_Paypal_Pro_Response
@@ -284,7 +321,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
284
  }
285
 
286
  /**
287
- * Gateway implementation for "authorize" operation
288
  *
289
  * @param array $options
290
  * @return PHP_Merchant_Paypal_Pro_Response
@@ -295,7 +332,7 @@ class PHP_Merchant_Paypal_Pro extends PHP_Merchant_Paypal
295
  }
296
 
297
  /**
298
- * Gateway implementation for "capture" operation
299
  *
300
  * @param array $options
301
  * @return PHP_Merchant_Paypal_Pro_Response
44
  'notify_url' => 'notify_url',
45
  ) );
46
 
47
+ // Apply a Discount if available
48
+ $this->add_discount();
49
 
50
  // Shopping Cart details
51
  $i = 0;
52
  foreach ( $this->options['items'] as $item ) {
53
  // Options Fields
54
  $item_optionals = array(
55
+ 'tax' => "tax{$i}",
56
  );
57
 
58
+ // Format Amount Field
59
  $item['amount'] = $this->format( $item['amount'] );
60
 
61
  // Required Fields
80
  return $request;
81
  }
82
 
83
+ /**
84
+ * Add Discount for the Shopping Cart.
85
+ *
86
+ * Since PayPal doesn't have distinct support for discounts, we have to add the discount
87
+ * as a separate item with a negative value.
88
+ *
89
+ * @return void
90
+ */
91
+ protected function add_discount() {
92
+ // Verify if a discount is set
93
+ if ( isset( $this->options['discount'] ) && (float) $this->options['discount'] != 0 ) {
94
+ $discount = (float) $this->options['discount'];
95
+ $sub_total = (float) $this->options['subtotal'];
96
+
97
+ // If discount amount is larger than or equal to the item total, we need to set item total to 0.01
98
+ // because PayPal does not accept 0 item total.
99
+ if ( $discount >= $sub_total ) {
100
+ $discount = $sub_total - 0.01;
101
+ }
102
+
103
+ // if there's shipping, we'll take 0.01 from there
104
+ if ( ! empty( $this->options['shipping'] ) ) {
105
+ $this->options['shipping'] -= 0.01;
106
+ } else {
107
+ $this->options['amount'] = 0.01;
108
+ }
109
+
110
+ // Add the Discount as an Item
111
+ $this->options['items'][] = array(
112
+ 'name' => __( 'Discount', 'wpsc' ),
113
+ 'amount' => - $discount,
114
+ 'quantity' => '1',
115
+ );
116
+ }
117
+ }
118
+
119
  /**
120
  * Add a shipping address to the PayPal request
121
  *
176
  /**
177
  * Gateway implementation for BMCreateButton
178
  *
179
+ * @param array $options
180
  * @return PHP_Merchant_Paypal_Pro_Response
181
  * @since 3.9
182
  */
188
  $request['BUTTONCODE'] = 'TOKEN';
189
  $request['BUTTONTYPE'] = 'PAYMENT';
190
  $request['cmd'] = '_cart';
191
+
192
  $response_str = $this->commit( 'BMCreateButton', $request );
193
  return new PHP_Merchant_Paypal_Pro_Response( $response_str );
194
  }
195
 
196
  /**
197
  * Build the request array
198
+ *
199
  * @param array $options
200
  * @return array
201
  * @since 3.9
217
 
218
  if ( $action != false ) {
219
  $request += $this->add_payment( $action );
220
+ $request['display'] = '1';
221
  }
222
 
223
  if ( ! empty( $this->options['shipping_address'] ) ) {
234
 
235
  // Common Fields
236
  $request += phpme_map( $this->options, array(
237
+ 'amount' => 'amount',
238
  'subtotal' => 'subtotal',
239
  'tax' => 'tax',
240
  'shipping' => 'shipping',
244
  'vendor' => 'merchant_email',
245
  'invoice' => 'invoice',
246
  'currency' => 'currency',
247
+ ) );
248
 
249
  $request = $this->add_sub( 'L_BUTTONVAR', $request );
250
 
260
  * @since 3.9
261
  */
262
  function build_checkout_request( $action, $options = array() ) {
263
+ $request = array();
264
 
265
  // Common Fields
266
  $request += phpme_map( $this->options, array(
284
  'REFUNDADVICE' => 'refund_advice',
285
  ) );
286
  // BN Code
287
+ $request['BUTTONSOURCE'] = 'WPeC_Cart_HSS';
288
 
289
+ return $request;
290
  }
291
 
292
  /**
297
  * @return array
298
  * @since 3.9
299
  */
300
+ private function add_sub( $sub, $arr ) {
301
  $request = array();
302
 
303
  $i = 0;
310
  }
311
 
312
  /**
313
+ * Gateway implementation for "purchase" operation
314
  *
315
  * @param array $options
316
  * @return PHP_Merchant_Paypal_Pro_Response
321
  }
322
 
323
  /**
324
+ * Gateway implementation for "authorize" operation
325
  *
326
  * @param array $options
327
  * @return PHP_Merchant_Paypal_Pro_Response
332
  }
333
 
334
  /**
335
+ * Gateway implementation for "capture" operation
336
  *
337
  * @param array $options
338
  * @return PHP_Merchant_Paypal_Pro_Response
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal-response.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/gateways/paypal.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/http-curl.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/php-merchant.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/common/test-accounts.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal-express-checkout.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal-ipn.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/gateways/paypal.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/index.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/http-curl.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x1.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x2.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x3.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-dg-cert-x4.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x1.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x2.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x3.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x4.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x5.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-ec-cert-x6.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-express-checkout.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-pro-cert-x1.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/remote/paypal-pro-cert-x2.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/LICENSE CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/README CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/VERSION CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/authentication.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/autorun.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/browser.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/collector.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/compatibility.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/cookies.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/default_reporter.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/detached.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/authentication_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/browser_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/docs.css CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/expectation_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/form_testing_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/group_test_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/index.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/mock_objects_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/overview.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/partial_mocks_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/reporter_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/unit_test_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/en/web_tester_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/authentication_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/browser_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/docs.css CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/expectation_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/form_testing_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/group_test_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/index.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/mock_objects_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/overview.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/partial_mocks_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/reporter_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/unit_test_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/docs/fr/web_tester_documentation.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/dumper.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/eclipse.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/encoding.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/errors.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/exceptions.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/expectation.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/pear_test_case.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/testdox.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/extensions/testdox/test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/form.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/frames.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/http.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/invoker.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/mock_objects.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/page.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/php_parser.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reflection_php4.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reflection_php5.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/remote.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/reporter.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/scorer.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/selector.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/shell_tester.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/simpletest.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/socket.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/tag.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/acceptance_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/adapter_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/all_tests.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/authentication_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/autorun_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/bad_test_suite.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/browser_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/collector_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/command_line_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/compatibility_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/cookies_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/detached_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/dumper_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/eclipse_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/encoding_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/errors_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/exceptions_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/expectation_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/form_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/frames_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/http_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/interfaces_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/interfaces_test_php5_1.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/live_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/mock_objects_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/page_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/parse_error_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/parsing_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/php_parser_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/reflection_php4_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/reflection_php5_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/remote_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/shell_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/shell_tester_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/simpletest_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/site/file.html CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/socket_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/collector/collectable.1 CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/collector/collectable.2 CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/empty_test_file.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/failing_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/latin1_sample CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/passing_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/spl_examples.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/supplementary_upload_sample.txt CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/test1.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/support/upload_sample.txt CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/tag_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/test_with_parse_error.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/unit_tester_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/unit_tests.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/url_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/user_agent_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/visual_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/web_tester_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test/xml_test.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/test_case.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/tidy_parser.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/unit_tester.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/url.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/user_agent.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/varlog.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/web_tester.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/php-merchant/tests/simpletest/xml.php CHANGED
File without changes
wpsc-components/merchant-core-v3/gateways/pro.css CHANGED
@@ -1,6 +1,29 @@
 
1
  IFRAME[name=hss_iframe] {
2
  max-width: none;
 
3
  }
4
  FORM[target=hss_iframe] {
5
  display: none;
6
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Desktop CSS */
2
  IFRAME[name=hss_iframe] {
3
  max-width: none;
4
+ display: none;
5
  }
6
  FORM[target=hss_iframe] {
7
  display: none;
8
  }
9
+
10
+ /* Mobile CSS */
11
+ @media only screen
12
+ and (min-device-width : 320px)
13
+ and (max-device-width : 480px) {
14
+ IFRAME[name=hss_iframe] {
15
+ height: 100% !important;
16
+ width: 100% !important;
17
+ right: 0;
18
+ bottom: 0;
19
+ border:none;
20
+ margin:0;
21
+ padding:0;
22
+ overflow:hidden;
23
+ z-index:999999;
24
+ display: block;
25
+ position: fixed;
26
+ top: 0;
27
+ left: 0;
28
+ }
29
+ }
wpsc-components/merchant-core-v3/gateways/pro.js CHANGED
@@ -1,42 +1,54 @@
1
- /*
2
- * PayPal Pro script
3
- */
4
  (function($) {
5
  $(window).load(function() {
6
- // Declare variables/doom elements
7
- var $checkout_btn = $( '.wpsc-checkout-form-button' ),
8
- $rd_btn = $( 'input[value="paypal-pro"]' ),
9
- $inputs = $( 'input[type="radio"]' ),
10
- $form = $( '#wpsc-checkout-form' ),
11
- $container = $( '.wpsc-payment-method' ),
12
  $hss_form;
13
 
14
  $checkout_btn.on( 'click', function() {
15
  if ( $rd_btn.is( ':checked' ) ) {
16
  // Empty the container
17
  $container.html( '' );
 
18
  // Disable FORM
19
  $form.on( 'submit', function() {
20
  return false;
21
  } );
22
 
23
  // Insert iFrame
24
- $container.html( '<iframe name="hss_iframe" width="570px" height="540px"></iframe>' );
 
 
 
 
25
 
26
  // Call the PayPal Pro API
27
- $.ajax({
28
  type: "POST",
29
  url: window.location,
30
- data: $form.serialize(),
31
 
32
  success: function(data) {
 
33
  $container.append( data );
34
  $hss_form = $( 'FORM', $container );
35
  $hss_form.attr( 'target', 'hss_iframe' );
36
- $hss_form.submit();
37
- }
 
38
 
39
- });
 
 
 
 
 
 
 
40
  }
41
  } );
42
  } );
1
+ /*global jQuery, pro_loc */
 
 
2
  (function($) {
3
  $(window).load(function() {
4
+ // Declare variables/DOM elements
5
+ var $checkout_btn = $( '.wpsc-checkout-form-button, .wpsc_buy_button' ),
6
+ $rd_btn = $( 'input[value="paypal-pro"]' ),
7
+ $inputs = $( 'input[type="radio"]' ),
8
+ $form = $( '#wpsc-checkout-form, .wpsc_checkout_forms' ),
9
+ $container = $( '.wpsc-payment-method, .wpsc_gateway_container' ),
10
  $hss_form;
11
 
12
  $checkout_btn.on( 'click', function() {
13
  if ( $rd_btn.is( ':checked' ) ) {
14
  // Empty the container
15
  $container.html( '' );
16
+
17
  // Disable FORM
18
  $form.on( 'submit', function() {
19
  return false;
20
  } );
21
 
22
  // Insert iFrame
23
+ $container.html( '<iframe id="pro-iframe" name="hss_iframe" width="570px" height="540px"></iframe>' );
24
+
25
+ // Insert the Spinner
26
+ $container.parents( '.wpsc-checkout-review' ).find( 'strong.wpsc-large' ).eq( -1 ).after( '<img src="' + pro_loc.spinner_url + '" class="pro-spinner" alt="spinner" />' );
27
+ var $spinner = $( '.pro-spinner' );
28
 
29
  // Call the PayPal Pro API
30
+ $.ajax( {
31
  type: "POST",
32
  url: window.location,
33
+ data: $form.serialize() + '&custom_gateway=paypal-pro',
34
 
35
  success: function(data) {
36
+ data = data.replace(/\\/g, '');
37
  $container.append( data );
38
  $hss_form = $( 'FORM', $container );
39
  $hss_form.attr( 'target', 'hss_iframe' );
40
+ $hss_form.find( 'input[type="image"]' ).click();
41
+
42
+ // Remove the Spinner
43
 
44
+ // Show the IFRAME
45
+ $( '#pro-iframe' ).show();
46
+
47
+ document.getElementById( 'pro-iframe' ).onload = function() {
48
+ $spinner.hide();
49
+ }
50
+ }
51
+ } );
52
  }
53
  } );
54
  } );
wpsc-components/merchant-core-v3/helpers/admin.php CHANGED
File without changes
wpsc-components/merchant-core-v3/helpers/checkout.php CHANGED
@@ -44,8 +44,9 @@ function _wpsc_filter_merchant_v3_gateway_loop_items( $gateways ) {
44
 
45
  function _wpsc_filter_merchant_v3_get_gateway_list( $list ) {
46
  // if merchant api v2 is not being active, proceed to output the gateway list
47
- if ( _wpsc_is_merchant_v2_active( $list ) )
48
  return $list;
 
49
 
50
  $active_gateways = WPSC_Payment_Gateways::get_active_gateways();
51
  $selected_gateway = wpsc_get_customer_meta( 'selected_gateway' );
@@ -93,8 +94,9 @@ add_action(
93
  );
94
 
95
  function _wpsc_action_merchant_v3_submit_checkout( $gateway_id, $log ) {
96
- if ( ! wpsc_is_payment_gateway_registered( $gateway_id ) )
97
  return;
 
98
 
99
  $gateway = wpsc_get_payment_gateway( $gateway_id );
100
  $gateway->set_purchase_log( $log );
44
 
45
  function _wpsc_filter_merchant_v3_get_gateway_list( $list ) {
46
  // if merchant api v2 is not being active, proceed to output the gateway list
47
+ if ( _wpsc_is_merchant_v2_active() ) {
48
  return $list;
49
+ }
50
 
51
  $active_gateways = WPSC_Payment_Gateways::get_active_gateways();
52
  $selected_gateway = wpsc_get_customer_meta( 'selected_gateway' );
94
  );
95
 
96
  function _wpsc_action_merchant_v3_submit_checkout( $gateway_id, $log ) {
97
+ if ( ! wpsc_is_payment_gateway_registered( $gateway_id ) ) {
98
  return;
99
+ }
100
 
101
  $gateway = wpsc_get_payment_gateway( $gateway_id );
102
  $gateway->set_purchase_log( $log );
wpsc-components/merchant-core-v3/helpers/common.php CHANGED
@@ -2,4 +2,15 @@
2
 
3
  function _wpsc_is_merchant_v2_active() {
4
  return defined( 'WPSC_MERCHANT_V2_PATH' ) && WPSC_MERCHANT_V2_PATH;
5
- }
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  function _wpsc_is_merchant_v2_active() {
4
  return defined( 'WPSC_MERCHANT_V2_PATH' ) && WPSC_MERCHANT_V2_PATH;
5
+ }
6
+
7
+ /**
8
+ * Return True if the gateway is registered and active, false otherwise.
9
+ *
10
+ * @param string $gateway_id
11
+ * @return bool
12
+ */
13
+ function wpsc_is_gateway_active( $gateway_id ) {
14
+ $active_gateways = WPSC_Payment_Gateways::get_active_gateways();
15
+ return in_array( $gateway_id, $active_gateways );
16
+ }
wpsc-components/merchant-core-v3/helpers/payment-gateway.php CHANGED
File without changes
wpsc-components/merchant-core-v3/merchant-core-v3.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
 
3
- define( 'WPSC_MERCHANT_V3_PATH', dirname( __FILE__ ) );
 
 
4
  define( 'WPSC_PAYMENT_STATUS_INCOMPLETE', 1 );
5
  define( 'WPSC_PAYMENT_STATUS_RECEIVED' , 2 );
6
  define( 'WPSC_PAYMENT_STATUS_ACCEPTED' , 3 );
1
  <?php
2
 
3
+ define( 'WPSC_MERCHANT_V3_PATH' , dirname( __FILE__ ) );
4
+ define( 'WPSC_MERCHANT_V3_SDKS_PATH', dirname( __FILE__ ) . '/libraries' );
5
+ define( 'WPSC_MERCHANT_V3_SDKS_URL' , plugin_dir_url( __FILE__ ) . 'libraries' );
6
  define( 'WPSC_PAYMENT_STATUS_INCOMPLETE', 1 );
7
  define( 'WPSC_PAYMENT_STATUS_RECEIVED' , 2 );
8
  define( 'WPSC_PAYMENT_STATUS_ACCEPTED' , 3 );
wpsc-core/wpsc-constants.php CHANGED
@@ -55,15 +55,15 @@ function wpsc_core_constants() {
55
 
56
  // Define Plugin version
57
  if ( ! defined( 'WPSC_VERSION' ) ) {
58
- define( 'WPSC_VERSION' , '3.9.5' );
59
  }
60
 
61
  if ( ! defined( 'WPSC_MINOR_VERSION' ) ) {
62
- define( 'WPSC_MINOR_VERSION' , 'c98078b' );
63
  }
64
 
65
  if ( ! defined( 'WPSC_PRESENTABLE_VERSION' ) ) {
66
- define( 'WPSC_PRESENTABLE_VERSION', '3.9.5' );
67
  }
68
 
69
  // Define a salt to use when we hash, WPSC_SALT may be defined for us in our config file, so check first
55
 
56
  // Define Plugin version
57
  if ( ! defined( 'WPSC_VERSION' ) ) {
58
+ define( 'WPSC_VERSION' , '3.10.0' );
59
  }
60
 
61
  if ( ! defined( 'WPSC_MINOR_VERSION' ) ) {
62
+ define( 'WPSC_MINOR_VERSION' , '2f8b780' );
63
  }
64
 
65
  if ( ! defined( 'WPSC_PRESENTABLE_VERSION' ) ) {
66
+ define( 'WPSC_PRESENTABLE_VERSION', '3.10.0' );
67
  }
68
 
69
  // Define a salt to use when we hash, WPSC_SALT may be defined for us in our config file, so check first