Easy Digital Downloads - Version 2.10

Version Description

Download this release

Release Info

Developer NoseGraze
Plugin Icon 128x128 Easy Digital Downloads
Version 2.10
Comparing to
See all releases

Code changes from version 2.9.26 to 2.10

Files changed (219) hide show
  1. assets/css/edd-admin.css +2 -1
  2. assets/css/edd-admin.min.css +1 -1
  3. assets/js/admin-scripts.js +0 -12
  4. assets/js/admin-scripts.min.js +1 -1
  5. assets/js/edd-checkout-global.js +6 -3
  6. assets/js/edd-checkout-global.min.js +1 -1
  7. easy-digital-downloads.php +10 -3
  8. includes/EDD_SL_Plugin_Updater.php +72 -41
  9. includes/admin/class-edd-notices.php +72 -0
  10. includes/admin/discounts/discount-actions.php +10 -0
  11. includes/admin/downloads/metabox.php +11 -2
  12. includes/admin/import/class-batch-import-downloads.php +3 -0
  13. includes/admin/import/class-batch-import-payments.php +4 -1
  14. includes/api/class-edd-api-v2.php +1 -1
  15. includes/cart/actions.php +10 -6
  16. includes/cart/class-edd-cart.php +8 -0
  17. includes/checkout/template.php +2 -2
  18. includes/class-edd-db-customers.php +34 -21
  19. includes/class-edd-discount.php +3 -4
  20. includes/class-edd-html-elements.php +12 -12
  21. includes/class-edd-license-handler.php +7 -1
  22. includes/download-functions.php +13 -2
  23. includes/gateways/paypal-standard.php +11 -2
  24. includes/gateways/stripe/apple-developer-merchantid-domain-association +1 -0
  25. includes/gateways/stripe/assets/css/build/admin.min.css +3 -0
  26. includes/gateways/stripe/assets/css/build/admin.min.css.map +1 -0
  27. includes/gateways/stripe/assets/css/build/app.min.css +3 -0
  28. includes/gateways/stripe/assets/css/build/app.min.css.map +1 -0
  29. includes/gateways/stripe/assets/css/src/admin.scss +137 -0
  30. includes/gateways/stripe/assets/css/src/frontend.scss +399 -0
  31. includes/gateways/stripe/assets/css/src/frontend/modal.scss +103 -0
  32. includes/gateways/stripe/assets/css/src/frontend/payment-request-button.scss +79 -0
  33. includes/gateways/stripe/assets/js/build/admin.min.js +1 -0
  34. includes/gateways/stripe/assets/js/build/app.min.js +1 -0
  35. includes/gateways/stripe/assets/js/build/notices.min.js +1 -0
  36. includes/gateways/stripe/assets/js/src/admin/index.js +104 -0
  37. includes/gateways/stripe/assets/js/src/admin/notices.js +36 -0
  38. includes/gateways/stripe/assets/js/src/admin/settings/index.js +5 -0
  39. includes/gateways/stripe/assets/js/src/admin/settings/requirements.js +40 -0
  40. includes/gateways/stripe/assets/js/src/admin/settings/stripe-connect.js +29 -0
  41. includes/gateways/stripe/assets/js/src/frontend/components/index.js +2 -0
  42. includes/gateways/stripe/assets/js/src/frontend/components/modal/index.js +46 -0
  43. includes/gateways/stripe/assets/js/src/frontend/components/payment-methods/index.js +259 -0
  44. includes/gateways/stripe/assets/js/src/frontend/index.js +64 -0
  45. includes/gateways/stripe/assets/js/src/frontend/payment-forms/buy-now/index.js +184 -0
  46. includes/gateways/stripe/assets/js/src/frontend/payment-forms/checkout/index.js +36 -0
  47. includes/gateways/stripe/assets/js/src/frontend/payment-forms/checkout/payment-form.js +250 -0
  48. includes/gateways/stripe/assets/js/src/frontend/payment-forms/index.js +8 -0
  49. includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-receipt/index.js +17 -0
  50. includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-receipt/payment-form.js +133 -0
  51. includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/checkout.js +407 -0
  52. includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/download.js +321 -0
  53. includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/index.js +27 -0
  54. includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/index.js +14 -0
  55. includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/payment-form.js +193 -0
  56. includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/payment-method-actions.js +184 -0
  57. includes/gateways/stripe/assets/js/src/frontend/stripe-elements/index.js +309 -0
  58. includes/gateways/stripe/assets/js/src/frontend/stripe-elements/intents.js +167 -0
  59. includes/gateways/stripe/assets/js/src/utils/api-request.js +51 -0
  60. includes/gateways/stripe/assets/js/src/utils/dom.js +43 -0
  61. includes/gateways/stripe/assets/js/src/utils/form.js +58 -0
  62. includes/gateways/stripe/assets/js/src/utils/index.js +9 -0
  63. includes/gateways/stripe/assets/js/src/utils/notice.js +61 -0
  64. includes/gateways/stripe/assets/js/src/utils/polyfill-closest.js +21 -0
  65. includes/gateways/stripe/assets/js/src/utils/polyfill-includes.js +17 -0
  66. includes/gateways/stripe/assets/js/src/utils/polyfill-object-entries.js +15 -0
  67. includes/gateways/stripe/assets/js/src/utils/polyfill-remove.js +18 -0
  68. includes/gateways/stripe/edd-stripe.php +58 -0
  69. includes/gateways/stripe/includes/admin/admin-actions.php +169 -0
  70. includes/gateways/stripe/includes/admin/admin-filters.php +119 -0
  71. includes/gateways/stripe/includes/admin/class-notices-registry.php +102 -0
  72. includes/gateways/stripe/includes/admin/class-notices.php +145 -0
  73. includes/gateways/stripe/includes/admin/notices.php +192 -0
  74. includes/gateways/stripe/includes/admin/notices/edd-recurring-requirement.php +38 -0
  75. includes/gateways/stripe/includes/admin/notices/edd-requirement.php +38 -0
  76. includes/gateways/stripe/includes/admin/notices/edd-stripe-core.php +49 -0
  77. includes/gateways/stripe/includes/admin/notices/php-requirement.php +107 -0
  78. includes/gateways/stripe/includes/admin/reporting/class-stripe-reports.php +26 -0
  79. includes/gateways/stripe/includes/admin/settings.php +454 -0
  80. includes/gateways/stripe/includes/admin/settings/stripe-connect.php +636 -0
  81. includes/gateways/stripe/includes/admin/upgrade-functions.php +131 -0
  82. includes/gateways/stripe/includes/card-actions.php +544 -0
  83. includes/gateways/stripe/includes/class-edd-stripe-rate-limiting.php +369 -0
  84. includes/gateways/stripe/includes/class-edd-stripe.php +248 -0
  85. includes/gateways/stripe/includes/class-stripe-api.php +139 -0
  86. includes/gateways/stripe/includes/compat.php +435 -0
  87. includes/gateways/stripe/includes/deprecated.php +72 -0
  88. includes/gateways/stripe/includes/elements.php +78 -0
  89. includes/gateways/stripe/includes/emails.php +51 -0
  90. includes/gateways/stripe/includes/functions.php +550 -0
  91. includes/gateways/stripe/includes/gateway-actions.php +77 -0
  92. includes/gateways/stripe/includes/gateway-filters.php +101 -0
  93. includes/gateways/stripe/includes/i18n.php +75 -0
  94. includes/gateways/stripe/includes/integrations/edd-all-access.php +27 -0
  95. includes/gateways/stripe/includes/integrations/edd-auto-register.php +32 -0
  96. includes/gateways/stripe/includes/integrations/wp-cli.php +95 -0
  97. includes/gateways/stripe/includes/payment-actions.php +1440 -0
  98. includes/gateways/stripe/includes/payment-methods/buy-now/ajax.php +63 -0
  99. includes/gateways/stripe/includes/payment-methods/buy-now/checkout.php +84 -0
  100. includes/gateways/stripe/includes/payment-methods/buy-now/functions.php +53 -0
  101. includes/gateways/stripe/includes/payment-methods/buy-now/index.php +13 -0
  102. includes/gateways/stripe/includes/payment-methods/buy-now/shortcode.php +105 -0
  103. includes/gateways/stripe/includes/payment-methods/buy-now/template.php +227 -0
  104. includes/gateways/stripe/includes/payment-methods/payment-request/admin/settings.php +114 -0
  105. includes/gateways/stripe/includes/payment-methods/payment-request/ajax.php +253 -0
  106. includes/gateways/stripe/includes/payment-methods/payment-request/apple-pay.php +280 -0
  107. includes/gateways/stripe/includes/payment-methods/payment-request/checkout.php +372 -0
  108. includes/gateways/stripe/includes/payment-methods/payment-request/functions.php +225 -0
  109. includes/gateways/stripe/includes/payment-methods/payment-request/index.php +18 -0
  110. includes/gateways/stripe/includes/payment-methods/payment-request/shortcode.php +31 -0
  111. includes/gateways/stripe/includes/payment-methods/payment-request/template.php +200 -0
  112. includes/gateways/stripe/includes/payment-receipt.php +85 -0
  113. includes/gateways/stripe/includes/scripts.php +190 -0
  114. includes/gateways/stripe/includes/template-functions.php +855 -0
  115. includes/gateways/stripe/includes/utils/class-registry.php +139 -0
  116. includes/gateways/stripe/includes/utils/exceptions/class-attribute-not-found.php +40 -0
  117. includes/gateways/stripe/includes/utils/exceptions/class-gateway-exception.php +76 -0
  118. includes/gateways/stripe/includes/utils/exceptions/class-stripe-api-unmet-requirements.php +18 -0
  119. includes/gateways/stripe/includes/utils/exceptions/class-stripe-object-not-found.php +16 -0
  120. includes/gateways/stripe/includes/utils/interface-static-registry.php +25 -0
  121. includes/gateways/stripe/includes/utils/modal.php +87 -0
  122. includes/gateways/stripe/includes/webhooks.php +181 -0
  123. includes/gateways/stripe/vendor/autoload.php +7 -0
  124. includes/gateways/stripe/vendor/composer/ClassLoader.php +445 -0
  125. includes/gateways/stripe/vendor/composer/LICENSE +21 -0
  126. includes/gateways/stripe/vendor/composer/autoload_classmap.php +9 -0
  127. includes/gateways/stripe/vendor/composer/autoload_namespaces.php +9 -0
  128. includes/gateways/stripe/vendor/composer/autoload_psr4.php +11 -0
  129. includes/gateways/stripe/vendor/composer/autoload_real.php +52 -0
  130. includes/gateways/stripe/vendor/composer/autoload_static.php +39 -0
  131. includes/gateways/stripe/vendor/composer/installed.json +163 -0
  132. includes/gateways/stripe/vendor/composer/installers/LICENSE +19 -0
  133. includes/gateways/stripe/vendor/composer/installers/README.md +210 -0
  134. includes/gateways/stripe/vendor/composer/installers/composer.json +85 -0
  135. includes/gateways/stripe/vendor/composer/installers/phpunit.xml.dist +25 -0
  136. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AglInstaller.php +21 -0
  137. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +9 -0
  138. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +11 -0
  139. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +45 -0
  140. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +136 -0
  141. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +123 -0
  142. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +9 -0
  143. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +84 -0
  144. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +11 -0
  145. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +10 -0
  146. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +11 -0
  147. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +12 -0
  148. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +35 -0
  149. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +21 -0
  150. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +50 -0
  151. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +16 -0
  152. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +16 -0
  153. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +9 -0
  154. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +11 -0
  155. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +9 -0
  156. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/GravInstaller.php +30 -0
  157. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +25 -0
  158. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php +11 -0
  159. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Installer.php +178 -0
  160. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +15 -0
  161. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +11 -0
  162. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +10 -0
  163. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +9 -0
  164. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +9 -0
  165. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +10 -0
  166. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +9 -0
  167. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +16 -0
  168. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +11 -0
  169. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +9 -0
  170. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php +25 -0
  171. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +50 -0
  172. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +111 -0
  173. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +56 -0
  174. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +46 -0
  175. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +59 -0
  176. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php +9 -0
  177. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php +11 -0
  178. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php +21 -0
  179. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php +32 -0
  180. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Plugin.php +17 -0
  181. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php +10 -0
  182. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php +11 -0
  183. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php +10 -0
  184. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +22 -0
  185. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php +10 -0
  186. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +58 -0
  187. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +36 -0
  188. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php +26 -0
  189. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +16 -0
  190. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +38 -0
  191. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php +12 -0
  192. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +14 -0
  193. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php +10 -0
  194. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php +9 -0
  195. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php +11 -0
  196. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php +11 -0
  197. includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php +10 -0
  198. includes/gateways/stripe/vendor/composer/installers/src/bootstrap.php +13 -0
  199. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php +61 -0
  200. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php +115 -0
  201. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php +83 -0
  202. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php +89 -0
  203. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php +63 -0
  204. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php +455 -0
  205. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php +66 -0
  206. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php +66 -0
  207. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php +44 -0
  208. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php +63 -0
  209. includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/TestCase.php +64 -0
  210. includes/gateways/stripe/vendor/composer/installers/tests/bootstrap.php +4 -0
  211. includes/gateways/stripe/vendor/stripe/stripe-php/CHANGELOG.md +1243 -0
  212. includes/gateways/stripe/vendor/stripe/stripe-php/CODE_OF_CONDUCT.md +77 -0
  213. includes/gateways/stripe/vendor/stripe/stripe-php/LICENSE +21 -0
  214. includes/gateways/stripe/vendor/stripe/stripe-php/Makefile +36 -0
  215. includes/gateways/stripe/vendor/stripe/stripe-php/README.md +266 -0
  216. includes/gateways/stripe/vendor/stripe/stripe-php/VERSION +1 -0
  217. includes/gateways/stripe/vendor/stripe/stripe-php/build.php +25 -0
  218. includes/gateways/stripe/vendor/stripe/stripe-php/composer.json +48 -0
  219. includes/gateways/stripe/vendor/stripe/stripe-php/data/ca-certificates.crt +102 -0
assets/css/edd-admin.css CHANGED
@@ -17,7 +17,8 @@
17
  text-indent: -9999px;
18
  visibility: hidden;
19
  }
20
- .edd-wrap a {
 
21
  text-decoration: none;
22
  }
23
  a.edd-delete {
17
  text-indent: -9999px;
18
  visibility: hidden;
19
  }
20
+ .edd-wrap a,
21
+ .edd-notice .notice-dismiss {
22
  text-decoration: none;
23
  }
24
  a.edd-delete {
assets/css/edd-admin.min.css CHANGED
@@ -1 +1 @@
1
- .edd-hidden{display:none}.edd-clearfix:after{content:".";display:block;height:0;text-indent:-9999px;visibility:hidden}.edd-wrap a{text-decoration:none}a.edd-delete{color:#a00}a.edd-delete:hover{color:red}.download_page_edd-settings .form-table label{color:#666;font-size:14px;font-style:italic;margin:4px 0 0}.download_page_edd-settings .form-table input.small-text~label,.download_page_edd-settings .form-table input[type=checkbox]+label{display:inline}.download_page_edd-settings .form-table tr>th>h3,.download_page_edd-settings .form-table tr>th>strong{font-size:1.2em;font-weight:600;margin:0 auto}.edd-help-tip{cursor:help}.edd-ui-tooltip{position:absolute;background:#333!important;border-width:1px!important;border-radius:3px!important;box-shadow:1px 1px 2px 1px rgba(214,214,214,.5)!important;color:#dedede!important;max-width:300px!important;padding:7px!important;text-rendering:optimizeLegibility;text-shadow:none!important;z-index:9999!important}.download_page_edd-settings .edd-settings-payment-icon-wrapper{margin-right:10px;line-height:16px;height:16px;display:table}#edd-add-ons h2.nav-tab-wrapper{position:relative}.edd-tab-span{top:-6px;right:0;position:absolute}.edd-add-ons-footer{padding-top:10px}#edd-add-ons h2{margin:0 0 15px}.edd-add-ons-view-wrapper{height:50px}#edd-add-ons h2 .button-primary{position:absolute}#edd-add-ons .edd-extension{background:#fff;border:1px solid #ccc;float:left;padding:14px;position:relative;margin:0 15px 15px 0;width:320px;height:315px}#edd-add-ons .edd-extension h3{font-size:13px;margin:0 0 8px}#edd-add-ons .edd-extension .button-secondary{position:absolute;bottom:14px;left:14px}#edd-add-ons .edd-browse-all{clear:both;width:100%}#edd-add-ons .edd-extension .third-party{display:none}#edd-add-ons .edd-starter-package{background-color:#85c0e5;border-color:#62a9d7;color:#fff}#edd-add-ons .edd-starter-package h3{color:#fff}#edd-add-ons .edd-extension .wp-post-image{width:100%;height:auto;vertical-align:bottom}#edd-products{height:100px;min-width:200px}#edd-add-discount input[type=text],#edd-edit-discount input[type=text]{width:300px}#edd-add-discount input.edd-price-field,#edd-edit-discount input.edd-price-field{padding:3px 5px;width:75px}.download_page_edd-addons .wrap .wp-heading-inline,.edit-php.post-type-download .wrap .wp-heading-inline{display:none}.download_page_edd-addons .wrap>.page-title-action,.edit-php.post-type-download .wrap>.page-title-action{display:none}.download_page_edd-addons .wrap .nav-tab-wrapper .page-title-action,.edit-php.post-type-download .wrap .nav-tab-wrapper .page-title-action{top:7px;margin-left:5px}#edd-payment-filters{background:#f5f5f5;clear:both;background-image:-webkit-gradient(linear,left bottom,left top,from(#f5f5f5),to(#fafafa));background-image:-webkit-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:-moz-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:-o-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:linear-gradient(to top,#f5f5f5,#fafafa);border-color:#dfdfdf;border-width:1px;border-style:solid;border-radius:3px;font-size:13px;line-height:2.1em;overflow:auto;padding:12px;margin:8px 0}#edd-payments-filter ul.subsubsub{margin-bottom:8px}#edd-payment-filters p{color:#777}#edd-payment-date-filters input{vertical-align:middle}tr.status-refunded td{background:#cecece;border-top-color:#ccc}.wp-list-table.downloads th#ID{width:80px}.wp-list-table.downloads th#details{width:130px}.wp-list-table.downloads th#date{width:140px}.wp-list-table.downloads th#user{width:130px}.edd-mobile-link{line-height:32px;vertical-align:middle}.edd-mobile-link img{max-width:80%;height:auto;float:left}@media handheld,only screen and (max-width:640px){.wp-list-table.downloads th{width:auto!important}}.download_page_edd-payment-history .ui-dialog .ui-dialog-titlebar-close span{margin-left:-8px;margin-top:-8px}#edd-download-link-textarea{width:100%}.edd_files_name_label{width:225px;float:left}.edd_files_url_label{width:220px;float:left}#postbox-container-1 .edd_files_name_label{width:80px}#postbox-container-1 .edd_files_url_label{width:80px}.edd-add-repeatable-row{margin:10px 0}.edd-add-repeatable-row .submit{padding:0!important}.edd_repeatable_upload_wrapper:not(:first-child),.edd_variable_prices_wrapper:not(:first-child){margin-top:12px}.edd-repeatable-row-actions{color:#777;font-size:12px}.edd-repeatable-row-actions a{text-decoration:none;width:auto;cursor:pointer;vertical-align:middle}.edd-repeatable-row-actions .toggle-custom-price-option-section{color:#777}.edd-repeatable-row-actions .toggle-custom-price-option-section:hover{color:#444}.edd-bundle-products-header,.edd-repeatable-row-header{clear:both;background:#f1f1f1;border:1px solid #e5e5e5}.edd-repeatable-row-header{cursor:move}.edd-bundled-product-row:after,.edd-bundled-product-row:before,.edd-repeatable-row-header:after,.edd-repeatable-row-header:before{content:'';display:table}.edd-bundled-product-row:after,.edd-repeatable-row-header:after{clear:both}.edd-repeatable-row-title{float:left;font-weight:600}.edd-bundled-product-item-reorder .edd-product-file-reorder{color:#e5e5e5;font-family:dashicons;content:"\f545";font-size:18px;font-weight:300;margin-left:4px;vertical-align:top;transition:.2s color}.edd-bundled-product-item-reorder .edd-product-file-reorder:hover{color:#bbb}.edd-repeatable-row-actions,.edd-repeatable-row-title{padding:8px;box-sizing:border-box}.edd-repeatable-row-actions{float:right;text-align:right;padding:8px}.edd-bundled-product-row .edd-remove-row,.edd-repeatable-row-actions .edd-remove-row{font-size:12px;width:auto;cursor:pointer}.edd-bundled-product-row,.edd-repeatable-row-standard-fields{background:#f9f9f9;padding:8px;border-width:0 1px 1px;border-style:solid;border-color:#e5e5e5}.edd-repeatable-row-setting-label{display:block;margin-bottom:4px}.edd-repeatable-row-setting-label .edd-help-tip{display:inline-block;margin-left:4px}.edd-bundled-product-row .edd-bundled-product-actions,.edd-bundled-product-row .edd-bundled-product-item,.edd-bundled-product-row .edd-bundled-product-item-reorder,.edd-bundled-product-row .edd-bundled-product-price-assignment,.edd-file-assignment,.edd-file-name,.edd-file-url,.edd-option-name,.edd-option-price,.edd_repeatable_default{display:inline-block;vertical-align:top}.edd-option-name{width:38%;margin-right:5%}.edd-option-price{min-width:100px}.edd_repeatable_default{text-align:center;min-width:80px}.edd-file-name{width:18%;margin-right:3%}.edd-file-url{width:65%}.edd-repeatable-row-standard-fields.has-variable-pricing .edd-file-url{width:38%;margin-right:5%}.edd-file-assignment{width:27%}.edd-file-assignment .edd-repeatable-row-setting-label{margin-bottom:0}.edd-custom-price-option-sections-wrap{display:none;border-width:0 1px 1px;border-style:solid;border-color:#e5e5e5;box-sizing:border-box;width:100%}.edd-custom-price-option-section{display:block;padding:10px 8px;border-bottom:1px solid rgba(222,222,222,.3)}.edd-custom-price-option-section:last-child{border-bottom:none}label.edd_prices_shipping{display:none!important}.edd-custom-price-option-section-title{display:block;font-size:14px;font-weight:600;padding:0 0 10px}.edd-custom-price-option-section>:not(.edd-custom-price-option-section-title){display:inline-block;padding-right:20px;vertical-align:top;margin-bottom:4px}.edd-custom-price-option-section>:not(.edd-custom-price-option-section-title) label{display:block;margin-bottom:2px}.edd-bundle-products-header{font-weight:600;padding:8px}.edd-bundled-product-row .edd-bundled-product-item-reorder{min-width:30px;margin-right:8px}.edd-bundled-product-row .edd-bundled-product-item-reorder .edd-product-file-reorder{font-size:20px;font-weight:300;padding:16px 4px 0;cursor:move}.edd-bundled-product-row .edd-bundled-product-item{width:60%;margin-right:3%}.edd-bundled-product-row.has-variable-pricing .edd-bundled-product-item{width:47%}.edd-bundled-product-row .edd-bundled-product-price-assignment{width:23%;margin-right:3%}.edd-bundled-product-row .edd-bundled-product-actions{float:right}.edd_repeatable_upload_wrapper .edd_repeatable_upload_field_container{position:relative}.edd_upload_file{background:#fff;display:block;padding:2px 8px 2px;position:absolute;top:3px;right:7px}.edd_upload_field{padding-right:8em}textarea#edd-payment-note{width:100%;height:4em;margin:0}#edd-purchased-files .row .edd-purchased-files-list-wrapper .download{line-height:1.4}#edd-purchased-files .edd-purchased-files-list-wrapper .edd-purchased-option{color:#666}input[class*=edd-price-field]{padding:3px 5px;width:75px}#edd-order-download-quantity[type=number].small-text,#edd-order-download-tax[type=text].small-text,[class*=item_] [class*=edd-payment-details-download-][type=number].small-text{height:25px}#edd-order-download-quantity[type=number].small-text,.item_price .edd-payment-details-download-quantity[type=number].small-text{width:55px}#edd-order-download-tax[type=text].small-text,.item_tax .edd-payment-details-download-item-tax[type=number].small-text{width:75px}.edd_repeatable_product_wrapper .edd-select,.edd_repeatable_upload_wrapper .pricing select{min-width:100%}#edd_product_notes_field{display:block;margin:12px 0 0;height:4em;width:100%}.edd_remove_repeatable{border:none;cursor:pointer;display:inline-block;padding:0;overflow:hidden;margin:8px 0 0 0;text-indent:-9999px;width:10px;height:10px}.edd_remove_repeatable:active,.edd_remove_repeatable:focus,.edd_remove_repeatable:hover{background-position:-10px 0!important}#edd-edit-order-form .column{width:32%}.edd-edit-purchase-element[class*=columns-] ul li{padding-right:1%}#edd-edit-order-form .column:nth-child(2n+1),#edd-edit-order-form .columns-4 .column:nth-child(2n+1),#edd-edit-order-form .columns-5 .column:nth-child(3n+1){margin-right:0}#edd-edit-order-form input.large-text{width:90%}.edd-edit-purchase-element ul li.download{width:35%}.edd-edit-purchase-element ul li.item_price{width:15%}.edd-edit-purchase-element ul li.item_price.item_quantity{width:25%}.edd-edit-purchase-element ul li.item_tax{width:15%}.edd-edit-purchase-element ul li.price{width:20%}.edd-admin-box .label{font-weight:600}.edd-admin-box-inside{border-bottom:1px solid #eee;clear:both;padding:3px 12px;margin:0;word-break:break-word}.rtl .edd-admin-box-inside{padding:5px 10px 5px 0}.edd-admin-box-inside .strong{font-weight:600}.edd-payment-fees .fee-label{color:#666;font-weight:400}.edd-admin-box .right{float:right}.rtl .edd-admin-box .right{float:left;margin-left:10px}#edd-order-details .inside,#edd-order-update .inside{margin:0;padding:0}#edd-order-update input.edd_datepicker{width:180px}#edd-order-update input[type=number].edd-payment-time-hour,#edd-order-update input[type=number].edd-payment-time-min{width:50px}#edd-order-update .edd-tax-rate{color:#9c9c9c;font-style:italic}#edd-order-resend-receipt .inside{margin-top:11px}#edd-order-resend-receipt .edd-order-resend-receipt-addresses{margin-top:10px}.edd-admin-box-inside:last-child{border-bottom:0}#edd-edit-order-form .data-payment-key{word-break:break-all}.edd-order-update-box #major-publishing-actions .button-secondary{margin-right:10px}.edd-edit-purchase-element .edd-select-chosen{width:196px}#edd-customer-details .order-data-address input,#edd-customer-details .order-data-column p.data input,#edd-edit-order-form .column input,#edd-order-address-country-wrap select,.edd-edit-purchase-element ul{clear:both;display:block}#edd-customer-details .customer-info .column{width:49%}#edd-customer-details .actions{float:right}.edd-order-data input.small-text{margin:0}.edd-order-data input.med-text{margin:0;width:100px}#edd-order-update span.label{display:inline;width:50px}.edd-order-update-box .button-primary{margin-right:0}#edd-edit-order-form .column .description{padding-right:10px}#edd-edit-order-form .column,.edd-edit-purchase-element ul li{display:inline-block;line-height:1.4;position:relative;margin:0;vertical-align:middle}.edd-edit-purchase-element .row{padding:12px}.edd-edit-purchase-element .row:not(:last-child){border-bottom:1px solid #eee}.edd-edit-purchase-element .row:nth-child(odd):not(.header){background-color:#f9f9f9}.edd-edit-purchase-element .row.header{padding:6px 12px;font-weight:600;vertical-align:top}.edd-edit-purchase-element ul{font-size:0}.edd-edit-purchase-element ul li{font-size:13px}#edd-order-data .data span{color:#666;font-weight:600}.edd-edit-purchase-element .inside{padding:12px}.edd-edit-purchase-element .edd-purchased-download-title{font-size:14px;font-weight:500}.edd-edit-purchase-element .edd-purchased-download-title .deleted{color:#777}.edd-edit-purchase-element .edd-purchased-download-actions{color:#777;line-height:1.4}.edd-edit-purchase-element .edd-purchased-download-actions .edd-purchased-download-actions-label{font-weight:500}.edd-edit-purchase-element .edd-purchased-download-actions a{color:#777;font-size:12px}.edd-edit-purchase-element .edd-purchased-download-actions a:hover{color:#444}.edd-edit-purchase-element .edd-purchased-download-actions .edd-order-remove-download{color:#a00}.edd-edit-purchase-element .edd-purchased-download-actions .edd-order-remove-download:hover{color:red}#edd-order-recalc-total{float:right}#edd_products .edd-select,.edd_repeatable_product_wrapper .edd-select,.edd_repeatable_upload_wrapper .pricing select{min-width:100%;max-width:200px}.edd_repeatable_product_wrapper td{overflow:visible}.edd-payment-details-label-mobile{display:none}@media screen and (max-width:1284px){.edd-edit-purchase-element ul li.download{padding-bottom:15px;width:100%}.edd-edit-purchase-element .edd-purchased-download-title{font-size:16px}.edd-edit-purchase-element ul li.item_price{width:22%}.edd-edit-purchase-element ul li.item_price.item_quantity{width:35%}.edd-edit-purchase-element ul li.item_tax{width:25%}.edd-edit-purchase-element ul li.price{width:20%}.edd-edit-purchase-element .edd-purchased-download-actions{padding-top:10px}.edd-add-download-to-purchase-header,.edd-purchased-files-header{display:none}.edd-payment-details-label-mobile{display:block;font-weight:500;padding-bottom:6px}}@media screen and (max-width:1024px){.edd-edit-purchase-element ul li.item_price.item_quantity{width:40%}.edd-edit-purchase-element ul li.price{width:24%}.edd-edit-purchase-element .edd-purchased-download-actions{padding-top:15px}.edd-edit-purchase-element .edd-purchased-download-actions,.edd-edit-purchase-element .edd-purchased-download-actions a{font-size:14px}}@media screen and (max-width:782px){#edd-edit-order-form .column{width:49%}.edd-edit-purchase-element ul li.item_price,.edd-edit-purchase-element ul li.item_price.item_quantity{padding-bottom:10px}.edd-edit-purchase-element ul li.item_price.item_quantity{width:35%}.edd-edit-purchase-element ul li.item_tax,.edd-edit-purchase-element ul li.price{width:20%;padding-bottom:10px}.edd-payment-details-label-mobile{font-size:14px;font-weight:500}.edd-payment-details-download-amount,.edd-price-currency{font-size:16px}.order-data-column input[type=email]{padding:6px 10px}}@media screen and (max-width:600px){.edd-edit-purchase-element ul li.item_price,.edd-edit-purchase-element ul li.item_price.item_quantity,.edd-edit-purchase-element ul li.item_tax{width:100%;padding-bottom:20px}.edd-edit-purchase-element .edd-add-download-to-purchase ul li.item_tax,.edd-edit-purchase-element ul li.price{width:100%;padding-bottom:0}.edd-edit-purchase-element .edd-add-download-to-purchase-actions{padding-top:15px}#edd-edit-order-form .column{width:100%}}#edd_product_stats .label{display:inline-block}#edd_product_stats hr{border-style:solid;border-width:1px;border-color:#ccc #fff #fff #ccc}#edd_product_stats .product-earnings-stats:before,#edd_product_stats .product-sales-stats:before{color:#82878c;font:normal 20px/1 dashicons;display:inline-block;padding:0 2px 0 0;position:relative;top:0;left:-1px;speak:none;text-decoration:none!important;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#edd_product_stats .product-sales-stats:before{content:'\f174'}#edd_product_stats .product-earnings-stats:before{content:'\f239'}.edd_dashboard_widget table thead td{border-bottom:1px solid #ececec;color:#777}.edd_dashboard_widget .table_left{float:left;width:45%}.edd_dashboard_widget .table_right{float:right;width:45%}.edd_dashboard_widget .inside{font-size:12px}.edd_dashboard_widget td{padding:3px 0}.edd_dashboard_widget .b,.edd_dashboard_widget .t{line-height:1.5;vertical-align:middle}.edd_dashboard_widget .b{font-size:14px;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;padding-right:6px;width:auto}.edd_dashboard_widget .t{font-size:12px;padding-right:12px;color:#777;width:100%}.edd_dashboard_widget .label_heading{border-top:1px solid #ececec;color:#8f8f8f;font-family:Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;display:block;padding-top:10px;margin:0 0 8px 12px}.edd_dashboard_widget .edd_dashboard_widget_subheading{border-top:1px solid #ececec;color:#8f8f8f;font-size:14px;padding-top:10px;margin:1em 0 0 0}.edd_dashboard_widget .edd_dashboard_widget_subheading+.table{margin:8px 0 0 0}.edd_dashboard_widget .edd_price_label{background:#00769c;border-radius:3px;color:#fff;font-size:10px;padding:2px 4px;margin-right:2px}.edd_dashboard_widget table{width:100%;margin-left:0;margin-bottom:1em}td.edd_order_label{width:80%}td.edd_order_price{text-align:right}@media handheld,only screen and (max-width:1000px){.edd_dashboard_widget .edd-recent-email{display:none}}#edd-dashboard-widgets-wrap .postbox h3{cursor:default}#edd-date-range-options,#edd-graphs-date-options{float:left}#edd-date-range-options span{float:left;line-height:24px;height:24px;margin-right:6px}.edd-import-export-form{position:relative}.edd-import-export-form .edd-progress{background:#ddd;position:absolute;bottom:15px;width:95%;height:15px}.edd-import-export-form .edd-progress div{background:#ccc;height:100%;width:0}.edd-import-export-form .notice-wrap{background-color:#f4f4f4;border-style:solid;border-width:1px 0;border-color:#eae9e9;padding:12px 12px 4px;overflow:auto;margin:20px -12px -23px;position:relative;width:100%}.edd-import-export-form .notice-wrap .spinner{margin:4px 10px 8px;float:right}.admin-color-fresh .edd-import-export-form .edd-progress div{background:#0073aa}.admin-color-light .edd-import-export-form .edd-progress div{background:#888}.admin-color-blue .edd-import-export-form .edd-progress div{background:#096484}.admin-color-coffee .edd-import-export-form .edd-progress div{background:#c7a589}.admin-color-ectoplasm .edd-import-export-form .edd-progress div{background:#a3b745}.admin-color-midnight .edd-import-export-form .edd-progress div{background:#e14d43}.admin-color-sunrise .edd-import-export-form .edd-progress div{background:#dd823b}#edd-graphs-filter label{vertical-align:inherit}#edd-graphs-filter .graph-option-section{float:left;line-height:2.5em;padding-right:5px}.edd-mix-totals{background-color:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);padding:10px}.edd-mix-chart{display:inline-block;width:49%;vertical-align:top}.edd-graph-notes{color:#9c9c9c}.edd-graph-notes span{display:block}.edd-pie-graph .legend{display:none}.edd-pie-legend{overflow:auto;margin-top:10px}.edd-legend-item-wrapper{color:#333;display:inline-block;font-size:8pt;padding:2px 5px 0 5px;width:48%;height:20px}.edd-legend-color{border:1px solid #cfcfcf;display:inline-block;margin-right:5px;width:20px;height:15px}.edd-pie-legend-item{display:inline-block;vertical-align:top;width:80%}[id*=edd-jilt-].button,[id*=edd-sendwp-].button{font-size:16px;height:auto;padding:8px 14px;margin:6px 0 0}[id*=edd-jilt-].button .dashicons,[id*=edd-sendwp-].button .dashicons{line-height:29px;margin-right:8px}[id*=edd-jilt-].button .edd-loading,[id*=edd-jilt-].button .edd-loading:after,[id*=edd-sendwp-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading:after{border-radius:50%;display:inline-block;width:14px;height:14px}[id*=edd-jilt-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading{position:relative;top:3px;margin-left:4px;box-shadow:0 0 2px rgba(0,0,0,.2)}[id*=edd-jilt-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading{-webkit-animation:edd-spinning 1.1s infinite linear;animation:edd-spinning 1.1s infinite linear;border-top:2px solid rgba(255,255,255,.5);border-right:2px solid rgba(255,255,255,.5);border-bottom:2px solid rgba(255,255,255,.5);border-left:2px solid #fff;font-size:14px;-ms-transform:translateZ(0);transform:translateZ(0)}#edd-jilt-disconnect.button .edd-loading.dark,#edd-sendwp-disconnect.button .edd-loading.dark{border-top-color:rgba(0,0,0,.2);border-right-color:rgba(0,0,0,.2);border-bottom-color:rgba(0,0,0,.2);border-left-color:#666;box-shadow:none}.jilt-notice{position:relative}@-webkit-keyframes edd-spinning{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes edd-spinning{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#edd_tax_rates{margin:1em 0 0}#edd_tax_rates .edd_tax_country *,#edd_tax_rates .edd_tax_state *{max-width:100%}#edd_tax_rates .edd_tax_country,#edd_tax_rates .edd_tax_state{width:180px}#edd_tax_rates .edd_tax_rate{width:80px}#edd_tax_rates th{padding:15px 10px}.wrap-licenses .form-table,.wrap-licenses caption,.wrap-licenses tbody,.wrap-licenses td,.wrap-licenses tfoot,.wrap-licenses th,.wrap-licenses thead,.wrap-licenses tr{display:block}.wrap-licenses .form-table tr{float:left;margin:0 15px 15px 0;background:#fff;border:1px solid #ccc;width:30.5%;max-width:350px;padding:14px;min-height:220px;position:relative;box-sizing:border-box}.wrap-licenses .form-table th{background:#f9f9f9;padding:14px;border-bottom:1px solid #ccc;margin:-14px -14px 20px;width:100%}.wrap-licenses .form-table td{padding:0}.wrap-licenses td input.regular-text{margin:0 0 8px;width:100%}.wrap-licenses .edd-license-data[class*=edd-license-]{position:absolute;background:#fafafa;padding:14px;border-top:1px solid #eee;margin:20px -14px -14px;min-height:67px;width:100%;bottom:14px;box-sizing:border-box}.wrap-licenses .edd-license-data[class*=edd-license-] a{color:#444}.wrap-licenses .edd-license-data[class*=edd-license-] a:hover{text-decoration:none}.wrap-licenses .edd-license-data.license-expires-soon-notice{background-color:#00a0d2;color:#fff;border-color:#00a0d2}.wrap-licenses .edd-license-data.edd-license-expired{background-color:#e24e4e;color:#fff;border-color:#e24e4e}.wrap-licenses .edd-license-data.edd-license-error,.wrap-licenses .edd-license-data.edd-license-invalid,.wrap-licenses .edd-license-data.edd-license-item_name_mismatch,.wrap-licenses .edd-license-data.edd-license-missing,.wrap-licenses .edd-license-data.edd-license-site_inactive{background-color:#ffebcd;border-color:#ffebcd}.wrap-licenses .edd-license-data p{font-size:13px;margin-top:0}.wrap-licenses .edd-license-data.edd-license-expired a,.wrap-licenses .edd-license-data.license-expires-soon-notice a{color:#fff}.wrap-licenses .edd-license-data.edd-license-expired a:hover,.wrap-licenses .edd-license-data.license-expires-soon-notice a:hover{text-decoration:none}.wrap-licenses p.submit{clear:both}#system-info-textarea{background:0 0;font-family:Menlo,Monaco,monospace;display:block;overflow:auto;white-space:pre;width:800px;height:400px}#TB_window #edd-add-download:active,#TB_window #edd-add-download:focus,#TB_window #edd-add-download:hover{color:#fff}.edd-graph .y1Axis{color:#edc240!important}.edd-graph .y2Axis{color:#afd8f8!important}.download_page_edd-tools .apikeys .column-user{width:192px}.edd-select-chosen{width:100%;max-width:300px}.chosen-container-multi .chosen-choices{background-image:none;border-color:#dfdfdf;-webkit-border-radius:3px;border-radius:3px}.chosen-container-multi .chosen-choices input{border-color:#dfdfdf;height:27px!important;margin:2px}.chosen-container .chosen-drop{border-color:#aaa;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,.1);box-shadow:1px 1px 2px rgba(0,0,0,.1)}.chosen-container .search-field{float:none!important}.chosen-container .search-field input{width:90%!important}.chosen-container-active .chosen-choices{border-color:#aaa;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,.1);box-shadow:1px 1px 2px rgba(0,0,0,.1)}.download_page_edd-tools .tablenav .actions{overflow:visible}.edd_user_search_wrap{position:relative;overflow:visible}.edd_user_search_results{position:absolute;left:0;top:27px}.edd_user_search_results a.edd-ajax-user-cancel{position:absolute;right:6px;top:2px}.edd_user_search_results ul{background:#f0f0f0;border:1px solid #dfdfdf;overflow-y:scroll;padding:10px 10px 4px;margin:0;max-height:200px;width:300px}.wp-list-table .type-download .row-actions{color:#999}@media screen and (max-width:1100px){.edd-mix-chart{display:block;width:100%}.wrap-licenses .form-table tr{width:46%;max-width:none;min-height:230px}}@media screen and (max-width:782px){.post-type-download .nav-tab-wrapper a{font-size:70%;padding:2px 4px}.download_page_edd-tools .apikeys .column-user{width:80px}.license-expiration-date-notice,.license-lifetime-notice,.license-null{padding-left:0}[class^=license-] input[type=text]{margin-bottom:3px}}@media screen and (max-width:600px){.wrap-licenses .form-table tr{width:100%;min-height:230px}#edd-edit-order-form input.large-text{width:100%}}#edd-item-wrapper{background:#f5f5f5;border:1px solid #e5e5e5;webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);box-shadow:0 1px 1px rgba(0,0,0,.04);max-width:830px}#edd-item-wrapper:after{content:"";display:block;clear:both;visibility:hidden;font-size:0;height:0}#edd-item-tab-wrapper{float:left;width:18%;z-index:1}#edd-item-tab-wrapper-list{background:#fff;margin:0}#edd-item-tab-wrapper-list li{display:block;background-color:#eaeaea;color:#444;font-size:12px;border-bottom:1px solid #e5e5e5;margin-bottom:0;-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto;word-wrap:break-word}#edd-item-tab-wrapper-list li a{display:block;padding:8px 10px 8px 6px}#edd-item-tab-wrapper-list li.active{display:block;background-color:#fff;padding:8px 10px 8px 6px}#edd-item-tab-wrapper-list .inactive a,#edd-item-tab-wrapper-list .inactive a:visited{background-color:#f5f5f5;color:#444;text-decoration:none}#edd-item-tab-wrapper-list .inactive a:hover{background-color:#fff}#edd-item-tab-wrapper-list .dashicons{color:#444;font-size:16px;min-width:24px;height:auto}#edd-item-card-wrapper .left{float:left}#edd-item-card-wrapper .right{float:right}#edd-item-card-wrapper input{font-weight:400}#edd-item-card-wrapper{background-color:#fff;border:1px solid #e5e5e5;display:inline-block;margin-left:-1px;min-height:200px;width:700px;z-index:2}.edd-item-has-tabs #edd-item-card-wrapper{border-width:0 0 0 1px;width:82%}#edd-item-card-wrapper .customer-section{border-bottom:1px solid #eee;margin-bottom:10px;overflow:auto}#edd-item-card-wrapper .customer-section table{margin-bottom:20px}#edd-item-card-wrapper>div{padding:0 20px}#edd-item-card-wrapper>div:first-child{padding-top:20px}#edd-item-card-wrapper>div:last-child{border:none;padding-bottom:20px}#edd-item-card-wrapper .avatar-wrap{padding-right:10px;text-align:center}#edd-item-card-wrapper .customer-id{font-size:24px;font-weight:600}#edd-item-card-wrapper .customer-main-wrapper input{width:200px}#edd-item-card-wrapper .customer-address-wrapper{margin-right:25px;max-width:33%;width:202px}#edd-item-card-wrapper .customer-address-wrapper select{width:200px}#edd-item-card-wrapper .customer-info{margin-top:5px;margin-bottom:10px;min-height:185px}#edd-item-card-wrapper .info-wrapper{min-height:125px;overflow:visible}#edd-item-card-wrapper a.delete{color:red;margin-right:5px;text-decoration:none}.customer-info .customer-name{font-size:24px;font-weight:600}.customer-edit-link a,.disconnect-user a{font-size:12px;font-weight:400;text-decoration:none}#customer-edit-actions{line-height:28px;margin-bottom:20px;text-align:center}#customer-edit-actions .button-secondary{margin-right:10px}#edd-item-card-wrapper .row-title{width:30%}#edd-item-card-wrapper .info-item{display:block;line-height:16px;padding-bottom:5px}#edd-item-card-wrapper .edit-item{display:none}#edd-item-card-wrapper .edd_user_search_results{left:1px;top:16px}#edd-item-card-wrapper .edd_user_search_results ul{width:200px}#edd-item-stats-wrapper{margin:0 auto;min-height:30px;text-align:center}#edd-item-stats-wrapper li{font-size:14px;float:left;line-height:22px;width:50%}#edd-item-stats-wrapper a{text-decoration:none}#edd-item-stats-wrapper .dashicons{color:#888}#edd-item-tables-wrapper table{text-align:center;width:100%}#edd-item-tables-wrapper th{text-align:center}#edd-item-tables-wrapper .downloads tr>td:first-child,#edd-item-tables-wrapper .downloads tr>th:first-child,#edd-item-tables-wrapper .emails tr>td:first-child,#edd-item-tables-wrapper .emails tr>th:first-child{text-align:left}#edd-item-tables-wrapper .downloads tr>td:only-child{text-align:center}#edd-item-tables-wrapper .emails .add-customer-email-row td{background-color:#f9f9f9;border-top:1px solid #e5e5e5}#edd-item-tables-wrapper .emails .primary-email-icon{font-size:13px;vertical-align:middle;line-height:1.5em}#edd-item-tables-wrapper .emails input{vertical-align:middle;margin:6px 0}#edd-item-tables-wrapper .emails .spinner{float:none}#edd-item-notes-wrapper{min-height:50px}.edd-item-notes-header img,.edd-item-notes-header span{font-weight:600;line-height:30px;vertical-align:middle}.customer-note-input{margin-bottom:5px;width:100%}#edd-customer-notes div:nth-of-type(even){background-color:#fcfcfc}.customer-note-wrapper{border-bottom:1px solid #f9f9f9;min-height:38px;padding:7px 0 7px 7px}.customer-note-wrapper span{display:block}.note-content-wrap{padding-top:7px}.delete-customer{text-align:center}#edd-item-card-wrapper .notice-container{padding-left:20px;padding-right:20px;margin-left:-20px;margin-right:-20px}#edd-item-card-wrapper .add-customer-email-wrapper>#add-customer-email{vertical-align:middle}@media screen and (max-width:810px) and (min-width:656px){.customer-info .customer-name{font-size:16px}#edd-item-card-wrapper .widefat td,.widefat th{padding:4px 6px;max-width:100px!important;display:table-cell}}@media screen and (max-width:781px){#edd-item-card-wrapper,#edd-item-tab-wrapper{margin:0;width:100%}#edd-item-tab-wrapper-list{background:#fff;margin:0}#edd-item-tab-wrapper-list li{float:left;display:inline;font-size:14px;box-sizing:border-box;border-width:0 1px 1px 0;border-style:solid;border-color:#e5e5e5;width:33.33333%}#edd-item-tab-wrapper-list li:nth-child(3n+3){border-width:0 0 1px 0}#edd-item-tab-wrapper-list .dashicons{font-size:18px}.edd-item-has-tabs #edd-item-card-wrapper{border-top:1px solid #e5e5e5;border-left:0;margin-top:-1px;width:100%}}@media screen and (max-width:656px){#edd-item-card-wrapper .customer-info{min-height:220px}.edd-item-info.customer-info{position:relative}#edd-item-card-wrapper .customer-address-wrapper{float:none;position:absolute;top:84px;left:110px;max-width:200px}#edd-item-card-wrapper .customer-main-wrapper{float:none;position:absolute;left:110px}.customer-info .customer-name{font-size:16px}#edd-item-card-wrapper #edd-item-stats-wrapper{padding-left:0;padding-right:0}#edd-item-card-wrapper .customer-section{margin-bottom:0}#edd-item-card-wrapper .widefat td,#edd-item-card-wrapper .widefat th{padding:4px 6px;max-width:100px!important;display:table-cell;overflow:hidden}#edd-item-card-wrapper .customer-id{font-size:16px}}@media screen and (max-width:480px){#edd-item-tab-wrapper-list li{width:50%}#edd-item-tab-wrapper-list li:nth-child(3n+3){border-width:0 1px 1px 0}#edd-item-tab-wrapper-list li:nth-child(even){border-width:0 0 1px 0}.edd-repeatable-row-actions,.edd-repeatable-row-title{text-align:left;width:100%}.edd-repeatable-row-title{padding-bottom:0}.edd-bundled-product-item-reorder,.edd-bundled-product-row .edd-bundled-product-item,.edd-bundled-product-row .edd-bundled-product-price-assignment,.edd-file-assignment,.edd-file-name,.edd-file-url,.edd-option-name,.edd-option-price,.edd_repeatable_default{float:none;text-align:left;width:100%!important;margin:10px 0}.edd-bundled-product-row .edd-bundled-product-actions{float:none}.edd-bundled-product-row .edd-bundled-product-item-reorder .edd-product-file-reorder{padding:0}#edd-payment-filters span{display:block;margin:2px 0}#edd-payment-filters a,.download_page_edd-reports .button{text-align:center}#edd-payment-date-filters span{display:block}#edd-payment-date-filters span>input{float:right}#edd-add-discount select[multiple] option,#edd-edit-discount select[multiple] option{height:20px}#edd-add-discount input[type=text],#edd-edit-discount input[type=text],#edd-payment-filters a,#edd-payment-filters input:not([type=radio]),#edd-payment-filters select,#system-info-textarea,.download_page_edd-reports .inside .button,.download_page_edd-reports .inside input[type=submit],.download_page_edd-reports .inside input[type=text],.download_page_edd-reports .inside select,.download_page_edd-settings .inside input[type=button],.download_page_edd-tools .inside input[type=submit],.download_page_edd-tools .inside input[type=text],.download_page_edd-tools .inside select{width:100%}#edd-add-discount select[multiple],#edd-edit-discount select[multiple],.download_page_edd-tools select[multiple]{height:200px!important}.download_page_edd-settings input[type=checkbox]{margin:2px 0}.post-type-download input[type=checkbox]{margin-left:2px}}.recount-stats-controls form{display:inline}.edd-recount-stats-descriptions span{display:none;line-height:24px}#edd-debug-log p.submit{margin:20px 0 0;padding:0}#edd-debug-log .edd-inline-button{margin-left:5px}.edd-settings-sidebar{padding-top:27px}.edd-settings-sidebar-content{background-color:#fff;text-align:center;border:1px solid #ddd;box-sizing:border-box;max-width:300px}.edd-settings-sidebar-content p{font-size:14px;line-height:1.5;margin-top:0}.edd-sidebar-header-section{background-color:#35495c;line-height:1;padding:26px 20px 24px;border-bottom:3px dashed #fafafa}.edd-sidebar-description-section{background-color:#fafafa;padding:16px 20px;border-bottom:1px solid #ddd}.edd-sidebar-description-section .edd-sidebar-description{margin:0}.edd-sidebar-coupon-section{font-size:14px;padding:16px 20px}.edd-sidebar-coupon-section label{display:block;line-height:1.4;margin-bottom:6px}.edd-sidebar-coupon-section label strong{color:#253b51;font-weight:700}.edd-sidebar-coupon-section input{background:#f4f7fa;font-size:22px;font-weight:600;text-align:center;padding:10px;border:2px dashed #2794da;border-radius:4px;margin-bottom:16px;box-shadow:none;width:100%}.edd-sidebar-coupon-section input:focus{border:2px dashed #2794da;box-shadow:none}.edd-settings-sidebar-content .edd-coupon-note{color:#6c7883;font-size:13px;font-style:italic;margin:0}.edd-settings-sidebar-content .edd-coupon-note a{color:#253b51}.edd-settings-sidebar-content .edd-coupon-note a:hover{text-decoration:none}.edd-sidebar-footer-section{background-color:#fafafa;padding:16px 20px;border-top:1px solid #ddd}.edd-sidebar-footer-section .edd-cta-button{display:block;background-color:#2794da;color:#fff;text-decoration:none;font-size:20px;font-weight:700;text-transform:uppercase;padding:17px 10px;border:none;border-radius:4px;width:100%;box-sizing:border-box;box-shadow:none;transition:background-color .2s}.edd-sidebar-footer-section .edd-cta-button:hover{background-color:#2386c5}@media all and (min-width:1080px){.edd-has-sidebar .edd-settings-content{float:left;width:67%}.edd-has-sidebar .edd-settings-sidebar{float:right;width:31%}}@media all and (min-width:1240px){.edd-has-sidebar .edd-settings-content{width:74%}.edd-has-sidebar .edd-settings-sidebar{width:23%}}.taxes-tab .edd-has-sidebar .edd-settings-content,.taxes-tab .edd-has-sidebar .edd-settings-sidebar{float:none;width:100%}.bfcm-promo-img-container{background-color:#35495c;width:100%;height:160px}.bfcm-code{color:#2794da;font-weight:700}.sale-ends{position:absolute;bottom:9px;right:14px;display:inline-block;color:#6c7883;font-size:12px;text-align:right;font-style:italic;width:150px}
1
+ .edd-hidden{display:none}.edd-clearfix:after{content:".";display:block;height:0;text-indent:-9999px;visibility:hidden}.edd-notice .notice-dismiss,.edd-wrap a{text-decoration:none}a.edd-delete{color:#a00}a.edd-delete:hover{color:red}.download_page_edd-settings .form-table label{color:#666;font-size:14px;font-style:italic;margin:4px 0 0}.download_page_edd-settings .form-table input.small-text~label,.download_page_edd-settings .form-table input[type=checkbox]+label{display:inline}.download_page_edd-settings .form-table tr>th>h3,.download_page_edd-settings .form-table tr>th>strong{font-size:1.2em;font-weight:600;margin:0 auto}.edd-help-tip{cursor:help}.edd-ui-tooltip{position:absolute;background:#333!important;border-width:1px!important;border-radius:3px!important;box-shadow:1px 1px 2px 1px rgba(214,214,214,.5)!important;color:#dedede!important;max-width:300px!important;padding:7px!important;text-rendering:optimizeLegibility;text-shadow:none!important;z-index:9999!important}.download_page_edd-settings .edd-settings-payment-icon-wrapper{margin-right:10px;line-height:16px;height:16px;display:table}#edd-add-ons h2.nav-tab-wrapper{position:relative}.edd-tab-span{top:-6px;right:0;position:absolute}.edd-add-ons-footer{padding-top:10px}#edd-add-ons h2{margin:0 0 15px}.edd-add-ons-view-wrapper{height:50px}#edd-add-ons h2 .button-primary{position:absolute}#edd-add-ons .edd-extension{background:#fff;border:1px solid #ccc;float:left;padding:14px;position:relative;margin:0 15px 15px 0;width:320px;height:315px}#edd-add-ons .edd-extension h3{font-size:13px;margin:0 0 8px}#edd-add-ons .edd-extension .button-secondary{position:absolute;bottom:14px;left:14px}#edd-add-ons .edd-browse-all{clear:both;width:100%}#edd-add-ons .edd-extension .third-party{display:none}#edd-add-ons .edd-starter-package{background-color:#85c0e5;border-color:#62a9d7;color:#fff}#edd-add-ons .edd-starter-package h3{color:#fff}#edd-add-ons .edd-extension .wp-post-image{width:100%;height:auto;vertical-align:bottom}#edd-products{height:100px;min-width:200px}#edd-add-discount input[type=text],#edd-edit-discount input[type=text]{width:300px}#edd-add-discount input.edd-price-field,#edd-edit-discount input.edd-price-field{padding:3px 5px;width:75px}.download_page_edd-addons .wrap .wp-heading-inline,.edit-php.post-type-download .wrap .wp-heading-inline{display:none}.download_page_edd-addons .wrap>.page-title-action,.edit-php.post-type-download .wrap>.page-title-action{display:none}.download_page_edd-addons .wrap .nav-tab-wrapper .page-title-action,.edit-php.post-type-download .wrap .nav-tab-wrapper .page-title-action{top:7px;margin-left:5px}#edd-payment-filters{background:#f5f5f5;clear:both;background-image:-webkit-gradient(linear,left bottom,left top,from(#f5f5f5),to(#fafafa));background-image:-webkit-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:-moz-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:-o-linear-gradient(bottom,#f5f5f5,#fafafa);background-image:linear-gradient(to top,#f5f5f5,#fafafa);border-color:#dfdfdf;border-width:1px;border-style:solid;border-radius:3px;font-size:13px;line-height:2.1em;overflow:auto;padding:12px;margin:8px 0}#edd-payments-filter ul.subsubsub{margin-bottom:8px}#edd-payment-filters p{color:#777}#edd-payment-date-filters input{vertical-align:middle}tr.status-refunded td{background:#cecece;border-top-color:#ccc}.wp-list-table.downloads th#ID{width:80px}.wp-list-table.downloads th#details{width:130px}.wp-list-table.downloads th#date{width:140px}.wp-list-table.downloads th#user{width:130px}.edd-mobile-link{line-height:32px;vertical-align:middle}.edd-mobile-link img{max-width:80%;height:auto;float:left}@media handheld,only screen and (max-width:640px){.wp-list-table.downloads th{width:auto!important}}.download_page_edd-payment-history .ui-dialog .ui-dialog-titlebar-close span{margin-left:-8px;margin-top:-8px}#edd-download-link-textarea{width:100%}.edd_files_name_label{width:225px;float:left}.edd_files_url_label{width:220px;float:left}#postbox-container-1 .edd_files_name_label{width:80px}#postbox-container-1 .edd_files_url_label{width:80px}.edd-add-repeatable-row{margin:10px 0}.edd-add-repeatable-row .submit{padding:0!important}.edd_repeatable_upload_wrapper:not(:first-child),.edd_variable_prices_wrapper:not(:first-child){margin-top:12px}.edd-repeatable-row-actions{color:#777;font-size:12px}.edd-repeatable-row-actions a{text-decoration:none;width:auto;cursor:pointer;vertical-align:middle}.edd-repeatable-row-actions .toggle-custom-price-option-section{color:#777}.edd-repeatable-row-actions .toggle-custom-price-option-section:hover{color:#444}.edd-bundle-products-header,.edd-repeatable-row-header{clear:both;background:#f1f1f1;border:1px solid #e5e5e5}.edd-repeatable-row-header{cursor:move}.edd-bundled-product-row:after,.edd-bundled-product-row:before,.edd-repeatable-row-header:after,.edd-repeatable-row-header:before{content:'';display:table}.edd-bundled-product-row:after,.edd-repeatable-row-header:after{clear:both}.edd-repeatable-row-title{float:left;font-weight:600}.edd-bundled-product-item-reorder .edd-product-file-reorder{color:#e5e5e5;font-family:dashicons;content:"\f545";font-size:18px;font-weight:300;margin-left:4px;vertical-align:top;transition:.2s color}.edd-bundled-product-item-reorder .edd-product-file-reorder:hover{color:#bbb}.edd-repeatable-row-actions,.edd-repeatable-row-title{padding:8px;box-sizing:border-box}.edd-repeatable-row-actions{float:right;text-align:right;padding:8px}.edd-bundled-product-row .edd-remove-row,.edd-repeatable-row-actions .edd-remove-row{font-size:12px;width:auto;cursor:pointer}.edd-bundled-product-row,.edd-repeatable-row-standard-fields{background:#f9f9f9;padding:8px;border-width:0 1px 1px;border-style:solid;border-color:#e5e5e5}.edd-repeatable-row-setting-label{display:block;margin-bottom:4px}.edd-repeatable-row-setting-label .edd-help-tip{display:inline-block;margin-left:4px}.edd-bundled-product-row .edd-bundled-product-actions,.edd-bundled-product-row .edd-bundled-product-item,.edd-bundled-product-row .edd-bundled-product-item-reorder,.edd-bundled-product-row .edd-bundled-product-price-assignment,.edd-file-assignment,.edd-file-name,.edd-file-url,.edd-option-name,.edd-option-price,.edd_repeatable_default{display:inline-block;vertical-align:top}.edd-option-name{width:38%;margin-right:5%}.edd-option-price{min-width:100px}.edd_repeatable_default{text-align:center;min-width:80px}.edd-file-name{width:18%;margin-right:3%}.edd-file-url{width:65%}.edd-repeatable-row-standard-fields.has-variable-pricing .edd-file-url{width:38%;margin-right:5%}.edd-file-assignment{width:27%}.edd-file-assignment .edd-repeatable-row-setting-label{margin-bottom:0}.edd-custom-price-option-sections-wrap{display:none;border-width:0 1px 1px;border-style:solid;border-color:#e5e5e5;box-sizing:border-box;width:100%}.edd-custom-price-option-section{display:block;padding:10px 8px;border-bottom:1px solid rgba(222,222,222,.3)}.edd-custom-price-option-section:last-child{border-bottom:none}label.edd_prices_shipping{display:none!important}.edd-custom-price-option-section-title{display:block;font-size:14px;font-weight:600;padding:0 0 10px}.edd-custom-price-option-section>:not(.edd-custom-price-option-section-title){display:inline-block;padding-right:20px;vertical-align:top;margin-bottom:4px}.edd-custom-price-option-section>:not(.edd-custom-price-option-section-title) label{display:block;margin-bottom:2px}.edd-bundle-products-header{font-weight:600;padding:8px}.edd-bundled-product-row .edd-bundled-product-item-reorder{min-width:30px;margin-right:8px}.edd-bundled-product-row .edd-bundled-product-item-reorder .edd-product-file-reorder{font-size:20px;font-weight:300;padding:16px 4px 0;cursor:move}.edd-bundled-product-row .edd-bundled-product-item{width:60%;margin-right:3%}.edd-bundled-product-row.has-variable-pricing .edd-bundled-product-item{width:47%}.edd-bundled-product-row .edd-bundled-product-price-assignment{width:23%;margin-right:3%}.edd-bundled-product-row .edd-bundled-product-actions{float:right}.edd_repeatable_upload_wrapper .edd_repeatable_upload_field_container{position:relative}.edd_upload_file{background:#fff;display:block;padding:2px 8px 2px;position:absolute;top:3px;right:7px}.edd_upload_field{padding-right:8em}textarea#edd-payment-note{width:100%;height:4em;margin:0}#edd-purchased-files .row .edd-purchased-files-list-wrapper .download{line-height:1.4}#edd-purchased-files .edd-purchased-files-list-wrapper .edd-purchased-option{color:#666}input[class*=edd-price-field]{padding:3px 5px;width:75px}#edd-order-download-quantity[type=number].small-text,#edd-order-download-tax[type=text].small-text,[class*=item_] [class*=edd-payment-details-download-][type=number].small-text{height:25px}#edd-order-download-quantity[type=number].small-text,.item_price .edd-payment-details-download-quantity[type=number].small-text{width:55px}#edd-order-download-tax[type=text].small-text,.item_tax .edd-payment-details-download-item-tax[type=number].small-text{width:75px}.edd_repeatable_product_wrapper .edd-select,.edd_repeatable_upload_wrapper .pricing select{min-width:100%}#edd_product_notes_field{display:block;margin:12px 0 0;height:4em;width:100%}.edd_remove_repeatable{border:none;cursor:pointer;display:inline-block;padding:0;overflow:hidden;margin:8px 0 0 0;text-indent:-9999px;width:10px;height:10px}.edd_remove_repeatable:active,.edd_remove_repeatable:focus,.edd_remove_repeatable:hover{background-position:-10px 0!important}#edd-edit-order-form .column{width:32%}.edd-edit-purchase-element[class*=columns-] ul li{padding-right:1%}#edd-edit-order-form .column:nth-child(2n+1),#edd-edit-order-form .columns-4 .column:nth-child(2n+1),#edd-edit-order-form .columns-5 .column:nth-child(3n+1){margin-right:0}#edd-edit-order-form input.large-text{width:90%}.edd-edit-purchase-element ul li.download{width:35%}.edd-edit-purchase-element ul li.item_price{width:15%}.edd-edit-purchase-element ul li.item_price.item_quantity{width:25%}.edd-edit-purchase-element ul li.item_tax{width:15%}.edd-edit-purchase-element ul li.price{width:20%}.edd-admin-box .label{font-weight:600}.edd-admin-box-inside{border-bottom:1px solid #eee;clear:both;padding:3px 12px;margin:0;word-break:break-word}.rtl .edd-admin-box-inside{padding:5px 10px 5px 0}.edd-admin-box-inside .strong{font-weight:600}.edd-payment-fees .fee-label{color:#666;font-weight:400}.edd-admin-box .right{float:right}.rtl .edd-admin-box .right{float:left;margin-left:10px}#edd-order-details .inside,#edd-order-update .inside{margin:0;padding:0}#edd-order-update input.edd_datepicker{width:180px}#edd-order-update input[type=number].edd-payment-time-hour,#edd-order-update input[type=number].edd-payment-time-min{width:50px}#edd-order-update .edd-tax-rate{color:#9c9c9c;font-style:italic}#edd-order-resend-receipt .inside{margin-top:11px}#edd-order-resend-receipt .edd-order-resend-receipt-addresses{margin-top:10px}.edd-admin-box-inside:last-child{border-bottom:0}#edd-edit-order-form .data-payment-key{word-break:break-all}.edd-order-update-box #major-publishing-actions .button-secondary{margin-right:10px}.edd-edit-purchase-element .edd-select-chosen{width:196px}#edd-customer-details .order-data-address input,#edd-customer-details .order-data-column p.data input,#edd-edit-order-form .column input,#edd-order-address-country-wrap select,.edd-edit-purchase-element ul{clear:both;display:block}#edd-customer-details .customer-info .column{width:49%}#edd-customer-details .actions{float:right}.edd-order-data input.small-text{margin:0}.edd-order-data input.med-text{margin:0;width:100px}#edd-order-update span.label{display:inline;width:50px}.edd-order-update-box .button-primary{margin-right:0}#edd-edit-order-form .column .description{padding-right:10px}#edd-edit-order-form .column,.edd-edit-purchase-element ul li{display:inline-block;line-height:1.4;position:relative;margin:0;vertical-align:middle}.edd-edit-purchase-element .row{padding:12px}.edd-edit-purchase-element .row:not(:last-child){border-bottom:1px solid #eee}.edd-edit-purchase-element .row:nth-child(odd):not(.header){background-color:#f9f9f9}.edd-edit-purchase-element .row.header{padding:6px 12px;font-weight:600;vertical-align:top}.edd-edit-purchase-element ul{font-size:0}.edd-edit-purchase-element ul li{font-size:13px}#edd-order-data .data span{color:#666;font-weight:600}.edd-edit-purchase-element .inside{padding:12px}.edd-edit-purchase-element .edd-purchased-download-title{font-size:14px;font-weight:500}.edd-edit-purchase-element .edd-purchased-download-title .deleted{color:#777}.edd-edit-purchase-element .edd-purchased-download-actions{color:#777;line-height:1.4}.edd-edit-purchase-element .edd-purchased-download-actions .edd-purchased-download-actions-label{font-weight:500}.edd-edit-purchase-element .edd-purchased-download-actions a{color:#777;font-size:12px}.edd-edit-purchase-element .edd-purchased-download-actions a:hover{color:#444}.edd-edit-purchase-element .edd-purchased-download-actions .edd-order-remove-download{color:#a00}.edd-edit-purchase-element .edd-purchased-download-actions .edd-order-remove-download:hover{color:red}#edd-order-recalc-total{float:right}#edd_products .edd-select,.edd_repeatable_product_wrapper .edd-select,.edd_repeatable_upload_wrapper .pricing select{min-width:100%;max-width:200px}.edd_repeatable_product_wrapper td{overflow:visible}.edd-payment-details-label-mobile{display:none}@media screen and (max-width:1284px){.edd-edit-purchase-element ul li.download{padding-bottom:15px;width:100%}.edd-edit-purchase-element .edd-purchased-download-title{font-size:16px}.edd-edit-purchase-element ul li.item_price{width:22%}.edd-edit-purchase-element ul li.item_price.item_quantity{width:35%}.edd-edit-purchase-element ul li.item_tax{width:25%}.edd-edit-purchase-element ul li.price{width:20%}.edd-edit-purchase-element .edd-purchased-download-actions{padding-top:10px}.edd-add-download-to-purchase-header,.edd-purchased-files-header{display:none}.edd-payment-details-label-mobile{display:block;font-weight:500;padding-bottom:6px}}@media screen and (max-width:1024px){.edd-edit-purchase-element ul li.item_price.item_quantity{width:40%}.edd-edit-purchase-element ul li.price{width:24%}.edd-edit-purchase-element .edd-purchased-download-actions{padding-top:15px}.edd-edit-purchase-element .edd-purchased-download-actions,.edd-edit-purchase-element .edd-purchased-download-actions a{font-size:14px}}@media screen and (max-width:782px){#edd-edit-order-form .column{width:49%}.edd-edit-purchase-element ul li.item_price,.edd-edit-purchase-element ul li.item_price.item_quantity{padding-bottom:10px}.edd-edit-purchase-element ul li.item_price.item_quantity{width:35%}.edd-edit-purchase-element ul li.item_tax,.edd-edit-purchase-element ul li.price{width:20%;padding-bottom:10px}.edd-payment-details-label-mobile{font-size:14px;font-weight:500}.edd-payment-details-download-amount,.edd-price-currency{font-size:16px}.order-data-column input[type=email]{padding:6px 10px}}@media screen and (max-width:600px){.edd-edit-purchase-element ul li.item_price,.edd-edit-purchase-element ul li.item_price.item_quantity,.edd-edit-purchase-element ul li.item_tax{width:100%;padding-bottom:20px}.edd-edit-purchase-element .edd-add-download-to-purchase ul li.item_tax,.edd-edit-purchase-element ul li.price{width:100%;padding-bottom:0}.edd-edit-purchase-element .edd-add-download-to-purchase-actions{padding-top:15px}#edd-edit-order-form .column{width:100%}}#edd_product_stats .label{display:inline-block}#edd_product_stats hr{border-style:solid;border-width:1px;border-color:#ccc #fff #fff #ccc}#edd_product_stats .product-earnings-stats:before,#edd_product_stats .product-sales-stats:before{color:#82878c;font:normal 20px/1 dashicons;display:inline-block;padding:0 2px 0 0;position:relative;top:0;left:-1px;speak:none;text-decoration:none!important;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#edd_product_stats .product-sales-stats:before{content:'\f174'}#edd_product_stats .product-earnings-stats:before{content:'\f239'}.edd_dashboard_widget table thead td{border-bottom:1px solid #ececec;color:#777}.edd_dashboard_widget .table_left{float:left;width:45%}.edd_dashboard_widget .table_right{float:right;width:45%}.edd_dashboard_widget .inside{font-size:12px}.edd_dashboard_widget td{padding:3px 0}.edd_dashboard_widget .b,.edd_dashboard_widget .t{line-height:1.5;vertical-align:middle}.edd_dashboard_widget .b{font-size:14px;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;padding-right:6px;width:auto}.edd_dashboard_widget .t{font-size:12px;padding-right:12px;color:#777;width:100%}.edd_dashboard_widget .label_heading{border-top:1px solid #ececec;color:#8f8f8f;font-family:Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;display:block;padding-top:10px;margin:0 0 8px 12px}.edd_dashboard_widget .edd_dashboard_widget_subheading{border-top:1px solid #ececec;color:#8f8f8f;font-size:14px;padding-top:10px;margin:1em 0 0 0}.edd_dashboard_widget .edd_dashboard_widget_subheading+.table{margin:8px 0 0 0}.edd_dashboard_widget .edd_price_label{background:#00769c;border-radius:3px;color:#fff;font-size:10px;padding:2px 4px;margin-right:2px}.edd_dashboard_widget table{width:100%;margin-left:0;margin-bottom:1em}td.edd_order_label{width:80%}td.edd_order_price{text-align:right}@media handheld,only screen and (max-width:1000px){.edd_dashboard_widget .edd-recent-email{display:none}}#edd-dashboard-widgets-wrap .postbox h3{cursor:default}#edd-date-range-options,#edd-graphs-date-options{float:left}#edd-date-range-options span{float:left;line-height:24px;height:24px;margin-right:6px}.edd-import-export-form{position:relative}.edd-import-export-form .edd-progress{background:#ddd;position:absolute;bottom:15px;width:95%;height:15px}.edd-import-export-form .edd-progress div{background:#ccc;height:100%;width:0}.edd-import-export-form .notice-wrap{background-color:#f4f4f4;border-style:solid;border-width:1px 0;border-color:#eae9e9;padding:12px 12px 4px;overflow:auto;margin:20px -12px -23px;position:relative;width:100%}.edd-import-export-form .notice-wrap .spinner{margin:4px 10px 8px;float:right}.admin-color-fresh .edd-import-export-form .edd-progress div{background:#0073aa}.admin-color-light .edd-import-export-form .edd-progress div{background:#888}.admin-color-blue .edd-import-export-form .edd-progress div{background:#096484}.admin-color-coffee .edd-import-export-form .edd-progress div{background:#c7a589}.admin-color-ectoplasm .edd-import-export-form .edd-progress div{background:#a3b745}.admin-color-midnight .edd-import-export-form .edd-progress div{background:#e14d43}.admin-color-sunrise .edd-import-export-form .edd-progress div{background:#dd823b}#edd-graphs-filter label{vertical-align:inherit}#edd-graphs-filter .graph-option-section{float:left;line-height:2.5em;padding-right:5px}.edd-mix-totals{background-color:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);padding:10px}.edd-mix-chart{display:inline-block;width:49%;vertical-align:top}.edd-graph-notes{color:#9c9c9c}.edd-graph-notes span{display:block}.edd-pie-graph .legend{display:none}.edd-pie-legend{overflow:auto;margin-top:10px}.edd-legend-item-wrapper{color:#333;display:inline-block;font-size:8pt;padding:2px 5px 0 5px;width:48%;height:20px}.edd-legend-color{border:1px solid #cfcfcf;display:inline-block;margin-right:5px;width:20px;height:15px}.edd-pie-legend-item{display:inline-block;vertical-align:top;width:80%}[id*=edd-jilt-].button,[id*=edd-sendwp-].button{font-size:16px;height:auto;padding:8px 14px;margin:6px 0 0}[id*=edd-jilt-].button .dashicons,[id*=edd-sendwp-].button .dashicons{line-height:29px;margin-right:8px}[id*=edd-jilt-].button .edd-loading,[id*=edd-jilt-].button .edd-loading:after,[id*=edd-sendwp-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading:after{border-radius:50%;display:inline-block;width:14px;height:14px}[id*=edd-jilt-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading{position:relative;top:3px;margin-left:4px;box-shadow:0 0 2px rgba(0,0,0,.2)}[id*=edd-jilt-].button .edd-loading,[id*=edd-sendwp-].button .edd-loading{-webkit-animation:edd-spinning 1.1s infinite linear;animation:edd-spinning 1.1s infinite linear;border-top:2px solid rgba(255,255,255,.5);border-right:2px solid rgba(255,255,255,.5);border-bottom:2px solid rgba(255,255,255,.5);border-left:2px solid #fff;font-size:14px;-ms-transform:translateZ(0);transform:translateZ(0)}#edd-jilt-disconnect.button .edd-loading.dark,#edd-sendwp-disconnect.button .edd-loading.dark{border-top-color:rgba(0,0,0,.2);border-right-color:rgba(0,0,0,.2);border-bottom-color:rgba(0,0,0,.2);border-left-color:#666;box-shadow:none}.jilt-notice{position:relative}@-webkit-keyframes edd-spinning{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes edd-spinning{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#edd_tax_rates{margin:1em 0 0}#edd_tax_rates .edd_tax_country *,#edd_tax_rates .edd_tax_state *{max-width:100%}#edd_tax_rates .edd_tax_country,#edd_tax_rates .edd_tax_state{width:180px}#edd_tax_rates .edd_tax_rate{width:80px}#edd_tax_rates th{padding:15px 10px}.wrap-licenses .form-table,.wrap-licenses caption,.wrap-licenses tbody,.wrap-licenses td,.wrap-licenses tfoot,.wrap-licenses th,.wrap-licenses thead,.wrap-licenses tr{display:block}.wrap-licenses .form-table tr{float:left;margin:0 15px 15px 0;background:#fff;border:1px solid #ccc;width:30.5%;max-width:350px;padding:14px;min-height:220px;position:relative;box-sizing:border-box}.wrap-licenses .form-table th{background:#f9f9f9;padding:14px;border-bottom:1px solid #ccc;margin:-14px -14px 20px;width:100%}.wrap-licenses .form-table td{padding:0}.wrap-licenses td input.regular-text{margin:0 0 8px;width:100%}.wrap-licenses .edd-license-data[class*=edd-license-]{position:absolute;background:#fafafa;padding:14px;border-top:1px solid #eee;margin:20px -14px -14px;min-height:67px;width:100%;bottom:14px;box-sizing:border-box}.wrap-licenses .edd-license-data[class*=edd-license-] a{color:#444}.wrap-licenses .edd-license-data[class*=edd-license-] a:hover{text-decoration:none}.wrap-licenses .edd-license-data.license-expires-soon-notice{background-color:#00a0d2;color:#fff;border-color:#00a0d2}.wrap-licenses .edd-license-data.edd-license-expired{background-color:#e24e4e;color:#fff;border-color:#e24e4e}.wrap-licenses .edd-license-data.edd-license-error,.wrap-licenses .edd-license-data.edd-license-invalid,.wrap-licenses .edd-license-data.edd-license-item_name_mismatch,.wrap-licenses .edd-license-data.edd-license-missing,.wrap-licenses .edd-license-data.edd-license-site_inactive{background-color:#ffebcd;border-color:#ffebcd}.wrap-licenses .edd-license-data p{font-size:13px;margin-top:0}.wrap-licenses .edd-license-data.edd-license-expired a,.wrap-licenses .edd-license-data.license-expires-soon-notice a{color:#fff}.wrap-licenses .edd-license-data.edd-license-expired a:hover,.wrap-licenses .edd-license-data.license-expires-soon-notice a:hover{text-decoration:none}.wrap-licenses p.submit{clear:both}#system-info-textarea{background:0 0;font-family:Menlo,Monaco,monospace;display:block;overflow:auto;white-space:pre;width:800px;height:400px}#TB_window #edd-add-download:active,#TB_window #edd-add-download:focus,#TB_window #edd-add-download:hover{color:#fff}.edd-graph .y1Axis{color:#edc240!important}.edd-graph .y2Axis{color:#afd8f8!important}.download_page_edd-tools .apikeys .column-user{width:192px}.edd-select-chosen{width:100%;max-width:300px}.chosen-container-multi .chosen-choices{background-image:none;border-color:#dfdfdf;-webkit-border-radius:3px;border-radius:3px}.chosen-container-multi .chosen-choices input{border-color:#dfdfdf;height:27px!important;margin:2px}.chosen-container .chosen-drop{border-color:#aaa;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,.1);box-shadow:1px 1px 2px rgba(0,0,0,.1)}.chosen-container .search-field{float:none!important}.chosen-container .search-field input{width:90%!important}.chosen-container-active .chosen-choices{border-color:#aaa;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,.1);box-shadow:1px 1px 2px rgba(0,0,0,.1)}.download_page_edd-tools .tablenav .actions{overflow:visible}.edd_user_search_wrap{position:relative;overflow:visible}.edd_user_search_results{position:absolute;left:0;top:27px}.edd_user_search_results a.edd-ajax-user-cancel{position:absolute;right:6px;top:2px}.edd_user_search_results ul{background:#f0f0f0;border:1px solid #dfdfdf;overflow-y:scroll;padding:10px 10px 4px;margin:0;max-height:200px;width:300px}.wp-list-table .type-download .row-actions{color:#999}@media screen and (max-width:1100px){.edd-mix-chart{display:block;width:100%}.wrap-licenses .form-table tr{width:46%;max-width:none;min-height:230px}}@media screen and (max-width:782px){.post-type-download .nav-tab-wrapper a{font-size:70%;padding:2px 4px}.download_page_edd-tools .apikeys .column-user{width:80px}.license-expiration-date-notice,.license-lifetime-notice,.license-null{padding-left:0}[class^=license-] input[type=text]{margin-bottom:3px}}@media screen and (max-width:600px){.wrap-licenses .form-table tr{width:100%;min-height:230px}#edd-edit-order-form input.large-text{width:100%}}#edd-item-wrapper{background:#f5f5f5;border:1px solid #e5e5e5;webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);box-shadow:0 1px 1px rgba(0,0,0,.04);max-width:830px}#edd-item-wrapper:after{content:"";display:block;clear:both;visibility:hidden;font-size:0;height:0}#edd-item-tab-wrapper{float:left;width:18%;z-index:1}#edd-item-tab-wrapper-list{background:#fff;margin:0}#edd-item-tab-wrapper-list li{display:block;background-color:#eaeaea;color:#444;font-size:12px;border-bottom:1px solid #e5e5e5;margin-bottom:0;-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto;word-wrap:break-word}#edd-item-tab-wrapper-list li a{display:block;padding:8px 10px 8px 6px}#edd-item-tab-wrapper-list li.active{display:block;background-color:#fff;padding:8px 10px 8px 6px}#edd-item-tab-wrapper-list .inactive a,#edd-item-tab-wrapper-list .inactive a:visited{background-color:#f5f5f5;color:#444;text-decoration:none}#edd-item-tab-wrapper-list .inactive a:hover{background-color:#fff}#edd-item-tab-wrapper-list .dashicons{color:#444;font-size:16px;min-width:24px;height:auto}#edd-item-card-wrapper .left{float:left}#edd-item-card-wrapper .right{float:right}#edd-item-card-wrapper input{font-weight:400}#edd-item-card-wrapper{background-color:#fff;border:1px solid #e5e5e5;display:inline-block;margin-left:-1px;min-height:200px;width:700px;z-index:2}.edd-item-has-tabs #edd-item-card-wrapper{border-width:0 0 0 1px;width:82%}#edd-item-card-wrapper .customer-section{border-bottom:1px solid #eee;margin-bottom:10px;overflow:auto}#edd-item-card-wrapper .customer-section table{margin-bottom:20px}#edd-item-card-wrapper>div{padding:0 20px}#edd-item-card-wrapper>div:first-child{padding-top:20px}#edd-item-card-wrapper>div:last-child{border:none;padding-bottom:20px}#edd-item-card-wrapper .avatar-wrap{padding-right:10px;text-align:center}#edd-item-card-wrapper .customer-id{font-size:24px;font-weight:600}#edd-item-card-wrapper .customer-main-wrapper input{width:200px}#edd-item-card-wrapper .customer-address-wrapper{margin-right:25px;max-width:33%;width:202px}#edd-item-card-wrapper .customer-address-wrapper select{width:200px}#edd-item-card-wrapper .customer-info{margin-top:5px;margin-bottom:10px;min-height:185px}#edd-item-card-wrapper .info-wrapper{min-height:125px;overflow:visible}#edd-item-card-wrapper a.delete{color:red;margin-right:5px;text-decoration:none}.customer-info .customer-name{font-size:24px;font-weight:600}.customer-edit-link a,.disconnect-user a{font-size:12px;font-weight:400;text-decoration:none}#customer-edit-actions{line-height:28px;margin-bottom:20px;text-align:center}#customer-edit-actions .button-secondary{margin-right:10px}#edd-item-card-wrapper .row-title{width:30%}#edd-item-card-wrapper .info-item{display:block;line-height:16px;padding-bottom:5px}#edd-item-card-wrapper .edit-item{display:none}#edd-item-card-wrapper .edd_user_search_results{left:1px;top:16px}#edd-item-card-wrapper .edd_user_search_results ul{width:200px}#edd-item-stats-wrapper{margin:0 auto;min-height:30px;text-align:center}#edd-item-stats-wrapper li{font-size:14px;float:left;line-height:22px;width:50%}#edd-item-stats-wrapper a{text-decoration:none}#edd-item-stats-wrapper .dashicons{color:#888}#edd-item-tables-wrapper table{text-align:center;width:100%}#edd-item-tables-wrapper th{text-align:center}#edd-item-tables-wrapper .downloads tr>td:first-child,#edd-item-tables-wrapper .downloads tr>th:first-child,#edd-item-tables-wrapper .emails tr>td:first-child,#edd-item-tables-wrapper .emails tr>th:first-child{text-align:left}#edd-item-tables-wrapper .downloads tr>td:only-child{text-align:center}#edd-item-tables-wrapper .emails .add-customer-email-row td{background-color:#f9f9f9;border-top:1px solid #e5e5e5}#edd-item-tables-wrapper .emails .primary-email-icon{font-size:13px;vertical-align:middle;line-height:1.5em}#edd-item-tables-wrapper .emails input{vertical-align:middle;margin:6px 0}#edd-item-tables-wrapper .emails .spinner{float:none}#edd-item-notes-wrapper{min-height:50px}.edd-item-notes-header img,.edd-item-notes-header span{font-weight:600;line-height:30px;vertical-align:middle}.customer-note-input{margin-bottom:5px;width:100%}#edd-customer-notes div:nth-of-type(even){background-color:#fcfcfc}.customer-note-wrapper{border-bottom:1px solid #f9f9f9;min-height:38px;padding:7px 0 7px 7px}.customer-note-wrapper span{display:block}.note-content-wrap{padding-top:7px}.delete-customer{text-align:center}#edd-item-card-wrapper .notice-container{padding-left:20px;padding-right:20px;margin-left:-20px;margin-right:-20px}#edd-item-card-wrapper .add-customer-email-wrapper>#add-customer-email{vertical-align:middle}@media screen and (max-width:810px) and (min-width:656px){.customer-info .customer-name{font-size:16px}#edd-item-card-wrapper .widefat td,.widefat th{padding:4px 6px;max-width:100px!important;display:table-cell}}@media screen and (max-width:781px){#edd-item-card-wrapper,#edd-item-tab-wrapper{margin:0;width:100%}#edd-item-tab-wrapper-list{background:#fff;margin:0}#edd-item-tab-wrapper-list li{float:left;display:inline;font-size:14px;box-sizing:border-box;border-width:0 1px 1px 0;border-style:solid;border-color:#e5e5e5;width:33.33333%}#edd-item-tab-wrapper-list li:nth-child(3n+3){border-width:0 0 1px 0}#edd-item-tab-wrapper-list .dashicons{font-size:18px}.edd-item-has-tabs #edd-item-card-wrapper{border-top:1px solid #e5e5e5;border-left:0;margin-top:-1px;width:100%}}@media screen and (max-width:656px){#edd-item-card-wrapper .customer-info{min-height:220px}.edd-item-info.customer-info{position:relative}#edd-item-card-wrapper .customer-address-wrapper{float:none;position:absolute;top:84px;left:110px;max-width:200px}#edd-item-card-wrapper .customer-main-wrapper{float:none;position:absolute;left:110px}.customer-info .customer-name{font-size:16px}#edd-item-card-wrapper #edd-item-stats-wrapper{padding-left:0;padding-right:0}#edd-item-card-wrapper .customer-section{margin-bottom:0}#edd-item-card-wrapper .widefat td,#edd-item-card-wrapper .widefat th{padding:4px 6px;max-width:100px!important;display:table-cell;overflow:hidden}#edd-item-card-wrapper .customer-id{font-size:16px}}@media screen and (max-width:480px){#edd-item-tab-wrapper-list li{width:50%}#edd-item-tab-wrapper-list li:nth-child(3n+3){border-width:0 1px 1px 0}#edd-item-tab-wrapper-list li:nth-child(even){border-width:0 0 1px 0}.edd-repeatable-row-actions,.edd-repeatable-row-title{text-align:left;width:100%}.edd-repeatable-row-title{padding-bottom:0}.edd-bundled-product-item-reorder,.edd-bundled-product-row .edd-bundled-product-item,.edd-bundled-product-row .edd-bundled-product-price-assignment,.edd-file-assignment,.edd-file-name,.edd-file-url,.edd-option-name,.edd-option-price,.edd_repeatable_default{float:none;text-align:left;width:100%!important;margin:10px 0}.edd-bundled-product-row .edd-bundled-product-actions{float:none}.edd-bundled-product-row .edd-bundled-product-item-reorder .edd-product-file-reorder{padding:0}#edd-payment-filters span{display:block;margin:2px 0}#edd-payment-filters a,.download_page_edd-reports .button{text-align:center}#edd-payment-date-filters span{display:block}#edd-payment-date-filters span>input{float:right}#edd-add-discount select[multiple] option,#edd-edit-discount select[multiple] option{height:20px}#edd-add-discount input[type=text],#edd-edit-discount input[type=text],#edd-payment-filters a,#edd-payment-filters input:not([type=radio]),#edd-payment-filters select,#system-info-textarea,.download_page_edd-reports .inside .button,.download_page_edd-reports .inside input[type=submit],.download_page_edd-reports .inside input[type=text],.download_page_edd-reports .inside select,.download_page_edd-settings .inside input[type=button],.download_page_edd-tools .inside input[type=submit],.download_page_edd-tools .inside input[type=text],.download_page_edd-tools .inside select{width:100%}#edd-add-discount select[multiple],#edd-edit-discount select[multiple],.download_page_edd-tools select[multiple]{height:200px!important}.download_page_edd-settings input[type=checkbox]{margin:2px 0}.post-type-download input[type=checkbox]{margin-left:2px}}.recount-stats-controls form{display:inline}.edd-recount-stats-descriptions span{display:none;line-height:24px}#edd-debug-log p.submit{margin:20px 0 0;padding:0}#edd-debug-log .edd-inline-button{margin-left:5px}.edd-settings-sidebar{padding-top:27px}.edd-settings-sidebar-content{background-color:#fff;text-align:center;border:1px solid #ddd;box-sizing:border-box;max-width:300px}.edd-settings-sidebar-content p{font-size:14px;line-height:1.5;margin-top:0}.edd-sidebar-header-section{background-color:#35495c;line-height:1;padding:26px 20px 24px;border-bottom:3px dashed #fafafa}.edd-sidebar-description-section{background-color:#fafafa;padding:16px 20px;border-bottom:1px solid #ddd}.edd-sidebar-description-section .edd-sidebar-description{margin:0}.edd-sidebar-coupon-section{font-size:14px;padding:16px 20px}.edd-sidebar-coupon-section label{display:block;line-height:1.4;margin-bottom:6px}.edd-sidebar-coupon-section label strong{color:#253b51;font-weight:700}.edd-sidebar-coupon-section input{background:#f4f7fa;font-size:22px;font-weight:600;text-align:center;padding:10px;border:2px dashed #2794da;border-radius:4px;margin-bottom:16px;box-shadow:none;width:100%}.edd-sidebar-coupon-section input:focus{border:2px dashed #2794da;box-shadow:none}.edd-settings-sidebar-content .edd-coupon-note{color:#6c7883;font-size:13px;font-style:italic;margin:0}.edd-settings-sidebar-content .edd-coupon-note a{color:#253b51}.edd-settings-sidebar-content .edd-coupon-note a:hover{text-decoration:none}.edd-sidebar-footer-section{background-color:#fafafa;padding:16px 20px;border-top:1px solid #ddd}.edd-sidebar-footer-section .edd-cta-button{display:block;background-color:#2794da;color:#fff;text-decoration:none;font-size:20px;font-weight:700;text-transform:uppercase;padding:17px 10px;border:none;border-radius:4px;width:100%;box-sizing:border-box;box-shadow:none;transition:background-color .2s}.edd-sidebar-footer-section .edd-cta-button:hover{background-color:#2386c5}@media all and (min-width:1080px){.edd-has-sidebar .edd-settings-content{float:left;width:67%}.edd-has-sidebar .edd-settings-sidebar{float:right;width:31%}}@media all and (min-width:1240px){.edd-has-sidebar .edd-settings-content{width:74%}.edd-has-sidebar .edd-settings-sidebar{width:23%}}.taxes-tab .edd-has-sidebar .edd-settings-content,.taxes-tab .edd-has-sidebar .edd-settings-sidebar{float:none;width:100%}.bfcm-promo-img-container{background-color:#35495c;width:100%;height:160px}.bfcm-code{color:#2794da;font-weight:700}.sale-ends{position:absolute;bottom:9px;right:14px;display:inline-block;color:#6c7883;font-size:12px;text-align:right;font-style:italic;width:150px}
assets/js/admin-scripts.js CHANGED
@@ -1204,18 +1204,6 @@ jQuery(document).ready(function ($) {
1204
 
1205
  emails : function() {
1206
 
1207
- // Show the email template previews
1208
- var email_preview_wrap = $('#email-preview-wrap');
1209
- if( email_preview_wrap.length ) {
1210
- var emailPreview = $('#email-preview');
1211
- email_preview_wrap.colorbox({
1212
- inline: true,
1213
- href: emailPreview,
1214
- width: '80%',
1215
- height: 'auto'
1216
- });
1217
- }
1218
-
1219
  $('#edd-sendwp-connect').on('click', function(e) {
1220
 
1221
  e.preventDefault();
1204
 
1205
  emails : function() {
1206
 
 
 
 
 
 
 
 
 
 
 
 
 
1207
  $('#edd-sendwp-connect').on('click', function(e) {
1208
 
1209
  e.preventDefault();
assets/js/admin-scripts.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){edd_attach_tooltips($(".edd-help-tip"));var EDD_Download_Configuration={init:function(){this.add(),this.move(),this.remove(),this.type(),this.prices(),this.files(),this.updatePrices()},clone_repeatable:function(row){var key=highest=1;return row.parent().find(".edd_repeatable_row").each(function(){var current=$(this).data("key");parseInt(current)>highest&&(highest=current)}),key=highest+=1,clone=row.clone(),clone.removeClass("edd_add_blank"),clone.attr("data-key",key),clone.find("input, select, textarea").val("").each(function(){var name=$(this).attr("name"),id=$(this).attr("id");name&&(name=name.replace(/\[(\d+)\]/,"["+parseInt(key)+"]"),$(this).attr("name",name)),$(this).attr("data-key",key),void 0!==id&&(id=id.replace(/(\d+)/,parseInt(key)),$(this).attr("id",id))}),clone.find("select").each(function(){$(this).val(row.find('select[name="'+$(this).attr("name")+'"]').val())}),clone.find('input[type="checkbox"]').each(function(){$(this).is(":checked")&&$(this).prop("checked",!1),$(this).val(1)}),clone.find("span.edd_price_id").each(function(){$(this).text(parseInt(key))}),clone.find("span.edd_file_id").each(function(){$(this).text(parseInt(key))}),clone.find(".edd_repeatable_default_input").each(function(){$(this).val(parseInt(key)).removeAttr("checked")}),clone.find(".edd_repeatable_condition_field").each(function(){$(this).find("option:eq(0)").prop("selected","selected")}),clone.find(".search-choice").remove(),clone.find(".chosen-container").remove(),edd_attach_tooltips(clone.find(".edd-help-tip")),clone},add:function(){$(document.body).on("click",".submit .edd_add_repeatable",function(e){e.preventDefault();var row=$(this).parent().parent().prev(".edd_repeatable_row"),clone=EDD_Download_Configuration.clone_repeatable(row);clone.insertAfter(row).find("input, textarea, select").filter(":visible").eq(0).focus(),clone.find(".edd-select-chosen").chosen({inherit_select_classes:!0,placeholder_text_single:edd_vars.one_option,placeholder_text_multiple:edd_vars.one_or_more_option}),clone.find(".edd-select-chosen").css("width","100%"),clone.find(".edd-select-chosen .chosen-search input").attr("placeholder",edd_vars.search_placeholder)})},move:function(){$(".edd_repeatable_table .edd-repeatables-wrap").sortable({handle:".edd-draghandle-anchor",items:".edd_repeatable_row",opacity:.6,cursor:"move",axis:"y",update:function(){var count=0;$(this).find(".edd_repeatable_row").each(function(){$(this).find("input.edd_repeatable_index").each(function(){$(this).val(count)}),count++})}})},remove:function(){$(document.body).on("click",".edd-remove-row, .edd_remove_repeatable",function(e){e.preventDefault();var firstFocusable,row=$(this).parents(".edd_repeatable_row"),count=row.parent().find(".edd_repeatable_row").length,type=$(this).data("type"),repeatable="div.edd_repeatable_"+type+"s";if(firstFocusable=($(this).is(".ui-sortable .edd_repeatable_row:first-child .edd-remove-row, .ui-sortable .edd_repeatable_row:first-child .edd_remove_repeatable")?row.next(".edd_repeatable_row"):row.prev(".edd_repeatable_row")).find("select, input, textarea, button").filter(":visible").eq(0),"price"===type){var price_row_id=row.data("key");$('.edd_repeatable_condition_field option[value="'+price_row_id+'"]').remove()}if(1<count)$("input, select",row).val(""),row.fadeOut("fast").remove(),firstFocusable.focus();else switch(type){case"price":alert(edd_vars.one_price_min);break;case"file":$("input, select",row).val("");break;default:alert(edd_vars.one_field_min)}$(repeatable).each(function(rowIndex){$(this).find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+rowIndex+"]"),$(this).attr("name",name).attr("id",name)})})})},type:function(){$(document.body).on("change","#_edd_product_type",function(e){var edd_products=$("#edd_products"),edd_download_files=$("#edd_download_files"),edd_download_limit_wrap=$("#edd_download_limit_wrap");"bundle"===$(this).val()?(edd_products.show(),edd_download_files.hide(),edd_download_limit_wrap.hide()):(edd_products.hide(),edd_download_files.show(),edd_download_limit_wrap.show())})},prices:function(){$(document.body).on("change","#edd_variable_pricing",function(e){var checked=$(this).is(":checked"),single=$("#edd_regular_price_field"),variable=$("#edd_variable_price_fields, .edd_repeatable_table .pricing"),bundleRow=$(".edd-bundled-product-row, .edd-repeatable-row-standard-fields");checked?(single.hide(),variable.show(),bundleRow.addClass("has-variable-pricing")):(single.show(),variable.hide(),bundleRow.removeClass("has-variable-pricing"))})},files:function(){var file_frame;window.formfield="",$(document.body).on("click",".edd_upload_file_button",function(e){e.preventDefault();var button=$(this);window.formfield=$(this).closest(".edd_repeatable_upload_wrapper"),file_frame||((file_frame=wp.media.frames.file_frame=wp.media({frame:"post",state:"insert",title:button.data("uploader-title"),button:{text:button.data("uploader-button-text")},multiple:"0"!=$(this).data("multiple")})).on("menu:render:default",function(view){view.unset("library-separator"),view.unset("gallery"),view.unset("featured-image"),view.unset("embed"),view.set({})}),file_frame.on("insert",function(){file_frame.state().get("selection").each(function(attachment,index){var selectedSize="image"===(attachment=attachment.toJSON()).type&&$(".attachment-display-settings .size option:selected").val(),selectedURL=attachment.url,selectedName=0<attachment.title.length?attachment.title:attachment.filename;if(selectedSize&&void 0!==attachment.sizes[selectedSize]&&(selectedURL=attachment.sizes[selectedSize].url),"image"===attachment.type&&(selectedName=selectedSize&&void 0!==attachment.sizes[selectedSize]?selectedName+"-"+attachment.sizes[selectedSize].width+"x"+attachment.sizes[selectedSize].height:selectedName+"-"+attachment.width+"x"+attachment.height),0===index)window.formfield.find(".edd_repeatable_attachment_id_field").val(attachment.id),window.formfield.find(".edd_repeatable_thumbnail_size_field").val(selectedSize),window.formfield.find(".edd_repeatable_upload_field").val(selectedURL),window.formfield.find(".edd_repeatable_name_field").val(selectedName);else{var row=window.formfield,clone=EDD_Download_Configuration.clone_repeatable(row);clone.find(".edd_repeatable_attachment_id_field").val(attachment.id),clone.find(".edd_repeatable_thumbnail_size_field").val(selectedSize),clone.find(".edd_repeatable_upload_field").val(selectedURL),clone.find(".edd_repeatable_name_field").val(selectedName),clone.insertAfter(row)}})})),file_frame.open()}),window.formfield=""},updatePrices:function(){$("#edd_price_fields").on("keyup",".edd_variable_prices_name",function(){var key=$(this).parents(".edd_repeatable_row").data("key"),name=$(this).val(),field_option=$(".edd_repeatable_condition_field option[value="+key+"]");0<field_option.length?field_option.text(name):$(".edd_repeatable_condition_field").append($("<option></option>").attr("value",key).text(name))})}};$(document.body).on("click",".toggle-custom-price-option-section",function(e){e.preventDefault();var show=$(this).html()==edd_vars.show_advanced_settings;show?$(this).html(edd_vars.hide_advanced_settings):$(this).html(edd_vars.show_advanced_settings);var header=$(this).parents(".edd-repeatable-row-header");header.siblings(".edd-custom-price-option-sections-wrap").slideToggle(),$(":input:not(input[type=button],input[type=submit],button):visible:first",show?header.siblings(".edd-custom-price-option-sections-wrap"):header.siblings(".edd-repeatable-row-standard-fields")).focus()}),EDD_Download_Configuration.init();var typingTimer,edd_datepicker=$(".edd_datepicker");if(0<edd_datepicker.length){edd_datepicker.datepicker({dateFormat:"mm/dd/yy"})}({init:function(){this.edit_address(),this.remove_download(),this.add_download(),this.change_customer(),this.new_customer(),this.edit_price(),this.recalculate_total(),this.variable_prices_check(),this.add_note(),this.remove_note(),this.resend_receipt(),this.copy_download_link()},edit_address:function(){$('select[name="edd-payment-address[0][country]"]').change(function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"edd-payment-address[0][state]"};return $.post(ajaxurl,data,function(response){var state_wrapper=$("#edd-order-address-state-wrap select, #edd-order-address-state-wrap input");$("#edd-order-address-state-wrap .chosen-container").remove(),"nostates"==response?state_wrapper.replaceWith('<input type="text" name="edd-payment-address[0][state]" value="" class="edd-edit-toggles medium-text"/>'):state_wrapper.replaceWith(response)}),!1})},remove_download:function(){$("#edd-purchased-files").on("click",".edd-order-remove-download",function(){if(1===$(document.body).find("#edd-purchased-files > .row:not(.header)").length)return alert(edd_vars.one_download_min),!1;if(confirm(edd_vars.delete_payment_download)){var key=$(this).data("key"),download_id=($(".edd-payment-id").val(),$('input[name="edd-payment-details-downloads['+key+'][id]"]').val()),price_id=$('input[name="edd-payment-details-downloads['+key+'][price_id]"]').val(),quantity=$('input[name="edd-payment-details-downloads['+key+'][quantity]"]').val(),amount=$('input[name="edd-payment-details-downloads['+key+'][amount]"]').val();if($('input[name="edd-payment-details-downloads['+key+'][tax]"]').length)var fees=$('input[name="edd-payment-details-downloads['+key+'][tax]"]').val();if($('input[name="edd-payment-details-downloads['+key+'][fees]"]').length)fees=$.parseJSON($('input[name="edd-payment-details-downloads['+key+'][fees]"]').val());var currently_removed=$('input[name="edd-payment-removed"]').val();(currently_removed=$.parseJSON(currently_removed)).length<1&&(currently_removed={});var removed_item=[{id:download_id,price_id:price_id,quantity:quantity,amount:amount,cart_index:key}];currently_removed[key]=removed_item,$('input[name="edd-payment-removed"]').val(JSON.stringify(currently_removed)),$(this).parent().parent().remove(),fees&&fees.length&&$.each(fees,function(key,value){$('*li[data-fee-id="'+value+'"]').remove()}),$("#edd-payment-downloads-changed").val(1),$(".edd-order-payment-recalc-totals").show()}return!1})},change_customer:function(){$("#edd-customer-details").on("click",".edd-payment-change-customer, .edd-payment-change-customer-cancel",function(e){e.preventDefault();var change_customer=$(this).hasClass("edd-payment-change-customer"),cancel=$(this).hasClass("edd-payment-change-customer-cancel");change_customer?($(".customer-info").hide(),$(".change-customer").show(),$(".edd-payment-change-customer-input").css("width","auto")):cancel&&($(".customer-info").show(),$(".change-customer").hide())})},new_customer:function(){$("#edd-customer-details").on("click",".edd-payment-new-customer, .edd-payment-new-customer-cancel",function(e){e.preventDefault();var new_customer=$(this).hasClass("edd-payment-new-customer"),cancel=$(this).hasClass("edd-payment-new-customer-cancel");new_customer?($(".customer-info").hide(),$(".new-customer").show()):cancel&&($(".customer-info").show(),$(".new-customer").hide());new_customer=$("#edd-new-customer");$(".new-customer").is(":visible")?new_customer.val(1):new_customer.val(0)})},add_download:function(){$(".edd-edit-purchase-element").on("click","#edd-order-add-download",function(e){e.preventDefault();var order_download_select=$("#edd_order_download_select"),order_download_quantity=$("#edd-order-download-quantity"),order_download_price=$("#edd-order-download-price"),order_download_tax=$("#edd-order-download-tax"),selected_price_option=$(".edd_price_options_select option:selected"),download_id=order_download_select.val(),download_title=order_download_select.find(":selected").text(),quantity=order_download_quantity.val(),item_price=order_download_price.val(),item_tax=order_download_tax.val(),price_id=selected_price_option.val(),price_name=selected_price_option.text();if(download_id<1)return!1;if(item_price||(item_price=0),item_price=parseFloat(item_price),isNaN(item_price))return alert(edd_vars.numeric_item_price),!1;if(item_tax=parseFloat(item_tax),isNaN(item_tax))return alert(edd_vars.numeric_item_tax),!1;if(isNaN(parseInt(quantity)))return alert(edd_vars.numeric_quantity),!1;price_name&&(download_title=download_title+" - "+price_name);var count=$("#edd-purchased-files div.row:not(.edd-purchased-files-header)").length;0==count&&alert(edd_vars.no_downloads_error);var clone=$("#edd-purchased-files div.row:not(.edd-purchased-files-header):last").clone();clone.find(".download span").html('<a href="post.php?post='+download_id+'&action=edit"></a>'),clone.find(".download span a").text(download_title),clone.find(".edd-payment-details-download-item-price").val(item_price.toFixed(edd_vars.currency_decimals)),clone.find(".edd-payment-details-download-item-tax").val(item_tax.toFixed(edd_vars.currency_decimals)),clone.find("input.edd-payment-details-download-id").val(download_id),clone.find("input.edd-payment-details-download-price-id").val(price_id);var item_total=item_price*quantity+item_tax;item_total=item_total.toFixed(edd_vars.currency_decimals),clone.find("span.edd-payment-details-download-amount").text(item_total),clone.find("input.edd-payment-details-download-amount").val(item_total),clone.find("input.edd-payment-details-download-quantity").val(quantity),clone.find("input.edd-payment-details-download-has-log").val(0),clone.find(".edd-copy-download-link-wrapper").remove(),clone.find("input").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("name",name).attr("id",name)}),clone.find("a.edd-order-remove-download").attr("data-key",parseInt(count)),$("#edd-payment-downloads-changed").val(1),$("#edd-purchased-files div.row .edd-purchased-download-title .deleted").length&&$("#edd-purchased-files div.row:last").remove(),$(clone).insertAfter("#edd-purchased-files div.row:last"),$(".edd-order-payment-recalc-totals").show(),$(".edd-add-download-field").val("")})},edit_price:function(){$(document.body).on("change keyup",".edd-payment-item-input",function(){var row=$(this).parents("ul.edd-purchased-files-list-wrapper");$(".edd-order-payment-recalc-totals").show();var quantity=row.find("input.edd-payment-details-download-quantity").val().replace(edd_vars.thousands_separator,""),item_price=row.find("input.edd-payment-details-download-item-price").val().replace(edd_vars.thousands_separator,""),item_tax=row.find("input.edd-payment-details-download-item-tax").val().replace(edd_vars.thousands_separator,"");if(item_price=parseFloat(item_price),isNaN(item_price))return alert(edd_vars.numeric_item_price),!1;item_tax=parseFloat(item_tax),isNaN(item_tax)&&(item_tax=0),isNaN(parseInt(quantity))&&(quantity=1);var item_total=item_price*quantity+item_tax;item_total=item_total.toFixed(edd_vars.currency_decimals),row.find("input.edd-payment-details-download-amount").val(item_total),row.find("span.edd-payment-details-download-amount").text(item_total)})},recalculate_total:function(){$("#edd-order-recalc-total").on("click",function(e){e.preventDefault();var total=0,tax=0,totals=$("#edd-purchased-files .row input.edd-payment-details-download-amount"),taxes=$("#edd-purchased-files .row input.edd-payment-details-download-item-tax");totals.length&&totals.each(function(){total+=parseFloat($(this).val())}),taxes.length&&taxes.each(function(){tax+=parseFloat($(this).val())}),$(".edd-payment-fees").length&&$(".edd-payment-fees span.fee-amount").each(function(){total+=parseFloat($(this).data("fee"))}),$("input[name=edd-payment-total]").val(total.toFixed(edd_vars.currency_decimals)),$("input[name=edd-payment-tax]").val(tax.toFixed(edd_vars.currency_decimals))})},variable_prices_check:function(){$(".edd-edit-purchase-element").on("change","select#edd_order_download_select",function(){var $this=$(this),download_id=$this.val();if(0<parseInt(download_id)){var postData={action:"edd_check_for_download_price_variations",download_id:download_id};$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$(".edd_price_options_select").remove(),$(response).insertAfter($this.next())}}).fail(function(data){window.console&&window.console.log&&console.log(data)})}})},add_note:function(){$("#edd-add-payment-note").on("click",function(e){e.preventDefault();var postData={action:"edd_insert_payment_note",payment_id:$(this).data("payment-id"),note:$("#edd-payment-note").val()};if(postData.note)$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$("#edd-payment-notes-inner").append(response),$(".edd-no-payment-notes").hide(),$("#edd-payment-note").val("")}}).fail(function(data){window.console&&window.console.log&&console.log(data)});else{var border_color=$("#edd-payment-note").css("border-color");$("#edd-payment-note").css("border-color","red"),setTimeout(function(){$("#edd-payment-note").css("border-color",border_color)},500)}})},remove_note:function(){$(document.body).on("click",".edd-delete-payment-note",function(e){if(e.preventDefault(),confirm(edd_vars.delete_payment_note)){var postData={action:"edd_delete_payment_note",payment_id:$(this).data("payment-id"),note_id:$(this).data("note-id")};return $.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){return $("#edd-payment-note-"+postData.note_id).remove(),$(".edd-payment-note").length||$(".edd-no-payment-notes").show(),!1}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!0}})},resend_receipt:function(){var emails_wrap=$(".edd-order-resend-receipt-addresses");$(document.body).on("click","#edd-select-receipt-email",function(e){e.preventDefault(),emails_wrap.slideDown()}),$(document.body).on("change",".edd-order-resend-receipt-email",function(){var href=$("#edd-select-receipt-email").prop("href")+"&email="+$(this).val();confirm(edd_vars.resend_receipt)&&(window.location=href)}),$(document.body).on("click","#edd-resend-receipt",function(e){return confirm(edd_vars.resend_receipt)})},copy_download_link:function(){$(document.body).on("click",".edd-copy-download-link",function(e){e.preventDefault();var $this=$(this),postData={action:"edd_get_file_download_link",payment_id:$('input[name="edd_payment_id"]').val(),download_id:$this.data("download-id"),price_id:$this.data("price-id")};$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(link){return $("#edd-download-link").dialog({width:400}).html('<textarea rows="10" cols="40" id="edd-download-link-textarea">'+link+"</textarea>"),$("#edd-download-link-textarea").focus().select(),!1}}).fail(function(data){window.console&&window.console.log&&console.log(data)})})}}).init(),{init:function(){this.type_select(),this.product_requirements()},type_select:function(){$("#edd-edit-discount #edd-type, #edd-add-discount #edd-type").change(function(){var val=$(this).val();$(".edd-amount-description").hide(),$(".edd-amount-description."+val+"-discount").show()})},product_requirements:function(){$("#products").change(function(){var product_conditions=$("#edd-discount-product-conditions");$(this).val()?product_conditions.show():product_conditions.hide()})}}.init(),{init:function(){this.date_options(),this.customers_export()},date_options:function(){$("#edd-graphs-date-options").change(function(){var $this=$(this),date_range_options=$("#edd-date-range-options");"other"===$this.val()?date_range_options.show():date_range_options.hide()})},customers_export:function(){$("#edd_customer_export_download").change(function(){var $this=$(this),download_id=$("option:selected",$this).val(),customer_export_option=$("#edd_customer_export_option");if("0"===$this.val()?customer_export_option.show():customer_export_option.hide(),0!=parseInt(download_id)){var data={action:"edd_check_for_download_price_variations",download_id:download_id,all_prices:!0},price_options_select=$(".edd_price_options_select");$.post(ajaxurl,data,function(response){price_options_select.remove(),$("#edd_customer_export_download_chosen").after(response)})}else price_options_select.remove()})}}.init(),{init:function(){this.general(),this.taxes(),this.emails(),this.misc()},general:function(){var edd_color_picker=$(".edd-color-picker");if(edd_color_picker.length&&edd_color_picker.wpColorPicker(),"undefined"==typeof wp||"1"!==edd_vars.new_media_ui){var edd_settings_upload_button=$(".edd_settings_upload_button");0<edd_settings_upload_button.length&&(window.formfield="",$(document.body).on("click",edd_settings_upload_button,function(e){e.preventDefault(),window.formfield=$(this).parent().prev(),window.tbframe_interval=setInterval(function(){jQuery("#TB_iframeContent").contents().find(".savesend .button").val(edd_vars.use_this_file).end().find("#insert-gallery, .wp-post-thumbnail").hide()},2e3),tb_show(edd_vars.add_new_download,"media-upload.php?TB_iframe=true")}),window.edd_send_to_editor=window.send_to_editor,window.send_to_editor=function(html){window.formfield?(imgurl=$("a","<div>"+html+"</div>").attr("href"),window.formfield.val(imgurl),window.clearInterval(window.tbframe_interval),tb_remove()):window.edd_send_to_editor(html),window.send_to_editor=window.edd_send_to_editor,window.formfield="",window.imagefield=!1})}else{var file_frame;window.formfield="",$(document.body).on("click",".edd_settings_upload_button",function(e){e.preventDefault();var button=$(this);window.formfield=$(this).parent().prev(),file_frame||((file_frame=wp.media.frames.file_frame=wp.media({frame:"post",state:"insert",title:button.data("uploader_title"),button:{text:button.data("uploader_button_text")},multiple:!1})).on("menu:render:default",function(view){view.unset("library-separator"),view.unset("gallery"),view.unset("featured-image"),view.unset("embed"),view.set({})}),file_frame.on("insert",function(){file_frame.state().get("selection").each(function(attachment,index){attachment=attachment.toJSON(),window.formfield.val(attachment.url)})})),file_frame.open()}),window.formfield=""}},taxes:function(){var no_states=$("select.edd-no-states");no_states.length&&no_states.closest("tr").addClass("hidden"),$('select[name="edd_settings[base_country]"]').change(function(){var $this=$(this),$tr=$this.closest("tr"),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"edd_settings[base_state]"};return $.post(ajaxurl,data,function(response){"nostates"==response?$tr.next().addClass("hidden"):($tr.next().removeClass("hidden"),$tr.next().find("select").replaceWith(response))}),!1}),$(document.body).on("change","#edd_tax_rates select.edd-tax-country",function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:$this.attr("name").replace("country","state")};return $.post(ajaxurl,data,function(response){if("nostates"==response){var text_field='<input type="text" name="'+data.field_name+'" value=""/>';$this.parent().next().find("select").replaceWith(text_field)}else $this.parent().next().find("input,select").show(),$this.parent().next().find("input,select").replaceWith(response)}),!1}),$("#edd_add_tax_rate").on("click",function(){var row=$("#edd_tax_rates tr:last"),clone=row.clone(),count=row.parent().find("tr").length;return clone.find("td input").not(":input[type=checkbox]").val(""),clone.find('td [type="checkbox"]').attr("checked",!1),clone.find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("name",name).attr("id",name)}),clone.find("label").each(function(){var name=$(this).attr("for");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("for",name)}),clone.insertAfter(row),!1}),$(document.body).on("click","#edd_tax_rates .edd_remove_tax_rate",function(){confirm(edd_vars.delete_tax_rate)&&(2===$("#edd_tax_rates tr:visible").length?($("#edd_tax_rates select").val(""),$('#edd_tax_rates input[type="text"]').val(""),$('#edd_tax_rates input[type="number"]').val(""),$('#edd_tax_rates input[type="checkbox"]').attr("checked",!1)):$(this).closest("tr").remove(),$("#edd_tax_rates tr").each(function(rowIndex){$(this).children().find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+(rowIndex-1)+"]"),$(this).attr("name",name).attr("id",name)})}));return!1})},emails:function(){var email_preview_wrap=$("#email-preview-wrap");if(email_preview_wrap.length){var emailPreview=$("#email-preview");email_preview_wrap.colorbox({inline:!0,href:emailPreview,width:"80%",height:"auto"})}$("#edd-sendwp-connect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading"></span>'),document.body.style.cursor="wait",easy_digital_downloads_sendwp_remote_install()}),$("#edd-sendwp-disconnect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading dark"></span>'),document.body.style.cursor="wait",easy_digital_downloads_sendwp_disconnect()}),$("#edd-jilt-connect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading"></span>'),document.body.style.cursor="wait",easy_digital_downloads_jilt_remote_install()}),$("#edd-jilt-disconnect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading dark"></span>'),document.body.style.cursor="wait",easy_digital_downloads_jilt_disconnect()})},misc:function(){var downloadMethod=$('select[name="edd_settings[download_method]"]'),symlink=downloadMethod.parent().parent().next();"direct"==downloadMethod.val()&&(symlink.hide(),symlink.find("input").prop("checked",!1)),downloadMethod.on("change",function(){"direct"==$(this).val()?(symlink.hide(),symlink.find("input").prop("checked",!1)):symlink.show()})}}.init(),$(".download_page_edd-payment-history .row-actions .delete a, a.edd-delete-payment").on("click",function(){return!!confirm(edd_vars.delete_payment)}),$("body").on("click","#the-list .editinline",function(){var post_id=$(this).closest("tr").attr("id");post_id=post_id.replace("post-","");var regprice=$("#post-"+post_id).find(".column-price .downloadprice-"+post_id).val();regprice!=$("#post-"+post_id+".column-price .downloadprice-"+post_id).val()?$(".regprice","#edd-download-data").val(regprice).attr("disabled",!1):$(".regprice","#edd-download-data").val(edd_vars.quick_edit_warning).attr("disabled","disabled")}),$(document.body).on("click","#bulk_edit",function(){var $bulk_row=$("#bulk-edit"),$post_ids=new Array;$bulk_row.find("#bulk-titles").children().each(function(){$post_ids.push($(this).attr("id").replace(/^(ttle)/i,""))});var $price=$('#edd-download-data input[name="_edd_regprice"]').val(),data={action:"edd_save_bulk_edit",edd_bulk_nonce:$post_ids,post_ids:$post_ids,price:$price};$.post(ajaxurl,data)}),$(".edd-select-chosen").chosen({inherit_select_classes:!0,placeholder_text_single:edd_vars.one_option,placeholder_text_multiple:edd_vars.one_or_more_option}),$(".edd-select-chosen .chosen-search input").each(function(){var selectElem=$(this).parent().parent().parent().prev("select.edd-select-chosen"),placeholder=(selectElem.data("search-type"),selectElem.data("search-placeholder"));$(this).attr("placeholder",placeholder)}),$(".chosen-choices").on("click",function(){var placeholder=$(this).parent().prev().data("search-placeholder");void 0===placeholder&&(placeholder=edd_vars.type_to_search),$(this).children("li").children("input").attr("placeholder",placeholder)});$(document.body).on("keyup",".edd-select.chosen-container .chosen-search input, .edd-select.chosen-container .search-field input",function(e){var val=$(this).val(),container=$(this).closest(".edd-select-chosen"),select=(container.attr("id").replace("_chosen",""),container.prev()),no_bundles=container.hasClass("no-bundles"),variations=container.hasClass("variations"),lastKey=e.which,search_type="edd_download_search";if(container.prev().data("search-type")){if("no_ajax"==select.data("search-type"))return;search_type="edd_"+select.data("search-type")+"_search"}val.length<=3&&"edd_download_search"==search_type||16==lastKey||13==lastKey||91==lastKey||17==lastKey||37==lastKey||38==lastKey||39==lastKey||40==lastKey||(clearTimeout(typingTimer),typingTimer=setTimeout(function(){$.ajax({type:"GET",url:ajaxurl,data:{action:search_type,s:val,no_bundles:no_bundles,variations:variations},dataType:"json",beforeSend:function(){select.closest("ul.chosen-results").empty()},success:function(data){$("option:not(:selected)",select).remove(),$.each(data,function(key,item){$('option[value="'+item.id+'"]',select).length||select.prepend('<option value="'+item.id+'">'+item.name+"</option>")}),$(".edd-select-chosen").trigger("chosen:updated"),select.next().find("input").val(val)}}).fail(function(response){window.console&&window.console.log&&console.log(response)}).done(function(response){})},342))}),$("#post").on("click",".edd-thickbox",function(){$(".edd-select-chosen","#choose-download").css("width","100%")}),{init:function(){this.revoke_api_key(),this.regenerate_api_key(),this.create_api_key(),this.recount_stats()},revoke_api_key:function(){$(document.body).on("click",".edd-revoke-api-key",function(e){return confirm(edd_vars.revoke_api_key)})},regenerate_api_key:function(){$(document.body).on("click",".edd-regenerate-api-key",function(e){return confirm(edd_vars.regenerate_api_key)})},create_api_key:function(){$(document.body).on("submit","#api-key-generate-form",function(e){var input=$('input[type="text"][name="user_id"]');input.css("border-color","#ddd");var user_id=input.val();if(user_id.length<1||0==user_id)return input.css("border-color","#ff0000"),!1})},recount_stats:function(){$(document.body).on("change","#recount-stats-type",function(){var export_form=$("#edd-tools-recount-form"),selected_type=$("option:selected",this).data("type"),submit_button=$("#recount-stats-submit"),products=$("#tools-product-dropdown");if(export_form.find(".notice-wrap").remove(),submit_button.removeClass("button-disabled").attr("disabled",!1),products.hide(),$(".edd-recount-stats-descriptions span").hide(),"recount-download"===selected_type)products.show(),products.find(".edd-select-chosen").css("width","auto");else if("reset-stats"===selected_type){export_form.append('<div class="notice-wrap"></div>'),export_form.find(".notice-wrap").html('<div class="notice notice-warning"><p><input type="checkbox" id="confirm-reset" name="confirm_reset_store" value="1" /> <label for="confirm-reset">'+edd_vars.reset_stats_warn+"</label></p></div>"),$("#recount-stats-submit").addClass("button-disabled").attr("disabled","disabled")}else products.hide(),products.val(0);$("#"+selected_type).show()}),$(document.body).on("change","#confirm-reset",function(){$(this).is(":checked")?$("#recount-stats-submit").removeClass("button-disabled").removeAttr("disabled"):$("#recount-stats-submit").addClass("button-disabled").attr("disabled","disabled")}),$("#edd-tools-recount-form").submit(function(e){var selection=$("#recount-stats-type").val(),export_form=$(this),selected_type=$("option:selected",this).data("type");if("reset-stats"===selected_type){if($("#confirm-reset").is(":checked"))return!0;has_errors=!0}export_form.find(".notice-wrap").remove(),export_form.append('<div class="notice-wrap"></div>');var notice_wrap=export_form.find(".notice-wrap"),has_errors=!1;(null!==selection&&0!==selection||(notice_wrap.html('<div class="updated error"><p>'+edd_vars.batch_export_no_class+"</p></div>"),has_errors=!0),"recount-download"===selected_type)&&(0==$('select[name="download_id"]').val()&&(notice_wrap.html('<div class="updated error"><p>'+edd_vars.batch_export_no_reqs+"</p></div>"),has_errors=!0));if(has_errors)return export_form.find(".button-disabled").removeClass("button-disabled"),!1})}}.init(),{init:function(){this.submit(),this.dismiss_message()},submit:function(){var self=this;$(document.body).on("submit",".edd-export-form",function(e){e.preventDefault();var submitButton=$(this).find('input[type="submit"]');if(!submitButton.hasClass("button-disabled")){var data=$(this).serialize();submitButton.addClass("button-disabled"),$(this).find(".notice-wrap").remove(),$(this).append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),self.process_step(1,data,self)}})},process_step:function(step,data,self){$.ajax({type:"POST",url:ajaxurl,data:{form:data,action:"edd_do_ajax_export",step:step},dataType:"json",success:function(response){if("done"==response.step||response.error||response.success){var export_form=$(".edd-export-form").find(".edd-progress").parent().parent(),notice_wrap=export_form.find(".notice-wrap");if(export_form.find(".button-disabled").removeClass("button-disabled"),response.error){var error_message=response.message;notice_wrap.html('<div class="updated error"><p>'+error_message+"</p></div>")}else if(response.success){var success_message=response.message;notice_wrap.html('<div id="edd-batch-success" class="updated notice is-dismissible"><p>'+success_message+'<span class="notice-dismiss"></span></p></div>')}else notice_wrap.remove(),window.location=response.url}else $(".edd-progress div").animate({width:response.percentage+"%"},50,function(){}),self.process_step(parseInt(response.step),data,self)}}).fail(function(response){window.console&&window.console.log&&console.log(response)})},dismiss_message:function(){$(document.body).on("click","#edd-batch-success .notice-dismiss",function(){$("#edd-batch-success").parent().slideUp("fast")})}}.init();var EDD_Import={init:function(){this.submit()},submit:function(){$(".edd-import-form").ajaxForm({beforeSubmit:this.before_submit,success:this.success,complete:this.complete,dataType:"json",error:this.error})},before_submit:function(arr,$form,options){if($form.find(".notice-wrap").remove(),$form.append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),!(window.File&&window.FileReader&&window.FileList&&window.Blob)){var import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");return import_form.find(".button-disabled").removeClass("button-disabled"),notice_wrap.html('<div class="update error"><p>'+edd_vars.unsupported_browser+"</p></div>"),!1}},success:function(responseText,statusText,xhr,$form){},complete:function(xhr){var response=jQuery.parseJSON(xhr.responseText);if(response.success){var $form=$(".edd-import-form .notice-wrap").parent();$form.find(".edd-import-file-wrap,.notice-wrap").remove(),$form.find(".edd-import-options").slideDown();var select=$form.find("select.edd-import-csv-column"),options=(select.parents("tr").first(),""),columns=response.data.columns.sort(function(a,b){return a<b?-1:b<a?1:0});$.each(columns,function(key,value){options+='<option value="'+value+'">'+value+"</option>"}),select.append(options),select.on("change",function(){var $key=$(this).val();$key&&0!=response.data.first_row[$key]?$(this).parent().next().html(response.data.first_row[$key]):$(this).parent().next().html("")}),$.each(select,function(){$(this).val($(this).attr("data-field")).change()}),$(document.body).on("click",".edd-import-proceed",function(e){e.preventDefault(),$form.append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),response.data.mapping=$form.serialize(),EDD_Import.process_step(1,response.data,self)})}else EDD_Import.error(xhr)},error:function(xhr){var response=jQuery.parseJSON(xhr.responseText),import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");import_form.find(".button-disabled").removeClass("button-disabled"),response.data.error?notice_wrap.html('<div class="update error"><p>'+response.data.error+"</p></div>"):notice_wrap.remove()},process_step:function(step,import_data,self){$.ajax({type:"POST",url:ajaxurl,data:{form:import_data.form,nonce:import_data.nonce,class:import_data.class,upload:import_data.upload,mapping:import_data.mapping,action:"edd_do_ajax_import",step:step},dataType:"json",success:function(response){if("done"==response.data.step||response.data.error){var import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");import_form.find(".button-disabled").removeClass("button-disabled"),response.data.error?notice_wrap.html('<div class="update error"><p>'+response.data.error+"</p></div>"):(import_form.find(".edd-import-options").hide(),$("html, body").animate({scrollTop:import_form.parent().offset().top},500),notice_wrap.html('<div class="updated"><p>'+response.data.message+"</p></div>"))}else $(".edd-progress div").animate({width:response.data.percentage+"%"},50,function(){}),EDD_Import.process_step(parseInt(response.data.step),import_data,self)}}).fail(function(response){window.console&&window.console.log&&console.log(response)})}};EDD_Import.init();var EDD_Customer={vars:{customer_card_wrap_editable:$(".edd-customer-card-wrapper .editable"),customer_card_wrap_edit_item:$(".edd-customer-card-wrapper .edit-item"),user_id:$('input[name="customerinfo[user_id]"]'),state_input:$(':input[name="customerinfo[state]"]'),note:$("#customer-note")},init:function(){this.edit_customer(),this.add_email(),this.user_search(),this.remove_user(),this.cancel_edit(),this.change_country(),this.add_note(),this.delete_checked()},edit_customer:function(){$(document.body).on("click","#edit-customer",function(e){e.preventDefault(),EDD_Customer.vars.customer_card_wrap_editable.hide(),EDD_Customer.vars.customer_card_wrap_edit_item.fadeIn().css("display","block")})},add_email:function(){$(document.body).on("click","#add-customer-email",function(e){e.preventDefault();var button=$(this),wrapper=button.parent();wrapper.parent().find(".notice-container").remove(),wrapper.find(".spinner").css("visibility","visible"),button.attr("disabled",!0);var postData={edd_action:"customer-add-email",customer_id:wrapper.find('input[name="customer-id"]').val(),email:wrapper.find('input[name="additional-email"]').val(),primary:wrapper.find('input[name="make-additional-primary"]').is(":checked"),_wpnonce:wrapper.find('input[name="add_email_nonce"]').val()};$.post(ajaxurl,postData,function(response){!0===response.success?window.location.href=response.redirect:(button.attr("disabled",!1),wrapper.after('<div class="notice-container"><div class="notice notice-error inline"><p>'+response.message+"</p></div></div>"),wrapper.find(".spinner").css("visibility","hidden"))},"json")})},user_search:function(){$(document.body).on("click.eddSelectUser",".edd_user_search_results a",function(e){e.preventDefault();var user_id=$(this).data("userid");EDD_Customer.vars.user_id.val(user_id)})},remove_user:function(){$(document.body).on("click","#disconnect-customer",function(e){if(e.preventDefault(),confirm(edd_vars.disconnect_customer)){var postData={edd_action:"disconnect-userid",customer_id:$('input[name="customerinfo[id]"]').val(),_wpnonce:$("#edit-customer-info #_wpnonce").val()};$.post(ajaxurl,postData,function(response){window.location.href=window.location.href},"json")}})},cancel_edit:function(){$(document.body).on("click","#edd-edit-customer-cancel",function(e){e.preventDefault(),EDD_Customer.vars.customer_card_wrap_edit_item.hide(),EDD_Customer.vars.customer_card_wrap_editable.show(),$(".edd_user_search_results").html("")})},change_country:function(){$('select[name="customerinfo[country]"]').change(function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"customerinfo[state]"};return $.post(ajaxurl,data,function(response){"nostates"==response?EDD_Customer.vars.state_input.replaceWith('<input type="text" name="'+data.field_name+'" value="" class="edd-edit-toggles medium-text"/>'):EDD_Customer.vars.state_input.replaceWith(response)}),!1})},add_note:function(){$(document.body).on("click","#add-customer-note",function(e){e.preventDefault();var postData={edd_action:"add-customer-note",customer_id:$("#customer-id").val(),customer_note:EDD_Customer.vars.note.val(),add_customer_note_nonce:$("#add_customer_note_nonce").val()};if(postData.customer_note)$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$("#edd-customer-notes").prepend(response),$(".edd-no-customer-notes").hide(),EDD_Customer.vars.note.val("")}}).fail(function(data){window.console&&window.console.log&&console.log(data)});else{var border_color=EDD_Customer.vars.note.css("border-color");EDD_Customer.vars.note.css("border-color","red"),setTimeout(function(){EDD_Customer.vars.note.css("border-color",border_color)},500)}})},delete_checked:function(){$("#edd-customer-delete-confirm").change(function(){var records_input=$("#edd-customer-delete-records"),submit_button=$("#edd-delete-customer");$(this).prop("checked")?(records_input.attr("disabled",!1),submit_button.attr("disabled",!1)):(records_input.attr("disabled",!0),records_input.prop("checked",!1),submit_button.attr("disabled",!0))})}};EDD_Customer.init(),$(".edd-ajax-user-search").keyup(function(){var user_search=$(this).val(),exclude="";$(this).data("exclude")&&(exclude=$(this).data("exclude")),$(".edd-ajax").show();var data={action:"edd_search_users",user_name:user_search,exclude:exclude};document.body.style.cursor="wait",$.ajax({type:"POST",data:data,dataType:"json",url:ajaxurl,success:function(search_response){$(".edd-ajax").hide(),$(".edd_user_search_results").removeClass("hidden"),$(".edd_user_search_results span").html(""),$(search_response.results).appendTo(".edd_user_search_results span"),document.body.style.cursor="default"}})}),$(document.body).on("click.eddSelectUser",".edd_user_search_results span a",function(e){e.preventDefault();var login=$(this).data("login");$(".edd-ajax-user-search").val(login),$(".edd_user_search_results").addClass("hidden"),$(".edd_user_search_results span").html("")}),$(document.body).on("click.eddCancelUserSearch",".edd_user_search_results a.edd-ajax-user-cancel",function(e){e.preventDefault(),$(".edd-ajax-user-search").val(""),$(".edd_user_search_results").addClass("hidden"),$(".edd_user_search_results span").html("")}),$("#edd_dashboard_sales").length&&$.ajax({type:"GET",data:{action:"edd_load_dashboard_widget"},url:ajaxurl,success:function(response){$("#edd_dashboard_sales .inside").html(response)}}),$(document.body).on("keydown",".customer-note-input",function(e){13==e.keyCode&&(e.metaKey||e.ctrlKey)&&$("#add-customer-note").click()})});var eddFormatCurrency=function(value){var numeric=parseFloat(value),storeCurrency=edd_vars.currency,decimalPlaces=edd_vars.currency_decimals;return numeric.toLocaleString(storeCurrency,{style:"currency",currency:storeCurrency,minimumFractionDigits:decimalPlaces,maximumFractionDigits:decimalPlaces})},eddFormatNumber=function(value){var numeric=parseFloat(value),storeCurrency=edd_vars.currency;edd_vars.currency_decimals;return numeric.toLocaleString(storeCurrency,{style:"decimal",minimumFractionDigits:0,maximumFractionDigits:0})},eddLabelFormatter=function(label,series){return'<div style="font-size:12px; text-align:center; padding:2px">'+label+"</div>"},eddLegendFormatterSales=function(label,series){var slug=label.toLowerCase().replace(/\s/g,"-"),color='<div class="edd-legend-color" style="background-color: '+series.color+'"></div>',value='<div class="edd-pie-legend-item">'+label+": "+Math.round(series.percent)+"% ("+eddFormatNumber(series.data[0][1])+")</div>",item='<div id="'+series.edd_vars.id+slug+'" class="edd-legend-item-wrapper">'+color+value+"</div>";return jQuery("#edd-pie-legend-"+series.edd_vars.id).append(item),item},eddLegendFormatterEarnings=function(label,series){var slug=label.toLowerCase().replace(/\s/g,"-"),color='<div class="edd-legend-color" style="background-color: '+series.color+'"></div>',value='<div class="edd-pie-legend-item">'+label+": "+Math.round(series.percent)+"% ("+eddFormatCurrency(series.data[0][1])+")</div>",item='<div id="'+series.edd_vars.id+slug+'" class="edd-legend-item-wrapper">'+color+value+"</div>";return jQuery("#edd-pie-legend-"+series.edd_vars.id).append(item),item};function edd_attach_tooltips(selector){selector.tooltip({content:function(){return jQuery(this).prop("title")},tooltipClass:"edd-ui-tooltip",position:{my:"center top",at:"center bottom+10",collision:"flipfit"},hide:{duration:200},show:{duration:200}})}function easy_digital_downloads_sendwp_remote_install(){jQuery.post(ajaxurl,{action:"edd_sendwp_remote_install"},function(response){response.success||!confirm(response.data.error)?easy_digital_downloads_sendwp_register_client(response.data.register_url,response.data.client_name,response.data.client_secret,response.data.client_redirect,response.data.partner_id):location.reload()})}function easy_digital_downloads_sendwp_disconnect(){jQuery.post(ajaxurl,{action:"edd_sendwp_disconnect"},function(response){location.reload()})}function easy_digital_downloads_sendwp_register_client(register_url,client_name,client_secret,client_redirect,partner_id){var form=document.createElement("form");function easy_digital_downloads_sendwp_append_form_input(name,value){var input=document.createElement("input");input.setAttribute("type","hidden"),input.setAttribute("name",name),input.setAttribute("value",value),form.appendChild(input)}form.setAttribute("method","POST"),form.setAttribute("action",register_url),easy_digital_downloads_sendwp_append_form_input("client_name",client_name),easy_digital_downloads_sendwp_append_form_input("client_secret",client_secret),easy_digital_downloads_sendwp_append_form_input("client_redirect",client_redirect),easy_digital_downloads_sendwp_append_form_input("partner_id",partner_id),document.body.appendChild(form),form.submit()}function easy_digital_downloads_jilt_remote_install(){jQuery.post(ajaxurl,{action:"edd_jilt_remote_install"},function(response){response.success||!confirm(response.data.error)?easy_digital_downloads_jilt_connect():location.reload()})}function easy_digital_downloads_jilt_connect(){jQuery.post(ajaxurl,{action:"edd_jilt_connect"},function(response){response.success||!confirm(response.data.error)?""===response.data.connect_url||location.assign(response.data.connect_url):location.reload()})}function easy_digital_downloads_jilt_disconnect(){jQuery.post(ajaxurl,{action:"edd_jilt_disconnect"},function(response){response.success||confirm(response.data.error),location.reload()})}
1
+ jQuery(document).ready(function($){edd_attach_tooltips($(".edd-help-tip"));var EDD_Download_Configuration={init:function(){this.add(),this.move(),this.remove(),this.type(),this.prices(),this.files(),this.updatePrices()},clone_repeatable:function(row){var key=highest=1;return row.parent().find(".edd_repeatable_row").each(function(){var current=$(this).data("key");parseInt(current)>highest&&(highest=current)}),key=highest+=1,clone=row.clone(),clone.removeClass("edd_add_blank"),clone.attr("data-key",key),clone.find("input, select, textarea").val("").each(function(){var name=$(this).attr("name"),id=$(this).attr("id");name&&(name=name.replace(/\[(\d+)\]/,"["+parseInt(key)+"]"),$(this).attr("name",name)),$(this).attr("data-key",key),void 0!==id&&(id=id.replace(/(\d+)/,parseInt(key)),$(this).attr("id",id))}),clone.find("select").each(function(){$(this).val(row.find('select[name="'+$(this).attr("name")+'"]').val())}),clone.find('input[type="checkbox"]').each(function(){$(this).is(":checked")&&$(this).prop("checked",!1),$(this).val(1)}),clone.find("span.edd_price_id").each(function(){$(this).text(parseInt(key))}),clone.find("span.edd_file_id").each(function(){$(this).text(parseInt(key))}),clone.find(".edd_repeatable_default_input").each(function(){$(this).val(parseInt(key)).removeAttr("checked")}),clone.find(".edd_repeatable_condition_field").each(function(){$(this).find("option:eq(0)").prop("selected","selected")}),clone.find(".search-choice").remove(),clone.find(".chosen-container").remove(),edd_attach_tooltips(clone.find(".edd-help-tip")),clone},add:function(){$(document.body).on("click",".submit .edd_add_repeatable",function(e){e.preventDefault();var row=$(this).parent().parent().prev(".edd_repeatable_row"),clone=EDD_Download_Configuration.clone_repeatable(row);clone.insertAfter(row).find("input, textarea, select").filter(":visible").eq(0).focus(),clone.find(".edd-select-chosen").chosen({inherit_select_classes:!0,placeholder_text_single:edd_vars.one_option,placeholder_text_multiple:edd_vars.one_or_more_option}),clone.find(".edd-select-chosen").css("width","100%"),clone.find(".edd-select-chosen .chosen-search input").attr("placeholder",edd_vars.search_placeholder)})},move:function(){$(".edd_repeatable_table .edd-repeatables-wrap").sortable({handle:".edd-draghandle-anchor",items:".edd_repeatable_row",opacity:.6,cursor:"move",axis:"y",update:function(){var count=0;$(this).find(".edd_repeatable_row").each(function(){$(this).find("input.edd_repeatable_index").each(function(){$(this).val(count)}),count++})}})},remove:function(){$(document.body).on("click",".edd-remove-row, .edd_remove_repeatable",function(e){e.preventDefault();var firstFocusable,row=$(this).parents(".edd_repeatable_row"),count=row.parent().find(".edd_repeatable_row").length,type=$(this).data("type"),repeatable="div.edd_repeatable_"+type+"s";if(firstFocusable=($(this).is(".ui-sortable .edd_repeatable_row:first-child .edd-remove-row, .ui-sortable .edd_repeatable_row:first-child .edd_remove_repeatable")?row.next(".edd_repeatable_row"):row.prev(".edd_repeatable_row")).find("select, input, textarea, button").filter(":visible").eq(0),"price"===type){var price_row_id=row.data("key");$('.edd_repeatable_condition_field option[value="'+price_row_id+'"]').remove()}if(1<count)$("input, select",row).val(""),row.fadeOut("fast").remove(),firstFocusable.focus();else switch(type){case"price":alert(edd_vars.one_price_min);break;case"file":$("input, select",row).val("");break;default:alert(edd_vars.one_field_min)}$(repeatable).each(function(rowIndex){$(this).find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+rowIndex+"]"),$(this).attr("name",name).attr("id",name)})})})},type:function(){$(document.body).on("change","#_edd_product_type",function(e){var edd_products=$("#edd_products"),edd_download_files=$("#edd_download_files"),edd_download_limit_wrap=$("#edd_download_limit_wrap");"bundle"===$(this).val()?(edd_products.show(),edd_download_files.hide(),edd_download_limit_wrap.hide()):(edd_products.hide(),edd_download_files.show(),edd_download_limit_wrap.show())})},prices:function(){$(document.body).on("change","#edd_variable_pricing",function(e){var checked=$(this).is(":checked"),single=$("#edd_regular_price_field"),variable=$("#edd_variable_price_fields, .edd_repeatable_table .pricing"),bundleRow=$(".edd-bundled-product-row, .edd-repeatable-row-standard-fields");checked?(single.hide(),variable.show(),bundleRow.addClass("has-variable-pricing")):(single.show(),variable.hide(),bundleRow.removeClass("has-variable-pricing"))})},files:function(){var file_frame;window.formfield="",$(document.body).on("click",".edd_upload_file_button",function(e){e.preventDefault();var button=$(this);window.formfield=$(this).closest(".edd_repeatable_upload_wrapper"),file_frame||((file_frame=wp.media.frames.file_frame=wp.media({frame:"post",state:"insert",title:button.data("uploader-title"),button:{text:button.data("uploader-button-text")},multiple:"0"!=$(this).data("multiple")})).on("menu:render:default",function(view){view.unset("library-separator"),view.unset("gallery"),view.unset("featured-image"),view.unset("embed"),view.set({})}),file_frame.on("insert",function(){file_frame.state().get("selection").each(function(attachment,index){var selectedSize="image"===(attachment=attachment.toJSON()).type&&$(".attachment-display-settings .size option:selected").val(),selectedURL=attachment.url,selectedName=0<attachment.title.length?attachment.title:attachment.filename;if(selectedSize&&void 0!==attachment.sizes[selectedSize]&&(selectedURL=attachment.sizes[selectedSize].url),"image"===attachment.type&&(selectedName=selectedSize&&void 0!==attachment.sizes[selectedSize]?selectedName+"-"+attachment.sizes[selectedSize].width+"x"+attachment.sizes[selectedSize].height:selectedName+"-"+attachment.width+"x"+attachment.height),0===index)window.formfield.find(".edd_repeatable_attachment_id_field").val(attachment.id),window.formfield.find(".edd_repeatable_thumbnail_size_field").val(selectedSize),window.formfield.find(".edd_repeatable_upload_field").val(selectedURL),window.formfield.find(".edd_repeatable_name_field").val(selectedName);else{var row=window.formfield,clone=EDD_Download_Configuration.clone_repeatable(row);clone.find(".edd_repeatable_attachment_id_field").val(attachment.id),clone.find(".edd_repeatable_thumbnail_size_field").val(selectedSize),clone.find(".edd_repeatable_upload_field").val(selectedURL),clone.find(".edd_repeatable_name_field").val(selectedName),clone.insertAfter(row)}})})),file_frame.open()}),window.formfield=""},updatePrices:function(){$("#edd_price_fields").on("keyup",".edd_variable_prices_name",function(){var key=$(this).parents(".edd_repeatable_row").data("key"),name=$(this).val(),field_option=$(".edd_repeatable_condition_field option[value="+key+"]");0<field_option.length?field_option.text(name):$(".edd_repeatable_condition_field").append($("<option></option>").attr("value",key).text(name))})}};$(document.body).on("click",".toggle-custom-price-option-section",function(e){e.preventDefault();var show=$(this).html()==edd_vars.show_advanced_settings;show?$(this).html(edd_vars.hide_advanced_settings):$(this).html(edd_vars.show_advanced_settings);var header=$(this).parents(".edd-repeatable-row-header");header.siblings(".edd-custom-price-option-sections-wrap").slideToggle(),$(":input:not(input[type=button],input[type=submit],button):visible:first",show?header.siblings(".edd-custom-price-option-sections-wrap"):header.siblings(".edd-repeatable-row-standard-fields")).focus()}),EDD_Download_Configuration.init();var typingTimer,edd_datepicker=$(".edd_datepicker");if(0<edd_datepicker.length){edd_datepicker.datepicker({dateFormat:"mm/dd/yy"})}({init:function(){this.edit_address(),this.remove_download(),this.add_download(),this.change_customer(),this.new_customer(),this.edit_price(),this.recalculate_total(),this.variable_prices_check(),this.add_note(),this.remove_note(),this.resend_receipt(),this.copy_download_link()},edit_address:function(){$('select[name="edd-payment-address[0][country]"]').change(function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"edd-payment-address[0][state]"};return $.post(ajaxurl,data,function(response){var state_wrapper=$("#edd-order-address-state-wrap select, #edd-order-address-state-wrap input");$("#edd-order-address-state-wrap .chosen-container").remove(),"nostates"==response?state_wrapper.replaceWith('<input type="text" name="edd-payment-address[0][state]" value="" class="edd-edit-toggles medium-text"/>'):state_wrapper.replaceWith(response)}),!1})},remove_download:function(){$("#edd-purchased-files").on("click",".edd-order-remove-download",function(){if(1===$(document.body).find("#edd-purchased-files > .row:not(.header)").length)return alert(edd_vars.one_download_min),!1;if(confirm(edd_vars.delete_payment_download)){var key=$(this).data("key"),download_id=($(".edd-payment-id").val(),$('input[name="edd-payment-details-downloads['+key+'][id]"]').val()),price_id=$('input[name="edd-payment-details-downloads['+key+'][price_id]"]').val(),quantity=$('input[name="edd-payment-details-downloads['+key+'][quantity]"]').val(),amount=$('input[name="edd-payment-details-downloads['+key+'][amount]"]').val();if($('input[name="edd-payment-details-downloads['+key+'][tax]"]').length)var fees=$('input[name="edd-payment-details-downloads['+key+'][tax]"]').val();if($('input[name="edd-payment-details-downloads['+key+'][fees]"]').length)fees=$.parseJSON($('input[name="edd-payment-details-downloads['+key+'][fees]"]').val());var currently_removed=$('input[name="edd-payment-removed"]').val();(currently_removed=$.parseJSON(currently_removed)).length<1&&(currently_removed={});var removed_item=[{id:download_id,price_id:price_id,quantity:quantity,amount:amount,cart_index:key}];currently_removed[key]=removed_item,$('input[name="edd-payment-removed"]').val(JSON.stringify(currently_removed)),$(this).parent().parent().remove(),fees&&fees.length&&$.each(fees,function(key,value){$('*li[data-fee-id="'+value+'"]').remove()}),$("#edd-payment-downloads-changed").val(1),$(".edd-order-payment-recalc-totals").show()}return!1})},change_customer:function(){$("#edd-customer-details").on("click",".edd-payment-change-customer, .edd-payment-change-customer-cancel",function(e){e.preventDefault();var change_customer=$(this).hasClass("edd-payment-change-customer"),cancel=$(this).hasClass("edd-payment-change-customer-cancel");change_customer?($(".customer-info").hide(),$(".change-customer").show(),$(".edd-payment-change-customer-input").css("width","auto")):cancel&&($(".customer-info").show(),$(".change-customer").hide())})},new_customer:function(){$("#edd-customer-details").on("click",".edd-payment-new-customer, .edd-payment-new-customer-cancel",function(e){e.preventDefault();var new_customer=$(this).hasClass("edd-payment-new-customer"),cancel=$(this).hasClass("edd-payment-new-customer-cancel");new_customer?($(".customer-info").hide(),$(".new-customer").show()):cancel&&($(".customer-info").show(),$(".new-customer").hide());new_customer=$("#edd-new-customer");$(".new-customer").is(":visible")?new_customer.val(1):new_customer.val(0)})},add_download:function(){$(".edd-edit-purchase-element").on("click","#edd-order-add-download",function(e){e.preventDefault();var order_download_select=$("#edd_order_download_select"),order_download_quantity=$("#edd-order-download-quantity"),order_download_price=$("#edd-order-download-price"),order_download_tax=$("#edd-order-download-tax"),selected_price_option=$(".edd_price_options_select option:selected"),download_id=order_download_select.val(),download_title=order_download_select.find(":selected").text(),quantity=order_download_quantity.val(),item_price=order_download_price.val(),item_tax=order_download_tax.val(),price_id=selected_price_option.val(),price_name=selected_price_option.text();if(download_id<1)return!1;if(item_price||(item_price=0),item_price=parseFloat(item_price),isNaN(item_price))return alert(edd_vars.numeric_item_price),!1;if(item_tax=parseFloat(item_tax),isNaN(item_tax))return alert(edd_vars.numeric_item_tax),!1;if(isNaN(parseInt(quantity)))return alert(edd_vars.numeric_quantity),!1;price_name&&(download_title=download_title+" - "+price_name);var count=$("#edd-purchased-files div.row:not(.edd-purchased-files-header)").length;0==count&&alert(edd_vars.no_downloads_error);var clone=$("#edd-purchased-files div.row:not(.edd-purchased-files-header):last").clone();clone.find(".download span").html('<a href="post.php?post='+download_id+'&action=edit"></a>'),clone.find(".download span a").text(download_title),clone.find(".edd-payment-details-download-item-price").val(item_price.toFixed(edd_vars.currency_decimals)),clone.find(".edd-payment-details-download-item-tax").val(item_tax.toFixed(edd_vars.currency_decimals)),clone.find("input.edd-payment-details-download-id").val(download_id),clone.find("input.edd-payment-details-download-price-id").val(price_id);var item_total=item_price*quantity+item_tax;item_total=item_total.toFixed(edd_vars.currency_decimals),clone.find("span.edd-payment-details-download-amount").text(item_total),clone.find("input.edd-payment-details-download-amount").val(item_total),clone.find("input.edd-payment-details-download-quantity").val(quantity),clone.find("input.edd-payment-details-download-has-log").val(0),clone.find(".edd-copy-download-link-wrapper").remove(),clone.find("input").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("name",name).attr("id",name)}),clone.find("a.edd-order-remove-download").attr("data-key",parseInt(count)),$("#edd-payment-downloads-changed").val(1),$("#edd-purchased-files div.row .edd-purchased-download-title .deleted").length&&$("#edd-purchased-files div.row:last").remove(),$(clone).insertAfter("#edd-purchased-files div.row:last"),$(".edd-order-payment-recalc-totals").show(),$(".edd-add-download-field").val("")})},edit_price:function(){$(document.body).on("change keyup",".edd-payment-item-input",function(){var row=$(this).parents("ul.edd-purchased-files-list-wrapper");$(".edd-order-payment-recalc-totals").show();var quantity=row.find("input.edd-payment-details-download-quantity").val().replace(edd_vars.thousands_separator,""),item_price=row.find("input.edd-payment-details-download-item-price").val().replace(edd_vars.thousands_separator,""),item_tax=row.find("input.edd-payment-details-download-item-tax").val().replace(edd_vars.thousands_separator,"");if(item_price=parseFloat(item_price),isNaN(item_price))return alert(edd_vars.numeric_item_price),!1;item_tax=parseFloat(item_tax),isNaN(item_tax)&&(item_tax=0),isNaN(parseInt(quantity))&&(quantity=1);var item_total=item_price*quantity+item_tax;item_total=item_total.toFixed(edd_vars.currency_decimals),row.find("input.edd-payment-details-download-amount").val(item_total),row.find("span.edd-payment-details-download-amount").text(item_total)})},recalculate_total:function(){$("#edd-order-recalc-total").on("click",function(e){e.preventDefault();var total=0,tax=0,totals=$("#edd-purchased-files .row input.edd-payment-details-download-amount"),taxes=$("#edd-purchased-files .row input.edd-payment-details-download-item-tax");totals.length&&totals.each(function(){total+=parseFloat($(this).val())}),taxes.length&&taxes.each(function(){tax+=parseFloat($(this).val())}),$(".edd-payment-fees").length&&$(".edd-payment-fees span.fee-amount").each(function(){total+=parseFloat($(this).data("fee"))}),$("input[name=edd-payment-total]").val(total.toFixed(edd_vars.currency_decimals)),$("input[name=edd-payment-tax]").val(tax.toFixed(edd_vars.currency_decimals))})},variable_prices_check:function(){$(".edd-edit-purchase-element").on("change","select#edd_order_download_select",function(){var $this=$(this),download_id=$this.val();if(0<parseInt(download_id)){var postData={action:"edd_check_for_download_price_variations",download_id:download_id};$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$(".edd_price_options_select").remove(),$(response).insertAfter($this.next())}}).fail(function(data){window.console&&window.console.log&&console.log(data)})}})},add_note:function(){$("#edd-add-payment-note").on("click",function(e){e.preventDefault();var postData={action:"edd_insert_payment_note",payment_id:$(this).data("payment-id"),note:$("#edd-payment-note").val()};if(postData.note)$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$("#edd-payment-notes-inner").append(response),$(".edd-no-payment-notes").hide(),$("#edd-payment-note").val("")}}).fail(function(data){window.console&&window.console.log&&console.log(data)});else{var border_color=$("#edd-payment-note").css("border-color");$("#edd-payment-note").css("border-color","red"),setTimeout(function(){$("#edd-payment-note").css("border-color",border_color)},500)}})},remove_note:function(){$(document.body).on("click",".edd-delete-payment-note",function(e){if(e.preventDefault(),confirm(edd_vars.delete_payment_note)){var postData={action:"edd_delete_payment_note",payment_id:$(this).data("payment-id"),note_id:$(this).data("note-id")};return $.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){return $("#edd-payment-note-"+postData.note_id).remove(),$(".edd-payment-note").length||$(".edd-no-payment-notes").show(),!1}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!0}})},resend_receipt:function(){var emails_wrap=$(".edd-order-resend-receipt-addresses");$(document.body).on("click","#edd-select-receipt-email",function(e){e.preventDefault(),emails_wrap.slideDown()}),$(document.body).on("change",".edd-order-resend-receipt-email",function(){var href=$("#edd-select-receipt-email").prop("href")+"&email="+$(this).val();confirm(edd_vars.resend_receipt)&&(window.location=href)}),$(document.body).on("click","#edd-resend-receipt",function(e){return confirm(edd_vars.resend_receipt)})},copy_download_link:function(){$(document.body).on("click",".edd-copy-download-link",function(e){e.preventDefault();var $this=$(this),postData={action:"edd_get_file_download_link",payment_id:$('input[name="edd_payment_id"]').val(),download_id:$this.data("download-id"),price_id:$this.data("price-id")};$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(link){return $("#edd-download-link").dialog({width:400}).html('<textarea rows="10" cols="40" id="edd-download-link-textarea">'+link+"</textarea>"),$("#edd-download-link-textarea").focus().select(),!1}}).fail(function(data){window.console&&window.console.log&&console.log(data)})})}}).init(),{init:function(){this.type_select(),this.product_requirements()},type_select:function(){$("#edd-edit-discount #edd-type, #edd-add-discount #edd-type").change(function(){var val=$(this).val();$(".edd-amount-description").hide(),$(".edd-amount-description."+val+"-discount").show()})},product_requirements:function(){$("#products").change(function(){var product_conditions=$("#edd-discount-product-conditions");$(this).val()?product_conditions.show():product_conditions.hide()})}}.init(),{init:function(){this.date_options(),this.customers_export()},date_options:function(){$("#edd-graphs-date-options").change(function(){var $this=$(this),date_range_options=$("#edd-date-range-options");"other"===$this.val()?date_range_options.show():date_range_options.hide()})},customers_export:function(){$("#edd_customer_export_download").change(function(){var $this=$(this),download_id=$("option:selected",$this).val(),customer_export_option=$("#edd_customer_export_option");if("0"===$this.val()?customer_export_option.show():customer_export_option.hide(),0!=parseInt(download_id)){var data={action:"edd_check_for_download_price_variations",download_id:download_id,all_prices:!0},price_options_select=$(".edd_price_options_select");$.post(ajaxurl,data,function(response){price_options_select.remove(),$("#edd_customer_export_download_chosen").after(response)})}else price_options_select.remove()})}}.init(),{init:function(){this.general(),this.taxes(),this.emails(),this.misc()},general:function(){var edd_color_picker=$(".edd-color-picker");if(edd_color_picker.length&&edd_color_picker.wpColorPicker(),"undefined"==typeof wp||"1"!==edd_vars.new_media_ui){var edd_settings_upload_button=$(".edd_settings_upload_button");0<edd_settings_upload_button.length&&(window.formfield="",$(document.body).on("click",edd_settings_upload_button,function(e){e.preventDefault(),window.formfield=$(this).parent().prev(),window.tbframe_interval=setInterval(function(){jQuery("#TB_iframeContent").contents().find(".savesend .button").val(edd_vars.use_this_file).end().find("#insert-gallery, .wp-post-thumbnail").hide()},2e3),tb_show(edd_vars.add_new_download,"media-upload.php?TB_iframe=true")}),window.edd_send_to_editor=window.send_to_editor,window.send_to_editor=function(html){window.formfield?(imgurl=$("a","<div>"+html+"</div>").attr("href"),window.formfield.val(imgurl),window.clearInterval(window.tbframe_interval),tb_remove()):window.edd_send_to_editor(html),window.send_to_editor=window.edd_send_to_editor,window.formfield="",window.imagefield=!1})}else{var file_frame;window.formfield="",$(document.body).on("click",".edd_settings_upload_button",function(e){e.preventDefault();var button=$(this);window.formfield=$(this).parent().prev(),file_frame||((file_frame=wp.media.frames.file_frame=wp.media({frame:"post",state:"insert",title:button.data("uploader_title"),button:{text:button.data("uploader_button_text")},multiple:!1})).on("menu:render:default",function(view){view.unset("library-separator"),view.unset("gallery"),view.unset("featured-image"),view.unset("embed"),view.set({})}),file_frame.on("insert",function(){file_frame.state().get("selection").each(function(attachment,index){attachment=attachment.toJSON(),window.formfield.val(attachment.url)})})),file_frame.open()}),window.formfield=""}},taxes:function(){var no_states=$("select.edd-no-states");no_states.length&&no_states.closest("tr").addClass("hidden"),$('select[name="edd_settings[base_country]"]').change(function(){var $this=$(this),$tr=$this.closest("tr"),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"edd_settings[base_state]"};return $.post(ajaxurl,data,function(response){"nostates"==response?$tr.next().addClass("hidden"):($tr.next().removeClass("hidden"),$tr.next().find("select").replaceWith(response))}),!1}),$(document.body).on("change","#edd_tax_rates select.edd-tax-country",function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:$this.attr("name").replace("country","state")};return $.post(ajaxurl,data,function(response){if("nostates"==response){var text_field='<input type="text" name="'+data.field_name+'" value=""/>';$this.parent().next().find("select").replaceWith(text_field)}else $this.parent().next().find("input,select").show(),$this.parent().next().find("input,select").replaceWith(response)}),!1}),$("#edd_add_tax_rate").on("click",function(){var row=$("#edd_tax_rates tr:last"),clone=row.clone(),count=row.parent().find("tr").length;return clone.find("td input").not(":input[type=checkbox]").val(""),clone.find('td [type="checkbox"]').attr("checked",!1),clone.find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("name",name).attr("id",name)}),clone.find("label").each(function(){var name=$(this).attr("for");name=name.replace(/\[(\d+)\]/,"["+parseInt(count)+"]"),$(this).attr("for",name)}),clone.insertAfter(row),!1}),$(document.body).on("click","#edd_tax_rates .edd_remove_tax_rate",function(){confirm(edd_vars.delete_tax_rate)&&(2===$("#edd_tax_rates tr:visible").length?($("#edd_tax_rates select").val(""),$('#edd_tax_rates input[type="text"]').val(""),$('#edd_tax_rates input[type="number"]').val(""),$('#edd_tax_rates input[type="checkbox"]').attr("checked",!1)):$(this).closest("tr").remove(),$("#edd_tax_rates tr").each(function(rowIndex){$(this).children().find("input, select").each(function(){var name=$(this).attr("name");name=name.replace(/\[(\d+)\]/,"["+(rowIndex-1)+"]"),$(this).attr("name",name).attr("id",name)})}));return!1})},emails:function(){$("#edd-sendwp-connect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading"></span>'),document.body.style.cursor="wait",easy_digital_downloads_sendwp_remote_install()}),$("#edd-sendwp-disconnect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading dark"></span>'),document.body.style.cursor="wait",easy_digital_downloads_sendwp_disconnect()}),$("#edd-jilt-connect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading"></span>'),document.body.style.cursor="wait",easy_digital_downloads_jilt_remote_install()}),$("#edd-jilt-disconnect").on("click",function(e){e.preventDefault(),$(this).html(edd_vars.wait+' <span class="edd-loading dark"></span>'),document.body.style.cursor="wait",easy_digital_downloads_jilt_disconnect()})},misc:function(){var downloadMethod=$('select[name="edd_settings[download_method]"]'),symlink=downloadMethod.parent().parent().next();"direct"==downloadMethod.val()&&(symlink.hide(),symlink.find("input").prop("checked",!1)),downloadMethod.on("change",function(){"direct"==$(this).val()?(symlink.hide(),symlink.find("input").prop("checked",!1)):symlink.show()})}}.init(),$(".download_page_edd-payment-history .row-actions .delete a, a.edd-delete-payment").on("click",function(){return!!confirm(edd_vars.delete_payment)}),$("body").on("click","#the-list .editinline",function(){var post_id=$(this).closest("tr").attr("id");post_id=post_id.replace("post-","");var regprice=$("#post-"+post_id).find(".column-price .downloadprice-"+post_id).val();regprice!=$("#post-"+post_id+".column-price .downloadprice-"+post_id).val()?$(".regprice","#edd-download-data").val(regprice).attr("disabled",!1):$(".regprice","#edd-download-data").val(edd_vars.quick_edit_warning).attr("disabled","disabled")}),$(document.body).on("click","#bulk_edit",function(){var $bulk_row=$("#bulk-edit"),$post_ids=new Array;$bulk_row.find("#bulk-titles").children().each(function(){$post_ids.push($(this).attr("id").replace(/^(ttle)/i,""))});var $price=$('#edd-download-data input[name="_edd_regprice"]').val(),data={action:"edd_save_bulk_edit",edd_bulk_nonce:$post_ids,post_ids:$post_ids,price:$price};$.post(ajaxurl,data)}),$(".edd-select-chosen").chosen({inherit_select_classes:!0,placeholder_text_single:edd_vars.one_option,placeholder_text_multiple:edd_vars.one_or_more_option}),$(".edd-select-chosen .chosen-search input").each(function(){var selectElem=$(this).parent().parent().parent().prev("select.edd-select-chosen"),placeholder=(selectElem.data("search-type"),selectElem.data("search-placeholder"));$(this).attr("placeholder",placeholder)}),$(".chosen-choices").on("click",function(){var placeholder=$(this).parent().prev().data("search-placeholder");void 0===placeholder&&(placeholder=edd_vars.type_to_search),$(this).children("li").children("input").attr("placeholder",placeholder)});$(document.body).on("keyup",".edd-select.chosen-container .chosen-search input, .edd-select.chosen-container .search-field input",function(e){var val=$(this).val(),container=$(this).closest(".edd-select-chosen"),select=(container.attr("id").replace("_chosen",""),container.prev()),no_bundles=container.hasClass("no-bundles"),variations=container.hasClass("variations"),lastKey=e.which,search_type="edd_download_search";if(container.prev().data("search-type")){if("no_ajax"==select.data("search-type"))return;search_type="edd_"+select.data("search-type")+"_search"}val.length<=3&&"edd_download_search"==search_type||16==lastKey||13==lastKey||91==lastKey||17==lastKey||37==lastKey||38==lastKey||39==lastKey||40==lastKey||(clearTimeout(typingTimer),typingTimer=setTimeout(function(){$.ajax({type:"GET",url:ajaxurl,data:{action:search_type,s:val,no_bundles:no_bundles,variations:variations},dataType:"json",beforeSend:function(){select.closest("ul.chosen-results").empty()},success:function(data){$("option:not(:selected)",select).remove(),$.each(data,function(key,item){$('option[value="'+item.id+'"]',select).length||select.prepend('<option value="'+item.id+'">'+item.name+"</option>")}),$(".edd-select-chosen").trigger("chosen:updated"),select.next().find("input").val(val)}}).fail(function(response){window.console&&window.console.log&&console.log(response)}).done(function(response){})},342))}),$("#post").on("click",".edd-thickbox",function(){$(".edd-select-chosen","#choose-download").css("width","100%")}),{init:function(){this.revoke_api_key(),this.regenerate_api_key(),this.create_api_key(),this.recount_stats()},revoke_api_key:function(){$(document.body).on("click",".edd-revoke-api-key",function(e){return confirm(edd_vars.revoke_api_key)})},regenerate_api_key:function(){$(document.body).on("click",".edd-regenerate-api-key",function(e){return confirm(edd_vars.regenerate_api_key)})},create_api_key:function(){$(document.body).on("submit","#api-key-generate-form",function(e){var input=$('input[type="text"][name="user_id"]');input.css("border-color","#ddd");var user_id=input.val();if(user_id.length<1||0==user_id)return input.css("border-color","#ff0000"),!1})},recount_stats:function(){$(document.body).on("change","#recount-stats-type",function(){var export_form=$("#edd-tools-recount-form"),selected_type=$("option:selected",this).data("type"),submit_button=$("#recount-stats-submit"),products=$("#tools-product-dropdown");if(export_form.find(".notice-wrap").remove(),submit_button.removeClass("button-disabled").attr("disabled",!1),products.hide(),$(".edd-recount-stats-descriptions span").hide(),"recount-download"===selected_type)products.show(),products.find(".edd-select-chosen").css("width","auto");else if("reset-stats"===selected_type){export_form.append('<div class="notice-wrap"></div>'),export_form.find(".notice-wrap").html('<div class="notice notice-warning"><p><input type="checkbox" id="confirm-reset" name="confirm_reset_store" value="1" /> <label for="confirm-reset">'+edd_vars.reset_stats_warn+"</label></p></div>"),$("#recount-stats-submit").addClass("button-disabled").attr("disabled","disabled")}else products.hide(),products.val(0);$("#"+selected_type).show()}),$(document.body).on("change","#confirm-reset",function(){$(this).is(":checked")?$("#recount-stats-submit").removeClass("button-disabled").removeAttr("disabled"):$("#recount-stats-submit").addClass("button-disabled").attr("disabled","disabled")}),$("#edd-tools-recount-form").submit(function(e){var selection=$("#recount-stats-type").val(),export_form=$(this),selected_type=$("option:selected",this).data("type");if("reset-stats"===selected_type){if($("#confirm-reset").is(":checked"))return!0;has_errors=!0}export_form.find(".notice-wrap").remove(),export_form.append('<div class="notice-wrap"></div>');var notice_wrap=export_form.find(".notice-wrap"),has_errors=!1;(null!==selection&&0!==selection||(notice_wrap.html('<div class="updated error"><p>'+edd_vars.batch_export_no_class+"</p></div>"),has_errors=!0),"recount-download"===selected_type)&&(0==$('select[name="download_id"]').val()&&(notice_wrap.html('<div class="updated error"><p>'+edd_vars.batch_export_no_reqs+"</p></div>"),has_errors=!0));if(has_errors)return export_form.find(".button-disabled").removeClass("button-disabled"),!1})}}.init(),{init:function(){this.submit(),this.dismiss_message()},submit:function(){var self=this;$(document.body).on("submit",".edd-export-form",function(e){e.preventDefault();var submitButton=$(this).find('input[type="submit"]');if(!submitButton.hasClass("button-disabled")){var data=$(this).serialize();submitButton.addClass("button-disabled"),$(this).find(".notice-wrap").remove(),$(this).append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),self.process_step(1,data,self)}})},process_step:function(step,data,self){$.ajax({type:"POST",url:ajaxurl,data:{form:data,action:"edd_do_ajax_export",step:step},dataType:"json",success:function(response){if("done"==response.step||response.error||response.success){var export_form=$(".edd-export-form").find(".edd-progress").parent().parent(),notice_wrap=export_form.find(".notice-wrap");if(export_form.find(".button-disabled").removeClass("button-disabled"),response.error){var error_message=response.message;notice_wrap.html('<div class="updated error"><p>'+error_message+"</p></div>")}else if(response.success){var success_message=response.message;notice_wrap.html('<div id="edd-batch-success" class="updated notice is-dismissible"><p>'+success_message+'<span class="notice-dismiss"></span></p></div>')}else notice_wrap.remove(),window.location=response.url}else $(".edd-progress div").animate({width:response.percentage+"%"},50,function(){}),self.process_step(parseInt(response.step),data,self)}}).fail(function(response){window.console&&window.console.log&&console.log(response)})},dismiss_message:function(){$(document.body).on("click","#edd-batch-success .notice-dismiss",function(){$("#edd-batch-success").parent().slideUp("fast")})}}.init();var EDD_Import={init:function(){this.submit()},submit:function(){$(".edd-import-form").ajaxForm({beforeSubmit:this.before_submit,success:this.success,complete:this.complete,dataType:"json",error:this.error})},before_submit:function(arr,$form,options){if($form.find(".notice-wrap").remove(),$form.append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),!(window.File&&window.FileReader&&window.FileList&&window.Blob)){var import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");return import_form.find(".button-disabled").removeClass("button-disabled"),notice_wrap.html('<div class="update error"><p>'+edd_vars.unsupported_browser+"</p></div>"),!1}},success:function(responseText,statusText,xhr,$form){},complete:function(xhr){var response=jQuery.parseJSON(xhr.responseText);if(response.success){var $form=$(".edd-import-form .notice-wrap").parent();$form.find(".edd-import-file-wrap,.notice-wrap").remove(),$form.find(".edd-import-options").slideDown();var select=$form.find("select.edd-import-csv-column"),options=(select.parents("tr").first(),""),columns=response.data.columns.sort(function(a,b){return a<b?-1:b<a?1:0});$.each(columns,function(key,value){options+='<option value="'+value+'">'+value+"</option>"}),select.append(options),select.on("change",function(){var $key=$(this).val();$key&&0!=response.data.first_row[$key]?$(this).parent().next().html(response.data.first_row[$key]):$(this).parent().next().html("")}),$.each(select,function(){$(this).val($(this).attr("data-field")).change()}),$(document.body).on("click",".edd-import-proceed",function(e){e.preventDefault(),$form.append('<div class="notice-wrap"><span class="spinner is-active"></span><div class="edd-progress"><div></div></div></div>'),response.data.mapping=$form.serialize(),EDD_Import.process_step(1,response.data,self)})}else EDD_Import.error(xhr)},error:function(xhr){var response=jQuery.parseJSON(xhr.responseText),import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");import_form.find(".button-disabled").removeClass("button-disabled"),response.data.error?notice_wrap.html('<div class="update error"><p>'+response.data.error+"</p></div>"):notice_wrap.remove()},process_step:function(step,import_data,self){$.ajax({type:"POST",url:ajaxurl,data:{form:import_data.form,nonce:import_data.nonce,class:import_data.class,upload:import_data.upload,mapping:import_data.mapping,action:"edd_do_ajax_import",step:step},dataType:"json",success:function(response){if("done"==response.data.step||response.data.error){var import_form=$(".edd-import-form").find(".edd-progress").parent().parent(),notice_wrap=import_form.find(".notice-wrap");import_form.find(".button-disabled").removeClass("button-disabled"),response.data.error?notice_wrap.html('<div class="update error"><p>'+response.data.error+"</p></div>"):(import_form.find(".edd-import-options").hide(),$("html, body").animate({scrollTop:import_form.parent().offset().top},500),notice_wrap.html('<div class="updated"><p>'+response.data.message+"</p></div>"))}else $(".edd-progress div").animate({width:response.data.percentage+"%"},50,function(){}),EDD_Import.process_step(parseInt(response.data.step),import_data,self)}}).fail(function(response){window.console&&window.console.log&&console.log(response)})}};EDD_Import.init();var EDD_Customer={vars:{customer_card_wrap_editable:$(".edd-customer-card-wrapper .editable"),customer_card_wrap_edit_item:$(".edd-customer-card-wrapper .edit-item"),user_id:$('input[name="customerinfo[user_id]"]'),state_input:$(':input[name="customerinfo[state]"]'),note:$("#customer-note")},init:function(){this.edit_customer(),this.add_email(),this.user_search(),this.remove_user(),this.cancel_edit(),this.change_country(),this.add_note(),this.delete_checked()},edit_customer:function(){$(document.body).on("click","#edit-customer",function(e){e.preventDefault(),EDD_Customer.vars.customer_card_wrap_editable.hide(),EDD_Customer.vars.customer_card_wrap_edit_item.fadeIn().css("display","block")})},add_email:function(){$(document.body).on("click","#add-customer-email",function(e){e.preventDefault();var button=$(this),wrapper=button.parent();wrapper.parent().find(".notice-container").remove(),wrapper.find(".spinner").css("visibility","visible"),button.attr("disabled",!0);var postData={edd_action:"customer-add-email",customer_id:wrapper.find('input[name="customer-id"]').val(),email:wrapper.find('input[name="additional-email"]').val(),primary:wrapper.find('input[name="make-additional-primary"]').is(":checked"),_wpnonce:wrapper.find('input[name="add_email_nonce"]').val()};$.post(ajaxurl,postData,function(response){!0===response.success?window.location.href=response.redirect:(button.attr("disabled",!1),wrapper.after('<div class="notice-container"><div class="notice notice-error inline"><p>'+response.message+"</p></div></div>"),wrapper.find(".spinner").css("visibility","hidden"))},"json")})},user_search:function(){$(document.body).on("click.eddSelectUser",".edd_user_search_results a",function(e){e.preventDefault();var user_id=$(this).data("userid");EDD_Customer.vars.user_id.val(user_id)})},remove_user:function(){$(document.body).on("click","#disconnect-customer",function(e){if(e.preventDefault(),confirm(edd_vars.disconnect_customer)){var postData={edd_action:"disconnect-userid",customer_id:$('input[name="customerinfo[id]"]').val(),_wpnonce:$("#edit-customer-info #_wpnonce").val()};$.post(ajaxurl,postData,function(response){window.location.href=window.location.href},"json")}})},cancel_edit:function(){$(document.body).on("click","#edd-edit-customer-cancel",function(e){e.preventDefault(),EDD_Customer.vars.customer_card_wrap_edit_item.hide(),EDD_Customer.vars.customer_card_wrap_editable.show(),$(".edd_user_search_results").html("")})},change_country:function(){$('select[name="customerinfo[country]"]').change(function(){var $this=$(this),data={action:"edd_get_shop_states",country:$this.val(),nonce:$this.data("nonce"),field_name:"customerinfo[state]"};return $.post(ajaxurl,data,function(response){"nostates"==response?EDD_Customer.vars.state_input.replaceWith('<input type="text" name="'+data.field_name+'" value="" class="edd-edit-toggles medium-text"/>'):EDD_Customer.vars.state_input.replaceWith(response)}),!1})},add_note:function(){$(document.body).on("click","#add-customer-note",function(e){e.preventDefault();var postData={edd_action:"add-customer-note",customer_id:$("#customer-id").val(),customer_note:EDD_Customer.vars.note.val(),add_customer_note_nonce:$("#add_customer_note_nonce").val()};if(postData.customer_note)$.ajax({type:"POST",data:postData,url:ajaxurl,success:function(response){$("#edd-customer-notes").prepend(response),$(".edd-no-customer-notes").hide(),EDD_Customer.vars.note.val("")}}).fail(function(data){window.console&&window.console.log&&console.log(data)});else{var border_color=EDD_Customer.vars.note.css("border-color");EDD_Customer.vars.note.css("border-color","red"),setTimeout(function(){EDD_Customer.vars.note.css("border-color",border_color)},500)}})},delete_checked:function(){$("#edd-customer-delete-confirm").change(function(){var records_input=$("#edd-customer-delete-records"),submit_button=$("#edd-delete-customer");$(this).prop("checked")?(records_input.attr("disabled",!1),submit_button.attr("disabled",!1)):(records_input.attr("disabled",!0),records_input.prop("checked",!1),submit_button.attr("disabled",!0))})}};EDD_Customer.init(),$(".edd-ajax-user-search").keyup(function(){var user_search=$(this).val(),exclude="";$(this).data("exclude")&&(exclude=$(this).data("exclude")),$(".edd-ajax").show();var data={action:"edd_search_users",user_name:user_search,exclude:exclude};document.body.style.cursor="wait",$.ajax({type:"POST",data:data,dataType:"json",url:ajaxurl,success:function(search_response){$(".edd-ajax").hide(),$(".edd_user_search_results").removeClass("hidden"),$(".edd_user_search_results span").html(""),$(search_response.results).appendTo(".edd_user_search_results span"),document.body.style.cursor="default"}})}),$(document.body).on("click.eddSelectUser",".edd_user_search_results span a",function(e){e.preventDefault();var login=$(this).data("login");$(".edd-ajax-user-search").val(login),$(".edd_user_search_results").addClass("hidden"),$(".edd_user_search_results span").html("")}),$(document.body).on("click.eddCancelUserSearch",".edd_user_search_results a.edd-ajax-user-cancel",function(e){e.preventDefault(),$(".edd-ajax-user-search").val(""),$(".edd_user_search_results").addClass("hidden"),$(".edd_user_search_results span").html("")}),$("#edd_dashboard_sales").length&&$.ajax({type:"GET",data:{action:"edd_load_dashboard_widget"},url:ajaxurl,success:function(response){$("#edd_dashboard_sales .inside").html(response)}}),$(document.body).on("keydown",".customer-note-input",function(e){13==e.keyCode&&(e.metaKey||e.ctrlKey)&&$("#add-customer-note").click()})});var eddFormatCurrency=function(value){var numeric=parseFloat(value),storeCurrency=edd_vars.currency,decimalPlaces=edd_vars.currency_decimals;return numeric.toLocaleString(storeCurrency,{style:"currency",currency:storeCurrency,minimumFractionDigits:decimalPlaces,maximumFractionDigits:decimalPlaces})},eddFormatNumber=function(value){var numeric=parseFloat(value),storeCurrency=edd_vars.currency;edd_vars.currency_decimals;return numeric.toLocaleString(storeCurrency,{style:"decimal",minimumFractionDigits:0,maximumFractionDigits:0})},eddLabelFormatter=function(label,series){return'<div style="font-size:12px; text-align:center; padding:2px">'+label+"</div>"},eddLegendFormatterSales=function(label,series){var slug=label.toLowerCase().replace(/\s/g,"-"),color='<div class="edd-legend-color" style="background-color: '+series.color+'"></div>',value='<div class="edd-pie-legend-item">'+label+": "+Math.round(series.percent)+"% ("+eddFormatNumber(series.data[0][1])+")</div>",item='<div id="'+series.edd_vars.id+slug+'" class="edd-legend-item-wrapper">'+color+value+"</div>";return jQuery("#edd-pie-legend-"+series.edd_vars.id).append(item),item},eddLegendFormatterEarnings=function(label,series){var slug=label.toLowerCase().replace(/\s/g,"-"),color='<div class="edd-legend-color" style="background-color: '+series.color+'"></div>',value='<div class="edd-pie-legend-item">'+label+": "+Math.round(series.percent)+"% ("+eddFormatCurrency(series.data[0][1])+")</div>",item='<div id="'+series.edd_vars.id+slug+'" class="edd-legend-item-wrapper">'+color+value+"</div>";return jQuery("#edd-pie-legend-"+series.edd_vars.id).append(item),item};function edd_attach_tooltips(selector){selector.tooltip({content:function(){return jQuery(this).prop("title")},tooltipClass:"edd-ui-tooltip",position:{my:"center top",at:"center bottom+10",collision:"flipfit"},hide:{duration:200},show:{duration:200}})}function easy_digital_downloads_sendwp_remote_install(){jQuery.post(ajaxurl,{action:"edd_sendwp_remote_install"},function(response){response.success||!confirm(response.data.error)?easy_digital_downloads_sendwp_register_client(response.data.register_url,response.data.client_name,response.data.client_secret,response.data.client_redirect,response.data.partner_id):location.reload()})}function easy_digital_downloads_sendwp_disconnect(){jQuery.post(ajaxurl,{action:"edd_sendwp_disconnect"},function(response){location.reload()})}function easy_digital_downloads_sendwp_register_client(register_url,client_name,client_secret,client_redirect,partner_id){var form=document.createElement("form");function easy_digital_downloads_sendwp_append_form_input(name,value){var input=document.createElement("input");input.setAttribute("type","hidden"),input.setAttribute("name",name),input.setAttribute("value",value),form.appendChild(input)}form.setAttribute("method","POST"),form.setAttribute("action",register_url),easy_digital_downloads_sendwp_append_form_input("client_name",client_name),easy_digital_downloads_sendwp_append_form_input("client_secret",client_secret),easy_digital_downloads_sendwp_append_form_input("client_redirect",client_redirect),easy_digital_downloads_sendwp_append_form_input("partner_id",partner_id),document.body.appendChild(form),form.submit()}function easy_digital_downloads_jilt_remote_install(){jQuery.post(ajaxurl,{action:"edd_jilt_remote_install"},function(response){response.success||!confirm(response.data.error)?easy_digital_downloads_jilt_connect():location.reload()})}function easy_digital_downloads_jilt_connect(){jQuery.post(ajaxurl,{action:"edd_jilt_connect"},function(response){response.success||!confirm(response.data.error)?""===response.data.connect_url||location.assign(response.data.connect_url):location.reload()})}function easy_digital_downloads_jilt_disconnect(){jQuery.post(ajaxurl,{action:"edd_jilt_disconnect"},function(response){response.success||confirm(response.data.error),location.reload()})}
assets/js/edd-checkout-global.js CHANGED
@@ -184,9 +184,12 @@ window.EDD_Checkout = (function($) {
184
 
185
  } else {
186
 
187
- if (!inputs.is('.card-address-2')) {
188
- inputs.attr('required','required');
189
- }
 
 
 
190
  $('#edd_cc_fields,#edd_cc_address').slideDown();
191
 
192
  }
184
 
185
  } else {
186
 
187
+ inputs.each( function () {
188
+ var $input = $( this );
189
+ if ( ! $input.is( '.card-name, .card-address, .card-address-2' ) ) {
190
+ $input.prop( 'required', true );
191
+ }
192
+ } );
193
  $('#edd_cc_fields,#edd_cc_address').slideDown();
194
 
195
  }
assets/js/edd-checkout-global.min.js CHANGED
@@ -1 +1 @@
1
- window.EDD_Checkout=function($){"use strict";var $body,$form,$edd_cart_amount,$checkout_form_wrap;function apply_discount(event){event.preventDefault();$(this);var discount_code=$("#edd-discount").val(),edd_discount_loader=$("#edd-discount-loader");if(""==discount_code||discount_code==edd_global_vars.enter_discount)return!1;var postData={action:"edd_apply_discount",code:discount_code,form:$("#edd_purchase_form").serialize()};return $("#edd-discount-error-wrap").html("").hide(),edd_discount_loader.show(),$.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(discount_response){if(discount_response)if("valid"==discount_response.msg){$(".edd_cart_discount").html(discount_response.html),$(".edd_cart_discount_row").show(),$(".edd_cart_amount").each(function(){$(this).text(discount_response.total),$(this).data("total",discount_response.total_plain)}),$("#edd-discount",$checkout_form_wrap).val(""),recalculate_taxes();var inputs=$("#edd_cc_fields .edd-input, #edd_cc_fields .edd-select,#edd_cc_address .edd-input, #edd_cc_address .edd-select,#edd_payment_mode_select .edd-input, #edd_payment_mode_select .edd-select");"0.00"==discount_response.total_plain?($("#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select").slideUp(),inputs.removeAttr("required"),$('input[name="edd-gateway"]').val("manual")):(inputs.is(".card-address-2")||inputs.attr("required","required"),$("#edd_cc_fields,#edd_cc_address").slideDown()),$body.trigger("edd_discount_applied",[discount_response])}else $("#edd-discount-error-wrap").html('<span class="edd_error">'+discount_response.msg+"</span>"),$("#edd-discount-error-wrap").show(),$body.trigger("edd_discount_invalid",[discount_response]);else window.console&&window.console.log&&console.log(discount_response),$body.trigger("edd_discount_failed",[discount_response]);edd_discount_loader.hide()}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}function remove_discount(event){var postData={action:"edd_remove_discount",code:$(this).data("code")};return $.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(discount_response){var zero="0"+edd_global_vars.decimal_separator+"00";$(".edd_cart_amount").each(function(){edd_global_vars.currency_sign+zero!=$(this).text()&&zero+edd_global_vars.currency_sign!=$(this).text()||window.location.reload(),$(this).text(discount_response.total),$(this).data("total",discount_response.total_plain)}),$(".edd_cart_discount").html(discount_response.html),discount_response.discounts||$(".edd_cart_discount_row").hide(),recalculate_taxes(),$("#edd_cc_fields,#edd_cc_address").slideDown(),$body.trigger("edd_discount_removed",[discount_response])}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}function update_item_quantities(event){var $this=$(this),quantity=$this.val(),key=$this.data("key"),download_id=$this.closest(".edd_cart_item").data("download-id"),options=$this.parent().find('input[name="edd-cart-download-'+key+'-options"]').val(),edd_cc_address=$("#edd_cc_address"),postData={action:"edd_update_quantity",quantity:quantity,download_id:download_id,options:options,billing_country:edd_cc_address.find("#billing_country").val(),card_state:edd_cc_address.find("#card_state").val()};return $.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(response){$(".edd_cart_subtotal_amount").each(function(){$(this).text(response.subtotal)}),$(".edd_cart_tax_amount").each(function(){$(this).text(response.taxes)}),$(".edd_cart_amount").each(function(){var total=response.total,subtotal=response.subtotal;$(this).text(total);var float_total=parseFloat(total.replace(/[^0-9\.-]+/g,"")),float_subtotal=parseFloat(subtotal.replace(/[^0-9\.-]+/g,""));$(this).data("total",float_total),$(this).data("subtotal",float_subtotal),$body.trigger("edd_quantity_updated",[response])})}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}return{init:function(){$body=$(document.body),$form=$("#edd_purchase_form"),$edd_cart_amount=$(".edd_cart_amount"),$edd_cart_amount.text(),$checkout_form_wrap=$("#edd_checkout_form_wrap"),$body.on("edd_gateway_loaded",function(e){var form,card_number,card_cvc,card_expiry;card_number=(form=$form).find(".card-number"),card_cvc=form.find(".card-cvc"),card_expiry=form.find(".card-expiry"),card_number.length&&"function"==typeof card_number.payment&&(card_number.payment("formatCardNumber"),card_cvc.payment("formatCardCVC"),card_expiry.payment("formatCardExpiry"))}),$body.on("keyup change",".edd-do-validate .card-number",function(){var field,card_field;field=$(this),(card_field=field).validateCreditCard(function(result){var $card_type=$(".card-type");null==result.card_type?($card_type.removeClass().addClass("off card-type"),card_field.removeClass("valid"),card_field.addClass("error")):($card_type.removeClass("off"),$card_type.addClass(result.card_type.name),result.length_valid&&result.luhn_valid?(card_field.addClass("valid"),card_field.removeClass("error")):(card_field.removeClass("valid"),card_field.addClass("error")))})}),$body.on("blur change",".card-name",function(){var name_field=$(this);name_field.validateCreditCard(function(result){null!=result.card_type?(name_field.removeClass("valid").addClass("error"),$("#edd-purchase-button").attr("disabled","disabled")):(name_field.removeClass("error").addClass("valid"),$("#edd-purchase-button").removeAttr("disabled"))})}),$body.on("submit","#edd_payment_mode",function(){if(0==$("#edd-gateway option:selected").val())return alert(edd_global_vars.no_gateway),!1}),$body.on("click","#edd_payment_mode_select input",function(){$("#edd_payment_mode_select label.edd-gateway-option-selected").removeClass("edd-gateway-option-selected"),$("#edd_payment_mode_select input:checked").parent().addClass("edd-gateway-option-selected")}),$checkout_form_wrap.on("click",".edd-apply-discount",apply_discount),$checkout_form_wrap.on("keypress","#edd-discount",function(event){if("13"==event.keyCode)return!1}),$checkout_form_wrap.on("keyup","#edd-discount",function(event){"13"==event.keyCode&&$checkout_form_wrap.find(".edd-apply-discount").trigger("click")}),$body.on("click",".edd_discount_remove",remove_discount),$body.on("click",".edd_discount_link",function(e){e.preventDefault(),$(".edd_discount_link").parent().hide(),$("#edd-discount-code-wrap").show().find("#edd-discount").focus()}),$body.find("#edd-discount-code-wrap").hide(),$body.find("#edd_show_discount").show(),$body.on("change",".edd-item-quantity",update_item_quantities),$body.on("click",".edd-amazon-logout #Logout",function(e){e.preventDefault(),amazon.Login.logout(),window.location=edd_amazon.checkoutUri})},recalculate_taxes:recalculate_taxes}}(window.jQuery),window.jQuery(document).ready(EDD_Checkout.init);var ajax_tax_count=0;function recalculate_taxes(state){if("1"==edd_global_vars.taxes_enabled){var $edd_cc_address=jQuery("#edd_cc_address");state||(state=$edd_cc_address.find("#card_state").val());var postData={action:"edd_recalculate_taxes",billing_country:$edd_cc_address.find("#billing_country").val(),state:state,card_zip:$edd_cc_address.find("input[name=card_zip]").val(),nonce:jQuery("#edd-checkout-address-fields-nonce").val()};jQuery("#edd_purchase_submit [type=submit]").after('<span class="edd-loading-ajax edd-recalculate-taxes-loading edd-loading"></span>');var current_ajax_count=++ajax_tax_count;jQuery.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(tax_response){if(current_ajax_count===ajax_tax_count){jQuery("#edd_checkout_cart_form").replaceWith(tax_response.html),jQuery(".edd_cart_amount").html(tax_response.total);var tax_data=new Object;tax_data.postdata=postData,tax_data.response=tax_response,jQuery("body").trigger("edd_taxes_recalculated",[tax_data])}jQuery(".edd-recalculate-taxes-loading").remove()}}).fail(function(data){window.console&&window.console.log&&(console.log(data),current_ajax_count===ajax_tax_count&&jQuery("body").trigger("edd_taxes_recalculated",[tax_data]))})}}
1
+ window.EDD_Checkout=function($){"use strict";var $body,$form,$edd_cart_amount,$checkout_form_wrap;function apply_discount(event){event.preventDefault();$(this);var discount_code=$("#edd-discount").val(),edd_discount_loader=$("#edd-discount-loader");if(""==discount_code||discount_code==edd_global_vars.enter_discount)return!1;var postData={action:"edd_apply_discount",code:discount_code,form:$("#edd_purchase_form").serialize()};return $("#edd-discount-error-wrap").html("").hide(),edd_discount_loader.show(),$.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(discount_response){if(discount_response)if("valid"==discount_response.msg){$(".edd_cart_discount").html(discount_response.html),$(".edd_cart_discount_row").show(),$(".edd_cart_amount").each(function(){$(this).text(discount_response.total),$(this).data("total",discount_response.total_plain)}),$("#edd-discount",$checkout_form_wrap).val(""),recalculate_taxes();var inputs=$("#edd_cc_fields .edd-input, #edd_cc_fields .edd-select,#edd_cc_address .edd-input, #edd_cc_address .edd-select,#edd_payment_mode_select .edd-input, #edd_payment_mode_select .edd-select");"0.00"==discount_response.total_plain?($("#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select").slideUp(),inputs.removeAttr("required"),$('input[name="edd-gateway"]').val("manual")):(inputs.each(function(){var $input=$(this);$input.is(".card-name, .card-address, .card-address-2")||$input.prop("required",!0)}),$("#edd_cc_fields,#edd_cc_address").slideDown()),$body.trigger("edd_discount_applied",[discount_response])}else $("#edd-discount-error-wrap").html('<span class="edd_error">'+discount_response.msg+"</span>"),$("#edd-discount-error-wrap").show(),$body.trigger("edd_discount_invalid",[discount_response]);else window.console&&window.console.log&&console.log(discount_response),$body.trigger("edd_discount_failed",[discount_response]);edd_discount_loader.hide()}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}function remove_discount(event){var postData={action:"edd_remove_discount",code:$(this).data("code")};return $.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(discount_response){var zero="0"+edd_global_vars.decimal_separator+"00";$(".edd_cart_amount").each(function(){edd_global_vars.currency_sign+zero!=$(this).text()&&zero+edd_global_vars.currency_sign!=$(this).text()||window.location.reload(),$(this).text(discount_response.total),$(this).data("total",discount_response.total_plain)}),$(".edd_cart_discount").html(discount_response.html),discount_response.discounts||$(".edd_cart_discount_row").hide(),recalculate_taxes(),$("#edd_cc_fields,#edd_cc_address").slideDown(),$body.trigger("edd_discount_removed",[discount_response])}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}function update_item_quantities(event){var $this=$(this),quantity=$this.val(),key=$this.data("key"),download_id=$this.closest(".edd_cart_item").data("download-id"),options=$this.parent().find('input[name="edd-cart-download-'+key+'-options"]').val(),edd_cc_address=$("#edd_cc_address"),postData={action:"edd_update_quantity",quantity:quantity,download_id:download_id,options:options,billing_country:edd_cc_address.find("#billing_country").val(),card_state:edd_cc_address.find("#card_state").val()};return $.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(response){$(".edd_cart_subtotal_amount").each(function(){$(this).text(response.subtotal)}),$(".edd_cart_tax_amount").each(function(){$(this).text(response.taxes)}),$(".edd_cart_amount").each(function(){var total=response.total,subtotal=response.subtotal;$(this).text(total);var float_total=parseFloat(total.replace(/[^0-9\.-]+/g,"")),float_subtotal=parseFloat(subtotal.replace(/[^0-9\.-]+/g,""));$(this).data("total",float_total),$(this).data("subtotal",float_subtotal),$body.trigger("edd_quantity_updated",[response])})}}).fail(function(data){window.console&&window.console.log&&console.log(data)}),!1}return{init:function(){$body=$(document.body),$form=$("#edd_purchase_form"),$edd_cart_amount=$(".edd_cart_amount"),$edd_cart_amount.text(),$checkout_form_wrap=$("#edd_checkout_form_wrap"),$body.on("edd_gateway_loaded",function(e){var form,card_number,card_cvc,card_expiry;card_number=(form=$form).find(".card-number"),card_cvc=form.find(".card-cvc"),card_expiry=form.find(".card-expiry"),card_number.length&&"function"==typeof card_number.payment&&(card_number.payment("formatCardNumber"),card_cvc.payment("formatCardCVC"),card_expiry.payment("formatCardExpiry"))}),$body.on("keyup change",".edd-do-validate .card-number",function(){var field,card_field;field=$(this),(card_field=field).validateCreditCard(function(result){var $card_type=$(".card-type");null==result.card_type?($card_type.removeClass().addClass("off card-type"),card_field.removeClass("valid"),card_field.addClass("error")):($card_type.removeClass("off"),$card_type.addClass(result.card_type.name),result.length_valid&&result.luhn_valid?(card_field.addClass("valid"),card_field.removeClass("error")):(card_field.removeClass("valid"),card_field.addClass("error")))})}),$body.on("blur change",".card-name",function(){var name_field=$(this);name_field.validateCreditCard(function(result){null!=result.card_type?(name_field.removeClass("valid").addClass("error"),$("#edd-purchase-button").attr("disabled","disabled")):(name_field.removeClass("error").addClass("valid"),$("#edd-purchase-button").removeAttr("disabled"))})}),$body.on("submit","#edd_payment_mode",function(){if(0==$("#edd-gateway option:selected").val())return alert(edd_global_vars.no_gateway),!1}),$body.on("click","#edd_payment_mode_select input",function(){$("#edd_payment_mode_select label.edd-gateway-option-selected").removeClass("edd-gateway-option-selected"),$("#edd_payment_mode_select input:checked").parent().addClass("edd-gateway-option-selected")}),$checkout_form_wrap.on("click",".edd-apply-discount",apply_discount),$checkout_form_wrap.on("keypress","#edd-discount",function(event){if("13"==event.keyCode)return!1}),$checkout_form_wrap.on("keyup","#edd-discount",function(event){"13"==event.keyCode&&$checkout_form_wrap.find(".edd-apply-discount").trigger("click")}),$body.on("click",".edd_discount_remove",remove_discount),$body.on("click",".edd_discount_link",function(e){e.preventDefault(),$(".edd_discount_link").parent().hide(),$("#edd-discount-code-wrap").show().find("#edd-discount").focus()}),$body.find("#edd-discount-code-wrap").hide(),$body.find("#edd_show_discount").show(),$body.on("change",".edd-item-quantity",update_item_quantities),$body.on("click",".edd-amazon-logout #Logout",function(e){e.preventDefault(),amazon.Login.logout(),window.location=edd_amazon.checkoutUri})},recalculate_taxes:recalculate_taxes}}(window.jQuery),window.jQuery(document).ready(EDD_Checkout.init);var ajax_tax_count=0;function recalculate_taxes(state){if("1"==edd_global_vars.taxes_enabled){var $edd_cc_address=jQuery("#edd_cc_address");state||(state=$edd_cc_address.find("#card_state").val());var postData={action:"edd_recalculate_taxes",billing_country:$edd_cc_address.find("#billing_country").val(),state:state,card_zip:$edd_cc_address.find("input[name=card_zip]").val(),nonce:jQuery("#edd-checkout-address-fields-nonce").val()};jQuery("#edd_purchase_submit [type=submit]").after('<span class="edd-loading-ajax edd-recalculate-taxes-loading edd-loading"></span>');var current_ajax_count=++ajax_tax_count;jQuery.ajax({type:"POST",data:postData,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(tax_response){if(current_ajax_count===ajax_tax_count){jQuery("#edd_checkout_cart_form").replaceWith(tax_response.html),jQuery(".edd_cart_amount").html(tax_response.total);var tax_data=new Object;tax_data.postdata=postData,tax_data.response=tax_response,jQuery("body").trigger("edd_taxes_recalculated",[tax_data])}jQuery(".edd-recalculate-taxes-loading").remove()}}).fail(function(data){window.console&&window.console.log&&(console.log(data),current_ajax_count===ajax_tax_count&&jQuery("body").trigger("edd_taxes_recalculated",[tax_data]))})}}
easy-digital-downloads.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: The easiest way to sell digital products with WordPress.
6
  * Author: Sandhills Development, LLC
7
  * Author URI: https://sandhillsdev.com
8
- * Version: 2.9.26
9
  * Text Domain: easy-digital-downloads
10
  * Domain Path: languages
11
  *
@@ -25,7 +25,7 @@
25
  * @package EDD
26
  * @category Core
27
  * @author Pippin Williamson
28
- * @version 2.9.26
29
  */
30
 
31
  // Exit if accessed directly.
@@ -206,7 +206,7 @@ final class Easy_Digital_Downloads {
206
 
207
  // Plugin version.
208
  if ( ! defined( 'EDD_VERSION' ) ) {
209
- define( 'EDD_VERSION', '2.9.26' );
210
  }
211
 
212
  // Plugin Folder Path.
@@ -288,6 +288,13 @@ final class Easy_Digital_Downloads {
288
  }
289
  require_once EDD_PLUGIN_DIR . 'includes/gateways/paypal-standard.php';
290
  require_once EDD_PLUGIN_DIR . 'includes/gateways/manual.php';
 
 
 
 
 
 
 
291
  require_once EDD_PLUGIN_DIR . 'includes/discount-functions.php';
292
  require_once EDD_PLUGIN_DIR . 'includes/payments/functions.php';
293
  require_once EDD_PLUGIN_DIR . 'includes/payments/actions.php';
5
  * Description: The easiest way to sell digital products with WordPress.
6
  * Author: Sandhills Development, LLC
7
  * Author URI: https://sandhillsdev.com
8
+ * Version: 2.10
9
  * Text Domain: easy-digital-downloads
10
  * Domain Path: languages
11
  *
25
  * @package EDD
26
  * @category Core
27
  * @author Pippin Williamson
28
+ * @version 2.10
29
  */
30
 
31
  // Exit if accessed directly.
206
 
207
  // Plugin version.
208
  if ( ! defined( 'EDD_VERSION' ) ) {
209
+ define( 'EDD_VERSION', '2.10' );
210
  }
211
 
212
  // Plugin Folder Path.
288
  }
289
  require_once EDD_PLUGIN_DIR . 'includes/gateways/paypal-standard.php';
290
  require_once EDD_PLUGIN_DIR . 'includes/gateways/manual.php';
291
+
292
+ $stripe = EDD_PLUGIN_DIR . 'includes/gateways/stripe/edd-stripe.php';
293
+
294
+ if ( file_exists( $stripe ) ) {
295
+ require_once( $stripe );
296
+ }
297
+
298
  require_once EDD_PLUGIN_DIR . 'includes/discount-functions.php';
299
  require_once EDD_PLUGIN_DIR . 'includes/payments/functions.php';
300
  require_once EDD_PLUGIN_DIR . 'includes/payments/actions.php';
includes/EDD_SL_Plugin_Updater.php CHANGED
@@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) exit;
7
  * Allows plugins to use their own update API.
8
  *
9
  * @author Easy Digital Downloads
10
- * @version 1.6.19
11
  */
12
  class EDD_SL_Plugin_Updater {
13
 
@@ -106,32 +106,50 @@ class EDD_SL_Plugin_Updater {
106
  return $_transient_data;
107
  }
108
 
109
- $version_info = $this->get_cached_version_info();
110
-
111
- if ( false === $version_info ) {
112
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
113
-
114
- $this->set_version_info_cache( $version_info );
115
-
 
116
  }
 
 
117
 
118
- if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
119
-
120
- if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
121
-
122
- $_transient_data->response[ $this->name ] = $version_info;
123
 
124
- // Make sure the plugin property is set to the plugin's name/location. See issue 1463 on Software Licensing's GitHub repo.
125
- $_transient_data->response[ $this->name ]->plugin = $this->name;
 
 
 
 
 
 
126
 
 
 
 
 
 
 
 
 
 
 
127
  }
128
 
129
- $_transient_data->last_checked = time();
130
- $_transient_data->checked[ $this->name ] = $this->version;
 
131
 
 
132
  }
133
 
134
- return $_transient_data;
135
  }
136
 
137
  /**
@@ -167,7 +185,7 @@ class EDD_SL_Plugin_Updater {
167
 
168
  if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
169
 
170
- $version_info = $this->get_cached_version_info();
171
 
172
  if ( false === $version_info ) {
173
  $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
@@ -185,10 +203,6 @@ class EDD_SL_Plugin_Updater {
185
  $version_info->icons = $this->convert_object_to_array( $version_info->icons );
186
  }
187
 
188
- if ( isset( $version_info->icons ) && ! is_array( $version_info->icons ) ) {
189
- $version_info->icons = $this->convert_object_to_array( $version_info->icons );
190
- }
191
-
192
  if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
193
  $version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
194
  }
@@ -201,12 +215,12 @@ class EDD_SL_Plugin_Updater {
201
  }
202
 
203
  if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
204
-
205
  $update_cache->response[ $this->name ] = $version_info;
206
-
 
207
  }
208
 
209
- $update_cache->last_checked = time();
210
  $update_cache->checked[ $this->name ] = $this->version;
211
 
212
  set_site_transient( 'update_plugins', $update_cache );
@@ -291,10 +305,8 @@ class EDD_SL_Plugin_Updater {
291
  )
292
  );
293
 
294
- $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
295
-
296
  // Get the transient where we store the api request for this plugin for 24 hours
297
- $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
298
 
299
  //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
300
  if ( empty( $edd_api_request_transient ) ) {
@@ -302,7 +314,7 @@ class EDD_SL_Plugin_Updater {
302
  $api_response = $this->api_request( 'plugin_information', $to_send );
303
 
304
  // Expires in 3 hours
305
- $this->set_version_info_cache( $api_response, $cache_key );
306
 
307
  if ( false !== $api_response ) {
308
  $_data = $api_response;
@@ -413,16 +425,16 @@ class EDD_SL_Plugin_Updater {
413
  }
414
 
415
  if ( false === $edd_plugin_url_available[ $store_hash ] ) {
416
- return;
417
  }
418
 
419
  $data = array_merge( $this->api_data, $_data );
420
 
421
  if ( $data['slug'] != $this->slug ) {
422
- return;
423
  }
424
 
425
- if( $this->api_url == trailingslashit ( home_url() ) ) {
426
  return false; // Don't allow a plugin to ping itself
427
  }
428
 
@@ -458,7 +470,7 @@ class EDD_SL_Plugin_Updater {
458
  $request->icons = maybe_unserialize( $request->icons );
459
  }
460
 
461
- if( ! empty( $request->sections ) ) {
462
  foreach( $request->sections as $key => $section ) {
463
  $request->$key = (array) $section;
464
  }
@@ -467,6 +479,9 @@ class EDD_SL_Plugin_Updater {
467
  return $request;
468
  }
469
 
 
 
 
470
  public function show_changelog() {
471
 
472
  global $edd_plugin_data;
@@ -488,9 +503,7 @@ class EDD_SL_Plugin_Updater {
488
  }
489
 
490
  $data = $edd_plugin_data[ $_REQUEST['slug'] ];
491
- $beta = ! empty( $data['beta'] ) ? true : false;
492
- $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info' );
493
- $version_info = $this->get_cached_version_info( $cache_key );
494
 
495
  if( false === $version_info ) {
496
 
@@ -511,7 +524,6 @@ class EDD_SL_Plugin_Updater {
511
  $version_info = json_decode( wp_remote_retrieve_body( $request ) );
512
  }
513
 
514
-
515
  if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
516
  $version_info->sections = maybe_unserialize( $version_info->sections );
517
  } else {
@@ -524,17 +536,28 @@ class EDD_SL_Plugin_Updater {
524
  }
525
  }
526
 
527
- $this->set_version_info_cache( $version_info, $cache_key );
528
 
 
 
529
  }
530
 
531
- if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
532
- echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
 
 
 
533
  }
534
 
535
  exit;
536
  }
537
 
 
 
 
 
 
 
538
  public function get_cached_version_info( $cache_key = '' ) {
539
 
540
  if( empty( $cache_key ) ) {
@@ -557,6 +580,12 @@ class EDD_SL_Plugin_Updater {
557
 
558
  }
559
 
 
 
 
 
 
 
560
  public function set_version_info_cache( $value = '', $cache_key = '' ) {
561
 
562
  if( empty( $cache_key ) ) {
@@ -570,6 +599,8 @@ class EDD_SL_Plugin_Updater {
570
 
571
  update_option( $cache_key, $data, 'no' );
572
 
 
 
573
  }
574
 
575
  /**
7
  * Allows plugins to use their own update API.
8
  *
9
  * @author Easy Digital Downloads
10
+ * @version 1.8.0
11
  */
12
  class EDD_SL_Plugin_Updater {
13
 
106
  return $_transient_data;
107
  }
108
 
109
+ $current = $this->get_repo_api_data();
110
+ if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
111
+ if ( version_compare( $this->version, $current->new_version, '<' ) ) {
112
+ $_transient_data->response[ $this->name ] = $current;
113
+ } else {
114
+ // Populating the no_update information is required to support auto-updates in WordPress 5.5.
115
+ $_transient_data->no_update[ $this->name ] = $current;
116
+ }
117
  }
118
+ $_transient_data->last_checked = time();
119
+ $_transient_data->checked[ $this->name ] = $this->version;
120
 
121
+ return $_transient_data;
122
+ }
 
 
 
123
 
124
+ /**
125
+ * Get repo API data from store.
126
+ * Save to cache.
127
+ *
128
+ * @return \stdClass
129
+ */
130
+ public function get_repo_api_data() {
131
+ $version_info = $this->get_cached_version_info();
132
 
133
+ if ( false === $version_info ) {
134
+ $version_info = $this->api_request(
135
+ 'plugin_latest_version',
136
+ array(
137
+ 'slug' => $this->slug,
138
+ 'beta' => $this->beta,
139
+ )
140
+ );
141
+ if ( ! $version_info ) {
142
+ return false;
143
  }
144
 
145
+ // This is required for your plugin to support auto-updates in WordPress 5.5.
146
+ $version_info->plugin = $this->name;
147
+ $version_info->id = $this->name;
148
 
149
+ $this->set_version_info_cache( $version_info );
150
  }
151
 
152
+ return $version_info;
153
  }
154
 
155
  /**
185
 
186
  if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
187
 
188
+ $version_info = $this->get_repo_api_data();
189
 
190
  if ( false === $version_info ) {
191
  $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
203
  $version_info->icons = $this->convert_object_to_array( $version_info->icons );
204
  }
205
 
 
 
 
 
206
  if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
207
  $version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
208
  }
215
  }
216
 
217
  if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
 
218
  $update_cache->response[ $this->name ] = $version_info;
219
+ } else {
220
+ $update_cache->no_update[ $this->name ] = $version_info;
221
  }
222
 
223
+ $update_cache->last_checked = time();
224
  $update_cache->checked[ $this->name ] = $this->version;
225
 
226
  set_site_transient( 'update_plugins', $update_cache );
305
  )
306
  );
307
 
 
 
308
  // Get the transient where we store the api request for this plugin for 24 hours
309
+ $edd_api_request_transient = $this->get_cached_version_info();
310
 
311
  //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
312
  if ( empty( $edd_api_request_transient ) ) {
314
  $api_response = $this->api_request( 'plugin_information', $to_send );
315
 
316
  // Expires in 3 hours
317
+ $this->set_version_info_cache( $api_response );
318
 
319
  if ( false !== $api_response ) {
320
  $_data = $api_response;
425
  }
426
 
427
  if ( false === $edd_plugin_url_available[ $store_hash ] ) {
428
+ return false;
429
  }
430
 
431
  $data = array_merge( $this->api_data, $_data );
432
 
433
  if ( $data['slug'] != $this->slug ) {
434
+ return false;
435
  }
436
 
437
+ if ( $this->api_url == trailingslashit ( home_url() ) ) {
438
  return false; // Don't allow a plugin to ping itself
439
  }
440
 
470
  $request->icons = maybe_unserialize( $request->icons );
471
  }
472
 
473
+ if ( ! empty( $request->sections ) ) {
474
  foreach( $request->sections as $key => $section ) {
475
  $request->$key = (array) $section;
476
  }
479
  return $request;
480
  }
481
 
482
+ /**
483
+ * If available, show the changelog for sites in a multisite install.
484
+ */
485
  public function show_changelog() {
486
 
487
  global $edd_plugin_data;
503
  }
504
 
505
  $data = $edd_plugin_data[ $_REQUEST['slug'] ];
506
+ $version_info = $this->get_cached_version_info();
 
 
507
 
508
  if( false === $version_info ) {
509
 
524
  $version_info = json_decode( wp_remote_retrieve_body( $request ) );
525
  }
526
 
 
527
  if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
528
  $version_info->sections = maybe_unserialize( $version_info->sections );
529
  } else {
536
  }
537
  }
538
 
539
+ $this->set_version_info_cache( $version_info );
540
 
541
+ // Delete the unneeded option
542
+ delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) );
543
  }
544
 
545
+ if ( isset( $version_info->sections ) ) {
546
+ $sections = $this->convert_object_to_array( $version_info->sections );
547
+ if ( ! empty( $sections['changelog'] ) ) {
548
+ echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
549
+ }
550
  }
551
 
552
  exit;
553
  }
554
 
555
+ /**
556
+ * Gets the plugin's cached version information from the database.
557
+ *
558
+ * @param string $cache_key
559
+ * @return boolean|string
560
+ */
561
  public function get_cached_version_info( $cache_key = '' ) {
562
 
563
  if( empty( $cache_key ) ) {
580
 
581
  }
582
 
583
+ /**
584
+ * Adds the plugin version information to the database.
585
+ *
586
+ * @param string $value
587
+ * @param string $cache_key
588
+ */
589
  public function set_version_info_cache( $value = '', $cache_key = '' ) {
590
 
591
  if( empty( $cache_key ) ) {
599
 
600
  update_option( $cache_key, $data, 'no' );
601
 
602
+ // Delete the duplicate option
603
+ delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
604
  }
605
 
606
  /**
includes/admin/class-edd-notices.php CHANGED
@@ -103,6 +103,74 @@ class EDD_Notices {
103
 
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  /* Commented out per https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/3475
107
  if( ! edd_test_ajax_works() && ! get_user_meta( get_current_user_id(), '_edd_admin_ajax_inaccessible_dismissed', true ) && current_user_can( 'manage_shop_settings' ) ) {
108
  echo '<div class="error">';
@@ -137,6 +205,10 @@ class EDD_Notices {
137
  break;
138
  case 'discount_invalid_code':
139
  $notices['error']['edd-discount-invalid-code'] = __( 'The discount code entered is invalid; only alphanumeric characters are allowed, please try again.', 'easy-digital-downloads' );
 
 
 
 
140
  }
141
  }
142
 
103
 
104
  }
105
 
106
+ /**
107
+ * Notice for users running PHP < 5.6.
108
+ * @since 2.10
109
+ */
110
+ if ( version_compare( PHP_VERSION, '5.6', '<' ) && ! get_user_meta( get_current_user_id(), '_edd_upgrade_php_56_dismissed', true ) && current_user_can( 'manage_shop_settings' ) ) {
111
+ echo '<div class="notice notice-warning is-dismissible edd-notice">';
112
+ printf(
113
+ '<h2>%s</h2>',
114
+ esc_html__( 'Upgrade PHP to Prepare for Easy Digital Downloads 3.0', 'easy-digital-downloads' )
115
+ );
116
+ echo wp_kses_post(
117
+ sprintf(
118
+ /* translators:
119
+ %1$s Opening paragraph tag, do not translate.
120
+ %2$s Current PHP version
121
+ %3$s Opening strong tag, do not translate.
122
+ %4$s Closing strong tag, do not translate.
123
+ %5$s Opening anchor tag, do not translate.
124
+ %6$s Closing anchor tag, do not translate.
125
+ %7$s Closing paragraph tag, do not translate.
126
+ */
127
+ __( '%1$sYour site is running an outdated version of PHP (%2$s), which requires an update. Easy Digital Downloads 3.0 will require %3$sPHP 5.6 or greater%4$s in order to keep your store online and selling. While 5.6 is the minimum version we will be supporting, we encourage you to update to the most recent version of PHP that your hosting provider offers. %5$sLearn more about updating PHP.%6$s%7$s', 'easy-digital-downloads' ),
128
+ '<p>',
129
+ PHP_VERSION,
130
+ '<strong>',
131
+ '</strong>',
132
+ '<a href="https://wordpress.org/support/update-php/" target="_blank" rel="noopener noreferrer">',
133
+ '</a>',
134
+ '</p>'
135
+ )
136
+ );
137
+ echo wp_kses_post(
138
+ sprintf(
139
+ /* translators:
140
+ %1$s Opening paragraph tag, do not translate.
141
+ %2$s Opening anchor tag, do not translate.
142
+ %3$s Closing anchor tag, do not translate.
143
+ %4$s Closing paragraph tag, do not translate.
144
+ */
145
+ __( '%1$sMany web hosts can give you instructions on how/where to upgrade your version of PHP through their control panel, or may even be able to do it for you. If you need to change hosts, please see %2$sour hosting recommendations%3$s.', 'easy-digital-downloads' ),
146
+ '<p>',
147
+ '<a href="https://easydigitaldownloads.com/recommended-wordpress-hosting/" target="_blank" rel="noopener noreferrer">',
148
+ '</a>',
149
+ '</p>'
150
+ )
151
+ );
152
+ echo wp_kses_post(
153
+ sprintf(
154
+ /* Translators: %1$s - Opening anchor tag, %2$s - The url to dismiss the ajax notice, %3$s - Complete the opening of the anchor tag, %4$s - Open span tag, %4$s - Close span tag */
155
+ __( '%1$s%2$s%3$s %4$s Dismiss this notice. %5$s', 'easy-digital-downloads' ),
156
+ '<a href="',
157
+ esc_url(
158
+ add_query_arg(
159
+ array(
160
+ 'edd_action' => 'dismiss_notices',
161
+ 'edd_notice' => 'upgrade_php_56',
162
+ )
163
+ )
164
+ ),
165
+ '" type="button" class="notice-dismiss">',
166
+ '<span class="screen-reader-text">',
167
+ '</span>
168
+ </a>'
169
+ )
170
+ );
171
+ echo '</div>';
172
+ }
173
+
174
  /* Commented out per https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/3475
175
  if( ! edd_test_ajax_works() && ! get_user_meta( get_current_user_id(), '_edd_admin_ajax_inaccessible_dismissed', true ) && current_user_can( 'manage_shop_settings' ) ) {
176
  echo '<div class="error">';
205
  break;
206
  case 'discount_invalid_code':
207
  $notices['error']['edd-discount-invalid-code'] = __( 'The discount code entered is invalid; only alphanumeric characters are allowed, please try again.', 'easy-digital-downloads' );
208
+ break;
209
+ case 'discount_invalid_amount' :
210
+ $notices['error']['edd-discount-invalid-amount'] = __( 'The discount amount must be a valid percentage or numeric flat amount. Please try again.', 'easy-digital-downloads' );
211
+ break;
212
  }
213
  }
214
 
includes/admin/discounts/discount-actions.php CHANGED
@@ -45,6 +45,11 @@ function edd_add_discount( $data ) {
45
  edd_die();
46
  }
47
 
 
 
 
 
 
48
  foreach ( $data as $key => $value ) {
49
 
50
  if ( $key === 'products' || $key === 'excluded-products' ) {
@@ -112,6 +117,11 @@ function edd_edit_discount( $data ) {
112
  wp_die( __( 'You do not have permission to edit discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
113
  }
114
 
 
 
 
 
 
115
  // Setup the discount code details
116
  $discount = array();
117
 
45
  edd_die();
46
  }
47
 
48
+ if ( ! is_numeric( $data['amount'] ) ) {
49
+ wp_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
50
+ edd_die();
51
+ }
52
+
53
  foreach ( $data as $key => $value ) {
54
 
55
  if ( $key === 'products' || $key === 'excluded-products' ) {
117
  wp_die( __( 'You do not have permission to edit discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
118
  }
119
 
120
+ if ( empty( $data['amount'] ) || ! is_numeric( $data['amount'] ) ) {
121
+ wp_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
122
+ edd_die();
123
+ }
124
+
125
  // Setup the discount code details
126
  $discount = array();
127
 
includes/admin/downloads/metabox.php CHANGED
@@ -416,11 +416,20 @@ function edd_render_price_row( $key, $args = array(), $post_id, $index ) {
416
  // Run our advanced settings now, so we know if we need to display the settings.
417
  // Output buffer so that the headers run, so we can log them and use them later
418
  ob_start();
419
- do_action( 'edd_download_price_table_head', $post_id );
 
 
420
  ob_end_clean();
421
 
422
  ob_start();
423
- do_action( 'edd_download_price_table_row', $post_id, $key, $args );
 
 
 
 
 
 
 
424
  $show_advanced = ob_get_clean();
425
  ?>
426
  <?php
416
  // Run our advanced settings now, so we know if we need to display the settings.
417
  // Output buffer so that the headers run, so we can log them and use them later
418
  ob_start();
419
+ if ( has_action( 'edd_download_price_table_head' ) ) {
420
+ do_action_deprecated( 'edd_download_price_table_head', array( $post_id ), '2.10', 'edd_download_price_option_row' );
421
+ }
422
  ob_end_clean();
423
 
424
  ob_start();
425
+ $found_fields = isset( $wp_filter['edd_download_price_table_row'] ) ? $wp_filter['edd_download_price_table_row'] : false;
426
+ if ( ! empty( $found_fields->callbacks ) ) {
427
+ if ( 1 !== count( $found_fields->callbacks ) ) {
428
+ do_action_deprecated( 'edd_download_price_table_row', array( $post_id, $key, $args ), '2.10', 'edd_download_price_option_row' );
429
+ } else {
430
+ do_action( 'edd_download_price_table_row', $post_id, $key, $args );
431
+ }
432
+ }
433
  $show_advanced = ob_get_clean();
434
  ?>
435
  <?php
includes/admin/import/class-batch-import-downloads.php CHANGED
@@ -70,6 +70,9 @@ class EDD_Batch_Downloads_Import extends EDD_Batch_Import {
70
 
71
  if( $offset > $this->total ) {
72
  $this->done = true;
 
 
 
73
  }
74
 
75
  if( ! $this->done && $this->csv->data ) {
70
 
71
  if( $offset > $this->total ) {
72
  $this->done = true;
73
+
74
+ // Delete the uploaded CSV file.
75
+ unlink( $this->file );
76
  }
77
 
78
  if( ! $this->done && $this->csv->data ) {
includes/admin/import/class-batch-import-payments.php CHANGED
@@ -90,6 +90,9 @@ class EDD_Batch_Payments_Import extends EDD_Batch_Import {
90
  global $wpdb;
91
  $sql = "DELETE FROM {$wpdb->prefix}edd_customermeta WHERE meta_key = '_canonical_import_id'";
92
  $wpdb->query( $sql );
 
 
 
93
  }
94
 
95
  if( ! $this->done && $this->csv->data ) {
@@ -548,7 +551,7 @@ class EDD_Batch_Payments_Import extends EDD_Batch_Import {
548
  $price = trim( substr( $d[1], 0, strpos( $d[1], '{' ) ) );
549
 
550
  } else {
551
-
552
  $price = trim( $d[1] );
553
  }
554
 
90
  global $wpdb;
91
  $sql = "DELETE FROM {$wpdb->prefix}edd_customermeta WHERE meta_key = '_canonical_import_id'";
92
  $wpdb->query( $sql );
93
+
94
+ // Delete the uploaded CSV file.
95
+ unlink( $this->file );
96
  }
97
 
98
  if( ! $this->done && $this->csv->data ) {
551
  $price = trim( substr( $d[1], 0, strpos( $d[1], '{' ) ) );
552
 
553
  } else {
554
+
555
  $price = trim( $d[1] );
556
  }
557
 
includes/api/class-edd-api-v2.php CHANGED
@@ -338,7 +338,7 @@ class EDD_API_V2 extends EDD_API_V1 {
338
 
339
  } elseif( $args['customer'] ) {
340
 
341
- $error['error'] = sprintf( __( 'Customer %s not found!', 'easy-digital-downloads' ), $customer );
342
  return $error;
343
 
344
  } else {
338
 
339
  } elseif( $args['customer'] ) {
340
 
341
+ $error['error'] = sprintf( __( 'Customer %s not found!', 'easy-digital-downloads' ), $args['customer'] );
342
  return $error;
343
 
344
  } else {
includes/cart/actions.php CHANGED
@@ -64,7 +64,7 @@ add_action( 'template_redirect', 'edd_process_cart_endpoints', 100 );
64
  * @param $data
65
  */
66
  function edd_process_add_to_cart( $data ) {
67
- $download_id = absint( $data['download_id'] );
68
  $options = isset( $data['edd_options'] ) ? $data['edd_options'] : array();
69
 
70
  if ( ! empty( $data['edd_download_quantity'] ) ) {
@@ -77,7 +77,9 @@ function edd_process_add_to_cart( $data ) {
77
  }
78
  }
79
 
80
- $cart = edd_add_to_cart( $download_id, $options );
 
 
81
 
82
  if ( edd_straight_to_checkout() && ! edd_is_checkout() ) {
83
  $query_args = remove_query_arg( array( 'edd_action', 'download_id', 'edd_options' ) );
@@ -159,10 +161,12 @@ add_action( 'edd_purchase_collection', 'edd_process_collection_purchase' );
159
  */
160
  function edd_process_cart_update( $data ) {
161
 
162
- foreach( $data['edd-cart-downloads'] as $key => $cart_download_id ) {
163
- $options = json_decode( stripslashes( $data['edd-cart-download-' . $key . '-options'] ), true );
164
- $quantity = absint( $data['edd-cart-download-' . $key . '-quantity'] );
165
- edd_set_cart_item_quantity( $cart_download_id, $quantity, $options );
 
 
166
  }
167
 
168
  }
64
  * @param $data
65
  */
66
  function edd_process_add_to_cart( $data ) {
67
+ $download_id = ! empty( $data['download_id'] ) ? absint( $data['download_id'] ) : false;
68
  $options = isset( $data['edd_options'] ) ? $data['edd_options'] : array();
69
 
70
  if ( ! empty( $data['edd_download_quantity'] ) ) {
77
  }
78
  }
79
 
80
+ if ( ! empty( $download_id ) ) {
81
+ edd_add_to_cart( $download_id, $options );
82
+ }
83
 
84
  if ( edd_straight_to_checkout() && ! edd_is_checkout() ) {
85
  $query_args = remove_query_arg( array( 'edd_action', 'download_id', 'edd_options' ) );
161
  */
162
  function edd_process_cart_update( $data ) {
163
 
164
+ if ( ! empty( $data['edd-cart-downloads'] ) && is_array( $data['edd-cart-downloads'] ) ) {
165
+ foreach ( $data['edd-cart-downloads'] as $key => $cart_download_id ) {
166
+ $options = json_decode( stripslashes( $data[ 'edd-cart-download-' . $key . '-options' ] ), true );
167
+ $quantity = absint( $data[ 'edd-cart-download-' . $key . '-quantity' ] );
168
+ edd_set_cart_item_quantity( $cart_download_id, $quantity, $options );
169
+ }
170
  }
171
 
172
  }
includes/cart/class-edd-cart.php CHANGED
@@ -639,6 +639,14 @@ class EDD_Cart {
639
 
640
  if ( ! isset( $item['options'] ) ) {
641
  $item['options'] = array();
 
 
 
 
 
 
 
 
642
  }
643
 
644
  $amount = 0;
639
 
640
  if ( ! isset( $item['options'] ) ) {
641
  $item['options'] = array();
642
+
643
+ /*
644
+ * Support for variable pricing when calling `edd_get_cart_item_discount_amount()`
645
+ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/issues/8246
646
+ */
647
+ if ( isset( $item['item_number']['options'] ) ) {
648
+ $item['options'] = $item['item_number']['options'];
649
+ }
650
  }
651
 
652
  $amount = 0;
includes/checkout/template.php CHANGED
@@ -676,7 +676,7 @@ function edd_show_payment_icons() {
676
 
677
  if( edd_string_is_image_url( $key ) ) {
678
 
679
- echo '<img class="payment-icon" src="' . esc_url( $key ) . '"/>';
680
 
681
  } else {
682
 
@@ -706,7 +706,7 @@ function edd_show_payment_icons() {
706
 
707
  }
708
 
709
- echo '<img class="payment-icon" src="' . esc_url( $image ) . '"/>';
710
  }
711
 
712
  }
676
 
677
  if( edd_string_is_image_url( $key ) ) {
678
 
679
+ echo '<img class="payment-icon" src="' . esc_url( $key ) . '" alt="' . esc_attr( $card ) . '"/>';
680
 
681
  } else {
682
 
706
 
707
  }
708
 
709
+ echo '<img class="payment-icon" src="' . esc_url( $image ) . '" alt="' . esc_attr( $card ) . '"/>';
710
  }
711
 
712
  }
includes/class-edd-db-customers.php CHANGED
@@ -319,46 +319,59 @@ class EDD_DB_Customers extends EDD_DB {
319
  /**
320
  * Updates the email address of a customer record when the email on a user is updated
321
  *
 
 
 
322
  * @since 2.4
 
323
  */
324
- public function update_customer_email_on_user_update( $user_id = 0, $old_user_data ) {
325
-
326
- $customer = new EDD_Customer( $user_id, true );
327
-
328
- if( ! $customer ) {
329
- return false;
330
- }
331
 
332
  $user = get_userdata( $user_id );
333
 
334
- if( ! empty( $user ) && $user->user_email !== $customer->email ) {
335
-
336
- if( ! $this->get_customer_by( 'email', $user->user_email ) ) {
 
337
 
338
- $success = $this->update( $customer->id, array( 'email' => $user->user_email ) );
339
 
340
- if( $success ) {
341
- // Update some payment meta if we need to
342
- $payments_array = explode( ',', $customer->payment_ids );
343
 
344
- if( ! empty( $payments_array ) ) {
 
 
 
345
 
346
- foreach ( $payments_array as $payment_id ) {
347
 
348
- edd_update_payment_meta( $payment_id, 'email', $user->user_email );
 
 
349
 
350
- }
 
351
 
352
- }
353
 
354
- do_action( 'edd_update_customer_email_on_user_update', $user, $customer );
355
 
356
- }
357
 
358
  }
359
 
360
  }
361
 
 
 
 
 
 
 
 
 
362
  }
363
 
364
  /**
319
  /**
320
  * Updates the email address of a customer record when the email on a user is updated
321
  *
322
+ * @param int $user_id User ID.
323
+ * @param WP_User $old_user_data Object containing user's data prior to update.
324
+ *
325
  * @since 2.4
326
+ * @return void
327
  */
328
+ public function update_customer_email_on_user_update( $user_id, $old_user_data ) {
 
 
 
 
 
 
329
 
330
  $user = get_userdata( $user_id );
331
 
332
+ // Bail if the email address didn't actually change just now.
333
+ if ( empty( $user ) || $user->user_email === $old_user_data->user_email ) {
334
+ return;
335
+ }
336
 
337
+ $customer = new EDD_Customer( $user_id, true );
338
 
339
+ if ( empty( $customer->id ) || $user->user_email === $customer->email ) {
340
+ return;
341
+ }
342
 
343
+ // Bail if we have another customer with this email address already.
344
+ if ( $this->get_customer_by( 'email', $user->user_email ) ) {
345
+ return;
346
+ }
347
 
348
+ $success = $this->update( $customer->id, array( 'email' => $user->user_email ) );
349
 
350
+ if ( ! $success ) {
351
+ return;
352
+ }
353
 
354
+ // Update some payment meta if we need to
355
+ $payments_array = explode( ',', $customer->payment_ids );
356
 
357
+ if( ! empty( $payments_array ) ) {
358
 
359
+ foreach ( $payments_array as $payment_id ) {
360
 
361
+ edd_update_payment_meta( $payment_id, 'email', $user->user_email );
362
 
363
  }
364
 
365
  }
366
 
367
+ /**
368
+ * Triggers after the customer has been successfully updated.
369
+ *
370
+ * @param WP_User $user
371
+ * @param EDD_Customer $customer
372
+ */
373
+ do_action( 'edd_update_customer_email_on_user_update', $user, $customer );
374
+
375
  }
376
 
377
  /**
includes/class-edd-discount.php CHANGED
@@ -1875,18 +1875,17 @@ class EDD_Discount {
1875
  * @return float $discounted_price Amount after discount.
1876
  */
1877
  public function get_discounted_amount( $base_price ) {
1878
- // Start off setting the amount as the base price.
1879
- $amount = $base_price;
1880
 
1881
  if ( 'flat' == $this->type ) {
1882
- $amount = $base_price - $this->amount;
1883
 
1884
  if ( $amount < 0 ) {
1885
  $amount = 0;
1886
  }
1887
  } else {
1888
  // Percentage discount
1889
- $amount = $base_price - ( $base_price * ( $this->amount / 100 ) );
1890
  }
1891
 
1892
  /**
1875
  * @return float $discounted_price Amount after discount.
1876
  */
1877
  public function get_discounted_amount( $base_price ) {
1878
+ $base_price = floatval( $base_price );
 
1879
 
1880
  if ( 'flat' == $this->type ) {
1881
+ $amount = $base_price - floatval( $this->amount );
1882
 
1883
  if ( $amount < 0 ) {
1884
  $amount = 0;
1885
  }
1886
  } else {
1887
  // Percentage discount
1888
+ $amount = $base_price - ( $base_price * ( floatval( $this->amount ) / 100 ) );
1889
  }
1890
 
1891
  /**
includes/class-edd-html-elements.php CHANGED
@@ -339,21 +339,21 @@ class EDD_HTML_Elements {
339
  $options[0] = __( 'No users found', 'easy-digital-downloads' );
340
  }
341
 
 
 
 
 
342
  // If a selected user has been specified, we need to ensure it's in the initial list of user displayed
343
- if( ! empty( $args['selected'] ) ) {
344
-
345
- if( ! array_key_exists( $args['selected'], $options ) ) {
346
-
347
- $user = get_userdata( $args['selected'] );
348
-
349
- if( $user ) {
350
-
351
- $options[ absint( $args['selected'] ) ] = esc_html( $user->display_name );
352
 
 
 
 
353
  }
354
-
355
  }
356
-
357
  }
358
 
359
  $output = $this->select( array(
@@ -573,7 +573,7 @@ class EDD_HTML_Elements {
573
 
574
  if ( $args['show_option_all'] ) {
575
  if ( $args['multiple'] && ! empty( $args['selected'] ) ) {
576
- $selected = selected( true, in_array( 0, $args['selected'] ), false );
577
  } else {
578
  $selected = selected( $args['selected'], 0, false );
579
  }
339
  $options[0] = __( 'No users found', 'easy-digital-downloads' );
340
  }
341
 
342
+ $selected = $args['selected'];
343
+ if ( ! is_array( $selected ) ) {
344
+ $selected = array( $selected );
345
+ }
346
  // If a selected user has been specified, we need to ensure it's in the initial list of user displayed
347
+ if ( ! empty( $selected ) ) {
348
+ foreach ( $selected as $selected_user ) {
349
+ if ( ! array_key_exists( $selected_user, $options ) ) {
350
+ $user = get_userdata( $selected_user );
 
 
 
 
 
351
 
352
+ if ( $user ) {
353
+ $options[ absint( $user->ID ) ] = esc_html( $user->display_name );
354
+ }
355
  }
 
356
  }
 
357
  }
358
 
359
  $output = $this->select( array(
573
 
574
  if ( $args['show_option_all'] ) {
575
  if ( $args['multiple'] && ! empty( $args['selected'] ) ) {
576
+ $selected = selected( true, in_array( 0, (array) $args['selected'] ), false );
577
  } else {
578
  $selected = selected( $args['selected'], 0, false );
579
  }
includes/class-edd-license-handler.php CHANGED
@@ -112,7 +112,7 @@ class EDD_License {
112
  //add_action( 'admin_init', array( $this, 'weekly_license_check' ) );
113
 
114
  // Updater
115
- add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
116
 
117
  // Display notices to admins
118
  add_action( 'admin_notices', array( $this, 'notices' ) );
@@ -130,6 +130,12 @@ class EDD_License {
130
  * @return void
131
  */
132
  public function auto_updater() {
 
 
 
 
 
 
133
  $betas = edd_get_option( 'enabled_betas', array() );
134
 
135
  $args = array(
112
  //add_action( 'admin_init', array( $this, 'weekly_license_check' ) );
113
 
114
  // Updater
115
+ add_action( 'init', array( $this, 'auto_updater' ) );
116
 
117
  // Display notices to admins
118
  add_action( 'admin_notices', array( $this, 'notices' ) );
130
  * @return void
131
  */
132
  public function auto_updater() {
133
+
134
+ $doing_cron = defined( 'DOING_CRON' ) && DOING_CRON;
135
+ if ( ! current_user_can( 'manage_options' ) && ! $doing_cron ) {
136
+ return;
137
+ }
138
+
139
  $betas = edd_get_option( 'enabled_betas', array() );
140
 
141
  $args = array(
includes/download-functions.php CHANGED
@@ -912,7 +912,7 @@ function edd_set_file_download_limit_override( $download_id = 0, $payment_id = 0
912
  * @param int $download_id Download ID
913
  * @param int $payment_id Payment ID
914
  * @param int $file_id File ID
915
- * @param int $price_id Price ID
916
  * @return bool True if at limit, false otherwise
917
  */
918
  function edd_is_file_at_download_limit( $download_id = 0, $payment_id = 0, $file_id = 0, $price_id = false ) {
@@ -963,7 +963,18 @@ function edd_is_file_at_download_limit( $download_id = 0, $payment_id = 0, $file
963
  }
964
  }
965
 
966
- return (bool) apply_filters( 'edd_is_file_at_download_limit', $ret, $download_id, $payment_id, $file_id );
 
 
 
 
 
 
 
 
 
 
 
967
  }
968
 
969
  /**
912
  * @param int $download_id Download ID
913
  * @param int $payment_id Payment ID
914
  * @param int $file_id File ID
915
+ * @param int|false $price_id Price ID
916
  * @return bool True if at limit, false otherwise
917
  */
918
  function edd_is_file_at_download_limit( $download_id = 0, $payment_id = 0, $file_id = 0, $price_id = false ) {
963
  }
964
  }
965
 
966
+ /**
967
+ * Filters whether or not a file is at its download limit.
968
+ *
969
+ * @param bool $ret
970
+ * @param int $download_id
971
+ * @param int $payment_id
972
+ * @param int $file_id
973
+ * @param int|false $price_id
974
+ *
975
+ * @since 2.10 Added `$price_id` parameter.
976
+ */
977
+ return (bool) apply_filters( 'edd_is_file_at_download_limit', $ret, $download_id, $payment_id, $file_id, $price_id );
978
  }
979
 
980
  /**
includes/gateways/paypal-standard.php CHANGED
@@ -289,12 +289,21 @@ function edd_process_paypal_purchase( $purchase_data ) {
289
  }
290
  }
291
 
 
292
  if ( $discounted_amount > '0' ) {
293
  $paypal_args['discount_amount_cart'] = edd_sanitize_amount( $discounted_amount );
 
 
 
 
 
 
 
294
  }
295
 
296
- if( $paypal_sum > $purchase_data['price'] ) {
297
- $difference = round( $paypal_sum - $purchase_data['price'], 2 );
 
298
  if( ! isset( $paypal_args['discount_amount_cart'] ) ) {
299
  $paypal_args['discount_amount_cart'] = 0;
300
  }
289
  }
290
  }
291
 
292
+ $price_before_discount = $purchase_data['price'];
293
  if ( $discounted_amount > '0' ) {
294
  $paypal_args['discount_amount_cart'] = edd_sanitize_amount( $discounted_amount );
295
+
296
+ /*
297
+ * Add the discounted amount back onto the price to get the "price before discount". We do this
298
+ * to avoid double applying any discounts below.
299
+ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/issues/6837
300
+ */
301
+ $price_before_discount += $paypal_args['discount_amount_cart'];
302
  }
303
 
304
+ // Check if there are any additional discounts we need to add that we haven't already accounted for.
305
+ if( $paypal_sum > $price_before_discount ) {
306
+ $difference = round( $paypal_sum - $price_before_discount, 2 );
307
  if( ! isset( $paypal_args['discount_amount_cart'] ) ) {
308
  $paypal_args['discount_amount_cart'] = 0;
309
  }
includes/gateways/stripe/apple-developer-merchantid-domain-association ADDED
@@ -0,0 +1 @@
 
1
+ 7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313536363233343735303036312C227369676E6174757265223A22333038303036303932613836343838366637306430313037303261303830333038303032303130313331306633303064303630393630383634383031363530333034303230313035303033303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031386233303832303138373032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303064303630393630383634383031363530333034303230313035303061303831393533303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333933303338333133393331333733313332333333303561333032613036303932613836343838366637306430313039333433313164333031623330306430363039363038363438303136353033303430323031303530306131306130363038326138363438636533643034303330323330326630363039326138363438383666373064303130393034333132323034323062303731303365313430613462386231376262613230316130336163643036396234653431366232613263383066383661383338313435633239373566633131333030613036303832613836343863653364303430333032303434363330343430323230343639306264636637626461663833636466343934396534633035313039656463663334373665303564373261313264376335666538633033303033343464663032323032363764353863393365626233353031333836363062353730373938613064643731313734316262353864626436613138363633353038353431656565393035303030303030303030303030227D
includes/gateways/stripe/assets/css/build/admin.min.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .edds-stripe-connect-acount-info .spinner{float:none;display:inline-block;margin:-2px 5px 0 0}#edds-payment-gateways-stripe-unmet-requirements{margin:-10px 0 0 -16px;padding-top:10px}#edds-payment-gateways-stripe-unmet-requirements input[type=checkbox]{margin:0 6px 0 0}.edds-requirements-not-met th{display:none}.edds-requirements-not-met td{padding:0}.edd-stripe-connect{display:inline-block;margin-bottom:1px;background-image:linear-gradient(#28A0E5, #015E94);-webkit-font-smoothing:antialiased;border:0;padding:1px;height:30px;text-decoration:none;border-radius:4px;box-shadow:0 1px 0 rgba(0,0,0,.2);cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.edd-stripe-connect span{display:block;position:relative;padding:0 12px 0 44px;height:30px;background:#1275ff;background-image:linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);font-size:14px;line-height:30px;color:#fff;font-weight:bold;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;text-shadow:0 -1px 0 rgba(0,0,0,.2);box-shadow:inset 0 1px 0 rgba(255,255,255,.25);border-radius:3px}.edd-stripe-connect span:before{content:"";display:block;position:absolute;left:11px;top:50%;width:23px;height:24px;margin-top:-12px;background-repeat:no-repeat;background-size:23px 24px}.edd-stripe-connect:active{background:#005d93}.edd-stripe-connect:active span{color:#eee;background:#008cdd;background-image:linear-gradient(#008CDD, #008CDD 85%, #239ADF);box-shadow:inset 0 1px 0 rgba(0,0,0,.1)}.edd-stripe-connect span:before,.edd-stripe-connect.blue span:before{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAYAAAARfGZ1AAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAADQklEQVRIDbWVaUiUQRjHZ96dXY/d1fYQj1U03dJSw9YkFgy6DIkILRArQSSC7PjQjQQqVH7oQ0GHQUWgpQhKHzoNSqiUwpXcsrwIjzVtPVrzbPV9Z6bZhYV3N3WXYAeGmWeeZ37z8J95GEgpBf5oeXn1Es4fYAdzPDlM6je4RBYhR+LMU89UxiCBGiCgkUwsBYSA+SlPKLQBQAYEAZm+3j42K96z3NyOF7VOeMrp62opRcacjPW5+43rDTpNSKQ8QKZAEg7xmPCTs/O27uGJgXuNbW0pxyvLfTmAEBzthEsFZLxRvPdi5rpYo2cmUiQJDA4IVeo0obGdlvGfXUPj0Sym2zPuHxvzcWjDyVupJ/YYizKTGNjLw/HiduNTAqIRIUJ6Vpp+ky8bCSFgwQ2xgkGxFi1ioNWEBGuJB31gbLIv/2pd7SpFoGxtpCYkLSEq4ptlzIYFO7tc7w0TKkeEYg5ADnrWkkYhD8s26GPq3nW0WKxTptftPYBI4Mj3O2fHvKNZBMVSDmMwarXNjDkSF3d5kExZeiCr8M2VI+VFu9IvsPcYtzAvkfoEZkEEE45jMppq3ppbCNPFIY1nD1cpo07lbMmvOXeoDCF8BLKy9uUAAjDkBh+c6bz78mNtVVP7MwET7JBnqb4xXpdWVpC1OVzWn+ELHLCsneX/s7rkRWl1463cy1U3WroG21jhCGKJXPOtKQnpAuENvsAppgDB3TcDVIrpDHbK5Kd+y7W8iodNybHh22rOHyxUK+UaMYjZaoyp25rYL54TSihSKmwZ14v3lc3ZFxdbeywjn/tGJnkmzrydX1ApxOEACKymmXLYfXVpi1JMEOGxPi1ep18doY4r2J7uFumQQ9yGf01bMcZW8dpyc0oIjxxpuC5wuUDX+ovWrnYeg3aXvdLIqnmOvXPsfH6uA5YbTb1DX8ofvTLzTy6ZV4K6fAw+gXiATfdffmjeaUgc1UdpdWplsCooQBrEnqUw82dhdnjit/Vxc4f59tP3DRjzJvYteqrl4rmNlJIfrOwpgNklesDRNQBCHYtQAQqD2CgACNjHAJnG1EyfV/S67fZiJB5t2OGEe4n7L3fS4fpEv/2hUEATfoPbuam5v8N7nps70YTbAAAAAElFTkSuQmCC")}@media only screen and (-webkit-min-device-pixel-ratio: 1.5),only screen and (min--moz-device-pixel-ratio: 1.5),only screen and (min-device-pixel-ratio: 1.5){.edd-stripe-connect span:before,.edd-stripe-connect.blue span:before{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAwCAYAAABuZUjcAAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAAIbklEQVRoBdVZa5BURxU+fZ9z57mzs7PvF4i7srAQSCifMVDERC0jYlzUlJalKeGPlCnL/NEfywpWacoiVZRVJIYfGjGUu5bxj5qHFSAYyQOBEsJzYSHDvnd2dp535j66PX1vNgsULDPs1cr2Vs+9e7v79NfnnnP663MJYwwWYxEWI2iOedEClxabxgkBwjEvOuA9PQOOlSw64JMr4vK8GidYYMcOES4tVSEAAZ8FAUqon1GiAJEEEG0CjFB8cTaxZUMAo1gEqQA0UABprAjPbrUwXnkesgqKP8CBk5vDIenrE+BKmwI+MawA1MbCkdV10cBDflXuVmSxQRbFkCAQZ9U2ZTaONyxKcyXDHjMs83ImV3rz6njmDRPMUZB80zAJOuvvsflkXpTP7DrWyeXcYCqk75AEieawrEoty1vrvlcV0ja3VQdb1rVUQVd9EFqqNIj5ZfDJooPBsCnohq2ldDMynC42XZnW7z09lu25lMxDMl34y0gyvTsBwyewc84Z4MEPpWIzF/MBcLLtNzJISmxZU+PmWETbtqGzfvVja5uguyF02+kCIEJUk6Ex4oMV9XP9ZnQT/nZ24it7XrtoJ5LZ7SjAM+Bg2+0ckAOcbBkQIaZFVzY1bGurjezYfn87PNQZ5+13ZaQRXMzH26Lg8ymfUokQdAR59INOc53GQ6q/Jiiua6oJ7+h9uAPua47cHeLrwHEmQRmTGLHV6x4v+JYwWsOFCGRDn6RKem1rPPrkN9Y0uqAXLN4VwCgjYGEE8rBgMAjwKsF9S9WgLa9qjYcf+Po9jXdlGrfC5Wj8Vg0Lf+ZENAFmpGB9TWTLhmUxUD1UDg/gtudRnK+a4RtkgqQyO+RT5LVrmiLgJcN19gcGNojUWriS5yRQm7pcBTc/vyCKdW1RrWwzOTiYhGf+dRUmcgZosgDVfgWaMCS2V2tO+OzG0MiVjdUwiFiYm9a7O4kJAoZEooV9H4T0O0ofODkKr5+6+nY6V3heVZQpv6ZWaz55qSJJnXjtUBW5pT7k8xeK5u+B0PQdBVbQgTLq9HbQYthyNVSmTT6A/nB0aGpF0K99+trY1F7TNI9PZGXkKUVRtYjGZCIOV1dHR4Ynz8FSLV8BrjK6uiAlpLcmco1ipmgpAaU8rfesboCuumBg31uJbx6+qH0uX9D/em0i85xFhaslKZKA8/82RtYDhd/1MkCuBnjxrLgKB0EQSb5oWO+9O1bZrsy3+Kc3dcH+b99b07NuyXe6P9r8z/am+C9lkuqCjo4qGGkQES76qJcuz/2GOlUoFuVsQS+98frlaSeq8Gkqqctrg7Dz853wwrfugUfXtj3W3tJ8oCletRUEXy1SCSSYHhdu41gFqILcZCrzwkvnJmE0U3JtHefiL7eS2l7th11f7IQ9j65aVh+r+nlzbd2TELJrHPLmIXZX3wyBX8MTQMm8PJ0u9Pe9chGQYy9omvXouHu/thJqI+Ef1sZDm0AMBmfPiQsSPDuY2zhWwSH5ISU5Pjm98x9nRo7+7JVBB3wl5nJz35Vo/z/esBQUVf2+QlkD9Aw42/Ts3Au7ushdAhQ5UzJoOjE+OrV9/1tDR7cNnIax7N2bDX9nm1bUQXdz9Rp/MLwRoqAtDOzcaO7rvDrAWW8vhcatWVNjF6cmJre9embkz1947h3YfXgIUgVzblQldxgFH0ZOr/qULwM15k4Zlci4Vd9ZU5ltY71oObHBnBFQBidmUk8kEsOP7Hntwqsb974NfS8PAh7LKoo23Hw+2R4FQcSzKlDPgFOEyf8kx3HW94kQ7xJgRRdAJG7CyIWxgiXNUN0+k5nJLN83k3n8D8eHN3+1ux5+8uBHIKiWt1G1Rn3IJkiUCcQzU3G0h9qWHMeJdoSrwtr9dl6I6DNjFwRRyxiKnStSqkPJPsGSmZ+mp1P9z2dzOy3Klj31yMdmX9S8V75APEsomMZwT9fz9i6vkW9AvEgQyqrBQM2Dq9rrD0gCgXfHA0jpjIRm2Zcw+3CR2tZl27SnMZFSZ1lWcRwZITeDckresAEXaoKwwBh7/WQubgTOQj5BVjdv7KiBJz7bztMNcHIk03JiONNyfiK/ntv2VMHAMx6BjpoA/Gj9Emdjul7W7e6TeQNDK9WJLRm361P5c1drEmAaymaYoXpfjZoiOk7FHWuh5dxEHmzLHiXM9oyTz9FawRZw65f5yyzXBMpd0JGhFKB5nSwRMVvumDv2cxm4m1f5X4AuWhRePDUOtqEPQJVVGfWcBz1ahmPlTlxzqaJLquYZU1HTvjcTMD6dOULM0n+g5nKposHzdWbo7FgEkDBviWlYx++53XtQ33kvDU8dHAJm6L8usdwEZn09S3qiPed5lcCSLUpI0eEA8620zLbDl6bh8T+egkI+/7Rl6kegcTSPst1QUKaM+brhrjnF2yUQJNxnrGMnR7KbTw5nYFVjyAl98w2+VdvVlA67Dw3BgROjAKa+yyrpz0BKTbJnez1NT6AKrrnA1bEi1av2v3xaiL90dnxL2Kc0rsXc4WpcQEc8AEtiGrRiejmK6WWeMDIxtVwwKExijB5KFuBYIg1cy8dx0dTQ/yQVc78yBXMIqJ5i/VvvkqHdSjXuM/THKy7w2LQJ6fpJms38QiHGvlzBt+RwJv2JQ2elbjyRtjIi1AIRMAsKPuQduHVzr2YW+kIBE5BTwOzzxLKOiMX8QVuWh00IpqD+S0WHtLlzefpLBOZo/IYvEqQPnTX5dxmy4xookqaCjRuT4mMi8g3bxs2KCkj3GFj4+QSzA0RkeskU8iCJeUiBDv09Jt8OPEV6k7DlP3gxxh/dAPymPh/Kf5d897dIOd9P7H8oEd4G1JV8wPGbRadx52sgLmrRAZ99EZ5+LZgV+v+4Llrg/wX6HRCxgvzAAwAAAABJRU5ErkJggg==")}}
2
+
3
+ /*# sourceMappingURL=admin.min.css.map*/
includes/gateways/stripe/assets/css/build/admin.min.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["webpack:///./assets/css/src/admin.scss"],"names":[],"mappings":"AAAA,0CAA0C,WAAW,qBAAqB,oBAAoB,iDAAiD,uBAAuB,iBAAiB,sEAAsE,iBAAiB,8BAA8B,aAAa,8BAA8B,UAAU,oBAAoB,qBAAqB,kBAAkB,mDAAmD,mCAAmC,SAAS,YAAY,YAAY,qBAAqB,kBAAkB,kCAAkC,eAAe,sBAAsB,yBAAyB,qBAAqB,iBAAiB,yBAAyB,cAAc,kBAAkB,sBAAsB,YAAY,mBAAmB,gEAAgE,eAAe,iBAAiB,WAAW,iBAAiB,wDAAwD,oCAAoC,+CAA+C,kBAAkB,gCAAgC,WAAW,cAAc,kBAAkB,UAAU,QAAQ,WAAW,YAAY,iBAAiB,4BAA4B,0BAA0B,2BAA2B,mBAAmB,gCAAgC,WAAW,mBAAmB,gEAAgE,wCAAwC,qEAAqE,qCAAqC,8mJAA8mJ,8JAA8J,qEAAqE,qCAAqC,u1M","file":"assets/css/build/admin.min.css","sourcesContent":[".edds-stripe-connect-acount-info .spinner{float:none;display:inline-block;margin:-2px 5px 0 0}#edds-payment-gateways-stripe-unmet-requirements{margin:-10px 0 0 -16px;padding-top:10px}#edds-payment-gateways-stripe-unmet-requirements input[type=checkbox]{margin:0 6px 0 0}.edds-requirements-not-met th{display:none}.edds-requirements-not-met td{padding:0}.edd-stripe-connect{display:inline-block;margin-bottom:1px;background-image:linear-gradient(#28A0E5, #015E94);-webkit-font-smoothing:antialiased;border:0;padding:1px;height:30px;text-decoration:none;border-radius:4px;box-shadow:0 1px 0 rgba(0,0,0,.2);cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.edd-stripe-connect span{display:block;position:relative;padding:0 12px 0 44px;height:30px;background:#1275ff;background-image:linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);font-size:14px;line-height:30px;color:#fff;font-weight:bold;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;text-shadow:0 -1px 0 rgba(0,0,0,.2);box-shadow:inset 0 1px 0 rgba(255,255,255,.25);border-radius:3px}.edd-stripe-connect span:before{content:\"\";display:block;position:absolute;left:11px;top:50%;width:23px;height:24px;margin-top:-12px;background-repeat:no-repeat;background-size:23px 24px}.edd-stripe-connect:active{background:#005d93}.edd-stripe-connect:active span{color:#eee;background:#008cdd;background-image:linear-gradient(#008CDD, #008CDD 85%, #239ADF);box-shadow:inset 0 1px 0 rgba(0,0,0,.1)}.edd-stripe-connect span:before,.edd-stripe-connect.blue span:before{background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAYAAAARfGZ1AAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAADQklEQVRIDbWVaUiUQRjHZ96dXY/d1fYQj1U03dJSw9YkFgy6DIkILRArQSSC7PjQjQQqVH7oQ0GHQUWgpQhKHzoNSqiUwpXcsrwIjzVtPVrzbPV9Z6bZhYV3N3WXYAeGmWeeZ37z8J95GEgpBf5oeXn1Es4fYAdzPDlM6je4RBYhR+LMU89UxiCBGiCgkUwsBYSA+SlPKLQBQAYEAZm+3j42K96z3NyOF7VOeMrp62opRcacjPW5+43rDTpNSKQ8QKZAEg7xmPCTs/O27uGJgXuNbW0pxyvLfTmAEBzthEsFZLxRvPdi5rpYo2cmUiQJDA4IVeo0obGdlvGfXUPj0Sym2zPuHxvzcWjDyVupJ/YYizKTGNjLw/HiduNTAqIRIUJ6Vpp+ky8bCSFgwQ2xgkGxFi1ioNWEBGuJB31gbLIv/2pd7SpFoGxtpCYkLSEq4ptlzIYFO7tc7w0TKkeEYg5ADnrWkkYhD8s26GPq3nW0WKxTptftPYBI4Mj3O2fHvKNZBMVSDmMwarXNjDkSF3d5kExZeiCr8M2VI+VFu9IvsPcYtzAvkfoEZkEEE45jMppq3ppbCNPFIY1nD1cpo07lbMmvOXeoDCF8BLKy9uUAAjDkBh+c6bz78mNtVVP7MwET7JBnqb4xXpdWVpC1OVzWn+ELHLCsneX/s7rkRWl1463cy1U3WroG21jhCGKJXPOtKQnpAuENvsAppgDB3TcDVIrpDHbK5Kd+y7W8iodNybHh22rOHyxUK+UaMYjZaoyp25rYL54TSihSKmwZ14v3lc3ZFxdbeywjn/tGJnkmzrydX1ApxOEACKymmXLYfXVpi1JMEOGxPi1ep18doY4r2J7uFumQQ9yGf01bMcZW8dpyc0oIjxxpuC5wuUDX+ovWrnYeg3aXvdLIqnmOvXPsfH6uA5YbTb1DX8ofvTLzTy6ZV4K6fAw+gXiATfdffmjeaUgc1UdpdWplsCooQBrEnqUw82dhdnjit/Vxc4f59tP3DRjzJvYteqrl4rmNlJIfrOwpgNklesDRNQBCHYtQAQqD2CgACNjHAJnG1EyfV/S67fZiJB5t2OGEe4n7L3fS4fpEv/2hUEATfoPbuam5v8N7nps70YTbAAAAAElFTkSuQmCC\")}@media only screen and (-webkit-min-device-pixel-ratio: 1.5),only screen and (min--moz-device-pixel-ratio: 1.5),only screen and (min-device-pixel-ratio: 1.5){.edd-stripe-connect span:before,.edd-stripe-connect.blue span:before{background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAwCAYAAABuZUjcAAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAAIbklEQVRoBdVZa5BURxU+fZ9z57mzs7PvF4i7srAQSCifMVDERC0jYlzUlJalKeGPlCnL/NEfywpWacoiVZRVJIYfGjGUu5bxj5qHFSAYyQOBEsJzYSHDvnd2dp535j66PX1vNgsULDPs1cr2Vs+9e7v79NfnnnP663MJYwwWYxEWI2iOedEClxabxgkBwjEvOuA9PQOOlSw64JMr4vK8GidYYMcOES4tVSEAAZ8FAUqon1GiAJEEEG0CjFB8cTaxZUMAo1gEqQA0UABprAjPbrUwXnkesgqKP8CBk5vDIenrE+BKmwI+MawA1MbCkdV10cBDflXuVmSxQRbFkCAQZ9U2ZTaONyxKcyXDHjMs83ImV3rz6njmDRPMUZB80zAJOuvvsflkXpTP7DrWyeXcYCqk75AEieawrEoty1vrvlcV0ja3VQdb1rVUQVd9EFqqNIj5ZfDJooPBsCnohq2ldDMynC42XZnW7z09lu25lMxDMl34y0gyvTsBwyewc84Z4MEPpWIzF/MBcLLtNzJISmxZU+PmWETbtqGzfvVja5uguyF02+kCIEJUk6Ex4oMV9XP9ZnQT/nZ24it7XrtoJ5LZ7SjAM+Bg2+0ckAOcbBkQIaZFVzY1bGurjezYfn87PNQZ5+13ZaQRXMzH26Lg8ymfUokQdAR59INOc53GQ6q/Jiiua6oJ7+h9uAPua47cHeLrwHEmQRmTGLHV6x4v+JYwWsOFCGRDn6RKem1rPPrkN9Y0uqAXLN4VwCgjYGEE8rBgMAjwKsF9S9WgLa9qjYcf+Po9jXdlGrfC5Wj8Vg0Lf+ZENAFmpGB9TWTLhmUxUD1UDg/gtudRnK+a4RtkgqQyO+RT5LVrmiLgJcN19gcGNojUWriS5yRQm7pcBTc/vyCKdW1RrWwzOTiYhGf+dRUmcgZosgDVfgWaMCS2V2tO+OzG0MiVjdUwiFiYm9a7O4kJAoZEooV9H4T0O0ofODkKr5+6+nY6V3heVZQpv6ZWaz55qSJJnXjtUBW5pT7k8xeK5u+B0PQdBVbQgTLq9HbQYthyNVSmTT6A/nB0aGpF0K99+trY1F7TNI9PZGXkKUVRtYjGZCIOV1dHR4Ynz8FSLV8BrjK6uiAlpLcmco1ipmgpAaU8rfesboCuumBg31uJbx6+qH0uX9D/em0i85xFhaslKZKA8/82RtYDhd/1MkCuBnjxrLgKB0EQSb5oWO+9O1bZrsy3+Kc3dcH+b99b07NuyXe6P9r8z/am+C9lkuqCjo4qGGkQES76qJcuz/2GOlUoFuVsQS+98frlaSeq8Gkqqctrg7Dz853wwrfugUfXtj3W3tJ8oCletRUEXy1SCSSYHhdu41gFqILcZCrzwkvnJmE0U3JtHefiL7eS2l7th11f7IQ9j65aVh+r+nlzbd2TELJrHPLmIXZX3wyBX8MTQMm8PJ0u9Pe9chGQYy9omvXouHu/thJqI+Ef1sZDm0AMBmfPiQsSPDuY2zhWwSH5ISU5Pjm98x9nRo7+7JVBB3wl5nJz35Vo/z/esBQUVf2+QlkD9Aw42/Ts3Au7ushdAhQ5UzJoOjE+OrV9/1tDR7cNnIax7N2bDX9nm1bUQXdz9Rp/MLwRoqAtDOzcaO7rvDrAWW8vhcatWVNjF6cmJre9embkz1947h3YfXgIUgVzblQldxgFH0ZOr/qULwM15k4Zlci4Vd9ZU5ltY71oObHBnBFQBidmUk8kEsOP7Hntwqsb974NfS8PAh7LKoo23Hw+2R4FQcSzKlDPgFOEyf8kx3HW94kQ7xJgRRdAJG7CyIWxgiXNUN0+k5nJLN83k3n8D8eHN3+1ux5+8uBHIKiWt1G1Rn3IJkiUCcQzU3G0h9qWHMeJdoSrwtr9dl6I6DNjFwRRyxiKnStSqkPJPsGSmZ+mp1P9z2dzOy3Klj31yMdmX9S8V75APEsomMZwT9fz9i6vkW9AvEgQyqrBQM2Dq9rrD0gCgXfHA0jpjIRm2Zcw+3CR2tZl27SnMZFSZ1lWcRwZITeDckresAEXaoKwwBh7/WQubgTOQj5BVjdv7KiBJz7bztMNcHIk03JiONNyfiK/ntv2VMHAMx6BjpoA/Gj9Emdjul7W7e6TeQNDK9WJLRm361P5c1drEmAaymaYoXpfjZoiOk7FHWuh5dxEHmzLHiXM9oyTz9FawRZw65f5yyzXBMpd0JGhFKB5nSwRMVvumDv2cxm4m1f5X4AuWhRePDUOtqEPQJVVGfWcBz1ahmPlTlxzqaJLquYZU1HTvjcTMD6dOULM0n+g5nKposHzdWbo7FgEkDBviWlYx++53XtQ33kvDU8dHAJm6L8usdwEZn09S3qiPed5lcCSLUpI0eEA8620zLbDl6bh8T+egkI+/7Rl6kegcTSPst1QUKaM+brhrjnF2yUQJNxnrGMnR7KbTw5nYFVjyAl98w2+VdvVlA67Dw3BgROjAKa+yyrpz0BKTbJnez1NT6AKrrnA1bEi1av2v3xaiL90dnxL2Kc0rsXc4WpcQEc8AEtiGrRiejmK6WWeMDIxtVwwKExijB5KFuBYIg1cy8dx0dTQ/yQVc78yBXMIqJ5i/VvvkqHdSjXuM/THKy7w2LQJ6fpJms38QiHGvlzBt+RwJv2JQ2elbjyRtjIi1AIRMAsKPuQduHVzr2YW+kIBE5BTwOzzxLKOiMX8QVuWh00IpqD+S0WHtLlzefpLBOZo/IYvEqQPnTX5dxmy4xookqaCjRuT4mMi8g3bxs2KCkj3GFj4+QSzA0RkeskU8iCJeUiBDv09Jt8OPEV6k7DlP3gxxh/dAPymPh/Kf5d897dIOd9P7H8oEd4G1JV8wPGbRadx52sgLmrRAZ99EZ5+LZgV+v+4Llrg/wX6HRCxgvzAAwAAAABJRU5ErkJggg==\")}}"],"sourceRoot":""}
includes/gateways/stripe/assets/css/build/app.min.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ :root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem * 1.5);padding:calc(var(--edds-modal-grid-unit) * 1.5);display:flex;justify-content:space-between;align-items:center;position:-webkit-sticky;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:"✕"}.edds-modal__content{margin:calc(1rem * 1.5);margin:calc(var(--edds-modal-grid-unit) * 1.5)}@-webkit-keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@-webkit-keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{-webkit-animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1);animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{-webkit-animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1);animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-prb{margin:15px 0;display:none}.edds-prb__or{font-size:90%;text-align:center;margin:15px 0;overflow:hidden}.edds-prb__or::before,.edds-prb__or::after{background-color:rgba(0,0,0,.1);content:"";display:inline-block;height:1px;position:relative;vertical-align:middle;width:50%}.edds-prb__or::before{right:.5em;margin-left:-50%}.edds-prb__or::after{left:.5em;margin-right:-50%}.edd_download_purchase_form.loading{position:relative}.edd_download_purchase_form.loading::after{content:"";position:absolute;left:0;width:100%;height:100%;top:0;z-index:100}.edd_download_purchase_form.loading>*{opacity:.65}#edd_checkout_form_wrap.loading{position:relative}#edd_checkout_form_wrap.loading::after{content:"";position:absolute;left:0;width:100%;height:100%;top:0;z-index:100}#edd_checkout_form_wrap.loading>*{opacity:.65}#edd_checkout_form_wrap .edds-prb{margin-bottom:0}#edd_checkout_form_wrap .edds-prb__or{display:none}#edd_checkout_form_wrap .edd-card-selector-radio label{display:inline;vertical-align:middle;font-weight:normal;line-height:24px;font-size:100%;margin:0px}.edd-card-selector-radio .edd-stripe-card-radio-item{width:100%;font-size:15px;padding:8px 12px;border:1px solid transparent}.edd-card-selector-radio .edd-stripe-card-radio-item label{line-height:1;margin:0;display:flex;align-items:center}.edd-card-selector-radio .edd-stripe-card-radio-item label .add-new-card,.edd-card-selector-radio .edd-stripe-card-radio-item label .card-label{margin-left:8px}.edd-card-selector-radio .edd-stripe-card-radio-item.selected{border:1px solid #f0f0f0;background-color:#fcfcfc;border-radius:3px}.edd-card-selector-radio div.card-label{width:65%;display:inline-block}.edd-card-selector-radio span.card-is-default{font-style:italic}.edd-card-selector-radio span.card-expired{color:#f33}.edd-stripe-card-selector+.edd-stripe-new-card{margin-top:20px}#edd-stripe-manage-cards .edd-stripe-add-new-card{margin:20px 0 10px}#edd-stripe-manage-cards div.edd-stripe-card-item{list-style:none;width:100%;display:-ms-inline-grid;display:inline-grid;border:1px solid #f0f0f0;padding:5px 10px;min-height:100px;margin-bottom:10px;border-radius:3px;margin-left:0px}.edd-stripe-card-item>span{display:block}.edd-stripe-card-item .card-meta>span{color:#999;display:block}.edd-stripe-card-item .card-actions a{text-decoration:none}.edd-stripe-card-item .card-actions a.delete{color:#f33}.card-actions .edd-loading-ajax{display:inline-block;margin-right:4px}.edd-stripe-card-item .card-update-form{display:none}.edd-stripe-card-item .card-update-form label{font-weight:bold}.edd-stripe-card-item .card-update-form input{margin-bottom:3px}.edd-stripe-card-item .card-update-form select{background:#fff;border:1px solid #e4e4e4;height:40px;margin-right:3px}.edd-stripe-card-item .card-update-form select:first-of-type{margin-right:3px}.edd-stripe-card-item .card-address-fields input,.edd-stripe-card-item .card-address-fields select{width:49%;display:inline-block}.edd-stripe-add-new-card label{font-weight:bold;display:block;position:relative;line-height:100%;font-size:95%;margin:0 0 5px}.edd-stripe-add-new-card label:after{display:block;visibility:hidden;float:none;clear:both;height:0;text-indent:-9999px;content:"."}.edd-stripe-add-new-card span.edd-description{color:#666;font-size:80%;display:block;margin:0 0 5px}.edd-stripe-add-new-card input.edd-input,.edd-stripe-add-new-card textarea.edd-input{display:inline-block;width:70%}.edd-stripe-add-new-card select.edd-select{display:block;width:60%}.edd-stripe-add-new-card select.edd-select.edd-select-small{display:inline;width:auto}.edd-stripe-add-new-card input.edd-input.error,.edd-stripe-add-new-card textarea.edd-input.error{border-color:#c4554e}.edd-stripe-add-new-card>p{margin:0 0 21px}.edd-stripe-add-new-card span.edd-required-indicator{color:#b94a48;display:inline}.edd-stripe-add-new-card textarea,.edd-stripe-add-new-card input[type=text],.edd-stripe-add-new-card input[type=email],.edd-stripe-add-new-card input[type=password],.edd-stripe-add-new-card input[type=tel]{padding:4px 6px}.edd-stripe-add-new-card input[type=radio]{border:none;margin-right:5px}.edd-stripe-add-new-card input[type=checkbox]{display:inline-block;margin:0 5px 0 0}.edd-stripe-add-new-card input[type=checkbox]+label,.edd-stripe-add-new-card input[type=checkbox]+label:after{display:inline}.edd-stripe-add-new-card .edd-payment-icons{height:32px;display:block;margin:0 0 8px}.edd-stripe-add-new-card .edd-payment-icons img.payment-icon{max-height:32px;width:auto;margin:0 3px 0 0;float:left;background:none;padding:0;border:none;box-shadow:none}.edd-stripe-add-new-card #edd-payment-mode-wrap label{display:inline-block;margin:0 20px 0 0}.edd-stripe-add-new-card #edd-payment-mode-wrap .edd-payment-mode-label{font-weight:bold;display:inline-block;position:relative;margin-bottom:5px}.edd-stripe-add-new-card fieldset{border:1px solid #eee;padding:1.387em;margin:0 0 21px}.edd-stripe-add-new-card #edd_purchase_submit,.edd-stripe-add-new-card #edd_discount_code,.edd-stripe-add-new-card #edd_register_account_fields{padding:0;border:none}.edd-stripe-add-new-card fieldset fieldset{margin:0;border:none;padding:0}.edd-stripe-add-new-card #edd-login-account-wrap,.edd-stripe-add-new-card #edd-new-account-wrap,.edd-stripe-add-new-card #edd_show_discount,.edd-stripe-add-new-card .edd-cart-adjustment,.edd-stripe-add-new-card #edd_final_total_wrap{background:#fafafa;color:#666;padding:.5em 1.387em}.edd-stripe-add-new-card #edd-discount-code-wrap,.edd-stripe-add-new-card #edd_final_total_wrap,.edd-stripe-add-new-card #edd_show_discount{border:1px solid #eee}.edd-stripe-add-new-card .edd-cart-adjustment{padding:1.387em}.edd-stripe-add-new-card .edd-cart-adjustment input.edd-input,.edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit{display:inline-block}.edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit{padding:3px 12px;margin-bottom:2px}.edd-stripe-add-new-card #edd-discount-error-wrap{width:100%;display:inline-block;margin:1em 0 0}.edd-stripe-add-new-card #edd-new-account-wrap,.edd-stripe-add-new-card #edd-login-account-wrap{margin:-1.387em -1.387em 21px;border-left:none;border-right:none;border-top:none}.edd-stripe-add-new-card #edd_payment_mode_select{margin-bottom:21px}.edd-stripe-add-new-card fieldset#edd_register_fields #edd_checkout_user_info{margin-bottom:21px}.edd-stripe-add-new-card fieldset#edd_register_account_fields legend{padding-top:11px}.edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_register_password,.edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_login_password{margin:0}.edd-stripe-add-new-card fieldset#edd_cc_fields{border:1px solid #f0f0f0;background:#f9f9f9;position:relative}.edd-stripe-add-new-card fieldset#edd_cc_fields legend{border:none;padding:0}.edd-stripe-add-new-card fieldset p:last-child{margin-bottom:0}#edd_secure_site_wrapper{padding:4px 4px 4px 0;font-weight:bold}.edd-stripe-add-new-card span.exp-divider{display:inline}.edd-stripe-card-element.StripeElement,.edd-stripe-card-exp-element.StripeElement,.edd-stripe-card-cvc-element.StripeElement{box-sizing:border-box;padding:10px 12px;border:1px solid #ccc;background-color:#fff}.edd-stripe-card-element.StripeElement--invalid{border-color:#c4554e !important}#edd-stripe-card-errors:not(:empty){margin:20px 0 0}#edd-card-wrap{position:relative}#edd-card-details-wrap{display:flex;justify-content:space-between;flex-wrap:wrap}#edd-card-details-wrap p:empty{width:100%}#edd-card-exp-wrap,#edd-card-cvv-wrap{width:48%}#edd-stripe-card-element-wrapper{position:relative}#edd_checkout_form_wrap .edd-stripe-new-card span.card-type{background-size:32px 24px !important;width:32px;height:24px;top:50%;transform:translate3d(0, -50%, 0);right:10px}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}
2
+
3
+ /*# sourceMappingURL=app.min.css.map*/
includes/gateways/stripe/assets/css/build/app.min.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["webpack:///./assets/css/src/frontend.scss"],"names":[],"mappings":"AAAA,MAAM,6BAA6B,0CAA0C,qBAAqB,aAAa,eAAe,MAAM,OAAO,QAAQ,SAAS,+BAA+B,qCAAqC,aAAa,uBAAuB,mBAAmB,uBAAuB,sBAAsB,gBAAgB,eAAe,gBAAgB,sBAAsB,gBAAgB,kCAAkC,gBAAgB,oBAAoB,yBAAyB,gDAAgD,aAAa,8BAA8B,mBAAmB,wBAAwB,gBAAgB,MAAM,UAAU,gBAAgB,6BAA6B,mBAAmB,gBAAgB,eAAe,SAAS,mBAAmB,cAAc,aAAa,0BAA0B,YAAY,qBAAqB,wBAAwB,+CAA+C,+BAA+B,KAAK,0BAA0B,GAAG,yBAAyB,uBAAuB,KAAK,0BAA0B,GAAG,yBAAyB,gCAAgC,KAAK,wBAAwB,GAAG,2BAA2B,wBAAwB,KAAK,wBAAwB,GAAG,2BAA2B,sBAAsB,aAAa,8BAA8B,cAAc,gEAAgE,6DAA6D,qDAAqD,+DAA+D,8DAA8D,sDAAsD,wFAAwF,sBAAsB,UAAU,cAAc,aAAa,cAAc,cAAc,kBAAkB,cAAc,gBAAgB,2CAA2C,gCAAgC,WAAW,qBAAqB,WAAW,kBAAkB,sBAAsB,UAAU,sBAAsB,WAAW,iBAAiB,qBAAqB,UAAU,kBAAkB,oCAAoC,kBAAkB,2CAA2C,WAAW,kBAAkB,OAAO,WAAW,YAAY,MAAM,YAAY,sCAAsC,YAAY,gCAAgC,kBAAkB,uCAAuC,WAAW,kBAAkB,OAAO,WAAW,YAAY,MAAM,YAAY,kCAAkC,YAAY,kCAAkC,gBAAgB,sCAAsC,aAAa,uDAAuD,eAAe,sBAAsB,mBAAmB,iBAAiB,eAAe,WAAW,qDAAqD,WAAW,eAAe,iBAAiB,6BAA6B,2DAA2D,cAAc,SAAS,aAAa,mBAAmB,gJAAgJ,gBAAgB,8DAA8D,yBAAyB,yBAAyB,kBAAkB,wCAAwC,UAAU,qBAAqB,8CAA8C,kBAAkB,2CAA2C,WAAW,+CAA+C,gBAAgB,kDAAkD,mBAAmB,kDAAkD,gBAAgB,WAAW,wBAAwB,oBAAoB,yBAAyB,iBAAiB,iBAAiB,mBAAmB,kBAAkB,gBAAgB,2BAA2B,cAAc,sCAAsC,WAAW,cAAc,sCAAsC,qBAAqB,6CAA6C,WAAW,gCAAgC,qBAAqB,iBAAiB,wCAAwC,aAAa,8CAA8C,iBAAiB,8CAA8C,kBAAkB,+CAA+C,gBAAgB,yBAAyB,YAAY,iBAAiB,6DAA6D,iBAAiB,mGAAmG,UAAU,qBAAqB,+BAA+B,iBAAiB,cAAc,kBAAkB,iBAAiB,cAAc,eAAe,qCAAqC,cAAc,kBAAkB,WAAW,WAAW,SAAS,oBAAoB,YAAY,8CAA8C,WAAW,cAAc,cAAc,eAAe,qFAAqF,qBAAqB,UAAU,2CAA2C,cAAc,UAAU,4DAA4D,eAAe,WAAW,iGAAiG,qBAAqB,2BAA2B,gBAAgB,qDAAqD,cAAc,eAAe,8MAA8M,gBAAgB,2CAA2C,YAAY,iBAAiB,8CAA8C,qBAAqB,iBAAiB,8GAA8G,eAAe,4CAA4C,YAAY,cAAc,eAAe,6DAA6D,gBAAgB,WAAW,iBAAiB,WAAW,gBAAgB,UAAU,YAAY,gBAAgB,sDAAsD,qBAAqB,kBAAkB,wEAAwE,iBAAiB,qBAAqB,kBAAkB,kBAAkB,kCAAkC,sBAAsB,gBAAgB,gBAAgB,gJAAgJ,UAAU,YAAY,2CAA2C,SAAS,YAAY,UAAU,yOAAyO,mBAAmB,WAAW,qBAAqB,4IAA4I,sBAAsB,8CAA8C,gBAAgB,6HAA6H,qBAAqB,+DAA+D,iBAAiB,kBAAkB,kDAAkD,WAAW,qBAAqB,eAAe,gGAAgG,8BAA8B,iBAAiB,kBAAkB,gBAAgB,kDAAkD,mBAAmB,8EAA8E,mBAAmB,qEAAqE,iBAAiB,yKAAyK,SAAS,gDAAgD,yBAAyB,mBAAmB,kBAAkB,uDAAuD,YAAY,UAAU,+CAA+C,gBAAgB,yBAAyB,sBAAsB,iBAAiB,0CAA0C,eAAe,6HAA6H,sBAAsB,kBAAkB,sBAAsB,sBAAsB,gDAAgD,gCAAgC,oCAAoC,gBAAgB,eAAe,kBAAkB,uBAAuB,aAAa,8BAA8B,eAAe,+BAA+B,WAAW,sCAAsC,UAAU,iCAAiC,kBAAkB,4DAA4D,qCAAqC,WAAW,YAAY,QAAQ,kCAAkC,WAAW,oBAAoB,YAAY,uCAAuC,cAAc,2HAA2H,WAAW,iEAAiE,kBAAkB,gBAAgB,4CAA4C,mBAAmB,qCAAqC,cAAc,wDAAwD,mBAAmB,yEAAyE,S","file":"assets/css/build/app.min.css","sourcesContent":[":root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem * 1.5);padding:calc(var(--edds-modal-grid-unit) * 1.5);display:flex;justify-content:space-between;align-items:center;position:-webkit-sticky;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:\"✕\"}.edds-modal__content{margin:calc(1rem * 1.5);margin:calc(var(--edds-modal-grid-unit) * 1.5)}@-webkit-keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@-webkit-keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{-webkit-animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1);animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{-webkit-animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1);animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-prb{margin:15px 0;display:none}.edds-prb__or{font-size:90%;text-align:center;margin:15px 0;overflow:hidden}.edds-prb__or::before,.edds-prb__or::after{background-color:rgba(0,0,0,.1);content:\"\";display:inline-block;height:1px;position:relative;vertical-align:middle;width:50%}.edds-prb__or::before{right:.5em;margin-left:-50%}.edds-prb__or::after{left:.5em;margin-right:-50%}.edd_download_purchase_form.loading{position:relative}.edd_download_purchase_form.loading::after{content:\"\";position:absolute;left:0;width:100%;height:100%;top:0;z-index:100}.edd_download_purchase_form.loading>*{opacity:.65}#edd_checkout_form_wrap.loading{position:relative}#edd_checkout_form_wrap.loading::after{content:\"\";position:absolute;left:0;width:100%;height:100%;top:0;z-index:100}#edd_checkout_form_wrap.loading>*{opacity:.65}#edd_checkout_form_wrap .edds-prb{margin-bottom:0}#edd_checkout_form_wrap .edds-prb__or{display:none}#edd_checkout_form_wrap .edd-card-selector-radio label{display:inline;vertical-align:middle;font-weight:normal;line-height:24px;font-size:100%;margin:0px}.edd-card-selector-radio .edd-stripe-card-radio-item{width:100%;font-size:15px;padding:8px 12px;border:1px solid transparent}.edd-card-selector-radio .edd-stripe-card-radio-item label{line-height:1;margin:0;display:flex;align-items:center}.edd-card-selector-radio .edd-stripe-card-radio-item label .add-new-card,.edd-card-selector-radio .edd-stripe-card-radio-item label .card-label{margin-left:8px}.edd-card-selector-radio .edd-stripe-card-radio-item.selected{border:1px solid #f0f0f0;background-color:#fcfcfc;border-radius:3px}.edd-card-selector-radio div.card-label{width:65%;display:inline-block}.edd-card-selector-radio span.card-is-default{font-style:italic}.edd-card-selector-radio span.card-expired{color:#f33}.edd-stripe-card-selector+.edd-stripe-new-card{margin-top:20px}#edd-stripe-manage-cards .edd-stripe-add-new-card{margin:20px 0 10px}#edd-stripe-manage-cards div.edd-stripe-card-item{list-style:none;width:100%;display:-ms-inline-grid;display:inline-grid;border:1px solid #f0f0f0;padding:5px 10px;min-height:100px;margin-bottom:10px;border-radius:3px;margin-left:0px}.edd-stripe-card-item>span{display:block}.edd-stripe-card-item .card-meta>span{color:#999;display:block}.edd-stripe-card-item .card-actions a{text-decoration:none}.edd-stripe-card-item .card-actions a.delete{color:#f33}.card-actions .edd-loading-ajax{display:inline-block;margin-right:4px}.edd-stripe-card-item .card-update-form{display:none}.edd-stripe-card-item .card-update-form label{font-weight:bold}.edd-stripe-card-item .card-update-form input{margin-bottom:3px}.edd-stripe-card-item .card-update-form select{background:#fff;border:1px solid #e4e4e4;height:40px;margin-right:3px}.edd-stripe-card-item .card-update-form select:first-of-type{margin-right:3px}.edd-stripe-card-item .card-address-fields input,.edd-stripe-card-item .card-address-fields select{width:49%;display:inline-block}.edd-stripe-add-new-card label{font-weight:bold;display:block;position:relative;line-height:100%;font-size:95%;margin:0 0 5px}.edd-stripe-add-new-card label:after{display:block;visibility:hidden;float:none;clear:both;height:0;text-indent:-9999px;content:\".\"}.edd-stripe-add-new-card span.edd-description{color:#666;font-size:80%;display:block;margin:0 0 5px}.edd-stripe-add-new-card input.edd-input,.edd-stripe-add-new-card textarea.edd-input{display:inline-block;width:70%}.edd-stripe-add-new-card select.edd-select{display:block;width:60%}.edd-stripe-add-new-card select.edd-select.edd-select-small{display:inline;width:auto}.edd-stripe-add-new-card input.edd-input.error,.edd-stripe-add-new-card textarea.edd-input.error{border-color:#c4554e}.edd-stripe-add-new-card>p{margin:0 0 21px}.edd-stripe-add-new-card span.edd-required-indicator{color:#b94a48;display:inline}.edd-stripe-add-new-card textarea,.edd-stripe-add-new-card input[type=text],.edd-stripe-add-new-card input[type=email],.edd-stripe-add-new-card input[type=password],.edd-stripe-add-new-card input[type=tel]{padding:4px 6px}.edd-stripe-add-new-card input[type=radio]{border:none;margin-right:5px}.edd-stripe-add-new-card input[type=checkbox]{display:inline-block;margin:0 5px 0 0}.edd-stripe-add-new-card input[type=checkbox]+label,.edd-stripe-add-new-card input[type=checkbox]+label:after{display:inline}.edd-stripe-add-new-card .edd-payment-icons{height:32px;display:block;margin:0 0 8px}.edd-stripe-add-new-card .edd-payment-icons img.payment-icon{max-height:32px;width:auto;margin:0 3px 0 0;float:left;background:none;padding:0;border:none;box-shadow:none}.edd-stripe-add-new-card #edd-payment-mode-wrap label{display:inline-block;margin:0 20px 0 0}.edd-stripe-add-new-card #edd-payment-mode-wrap .edd-payment-mode-label{font-weight:bold;display:inline-block;position:relative;margin-bottom:5px}.edd-stripe-add-new-card fieldset{border:1px solid #eee;padding:1.387em;margin:0 0 21px}.edd-stripe-add-new-card #edd_purchase_submit,.edd-stripe-add-new-card #edd_discount_code,.edd-stripe-add-new-card #edd_register_account_fields{padding:0;border:none}.edd-stripe-add-new-card fieldset fieldset{margin:0;border:none;padding:0}.edd-stripe-add-new-card #edd-login-account-wrap,.edd-stripe-add-new-card #edd-new-account-wrap,.edd-stripe-add-new-card #edd_show_discount,.edd-stripe-add-new-card .edd-cart-adjustment,.edd-stripe-add-new-card #edd_final_total_wrap{background:#fafafa;color:#666;padding:.5em 1.387em}.edd-stripe-add-new-card #edd-discount-code-wrap,.edd-stripe-add-new-card #edd_final_total_wrap,.edd-stripe-add-new-card #edd_show_discount{border:1px solid #eee}.edd-stripe-add-new-card .edd-cart-adjustment{padding:1.387em}.edd-stripe-add-new-card .edd-cart-adjustment input.edd-input,.edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit{display:inline-block}.edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit{padding:3px 12px;margin-bottom:2px}.edd-stripe-add-new-card #edd-discount-error-wrap{width:100%;display:inline-block;margin:1em 0 0}.edd-stripe-add-new-card #edd-new-account-wrap,.edd-stripe-add-new-card #edd-login-account-wrap{margin:-1.387em -1.387em 21px;border-left:none;border-right:none;border-top:none}.edd-stripe-add-new-card #edd_payment_mode_select{margin-bottom:21px}.edd-stripe-add-new-card fieldset#edd_register_fields #edd_checkout_user_info{margin-bottom:21px}.edd-stripe-add-new-card fieldset#edd_register_account_fields legend{padding-top:11px}.edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_register_password,.edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_login_password{margin:0}.edd-stripe-add-new-card fieldset#edd_cc_fields{border:1px solid #f0f0f0;background:#f9f9f9;position:relative}.edd-stripe-add-new-card fieldset#edd_cc_fields legend{border:none;padding:0}.edd-stripe-add-new-card fieldset p:last-child{margin-bottom:0}#edd_secure_site_wrapper{padding:4px 4px 4px 0;font-weight:bold}.edd-stripe-add-new-card span.exp-divider{display:inline}.edd-stripe-card-element.StripeElement,.edd-stripe-card-exp-element.StripeElement,.edd-stripe-card-cvc-element.StripeElement{box-sizing:border-box;padding:10px 12px;border:1px solid #ccc;background-color:#fff}.edd-stripe-card-element.StripeElement--invalid{border-color:#c4554e !important}#edd-stripe-card-errors:not(:empty){margin:20px 0 0}#edd-card-wrap{position:relative}#edd-card-details-wrap{display:flex;justify-content:space-between;flex-wrap:wrap}#edd-card-details-wrap p:empty{width:100%}#edd-card-exp-wrap,#edd-card-cvv-wrap{width:48%}#edd-stripe-card-element-wrapper{position:relative}#edd_checkout_form_wrap .edd-stripe-new-card span.card-type{background-size:32px 24px !important;width:32px;height:24px;top:50%;transform:translate3d(0, -50%, 0);right:10px}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}"],"sourceRoot":""}
includes/gateways/stripe/assets/css/src/admin.scss ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .edds-stripe-connect-acount-info .spinner {
2
+ float: none;
3
+ display: inline-block;
4
+ margin: -2px 5px 0 0;
5
+ }
6
+
7
+ // Payment Gateways setting.
8
+ #edds-payment-gateways-stripe-unmet-requirements {
9
+ margin: -10px 0 0 -16px;
10
+ padding-top: 10px;
11
+
12
+ input[type="checkbox"] {
13
+ margin: 0 6px 0 0;
14
+ }
15
+ }
16
+
17
+ // Settings subtab.
18
+ .edds-requirements-not-met {
19
+
20
+ th {
21
+ display: none;
22
+ }
23
+
24
+ td {
25
+ padding: 0;
26
+ }
27
+ }
28
+
29
+ /*
30
+ * Stripe Connect
31
+ */
32
+ .edd-stripe-connect {
33
+ display: inline-block;
34
+ margin-bottom: 1px;
35
+
36
+ background-image: -webkit-linear-gradient(#28A0E5, #015E94);
37
+ background-image: -moz-linear-gradient(#28A0E5, #015E94);
38
+ background-image: -ms-linear-gradient(#28A0E5, #015E94);
39
+ background-image: linear-gradient(#28A0E5, #015E94);
40
+
41
+ -webkit-font-smoothing: antialiased;
42
+ border: 0;
43
+ padding: 1px;
44
+ height: 30px;
45
+ text-decoration: none;
46
+
47
+ -moz-border-radius: 4px;
48
+ -webkit-border-radius: 4px;
49
+ border-radius: 4px;
50
+
51
+ -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
52
+ -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
53
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
54
+
55
+ cursor: pointer;
56
+
57
+ -moz-user-select: none;
58
+ -webkit-user-select: none;
59
+ -ms-user-select: none;
60
+ user-select: none;
61
+ }
62
+
63
+ .edd-stripe-connect span {
64
+ display: block;
65
+ position: relative;
66
+ padding: 0 12px 0 44px;
67
+ height: 30px;
68
+
69
+ background: #1275FF;
70
+ background-image: -webkit-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
71
+ background-image: -moz-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
72
+ background-image: -ms-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
73
+ background-image: linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
74
+
75
+ font-size: 14px;
76
+ line-height: 30px;
77
+ color: white;
78
+ font-weight: bold;
79
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
80
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
81
+
82
+ -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.25);
83
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
84
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
85
+
86
+ -moz-border-radius: 3px;
87
+ -webkit-border-radius: 3px;
88
+ border-radius: 3px;
89
+ }
90
+
91
+ .edd-stripe-connect span:before {
92
+ content: '';
93
+ display: block;
94
+ position: absolute;
95
+ left: 11px;
96
+ top: 50%;
97
+ width: 23px;
98
+ height: 24px;
99
+ margin-top: -12px;
100
+ background-repeat: no-repeat;
101
+ background-size: 23px 24px;
102
+ }
103
+
104
+ .edd-stripe-connect:active {
105
+ background: #005D93;
106
+ }
107
+
108
+ .edd-stripe-connect:active span {
109
+ color: #EEE;
110
+
111
+ background: #008CDD;
112
+ background-image: -webkit-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
113
+ background-image: -moz-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
114
+ background-image: -ms-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
115
+ background-image: linear-gradient(#008CDD, #008CDD 85%, #239ADF);
116
+
117
+ -moz-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
118
+ -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
119
+ box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
120
+ }
121
+
122
+ .edd-stripe-connect:active span:before {
123
+
124
+ }
125
+
126
+ .edd-stripe-connect span:before, .edd-stripe-connect.blue span:before {
127
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAYAAAARfGZ1AAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAADQklEQVRIDbWVaUiUQRjHZ96dXY/d1fYQj1U03dJSw9YkFgy6DIkILRArQSSC7PjQjQQqVH7oQ0GHQUWgpQhKHzoNSqiUwpXcsrwIjzVtPVrzbPV9Z6bZhYV3N3WXYAeGmWeeZ37z8J95GEgpBf5oeXn1Es4fYAdzPDlM6je4RBYhR+LMU89UxiCBGiCgkUwsBYSA+SlPKLQBQAYEAZm+3j42K96z3NyOF7VOeMrp62opRcacjPW5+43rDTpNSKQ8QKZAEg7xmPCTs/O27uGJgXuNbW0pxyvLfTmAEBzthEsFZLxRvPdi5rpYo2cmUiQJDA4IVeo0obGdlvGfXUPj0Sym2zPuHxvzcWjDyVupJ/YYizKTGNjLw/HiduNTAqIRIUJ6Vpp+ky8bCSFgwQ2xgkGxFi1ioNWEBGuJB31gbLIv/2pd7SpFoGxtpCYkLSEq4ptlzIYFO7tc7w0TKkeEYg5ADnrWkkYhD8s26GPq3nW0WKxTptftPYBI4Mj3O2fHvKNZBMVSDmMwarXNjDkSF3d5kExZeiCr8M2VI+VFu9IvsPcYtzAvkfoEZkEEE45jMppq3ppbCNPFIY1nD1cpo07lbMmvOXeoDCF8BLKy9uUAAjDkBh+c6bz78mNtVVP7MwET7JBnqb4xXpdWVpC1OVzWn+ELHLCsneX/s7rkRWl1463cy1U3WroG21jhCGKJXPOtKQnpAuENvsAppgDB3TcDVIrpDHbK5Kd+y7W8iodNybHh22rOHyxUK+UaMYjZaoyp25rYL54TSihSKmwZ14v3lc3ZFxdbeywjn/tGJnkmzrydX1ApxOEACKymmXLYfXVpi1JMEOGxPi1ep18doY4r2J7uFumQQ9yGf01bMcZW8dpyc0oIjxxpuC5wuUDX+ovWrnYeg3aXvdLIqnmOvXPsfH6uA5YbTb1DX8ofvTLzTy6ZV4K6fAw+gXiATfdffmjeaUgc1UdpdWplsCooQBrEnqUw82dhdnjit/Vxc4f59tP3DRjzJvYteqrl4rmNlJIfrOwpgNklesDRNQBCHYtQAQqD2CgACNjHAJnG1EyfV/S67fZiJB5t2OGEe4n7L3fS4fpEv/2hUEATfoPbuam5v8N7nps70YTbAAAAAElFTkSuQmCC");
128
+ }
129
+
130
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
131
+ only screen and (min--moz-device-pixel-ratio: 1.5),
132
+ only screen and (min-device-pixel-ratio: 1.5) {
133
+ .edd-stripe-connect span:before, .edd-stripe-connect.blue span:before {
134
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAwCAYAAABuZUjcAAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAAIbklEQVRoBdVZa5BURxU+fZ9z57mzs7PvF4i7srAQSCifMVDERC0jYlzUlJalKeGPlCnL/NEfywpWacoiVZRVJIYfGjGUu5bxj5qHFSAYyQOBEsJzYSHDvnd2dp535j66PX1vNgsULDPs1cr2Vs+9e7v79NfnnnP663MJYwwWYxEWI2iOedEClxabxgkBwjEvOuA9PQOOlSw64JMr4vK8GidYYMcOES4tVSEAAZ8FAUqon1GiAJEEEG0CjFB8cTaxZUMAo1gEqQA0UABprAjPbrUwXnkesgqKP8CBk5vDIenrE+BKmwI+MawA1MbCkdV10cBDflXuVmSxQRbFkCAQZ9U2ZTaONyxKcyXDHjMs83ImV3rz6njmDRPMUZB80zAJOuvvsflkXpTP7DrWyeXcYCqk75AEieawrEoty1vrvlcV0ja3VQdb1rVUQVd9EFqqNIj5ZfDJooPBsCnohq2ldDMynC42XZnW7z09lu25lMxDMl34y0gyvTsBwyewc84Z4MEPpWIzF/MBcLLtNzJISmxZU+PmWETbtqGzfvVja5uguyF02+kCIEJUk6Ex4oMV9XP9ZnQT/nZ24it7XrtoJ5LZ7SjAM+Bg2+0ckAOcbBkQIaZFVzY1bGurjezYfn87PNQZ5+13ZaQRXMzH26Lg8ymfUokQdAR59INOc53GQ6q/Jiiua6oJ7+h9uAPua47cHeLrwHEmQRmTGLHV6x4v+JYwWsOFCGRDn6RKem1rPPrkN9Y0uqAXLN4VwCgjYGEE8rBgMAjwKsF9S9WgLa9qjYcf+Po9jXdlGrfC5Wj8Vg0Lf+ZENAFmpGB9TWTLhmUxUD1UDg/gtudRnK+a4RtkgqQyO+RT5LVrmiLgJcN19gcGNojUWriS5yRQm7pcBTc/vyCKdW1RrWwzOTiYhGf+dRUmcgZosgDVfgWaMCS2V2tO+OzG0MiVjdUwiFiYm9a7O4kJAoZEooV9H4T0O0ofODkKr5+6+nY6V3heVZQpv6ZWaz55qSJJnXjtUBW5pT7k8xeK5u+B0PQdBVbQgTLq9HbQYthyNVSmTT6A/nB0aGpF0K99+trY1F7TNI9PZGXkKUVRtYjGZCIOV1dHR4Ynz8FSLV8BrjK6uiAlpLcmco1ipmgpAaU8rfesboCuumBg31uJbx6+qH0uX9D/em0i85xFhaslKZKA8/82RtYDhd/1MkCuBnjxrLgKB0EQSb5oWO+9O1bZrsy3+Kc3dcH+b99b07NuyXe6P9r8z/am+C9lkuqCjo4qGGkQES76qJcuz/2GOlUoFuVsQS+98frlaSeq8Gkqqctrg7Dz853wwrfugUfXtj3W3tJ8oCletRUEXy1SCSSYHhdu41gFqILcZCrzwkvnJmE0U3JtHefiL7eS2l7th11f7IQ9j65aVh+r+nlzbd2TELJrHPLmIXZX3wyBX8MTQMm8PJ0u9Pe9chGQYy9omvXouHu/thJqI+Ef1sZDm0AMBmfPiQsSPDuY2zhWwSH5ISU5Pjm98x9nRo7+7JVBB3wl5nJz35Vo/z/esBQUVf2+QlkD9Aw42/Ts3Au7ushdAhQ5UzJoOjE+OrV9/1tDR7cNnIax7N2bDX9nm1bUQXdz9Rp/MLwRoqAtDOzcaO7rvDrAWW8vhcatWVNjF6cmJre9embkz1947h3YfXgIUgVzblQldxgFH0ZOr/qULwM15k4Zlci4Vd9ZU5ltY71oObHBnBFQBidmUk8kEsOP7Hntwqsb974NfS8PAh7LKoo23Hw+2R4FQcSzKlDPgFOEyf8kx3HW94kQ7xJgRRdAJG7CyIWxgiXNUN0+k5nJLN83k3n8D8eHN3+1ux5+8uBHIKiWt1G1Rn3IJkiUCcQzU3G0h9qWHMeJdoSrwtr9dl6I6DNjFwRRyxiKnStSqkPJPsGSmZ+mp1P9z2dzOy3Klj31yMdmX9S8V75APEsomMZwT9fz9i6vkW9AvEgQyqrBQM2Dq9rrD0gCgXfHA0jpjIRm2Zcw+3CR2tZl27SnMZFSZ1lWcRwZITeDckresAEXaoKwwBh7/WQubgTOQj5BVjdv7KiBJz7bztMNcHIk03JiONNyfiK/ntv2VMHAMx6BjpoA/Gj9Emdjul7W7e6TeQNDK9WJLRm361P5c1drEmAaymaYoXpfjZoiOk7FHWuh5dxEHmzLHiXM9oyTz9FawRZw65f5yyzXBMpd0JGhFKB5nSwRMVvumDv2cxm4m1f5X4AuWhRePDUOtqEPQJVVGfWcBz1ahmPlTlxzqaJLquYZU1HTvjcTMD6dOULM0n+g5nKposHzdWbo7FgEkDBviWlYx++53XtQ33kvDU8dHAJm6L8usdwEZn09S3qiPed5lcCSLUpI0eEA8620zLbDl6bh8T+egkI+/7Rl6kegcTSPst1QUKaM+brhrjnF2yUQJNxnrGMnR7KbTw5nYFVjyAl98w2+VdvVlA67Dw3BgROjAKa+yyrpz0BKTbJnez1NT6AKrrnA1bEi1av2v3xaiL90dnxL2Kc0rsXc4WpcQEc8AEtiGrRiejmK6WWeMDIxtVwwKExijB5KFuBYIg1cy8dx0dTQ/yQVc78yBXMIqJ5i/VvvkqHdSjXuM/THKy7w2LQJ6fpJms38QiHGvlzBt+RwJv2JQ2elbjyRtjIi1AIRMAsKPuQduHVzr2YW+kIBE5BTwOzzxLKOiMX8QVuWh00IpqD+S0WHtLlzefpLBOZo/IYvEqQPnTX5dxmy4xookqaCjRuT4mMi8g3bxs2KCkj3GFj4+QSzA0RkeskU8iCJeUiBDv09Jt8OPEV6k7DlP3gxxh/dAPymPh/Kf5d897dIOd9P7H8oEd4G1JV8wPGbRadx52sgLmrRAZ99EZ5+LZgV+v+4Llrg/wX6HRCxgvzAAwAAAABJRU5ErkJggg==");
135
+ }
136
+ }
137
+ /* End of Stripe Connect */
includes/gateways/stripe/assets/css/src/frontend.scss ADDED
@@ -0,0 +1,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencices
3
+ */
4
+ @import './frontend/modal.scss';
5
+ @import './frontend/payment-request-button.scss';
6
+
7
+ #edd_checkout_form_wrap .edd-card-selector-radio label {
8
+ display: inline;
9
+ vertical-align: middle;
10
+ font-weight: normal;
11
+ line-height: 24px;
12
+ font-size: 100%;
13
+ margin: 0px;
14
+ }
15
+
16
+ .edd-card-selector-radio .edd-stripe-card-radio-item {
17
+ width: 100%;
18
+ font-size: 15px;
19
+ padding: 8px 12px;
20
+ border: 1px solid transparent;
21
+
22
+ label {
23
+ line-height: 1;
24
+ margin: 0;
25
+ display: flex;
26
+ align-items: center;
27
+
28
+ .add-new-card,
29
+ .card-label {
30
+ margin-left: 8px;
31
+ }
32
+ }
33
+ }
34
+
35
+ .edd-card-selector-radio .edd-stripe-card-radio-item.selected {
36
+ border: 1px solid #f0f0f0;
37
+ background-color: #fcfcfc;
38
+ -webkit-border-radius: 3px;
39
+ -moz-border-radius: 3px;
40
+ border-radius: 3px;
41
+ }
42
+
43
+ .edd-card-selector-radio div.card-label {
44
+ width: 65%;
45
+ display: inline-block;
46
+ }
47
+
48
+ .edd-card-selector-radio span.card-is-default {
49
+ font-style: italic;
50
+ }
51
+
52
+ .edd-card-selector-radio span.card-expired {
53
+ color: #ff3333;
54
+ }
55
+
56
+ .edd-stripe-card-selector + .edd-stripe-new-card {
57
+ margin-top: 20px;
58
+ }
59
+
60
+ #edd-stripe-manage-cards .edd-stripe-add-new-card {
61
+ margin: 20px 0 10px;
62
+ }
63
+
64
+ #edd-stripe-manage-cards div.edd-stripe-card-item {
65
+ list-style: none;
66
+ width: 100%;
67
+ display: inline-grid;
68
+ border: 1px solid #f0f0f0;
69
+ padding: 5px 10px;
70
+ min-height: 100px;
71
+ margin-bottom: 10px;
72
+ -webkit-border-radius: 3px;
73
+ -moz-border-radius: 3px;
74
+ border-radius: 3px;
75
+ margin-left: 0px;
76
+ }
77
+
78
+ .edd-stripe-card-item > span {
79
+ display: block;
80
+ }
81
+
82
+ .edd-stripe-card-item .card-meta > span {
83
+ color: #999;
84
+ display: block;
85
+ }
86
+
87
+ .edd-stripe-card-item .card-actions a {
88
+ text-decoration: none;
89
+ }
90
+
91
+ .edd-stripe-card-item .card-actions a.delete {
92
+ color: #ff3333;
93
+ }
94
+
95
+ .card-actions .edd-loading-ajax {
96
+ display: inline-block;
97
+ margin-right: 4px;
98
+ }
99
+
100
+ .edd-stripe-card-item .card-update-form {
101
+ display: none;
102
+ }
103
+
104
+ .edd-stripe-card-item .card-update-form label {
105
+ font-weight: bold;
106
+ }
107
+
108
+ .edd-stripe-card-item .card-update-form input {
109
+ margin-bottom: 3px;
110
+ }
111
+
112
+ .edd-stripe-card-item .card-update-form select {
113
+ background: #fff;
114
+ border: 1px solid #e4e4e4;
115
+ height: 40px;
116
+ margin-right: 3px;
117
+ }
118
+
119
+ .edd-stripe-card-item .card-update-form select:first-of-type {
120
+ margin-right: 3px;
121
+ }
122
+
123
+ .edd-stripe-card-item .card-address-fields input,
124
+ .edd-stripe-card-item .card-address-fields select {
125
+ width: 49%;
126
+ display: inline-block;
127
+ }
128
+
129
+ /* Checkout Fields */
130
+ .edd-stripe-add-new-card label {
131
+ font-weight: bold;
132
+ display: block;
133
+ position: relative;
134
+ line-height: 100%;
135
+ font-size: 95%;
136
+ margin: 0 0 5px;
137
+ }
138
+ .edd-stripe-add-new-card label:after {
139
+ display: block;
140
+ visibility: hidden;
141
+ float: none;
142
+ clear: both;
143
+ height: 0;
144
+ text-indent: -9999px;
145
+ content: ".";
146
+ }
147
+ .edd-stripe-add-new-card span.edd-description {
148
+ color: #666;
149
+ font-size: 80%;
150
+ display: block;
151
+ margin: 0 0 5px;
152
+ }
153
+ .edd-stripe-add-new-card input.edd-input,
154
+ .edd-stripe-add-new-card textarea.edd-input {
155
+ display: inline-block;
156
+ width: 70%;
157
+ }
158
+ .edd-stripe-add-new-card select.edd-select {
159
+ display: block;
160
+ width: 60%;
161
+ }
162
+ .edd-stripe-add-new-card select.edd-select.edd-select-small {
163
+ display: inline;
164
+ width: auto;
165
+ }
166
+ .edd-stripe-add-new-card input.edd-input.error,
167
+ .edd-stripe-add-new-card textarea.edd-input.error {
168
+ border-color: #c4554e;
169
+ }
170
+ .edd-stripe-add-new-card > p {
171
+ margin: 0 0 21px;
172
+ }
173
+ .edd-stripe-add-new-card span.edd-required-indicator {
174
+ color: #b94a48;
175
+ display: inline;
176
+ }
177
+ .edd-stripe-add-new-card textarea,
178
+ .edd-stripe-add-new-card input[type="text"],
179
+ .edd-stripe-add-new-card input[type="email"],
180
+ .edd-stripe-add-new-card input[type="password"],
181
+ .edd-stripe-add-new-card input[type="tel"] {
182
+ padding: 4px 6px;
183
+ }
184
+ .edd-stripe-add-new-card input[type="radio"] {
185
+ border: none;
186
+ margin-right: 5px;
187
+ }
188
+ .edd-stripe-add-new-card input[type="checkbox"] {
189
+ display: inline-block;
190
+ margin: 0 5px 0 0;
191
+ }
192
+ .edd-stripe-add-new-card input[type="checkbox"] + label,
193
+ .edd-stripe-add-new-card input[type="checkbox"] + label:after {
194
+ display: inline;
195
+ }
196
+ .edd-stripe-add-new-card .edd-payment-icons {
197
+ height: 32px;
198
+ display: block;
199
+ margin: 0 0 8px;
200
+ }
201
+ .edd-stripe-add-new-card .edd-payment-icons img.payment-icon {
202
+ max-height: 32px;
203
+ width: auto;
204
+ margin: 0 3px 0 0;
205
+ float: left;
206
+ background: none;
207
+ padding: 0;
208
+ border: none;
209
+ -webkit-box-shadow: none;
210
+ -moz-box-shadow: none;
211
+ box-shadow: none;
212
+ }
213
+ .edd-stripe-add-new-card #edd-payment-mode-wrap label {
214
+ display: inline-block;
215
+ margin: 0 20px 0 0;
216
+ }
217
+ .edd-stripe-add-new-card #edd-payment-mode-wrap .edd-payment-mode-label {
218
+ font-weight: bold;
219
+ display: inline-block;
220
+ position: relative;
221
+ margin-bottom: 5px;
222
+ }
223
+ .edd-stripe-add-new-card fieldset {
224
+ border: 1px solid #eee;
225
+ padding: 1.387em;
226
+ margin: 0 0 21px;
227
+ }
228
+ .edd-stripe-add-new-card #edd_purchase_submit,
229
+ .edd-stripe-add-new-card #edd_discount_code,
230
+ .edd-stripe-add-new-card #edd_register_account_fields {
231
+ padding: 0;
232
+ border: none;
233
+ }
234
+ .edd-stripe-add-new-card fieldset fieldset {
235
+ margin: 0;
236
+ border: none;
237
+ padding: 0;
238
+ }
239
+ .edd-stripe-add-new-card #edd-login-account-wrap,
240
+ .edd-stripe-add-new-card #edd-new-account-wrap,
241
+ .edd-stripe-add-new-card #edd_show_discount,
242
+ .edd-stripe-add-new-card .edd-cart-adjustment,
243
+ .edd-stripe-add-new-card #edd_final_total_wrap {
244
+ background: #fafafa;
245
+ color: #666;
246
+ padding: 0.5em 1.387em;
247
+ }
248
+ .edd-stripe-add-new-card #edd-discount-code-wrap,
249
+ .edd-stripe-add-new-card #edd_final_total_wrap,
250
+ .edd-stripe-add-new-card #edd_show_discount {
251
+ border: 1px solid #eee;
252
+ }
253
+ .edd-stripe-add-new-card .edd-cart-adjustment {
254
+ padding: 1.387em;
255
+ }
256
+ .edd-stripe-add-new-card .edd-cart-adjustment input.edd-input,
257
+ .edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit {
258
+ display: inline-block;
259
+ }
260
+ .edd-stripe-add-new-card .edd-cart-adjustment input.edd-submit {
261
+ padding: 3px 12px;
262
+ margin-bottom: 2px;
263
+ }
264
+ .edd-stripe-add-new-card #edd-discount-error-wrap {
265
+ width: 100%;
266
+ display: inline-block;
267
+ margin: 1em 0 0;
268
+ }
269
+ .edd-stripe-add-new-card #edd-new-account-wrap,
270
+ .edd-stripe-add-new-card #edd-login-account-wrap {
271
+ margin: -1.387em -1.387em 21px;
272
+ border-left: none;
273
+ border-right: none;
274
+ border-top: none;
275
+ }
276
+ .edd-stripe-add-new-card #edd_payment_mode_select {
277
+ margin-bottom: 21px;
278
+ }
279
+ .edd-stripe-add-new-card fieldset#edd_register_fields #edd_checkout_user_info {
280
+ margin-bottom: 21px;
281
+ }
282
+ .edd-stripe-add-new-card fieldset#edd_register_account_fields legend {
283
+ padding-top: 11px;
284
+ }
285
+ .edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_register_password,
286
+ .edd-stripe-add-new-card fieldset#edd_register_account_fields p.edd_login_password {
287
+ margin: 0;
288
+ }
289
+ .edd-stripe-add-new-card fieldset#edd_cc_fields {
290
+ border: 1px solid #f0f0f0;
291
+ background: #f9f9f9;
292
+ position: relative;
293
+ }
294
+ .edd-stripe-add-new-card fieldset#edd_cc_fields legend {
295
+ border: none;
296
+ padding: 0;
297
+ }
298
+ .edd-stripe-add-new-card fieldset p:last-child {
299
+ margin-bottom: 0;
300
+ }
301
+ #edd_secure_site_wrapper {
302
+ padding: 4px 4px 4px 0;
303
+ font-weight: bold;
304
+ }
305
+ .edd-stripe-add-new-card span.exp-divider {
306
+ display: inline;
307
+ }
308
+
309
+ /**
310
+ * Stripe Elements - Card
311
+ */
312
+ .edd-stripe-card-element.StripeElement,
313
+ .edd-stripe-card-exp-element.StripeElement,
314
+ .edd-stripe-card-cvc-element.StripeElement {
315
+ box-sizing: border-box;
316
+ padding: 10px 12px;
317
+ border: 1px solid #ccc;
318
+ background-color: white;
319
+ }
320
+
321
+ .edd-stripe-card-element.StripeElement--invalid {
322
+ border-color: #c4554e !important;
323
+ }
324
+
325
+ #edd-stripe-card-errors:not(:empty) {
326
+ margin: 20px 0 0;
327
+ }
328
+
329
+ #edd-card-wrap {
330
+ position: relative;
331
+ }
332
+
333
+ #edd-card-details-wrap {
334
+ display: flex;
335
+ justify-content: space-between;
336
+ flex-wrap: wrap;
337
+ }
338
+
339
+ #edd-card-details-wrap p:empty {
340
+ width: 100%;
341
+ }
342
+
343
+ #edd-card-exp-wrap,
344
+ #edd-card-cvv-wrap {
345
+ width: 48%;
346
+ }
347
+
348
+ #edd-stripe-card-element-wrapper {
349
+ position: relative;
350
+ }
351
+
352
+ #edd_checkout_form_wrap .edd-stripe-new-card span.card-type {
353
+ background-size: 32px 24px !important;
354
+ width: 32px;
355
+ height: 24px;
356
+ top: 50%;
357
+ transform: translate3d(0, -50%, 0);
358
+ right: 10px;
359
+ }
360
+
361
+ /**
362
+ * "Buy Now" modal.
363
+ */
364
+ .edds-buy-now-modal {
365
+ width: 500px;
366
+
367
+ .edds-modal__close {
368
+ padding: 0.5rem;
369
+ }
370
+
371
+ #edd_checkout_form_wrap {
372
+
373
+ input.edd-input,
374
+ textarea.edd-input {
375
+ width: 100%;
376
+ }
377
+
378
+ #edd_purchase_submit {
379
+ margin-top: 1.5rem;
380
+ margin-bottom: 0;
381
+ }
382
+ }
383
+
384
+ .edds-field-spacer-shim {
385
+ margin-bottom: 1rem;
386
+ }
387
+
388
+ .edd-alert-error {
389
+ margin: 20px 0;
390
+ }
391
+
392
+ #edd-stripe-card-errors:not(:empty) {
393
+ margin-bottom: 20px;
394
+
395
+ .edd-alert-error {
396
+ margin: 0;
397
+ }
398
+ }
399
+ }
includes/gateways/stripe/assets/css/src/frontend/modal.scss ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --edds-modal-grid-unit: 1rem;
3
+ --edds-modal-overlay: rgba(0, 0, 0, 0.60);
4
+ }
5
+
6
+ .edds-modal__overlay {
7
+ z-index: 9999;
8
+ position: fixed;
9
+ top: 0;
10
+ left: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ background: var(--edds-modal-overlay);
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: center;
17
+ }
18
+
19
+ .edds-modal__container {
20
+ background-color: #fff;
21
+ min-width: 350px;
22
+ max-width: 90vw;
23
+ max-height: 90vh;
24
+ box-sizing: border-box;
25
+ overflow-y: auto;
26
+ }
27
+
28
+ .admin-bar .edds-modal__container {
29
+ margin-top: 32px;
30
+ }
31
+
32
+ .edds-modal__header {
33
+ padding: calc(var(--edds-modal-grid-unit) * 1.5);
34
+ display: flex;
35
+ justify-content: space-between;
36
+ align-items: center;
37
+ position: sticky;
38
+ top: 0;
39
+ z-index: 2;
40
+ background: #fff;
41
+ border-bottom: 1px solid #eee;
42
+ }
43
+
44
+ .edds-modal__title {
45
+ text-align: left;
46
+ font-size: 150%;
47
+ margin: 0;
48
+ }
49
+
50
+ .edds-modal__close {
51
+ line-height: 1;
52
+ padding: 1rem;
53
+
54
+ &:before {
55
+ content: "\2715";
56
+ }
57
+ }
58
+
59
+ .edds-modal__content {
60
+ margin: calc(var(--edds-modal-grid-unit) * 1.5);
61
+ }
62
+
63
+ /**
64
+ * Animations
65
+ */
66
+ @keyframes eddsSlideIn {
67
+ from {
68
+ transform: translateY(15%);
69
+ }
70
+ to {
71
+ transform: translateY(0);
72
+ }
73
+ }
74
+
75
+ @keyframes eddsSlideOut {
76
+ from {
77
+ transform: translateY(0);
78
+ }
79
+ to {
80
+ transform: translateY(15%);
81
+ }
82
+ }
83
+
84
+ .edds-modal.has-slide {
85
+ display: none;
86
+ }
87
+
88
+ .edds-modal.has-slide.is-open {
89
+ display: block;
90
+ }
91
+
92
+ .edds-modal.has-slide[aria-hidden="false"] .edds-modal__container {
93
+ animation: eddsSlideIn 0.3s cubic-bezier(0.0, 0.0, 0.2, 1);
94
+ }
95
+
96
+ .edds-modal.has-slide[aria-hidden="true"] .edds-modal__container {
97
+ animation: eddsSlideOut 0.3s cubic-bezier(0.0, 0.0, 0.2, 1);
98
+ }
99
+
100
+ .edds-modal.has-slide .edds-modal__container,
101
+ .edds-modal.has-slide .edds-modal__overlay {
102
+ will-change: transform;
103
+ }
includes/gateways/stripe/assets/css/src/frontend/payment-request-button.scss ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .edds-prb {
2
+ margin: 15px 0;
3
+ display: none;
4
+
5
+ &__or {
6
+ font-size: 90%;
7
+ text-align: center;
8
+ margin: 15px 0;
9
+ overflow: hidden;
10
+
11
+ &::before,
12
+ &::after {
13
+ background-color: rgba(0, 0, 0, .10);
14
+ content: "";
15
+ display: inline-block;
16
+ height: 1px;
17
+ position: relative;
18
+ vertical-align: middle;
19
+ width: 50%;
20
+ }
21
+
22
+ &::before {
23
+ right: 0.5em;
24
+ margin-left: -50%;
25
+ }
26
+
27
+ &::after {
28
+ left: 0.5em;
29
+ margin-right: -50%;
30
+ }
31
+ }
32
+ }
33
+
34
+ @mixin loadingState {
35
+
36
+ &.loading {
37
+ position: relative;
38
+
39
+ &::after {
40
+ content: "";
41
+ position: absolute;
42
+ left: 0;
43
+ width: 100%;
44
+ height: 100%;
45
+ top: 0;
46
+ z-index: 100;
47
+ }
48
+
49
+ > * {
50
+ opacity: 0.65;
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Purchase link loading state.
57
+ *
58
+ * Disables interaction while redirecting.
59
+ */
60
+ .edd_download_purchase_form {
61
+
62
+ @include loadingState;
63
+ }
64
+
65
+ /**
66
+ * Checkout
67
+ */
68
+ #edd_checkout_form_wrap {
69
+
70
+ @include loadingState;
71
+
72
+ .edds-prb {
73
+ margin-bottom: 0;
74
+ }
75
+
76
+ .edds-prb__or {
77
+ display: none;
78
+ }
79
+ }
includes/gateways/stripe/assets/js/build/admin.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=100)}({0:function(e,t,n){"use strict";n.d(t,"a",(function(){return r.a})),n.d(t,"e",(function(){return i.a})),n.d(t,"c",(function(){return c})),n.d(t,"g",(function(){return u})),n.d(t,"f",(function(){return s.b})),n.d(t,"i",(function(){return s.c})),n.d(t,"b",(function(){return s.a})),n.d(t,"h",(function(){return d})),n.d(t,"j",(function(){return a})),n.d(t,"d",(function(){return l})),n(25),n(26),n(27),n(28);var r=n(15),o=n(16),i=n.n(o);function c(){i()(arguments,(function(e){document.addEventListener("DOMContentLoaded",e)}))}function u(e){for(var t=[],n=e.nextElementSibling;n;)1===n.nodeType&&t.push(n),n=n.nextElementSibling;return t}var s=n(17);function d(e){var t=!0;return i()(e.querySelectorAll("input"),(function(e){e.checkValidity&&!e.checkValidity()&&(t=!1)})),t}function a(e){var t=document.createElement("input");t.type="submit",t.style.display="none",e.appendChild(t),t.click(),t.remove()}function l(e){return e?""===e.value?null:e.value:null}},100:function(e,t,n){"use strict";n.r(t),function(e){var t,r,o=n(8),i=n.n(o);n(101),n(103),e(document).ready((function(){(t=document.getElementById("edd_settings[test_mode]"))&&(r=document.getElementById("edd_settings[stripe_connect_test_mode_toggle_notice]"),c.init()),e(".edds-api-key-toggle button").on("click",(function(t){t.preventDefault(),e(".edds-api-key-toggle, .edds-api-key-row").toggleClass("edd-hidden")}))}));var c={init:function(){this.listeners()},listeners:function(){var e=this;t.addEventListener("change",(function(){if(edd_stripe_admin.stripe_enabled){if(this.checked)if("false"===edd_stripe_admin.test_key_exists)e.showNotice(r,"warning"),e.addHiddenMarker();else{e.hideNotice(r);var t=document.getElementById("edd-test-mode-toggled");t&&t.parentNode.removeChild(t)}if(!this.checked)if("false"===edd_stripe_admin.live_key_exists)e.showNotice(r,"warning"),e.addHiddenMarker();else{e.hideNotice(r);var n=document.getElementById("edd-test-mode-toggled");n&&n.parentNode.removeChild(n)}}}))},addHiddenMarker:function(){var e=document.getElementById("submit");e&&e.parentNode.insertAdjacentHTML("beforeend",'<input type="hidden" class="edd-hidden" id="edd-test-mode-toggled" name="edd-test-mode-toggled" />')},showNotice:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"error";e&&"object"===i()(e)&&(e.className="notice notice-"+t)},hideNotice:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e&&"object"===i()(e)&&(e.className="edd-hidden")}}}.call(this,n(5))},101:function(e,t,n){},103:function(e,t,n){"use strict";var r=n(0);Object(r.c)((function(){document.querySelector(".edds-requirements-not-met")&&(document.querySelector(".edd-settings-wrap .submit").style.display="none")})),Object(r.c)((function(){var e=document.getElementById("edds-payment-gateways-stripe-unmet-requirements");if(e){var t=document.querySelector('label[for="edd_settings[gateways][stripe]"]');t.parentNode.insertBefore(e,t.nextSibling);var n=document.getElementById("edd_settings[gateways][stripe]");n.disabled=!0,n.checked=!1,e.insertBefore(n,e.querySelector("p")),e.insertBefore(t,e.querySelector("p"))}}));var o=n(3),i=n.n(o);function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}Object(r.c)((function(){var e=document.getElementById("edds-stripe-connect-account"),t=document.getElementById("edds-stripe-disconnect-reconnect");if(e)return Object(r.a)("edds_stripe_connect_account_info",function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){i()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},e.dataset)).done((function(n){e.innerHTML=n.message,e.classList.add("notice-".concat(n.status)),n.actions&&(t.innerHTML=n.actions)})).fail((function(t){e.innerHTML=t.message,e.classList.add("notice-error")}))}))},15:function(e,t,n){"use strict";(function(e){n.d(t,"a",(function(){return d}));var r=n(8),o=n.n(r),i=n(3),c=n.n(i);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){c()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function d(t,n){var r={type:"POST",dataType:"json",xhrFields:{withCredentials:!0},url:window.edd_scripts&&window.edd_scripts.ajaxurl||window.ajaxurl,data:s({action:t},n)},i=e.Deferred((function(t){t.jqXHR=e.ajax(r).done((function(e){"1"!==e&&1!==e||(e={success:!0}),"object"===o()(e)&&void 0!==o()(e.success)?t[e.success?"resolveWith":"rejectWith"](this,[e.data]):t.rejectWith(this,[e])})).fail((function(){t.rejectWith(this,arguments)}))})),c=i.promise();return c.abort=function(){return i.jqXHR.abort(),this},c}}).call(this,n(5))},16:function(e,t){var n=/^(?:0|[1-9]\d*)$/;function r(e,t){for(var n=-1,r=e?e.length:0;++n<r&&!1!==t(e[n],n,e););return e}var o,i,c=Object.prototype,u=c.hasOwnProperty,s=c.toString,d=c.propertyIsEnumerable,a=(o=Object.keys,i=Object,function(e){return o(i(e))});var l,f=(l=function(e,t){return e&&p(e,t,g)},function(e,t){if(null==e)return e;if(!m(e))return l(e,t);for(var n=e.length,r=-1,o=Object(e);++r<n&&!1!==t(o[r],r,o););return e}),p=function(e,t,n){for(var r=-1,o=Object(e),i=n(e),c=i.length;c--;){var u=i[++r];if(!1===t(o[u],u,o))break}return e};function y(e,t){return!!(t=null==t?9007199254740991:t)&&("number"==typeof e||n.test(e))&&e>-1&&e%1==0&&e<t}var b=Array.isArray;function m(e){return null!=e&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&!function(e){var t=function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(e)?s.call(e):"";return"[object Function]"==t||"[object GeneratorFunction]"==t}(e)}function g(e){return m(e)?function(e,t){var n=b(e)||function(e){return function(e){return function(e){return!!e&&"object"==typeof e}(e)&&m(e)}(e)&&u.call(e,"callee")&&(!d.call(e,"callee")||"[object Arguments]"==s.call(e))}(e)?function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}(e.length,String):[],r=n.length,o=!!r;for(var i in e)!t&&!u.call(e,i)||o&&("length"==i||y(i,r))||n.push(i);return n}(e):function(e){if(n=(t=e)&&t.constructor,t!==("function"==typeof n&&n.prototype||c))return a(e);var t,n,r=[];for(var o in Object(e))u.call(e,o)&&"constructor"!=o&&r.push(o);return r}(e)}function h(e){return e}e.exports=function(e,t){return(b(e)?r:f)(e,"function"==typeof t?t:h)}},17:function(e,t,n){"use strict";(function(e){function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"error",n=document.createElement("p");return n.classList.add("edd-alert"),n.classList.add("edd-stripe-alert"),n.style.clear="both","error"===t?n.classList.add("edd-alert-error"):n.classList.add("edd-alert-success"),n.innerHTML=e||edd_stripe_vars.generic_error,n}function o(t){var n=t.errorType,o=t.errorMessage,i=t.errorContainer,c=t.errorContainerReplace,u=void 0===c||c,s=e(i),d=r(o,n);!0===u?s.html(d):s.before(d)}function i(t){e(t).html("")}n.d(t,"b",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"a",(function(){return i}))}).call(this,n(5))},25:function(e,t){String.prototype.includes||(String.prototype.includes=function(e,t){"use strict";return"number"!=typeof t&&(t=0),!(t+e.length>this.length)&&-1!==this.indexOf(e,t)})},26:function(e,t){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),Element.prototype.closest||(Element.prototype.closest=function(e){var t=this;do{if(Element.prototype.matches.call(t,e))return t;t=t.parentElement||t.parentNode}while(null!==t&&1===t.nodeType);return null})},27:function(e,t){Object.entries||(Object.entries=function(e){for(var t=Object.keys(e),n=t.length,r=new Array(n);n--;)r[n]=[t[n],e[t[n]]];return r})},28:function(e,t){[Element.prototype,CharacterData.prototype,DocumentType.prototype].forEach((function(e){e.hasOwnProperty("remove")||Object.defineProperty(e,"remove",{configurable:!0,enumerable:!0,writable:!0,value:function(){this.parentNode.removeChild(this)}})}))},3:function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},5:function(e,t){e.exports=jQuery},8:function(e,t){function n(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?(e.exports=n=function(e){return typeof e},e.exports.default=e.exports,e.exports.__esModule=!0):(e.exports=n=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.default=e.exports,e.exports.__esModule=!0),n(t)}e.exports=n,e.exports.default=e.exports,e.exports.__esModule=!0}});
includes/gateways/stripe/assets/js/build/app.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=59)}([function(e,t,n){"use strict";n.d(t,"a",(function(){return r.a})),n.d(t,"e",(function(){return i.a})),n.d(t,"c",(function(){return c})),n.d(t,"g",(function(){return a})),n.d(t,"f",(function(){return u.b})),n.d(t,"i",(function(){return u.c})),n.d(t,"b",(function(){return u.a})),n.d(t,"h",(function(){return s})),n.d(t,"j",(function(){return d})),n.d(t,"d",(function(){return l})),n(25),n(26),n(27),n(28);var r=n(15),o=n(16),i=n.n(o);function c(){i()(arguments,(function(e){document.addEventListener("DOMContentLoaded",e)}))}function a(e){for(var t=[],n=e.nextElementSibling;n;)1===n.nodeType&&t.push(n),n=n.nextElementSibling;return t}var u=n(17);function s(e){var t=!0;return i()(e.querySelectorAll("input"),(function(e){e.checkValidity&&!e.checkValidity()&&(t=!1)})),t}function d(e){var t=document.createElement("input");t.type="submit",t.style.display="none",e.appendChild(t),t.click(),t.remove()}function l(e){return e?""===e.value?null:e.value:null}},function(e,t,n){e.exports=n(93)},function(e,t,n){"use strict";(function(e,r){n.d(t,"c",(function(){return f})),n.d(t,"g",(function(){return p})),n.d(t,"e",(function(){return h})),n.d(t,"d",(function(){return y}));var o=n(3),i=n.n(o),c=n(0),a=n(56);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}n.d(t,"a",(function(){return a.a})),n.d(t,"b",(function(){return a.b})),n.d(t,"f",(function(){return a.c})),n.d(t,"h",(function(){return a.d}));var s={card:"#edd-stripe-card-element"},d={cardNumber:"#edd-stripe-card-element",cardExpiry:"#edd-stripe-card-exp-element",cardCvc:"#edd-stripe-card-cvc-element"},l=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?u(Object(n),!0).forEach((function(t){i()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):u(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},edd_stripe_vars.elementsOptions);function f(e,t){var n;return t||(t="true"===edd_stripe_vars.elementsSplitFields?d:s),Object(c.e)(t,(function(t,r){n=function(e,t,n){var r=document.querySelector(t);if(r){l.style||(l.style=function(){var e=document.querySelector(".card-name.edd-input");if(!e)return null;var t=window.getComputedStyle(e);if(!document.getElementById("edds-stripe-element-styles")){var n=document.createElement("style");n.innerHTML="\n\t\t\t.edd-stripe-card-element.StripeElement,\n\t\t\t.edd-stripe-card-exp-element.StripeElement,\n\t\t\t.edd-stripe-card-cvc-element.StripeElement {\n\t\t\t\tbackground-color: ".concat(t.getPropertyValue("background-color"),";\n\n\t\t\t\t").concat(["top","right","bottom","left"].map((function(e){return"border-".concat(e,"-color: ").concat(t.getPropertyValue("border-".concat(e,"-color")),";\n\t\t\t\t\t\t\t border-").concat(e,"-width: ").concat(t.getPropertyValue("border-".concat(e,"-width")),";\n\t\t\t\t\t\t\t border-").concat(e,"-style: ").concat(t.getPropertyValue("border-".concat(e,"-style")),";\n\t\t\t\t\t\t\t padding-").concat(e,": ").concat(t.getPropertyValue("padding-".concat(e)),";")})).join(""),"\n\t\t\t\t").concat(["top-right","bottom-right","bottom-left","top-left"].map((function(e){return"border-".concat(e,"-radius: ").concat(t.getPropertyValue("border-top-right-radius"),";")})).join(""),"\n\t\t\t}").replace(/\s/g,""),n.id="edds-stripe-element-styles",document.body.appendChild(n)}return{base:{color:t.getPropertyValue("color"),fontFamily:t.getPropertyValue("font-family"),fontSize:t.getPropertyValue("font-size"),fontWeight:t.getPropertyValue("font-weight"),fontSmoothing:t.getPropertyValue("-webkit-font-smoothing")}}}()),"cardNumber"===n&&l.hasOwnProperty("hidePostalCode")&&delete l.hidePostalCode,delete l.i18n;var o=e.create(n,l);return o.addEventListener("change",(function(e){!function(e,t){var n=t.closest(".edd-stripe-new-card").querySelector("#edd-stripe-card-errors");if(n.innerHTML="",e.error){var r=e.error,o=r.code,i=r.message,a=window.edd_stripe_vars.elementsOptions.i18n.errorMessages,u=a[o]?a[o]:i;n.appendChild(Object(c.f)(u))}}(e,r),function(e){var t=e.brand;if(e.elementType,"cardNumber"===e.elementType){var n=document.querySelector(".card-type");"unknown"===t?n.className="card-type":n.classList.add(t)}}(e)})).mount(r),o}}(e,t,r)})),window.eddStripe.cardElement=n,n}function p(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"#edd-stripe-card-element",n=f(e,{card:t}),r=document.getElementById("edd-card-details-wrap");return r&&(r.style.display="none"),n}function h(t,n){var o=e('input[name="edd_stripe_existing_card"]:checked');return o.length>0&&"new"!==o.val()?r.resolve({id:o.val(),exists:!0}):window.eddStripe.createPaymentMethod("card",n,{billing_details:y(t)}).then((function(e){if(e.error)throw e.error;return{id:e.paymentMethod.id,exists:!1}}))}function y(e){return{name:Object(c.d)(e.querySelector(".card-name")),address:{line1:Object(c.d)(e.querySelector(".card-address")),line2:Object(c.d)(e.querySelector(".card-address-2")),city:Object(c.d)(e.querySelector(".card-city")),state:Object(c.d)(e.querySelector(".card_state")),postal_code:Object(c.d)(e.querySelector(".card-zip")),country:Object(c.d)(e.querySelector("#billing_country"))}}}}).call(this,n(5),n(24))},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){(function(t){function n(e,n,r,o,i,c,a){try{var u=e[c](a),s=u.value}catch(e){return void r(e)}u.done?n(s):t.resolve(s).then(o,i)}e.exports=function(e){return function(){var r=this,o=arguments;return new t((function(t,i){var c=e.apply(r,o);function a(e){n(c,t,i,a,u,"next",e)}function u(e){n(c,t,i,a,u,"throw",e)}a(void 0)}))}},e.exports.default=e.exports,e.exports.__esModule=!0}).call(this,n(24))},function(e,t){e.exports=jQuery},function(e,t,n){"use strict";n.d(t,"d",(function(){return r.d})),n.d(t,"b",(function(){return r.b})),n.d(t,"a",(function(){return r.a})),n.d(t,"h",(function(){return w})),n.d(t,"g",(function(){return A})),n.d(t,"c",(function(){return C})),n.d(t,"f",(function(){return D.c})),n.d(t,"e",(function(){return D.b}));var r=n(11),o=n(3),i=n.n(o),c=n(0);function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return Object(c.a)(e,u({payment_method:t,nonce:document.getElementById("card_update_nonce_"+t).value},n)).fail((function(e){h(t,e)})).done((function(e){h(t,e,"success"),setTimeout((function(){location.reload()}),1500)}))}function d(e){e.preventDefault();var t=e.target.dataset.source,n=document.getElementById(t+"-update-form"),r=document.getElementById(t+"-card-actions"),o="block"===n.style.display;n.style.display=o?"none":"block",r.style.display=o?"block":"none"}function l(e){e.preventDefault();var t=e.target,n={};["address_city","address_country","address_line1","address_line2","address_zip","address_state","exp_month","exp_year"].forEach((function(e){var r=t.querySelector('[name="'+e+'"]');n[e]=Object(c.d)(r)}));var r=t.querySelector('input[type="submit"]');r.disabled=!0,r.value=r.dataset.loading,s("edds_update_payment_method",e.target.dataset.source,n).fail((function(e){r.disabled=!1,r.value=r.dataset.submit}))}function f(e){e.preventDefault();var t=e.target.innerText;e.target.innerHTML='<span class="edd-loading-ajax edd-loading"></span>',s("edds_delete_payment_method",e.target.dataset.source).fail((function(n){e.target.innerText=t}))}function p(e){e.preventDefault();var t=e.target.innerText;e.target.innerHTML='<span class="edd-loading-ajax edd-loading"></span>',s("edds_set_payment_method_default",e.target.dataset.source).fail((function(n){e.target.innerText=t}))}function h(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"error",r=Object(c.f)(t&&t.message?t.message:edd_stripe_vars.generic_error,n);Object(c.e)(document.querySelectorAll(".edd-stripe-alert"),(function(e){e.remove()}));var o=document.getElementById(e+"_card_item");o.insertBefore(r,o.querySelector(".card-details"))}var y=n(2);function v(e){e.preventDefault();var t=document.getElementById("edd-stripe-add-new-card"),n=t.querySelector(".edd-stripe-add-new-card"),r="block"===n.style.display,o=t.querySelector("#edd-stripe-add-new-cancel");if(r&&o!==e.target){var i=document.createEvent("Event");i.initEvent("submit",!0,!0),t.dispatchEvent(i)}else n.style.display=r?"none":"block",o.style.display=r?"none":"inline-block"}function m(e){e.preventDefault();var t,n,r=e.target;if(Object(c.h)(r))try{(n=document.querySelector(".edd-stripe-add-new")).value=n.dataset.loading,n.disabled=!0,(t=r,window.eddStripe.createPaymentMethod("card",window.eddStripe.cardElement,{billing_details:Object(y.d)(t)}).then((function(e){if(e.error)throw e.error;return e.paymentMethod}))).then(b).catch((function(e){_(e),g()}))}catch(e){_(e),g()}else Object(c.j)(r)}function b(e){Object(c.a)("edds_add_payment_method",{payment_method_id:e.id,nonce:document.getElementById("edd-stripe-add-card-nonce").value}).fail(_).done((function(e){_(e,"success"),setTimeout((function(){location.reload()}),1500)}))}function g(){var e=document.querySelector(".edd-stripe-add-new");e.value=e.dataset.submit,e.disabled=!1}function _(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"error",n=Object(c.f)(e&&e.message?e.message:edd_stripe_vars.generic_error,t);Object(c.e)(document.querySelectorAll(".edd-stripe-alert"),(function(e){e.remove()})),document.querySelector(".edd-stripe-add-card-actions").insertBefore(n,document.querySelector(".edd-stripe-add-new"))}function w(){document.getElementById("edd-stripe-manage-cards")&&(Object(c.e)(document.querySelectorAll(".edd-stripe-update-card"),(function(e){e.addEventListener("click",d)})),Object(c.e)(document.querySelectorAll(".edd-stripe-cancel-update"),(function(e){e.addEventListener("click",d)})),Object(c.e)(document.querySelectorAll(".card-update-form"),(function(e){e.addEventListener("submit",l)})),Object(c.e)(document.querySelectorAll(".edd-stripe-delete-card"),(function(e){e.addEventListener("click",f)})),Object(c.e)(document.querySelectorAll(".edd-stripe-default-card"),(function(e){e.addEventListener("click",p)})),Object(y.c)(window.eddStripe.elements()),document.querySelector(".edd-stripe-add-new").addEventListener("click",v),document.getElementById("edd-stripe-add-new-cancel").addEventListener("click",v),document.getElementById("edd-stripe-add-new-card").addEventListener("submit",m),document.getElementById("card_name").required=!0)}var O=n(12),j=n(4),x=n.n(j),S=n(1),E=n.n(S);function k(e){return P.apply(this,arguments)}function P(){return(P=x()(E.a.mark((function e(t){var n,r,o,i,c;return E.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t.preventDefault(),n=document.getElementById("edds-update-payment-method"),q(),e.prev=3,e.next=6,Object(y.e)(n,window.eddStripe.cardElement);case 6:return r=e.sent,e.next=9,Object(y.h)(n.dataset.paymentIntent,"payment_method");case 9:return o=e.sent,e.next=12,Object(y.f)(o,{payment_method:r.id});case 12:return i=e.sent,e.next=15,L(i.id);case 15:if(!(c=e.sent).payment){e.next=20;break}window.location.reload(),e.next=21;break;case 20:throw c;case 21:e.next=27;break;case 23:e.prev=23,e.t0=e.catch(3),M(e.t0),T();case 27:case"end":return e.stop()}}),e,null,[[3,23]])})))).apply(this,arguments)}function L(e){return Object(c.a)("edds_complete_payment_authorization",{intent_id:e,"edds-complete-payment-authorization":document.getElementById("edds-complete-payment-authorization").value})}function q(){var e=document.getElementById("edds-update-payment-method-submit");e.value=e.dataset.loading,e.disabled=!0}function T(){var e=document.getElementById("edds-update-payment-method-submit");e.value=e.dataset.submit,e.disabled=!1}function M(e){var t=Object(c.f)(e&&e.message?e.message:edd_stripe_vars.generic_error,"error"),n=document.getElementById("edds-update-payment-method-errors");n.innerHTML="",n.appendChild(t)}function A(){document.getElementById("edds-update-payment-method")&&(Object(y.c)(window.eddStripe.elements()),document.getElementById("edds-update-payment-method").addEventListener("submit",k),Object(O.a)())}var I=n(14);function C(){Object(c.e)(document.querySelectorAll(".edds-buy-now"),(function(e){e.classList.contains("edd-free-download")||e.addEventListener("click",(function(e){var t=e.currentTarget.dataset,n=t.downloadId,o=t.nonce;if(n){e.preventDefault(),e.stopImmediatePropagation();var i=0,a=1,u=e.currentTarget.closest(".edd_download_purchase_form"),s=u.querySelector(".edd_price_option_".concat(n,":checked"));s&&(i=s.value);var d=u.querySelector('input[name="edd_download_quantity"]');d&&(a=d.value),function(e){var t=e.downloadId,n=e.priceId,o=e.quantity,i=e.nonce,a=document.querySelector("#edds-buy-now-modal-content");I.a.open("edds-buy-now",{onShow:function(){a.innerHTML='<span class="edd-loading-ajax edd-loading"></span>',function(e,t,n,r){edd_scripts.ajaxurl;var o={download_id:e,price_id:t,quantity:n,nonce:r};return Object(c.a)("edds_add_to_cart",o)}(t,n,o,i).then((function(e){var t=e.checkout;a.innerHTML=t,window.EDD_Checkout.init();var n=document.querySelector("#edds-buy-now-modal-content .edd_cart_amount");parseFloat(n.dataset.total)>0&&(Object(r.c)(),Object(I.b)())})).fail((function(e){var t=e.message;document.querySelector("#edds-buy-now-modal-content").innerHTML=t}))},onClose:function(){Object(c.a)("edds_empty_cart")}})}({downloadId:n,priceId:i,quantity:a,nonce:o})}}))})),jQuery(document.body).on("edd_checkout_error",(function(){var e=document.querySelector("#edds-buy-now #edd-purchase-button");if(e){var t=edd_stripe_vars.i18n.completePurchase,n=document.querySelector(".edd_cart_amount").dataset,r=n.total,o=n.totalCurrency;"0"!==r&&setTimeout((function(){e.value="".concat(o," - ").concat(t)}),10)}}))}var D=n(20)},function(e,t,n){(function(t){var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof t&&t)||Function("return this")()}).call(this,n(36))},function(e,t){function n(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?(e.exports=n=function(e){return typeof e},e.exports.default=e.exports,e.exports.__esModule=!0):(e.exports=n=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.default=e.exports,e.exports.__esModule=!0),n(t)}e.exports=n,e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";(function(e){n.d(t,"d",(function(){return i}));var r=n(14),o=n(21);function i(){if("1"===edd_scripts.is_checkout){var t=document.querySelector('input[name="edd-gateway"]');t&&"stripe"===t.value&&(Object(o.c)(),Object(r.b)()),e(document.body).on("edd_gateway_loaded",(function(e,t){"stripe"===t&&(Object(o.c)(),Object(r.b)())}))}}n.d(t,"a",(function(){return o.a})),n.d(t,"b",(function(){return o.b})),n.d(t,"c",(function(){return o.c}))}).call(this,n(5))},function(e,t,n){"use strict";(function(e){n.d(t,"a",(function(){return o}));var r=n(0);function o(){i()&&(c(!1),i().addEventListener("change",(function(e){return c(e.target.checked)})));var t=document.querySelectorAll(".edd-stripe-existing-card");if(0!==t.length){Object(r.e)(t,(function(t){return t.addEventListener("change",(function(t){return function(t){var n="new"===t.value,r=document.querySelector(".edd-stripe-new-card"),o=document.querySelector(".edd-stripe-update-billing-address-wrapper");r.style.display=n?"block":"none",o&&(o.style.display=n?"none":"block"),e(".edd-stripe-card-radio-item").removeClass("selected"),e(t).closest(".edd-stripe-card-radio-item").addClass("selected");var a={card_address:"address_line1",card_address_2:"address_line2",card_city:"address_city",card_state:"address_state",card_zip:"address_zip",billing_country:"address_country"};if(n){for(var u in a){if(!a.hasOwnProperty(u))return;var s=document.getElementById(u);s&&(s.value="",s.selected="")}window.EDD_Checkout.recalculate_taxes&&window.EDD_Checkout.recalculate_taxes(),c(!0)}else{var d=[],l=document.getElementById(t.id+"-billing-details");if(!l)return;c(!1),i()&&(i().checked=!1);var f=l.dataset;for(var p in a)if(a.hasOwnProperty(p)){var h=document.getElementById(p);if(h){var y=f[a[p]];if(h.value=y,""!==y&&d.push(y),h.required&&""===y&&(c(!0),i()&&(i().checked=!0),o&&(o.style.display="none")),"billing_country"===p){var v=document.createEvent("Event");v.initEvent("change",!0,!0),h.dispatchEvent(v)}}}e(document).ajaxSuccess((function(e,t,n){if(n&&n.data&&t&&n.data.includes("action=edd_get_shop_states")&&n.data.includes("field_name=card_state")&&t.responseText&&t.responseText.includes("card_state")){var r=document.getElementById("card_state");r&&(r.value=f.address_state,window.EDD_Checkout.recalculate_taxes&&window.EDD_Checkout.recalculate_taxes(r.value))}}));var m=document.querySelector(".edd-stripe-update-billing-address-current");if(m){m.innerText=d.join(", ");var b=f.brand,g=f.last4;document.querySelector(".edd-stripe-update-billing-address-brand").innerHTML=b,document.querySelector(".edd-stripe-update-billing-address-last4").innerHTML=g}}}(t.target)}))}));var n=document.querySelector(".edd-stripe-existing-card:checked");n||((n=document.querySelector(".edd-stripe-existing-card:first-of-type")).checked=!0);var o=document.createEvent("Event");o.initEvent("change",!0,!1),n.dispatchEvent(o)}}function i(){return document.getElementById("edd-stripe-update-billing-address")}function c(e){var t=document.querySelector(".edd-stripe-update-billing-address-wrapper");if(t){var n=Object(r.g)(t),o=document.querySelector(".edd-stripe-update-billing-address-current");n.forEach((function(t){t.style.display=e?"block":"none"})),o&&(o.style.display=e?"none":"block")}}}).call(this,n(5))},function(e,t,n){var r=n(99);e.exports=function(e,t){if(null==e)return{};var n,o,i=r(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(o=0;o<c.length;o++)n=c[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){"use strict";n.d(t,"a",(function(){return b})),n.d(t,"b",(function(){return g.a}));var r=n(3),o=n.n(r);function i(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function c(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return a(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?a(e,void 0):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}n(61),n(78);var u,s,d,l,f,p=(u=["a[href]","area[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","iframe","object","embed","[contenteditable]",'[tabindex]:not([tabindex^="-"])'],s=function(){function e(t){var n=t.targetModal,r=t.triggers,o=void 0===r?[]:r,i=t.onShow,a=void 0===i?function(){}:i,u=t.onClose,s=void 0===u?function(){}:u,d=t.openTrigger,l=void 0===d?"data-micromodal-trigger":d,f=t.closeTrigger,p=void 0===f?"data-micromodal-close":f,h=t.openClass,y=void 0===h?"is-open":h,v=t.disableScroll,m=void 0!==v&&v,b=t.disableFocus,g=void 0!==b&&b,_=t.awaitCloseAnimation,w=void 0!==_&&_,O=t.awaitOpenAnimation,j=void 0!==O&&O,x=t.debugMode,S=void 0!==x&&x;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.modal=document.getElementById(n),this.config={debugMode:S,disableScroll:m,openTrigger:l,closeTrigger:p,openClass:y,onShow:a,onClose:s,awaitCloseAnimation:w,awaitOpenAnimation:j,disableFocus:g},o.length>0&&this.registerTriggers.apply(this,c(o)),this.onClick=this.onClick.bind(this),this.onKeydown=this.onKeydown.bind(this)}var t,n;return t=e,(n=[{key:"registerTriggers",value:function(){for(var e=this,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.filter(Boolean).forEach((function(t){t.addEventListener("click",(function(t){return e.showModal(t)}))}))}},{key:"showModal",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(this.activeElement=document.activeElement,this.modal.setAttribute("aria-hidden","false"),this.modal.classList.add(this.config.openClass),this.scrollBehaviour("disable"),this.addEventListeners(),this.config.awaitOpenAnimation){var n=function t(){e.modal.removeEventListener("animationend",t,!1),e.setFocusToFirstNode()};this.modal.addEventListener("animationend",n,!1)}else this.setFocusToFirstNode();this.config.onShow(this.modal,this.activeElement,t)}},{key:"closeModal",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=this.modal;if(this.modal.setAttribute("aria-hidden","true"),this.removeEventListeners(),this.scrollBehaviour("enable"),this.activeElement&&this.activeElement.focus&&this.activeElement.focus(),this.config.onClose(this.modal,this.activeElement,e),this.config.awaitCloseAnimation){var n=this.config.openClass;this.modal.addEventListener("animationend",(function e(){t.classList.remove(n),t.removeEventListener("animationend",e,!1)}),!1)}else t.classList.remove(this.config.openClass)}},{key:"closeModalById",value:function(e){this.modal=document.getElementById(e),this.modal&&this.closeModal()}},{key:"scrollBehaviour",value:function(e){if(this.config.disableScroll){var t=document.querySelector("body");switch(e){case"enable":Object.assign(t.style,{overflow:""});break;case"disable":Object.assign(t.style,{overflow:"hidden"})}}}},{key:"addEventListeners",value:function(){this.modal.addEventListener("touchstart",this.onClick),this.modal.addEventListener("click",this.onClick),document.addEventListener("keydown",this.onKeydown)}},{key:"removeEventListeners",value:function(){this.modal.removeEventListener("touchstart",this.onClick),this.modal.removeEventListener("click",this.onClick),document.removeEventListener("keydown",this.onKeydown)}},{key:"onClick",value:function(e){e.target.hasAttribute(this.config.closeTrigger)&&this.closeModal(e)}},{key:"onKeydown",value:function(e){27===e.keyCode&&this.closeModal(e),9===e.keyCode&&this.retainFocus(e)}},{key:"getFocusableNodes",value:function(){var e=this.modal.querySelectorAll(u);return Array.apply(void 0,c(e))}},{key:"setFocusToFirstNode",value:function(){var e=this;if(!this.config.disableFocus){var t=this.getFocusableNodes();if(0!==t.length){var n=t.filter((function(t){return!t.hasAttribute(e.config.closeTrigger)}));n.length>0&&n[0].focus(),0===n.length&&t[0].focus()}}}},{key:"retainFocus",value:function(e){var t=this.getFocusableNodes();if(0!==t.length)if(t=t.filter((function(e){return null!==e.offsetParent})),this.modal.contains(document.activeElement)){var n=t.indexOf(document.activeElement);e.shiftKey&&0===n&&(t[t.length-1].focus(),e.preventDefault()),!e.shiftKey&&t.length>0&&n===t.length-1&&(t[0].focus(),e.preventDefault())}else t[0].focus()}}])&&i(t.prototype,n),e}(),d=null,l=function(e){if(!document.getElementById(e))return console.warn("MicroModal: ❗Seems like you have missed %c'".concat(e,"'"),"background-color: #f8f9fa;color: #50596c;font-weight: bold;","ID somewhere in your code. Refer example below to resolve it."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'<div class="modal" id="'.concat(e,'"></div>')),!1},f=function(e,t){if(function(e){e.length<=0&&(console.warn("MicroModal: ❗Please specify at least one %c'micromodal-trigger'","background-color: #f8f9fa;color: #50596c;font-weight: bold;","data attribute."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'<a href="#" data-micromodal-trigger="my-modal"></a>'))}(e),!t)return!0;for(var n in t)l(n);return!0},{init:function(e){var t=Object.assign({},{openTrigger:"data-micromodal-trigger"},e),n=c(document.querySelectorAll("[".concat(t.openTrigger,"]"))),r=function(e,t){var n=[];return e.forEach((function(e){var r=e.attributes[t].value;void 0===n[r]&&(n[r]=[]),n[r].push(e)})),n}(n,t.openTrigger);if(!0!==t.debugMode||!1!==f(n,r))for(var o in r){var i=r[o];t.targetModal=o,t.triggers=c(i),d=new s(t)}},show:function(e,t){var n=t||{};n.targetModal=e,!0===n.debugMode&&!1===l(e)||(d&&d.removeEventListeners(),(d=new s(n)).showModal())},close:function(e){e?d.closeModalById(e):d.closeModal()}});window.MicroModal=p;var h=p;function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function v(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){o()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var m={disableScroll:!0,awaitOpenAnimation:!0,awaitCloseAnimation:!0},b={setup:function(e){var t=v(v({},m),e);h.init(t)},open:function(e,t){var n=v(v({},m),t);h.show(e,n)},close:function(e){h.close(e)}},g=n(12)},function(e,t,n){"use strict";(function(e){n.d(t,"a",(function(){return s}));var r=n(8),o=n.n(r),i=n(3),c=n.n(i);function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){c()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(t,n){var r={type:"POST",dataType:"json",xhrFields:{withCredentials:!0},url:window.edd_scripts&&window.edd_scripts.ajaxurl||window.ajaxurl,data:u({action:t},n)},i=e.Deferred((function(t){t.jqXHR=e.ajax(r).done((function(e){"1"!==e&&1!==e||(e={success:!0}),"object"===o()(e)&&void 0!==o()(e.success)?t[e.success?"resolveWith":"rejectWith"](this,[e.data]):t.rejectWith(this,[e])})).fail((function(){t.rejectWith(this,arguments)}))})),c=i.promise();return c.abort=function(){return i.jqXHR.abort(),this},c}}).call(this,n(5))},function(e,t){var n=/^(?:0|[1-9]\d*)$/;function r(e,t){for(var n=-1,r=e?e.length:0;++n<r&&!1!==t(e[n],n,e););return e}var o,i,c=Object.prototype,a=c.hasOwnProperty,u=c.toString,s=c.propertyIsEnumerable,d=(o=Object.keys,i=Object,function(e){return o(i(e))});var l,f=(l=function(e,t){return e&&p(e,t,m)},function(e,t){if(null==e)return e;if(!v(e))return l(e,t);for(var n=e.length,r=-1,o=Object(e);++r<n&&!1!==t(o[r],r,o););return e}),p=function(e,t,n){for(var r=-1,o=Object(e),i=n(e),c=i.length;c--;){var a=i[++r];if(!1===t(o[a],a,o))break}return e};function h(e,t){return!!(t=null==t?9007199254740991:t)&&("number"==typeof e||n.test(e))&&e>-1&&e%1==0&&e<t}var y=Array.isArray;function v(e){return null!=e&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&!function(e){var t=function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(e)?u.call(e):"";return"[object Function]"==t||"[object GeneratorFunction]"==t}(e)}function m(e){return v(e)?function(e,t){var n=y(e)||function(e){return function(e){return function(e){return!!e&&"object"==typeof e}(e)&&v(e)}(e)&&a.call(e,"callee")&&(!s.call(e,"callee")||"[object Arguments]"==u.call(e))}(e)?function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}(e.length,String):[],r=n.length,o=!!r;for(var i in e)!t&&!a.call(e,i)||o&&("length"==i||h(i,r))||n.push(i);return n}(e):function(e){if(n=(t=e)&&t.constructor,t!==("function"==typeof n&&n.prototype||c))return d(e);var t,n,r=[];for(var o in Object(e))a.call(e,o)&&"constructor"!=o&&r.push(o);return r}(e)}function b(e){return e}e.exports=function(e,t){return(y(e)?r:f)(e,"function"==typeof t?t:b)}},function(e,t,n){"use strict";(function(e){function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"error",n=document.createElement("p");return n.classList.add("edd-alert"),n.classList.add("edd-stripe-alert"),n.style.clear="both","error"===t?n.classList.add("edd-alert-error"):n.classList.add("edd-alert-success"),n.innerHTML=e||edd_stripe_vars.generic_error,n}function o(t){var n=t.errorType,o=t.errorMessage,i=t.errorContainer,c=t.errorContainerReplace,a=void 0===c||c,u=e(i),s=r(o,n);!0===a?u.html(s):u.before(s)}function i(t){e(t).html("")}n.d(t,"b",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"a",(function(){return i}))}).call(this,n(5))},function(e,t,n){var r=n(9);e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},function(e,t,n){var r=n(7),o=n(45),i=n(10),c=n(46),a=n(54),u=n(84),s=o("wks"),d=r.Symbol,l=u?d:d&&d.withoutSetter||c;e.exports=function(e){return i(s,e)||(a&&i(d,e)?s[e]=d[e]:s[e]=l("Symbol."+e)),s[e]}},function(e,t,n){"use strict";n.d(t,"c",(function(){return j})),n.d(t,"b",(function(){return x.a})),n.d(t,"a",(function(){return S}));var r=n(58),o=n.n(r),i=n(3),c=n.n(i),a=n(13),u=n.n(a),s=n(4),d=n.n(s),l=n(1),f=n.n(l),p=n(0),h=(n(2),n(6));function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function v(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){c()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function m(e){var t,n=!1,r=1,o=e.querySelector('[name="download_id"]');t=parseFloat(o.value);var i=e.querySelector(".edd_price_option_".concat(t,":checked"));i&&(n=parseFloat(i.value));var c=e.querySelector('input[name="edd_download_quantity"]');return c&&(r=parseFloat(c.value)),{downloadId:t,priceId:n,quantity:r}}function b(e,t){return g.apply(this,arguments)}function g(){return(g=d()(f.a.mark((function e(t,n){var r,o,i,c,a,s,d;return f.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=m(n),o=r.downloadId,i=r.priceId,c=r.quantity,e.prev=1,e.next=4,Object(p.a)("edds_prb_ajax_get_options",{downloadId:o,priceId:i,quantity:c});case 4:a=e.sent,s=a["display-items"],d=u()(a,["display-items"]),t.update(v({displayItems:s},d)),e.next=13;break;case 10:e.prev=10,e.t0=e.catch(1),Object(p.i)({errorMessage:"",errorContainer:n,errorContainerReplace:!1});case 13:case"end":return e.stop()}}),e,null,[[1,10]])})))).apply(this,arguments)}function _(e,t,n){e.complete("success"),n.classList.remove("loading"),Object(p.i)({errorMessage:t.message,errorContainer:n,errorContainerReplace:!1}),jQuery("a.edd-add-to-cart",n).hide(),jQuery(".edd_download_quantity_wrapper",n).hide(),jQuery(".edd_price_options",n).hide(),jQuery(".edd_go_to_checkout",n).show().removeAttr("data-edd-loading")}function w(){return(w=d()(f.a.mark((function e(t,n,r){var o,i,c,a,u,s,l,y,v,b,g,w,O;return f.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,o=m(n),i=o.downloadId,c=o.priceId,a=o.quantity,u=r.paymentMethod,s=r.payerEmail,l=r.payerName,e.next=5,Object(p.a)("edds_prb_ajax_process_checkout",{email:s,name:l,paymentMethod:u,downloadId:i,priceId:c,quantity:a,context:"download"});case 5:y=e.sent,v=y.intent,b=y.intent,g=b.client_secret,w=b.object,r.complete("success"),n.classList.add("loading"),O="setup_intent"===w?"confirmCardSetup":"confirmCardPayment",eddStripe[O](g,{payment_method:u.id},{handleActions:!1}).then((function(e){var t=e.error;if(t)throw t;eddStripe[O](g).then(function(){var e=d()(f.a.mark((function e(t){var o,i,c,a;return f.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(o=t.error,e.prev=1,!o){e.next=4;break}throw o;case 4:return e.next=6,Object(h.b)(v);case 6:return i=e.sent,c=i.intent,a=i.nonce,e.next=11,Object(h.a)(c,a);case 11:window.location.replace(edd_stripe_vars.successPageUri),e.next=17;break;case 14:e.prev=14,e.t0=e.catch(1),_(r,e.t0,n);case 17:case"end":return e.stop()}}),e,null,[[1,14]])})));return function(t){return e.apply(this,arguments)}}())})).catch((function(e){_(r,e,n)})),e.next=19;break;case 16:e.prev=16,e.t0=e.catch(0),_(r,e.t0,n);case 19:case"end":return e.stop()}}),e,null,[[0,16]])})))).apply(this,arguments)}function O(e){var t=window.eddStripe;try{var n=S(e.dataset),r=n["display-items"],o=u()(n,["display-items"]),i=e.closest(".edd_download_purchase_form"),c=t.paymentRequest(v({requestPayerEmail:!0,displayItems:r},o)),a=t.elements().create("paymentRequestButton",{paymentRequest:c}),s=document.querySelector("#".concat(e.id));c.canMakePayment().then((function(t){t&&(!0===t.applePay&&"true"===edd_stripe_vars.isTestMode||(s.style.display="block",i.classList.add("edd-prb--is-active"),a.mount("#".concat(e.id," .edds-prb__button")),function(e,t){var n=t.querySelectorAll('.edd_price_options input[type="radio"]');Object(p.e)(n,(function(n){n.addEventListener("change",(function(){return b(e,t)}))}));var r=t.querySelector('input[name="edd_download_quantity"]');r&&r.addEventListener("change",(function(){return b(e,t)}))}(c,i)))})),c.on("paymentmethod",(function(e){!function(e,t,n){w.apply(this,arguments)}(c,i,e)}))}catch(e){Object(p.i)({errorMessage:e.message,errorContainer:purchaseLink,errorContainerReplace:!1})}}function j(){Object(p.e)(document.querySelectorAll(".edds-prb.edds-prb--download"),O)}var x=n(57);function S(e){for(var t={},n=0,r=Object.entries(e);n<r.length;n++){var i=o()(r[n],2),c=i[0],a=i[1],u=a;try{u=JSON.parse(a)}catch(e){}t[c]=u}return t}},function(e,t,n){"use strict";(function(e){n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return f})),n.d(t,"a",(function(){return p}));var r=n(4),o=n.n(r),i=n(1),c=n.n(i),a=n(2),u=n(0);function s(){Object(a.c)(window.eddStripe.elements()),e("#edd_purchase_form").off("submit",y),e("#edd_purchase_form").on("submit",y),e(document).off("ajaxSuccess",h),e(document).on("ajaxSuccess",h)}function d(){return(d=o()(c.a.mark((function t(){var n,r,o,i,u,s,d,h,y,b;return c.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,n=e("#edd_purchase_form").serialize(),t.next=4,Object(a.e)(document.getElementById("edd_purchase_form"),window.eddStripe.cardElement);case 4:return r=t.sent,t.next=7,l(r.id,r.exists);case 7:return o=t.sent,i=o.intent,u=o.nonce,e("#edd-process-checkout-nonce").val(u),t.next=13,Object(a.f)(i,{form_data:n+="&edd-process-checkout-nonce=".concat(u)});case 13:return s=t.sent,t.next=16,f(s);case 16:return d=t.sent,h=d.intent,y=d.nonce,t.next=21,Object(a.a)(h,{},y);case 21:if("succeeded"!==(b=t.sent).status&&("canceled"!==b.status||"abandoned"!==b.cancellation_reason)){t.next=28;break}return t.next=25,p(b,y);case 25:window.location.replace(edd_stripe_vars.successPageUri),t.next=29;break;case 28:window.location.replace(edd_stripe_vars.failurePageUri);case 29:t.next=35;break;case 31:t.prev=31,t.t0=t.catch(0),m(t.t0),v();case 35:case"end":return t.stop()}}),t,null,[[0,31]])})))).apply(this,arguments)}function l(t,n){return Object(u.a)("edds_process_purchase_form",{form_data:e("#edd_purchase_form").serialize(),payment_method_id:t,payment_method_exists:n})}function f(t){var n=e("#edd_purchase_form"),r=n.serialize();if(0===n.length){var o=e("#edd-process-checkout-nonce").val();r="edd-process-checkout-nonce=".concat(o)}return Object(u.a)("edds_create_payment",{form_data:r,intent:t})}function p(t,n){var r=e("#edd_purchase_form"),o=r.serialize();if(0===r.length){var i=e("#edd-process-checkout-nonce").val();o="edd-process-checkout-nonce=".concat(i)}return n&&(o+="&edd-process-checkout-nonce=".concat(n)),Object(u.a)("edds_complete_payment",{form_data:o,intent:t})}function h(e,t,n){if(n&&n.data&&t)return n.data.includes("action=edd_process_checkout")&&n.data.includes("edd-gateway=stripe")&&t.responseText&&"success"===t.responseText.trim()?function(){return d.apply(this,arguments)}():void 0}function y(t){"stripe"===e('input[name="edd-gateway"]').val()&&e(".edd_cart_total .edd_cart_amount").data("total")>0&&(t.preventDefault(),e("#edd_purchase_form #edd_purchase_submit [type=submit]").trigger("click"))}function v(){document.querySelector("#edd_purchase_form #edd_purchase_submit [type=submit]").value=edd_global_vars.complete_purchase,e(".edd-loading-ajax").remove(),e(".edd_errors").remove(),e(".edd-error").hide(),e("#edd-purchase-button").attr("disabled",!1)}function m(t){var n=Object(u.f)(t&&t.message?t.message:edd_stripe_vars.generic_error);e(".edd-stripe-alert").remove(),e(edd_global_vars.checkout_error_anchor).before(n),e(document.body).trigger("edd_checkout_error",[t]),window.console&&t.responseText&&window.console.error(t.responseText)}}).call(this,n(5))},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(18),o=n(32),i=n(29);e.exports=r?function(e,t,n){return o.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=n(90).Promise},function(e,t){String.prototype.includes||(String.prototype.includes=function(e,t){"use strict";return"number"!=typeof t&&(t=0),!(t+e.length>this.length)&&-1!==this.indexOf(e,t)})},function(e,t){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),Element.prototype.closest||(Element.prototype.closest=function(e){var t=this;do{if(Element.prototype.matches.call(t,e))return t;t=t.parentElement||t.parentNode}while(null!==t&&1===t.nodeType);return null})},function(e,t){Object.entries||(Object.entries=function(e){for(var t=Object.keys(e),n=t.length,r=new Array(n);n--;)r[n]=[t[n],e[t[n]]];return r})},function(e,t){[Element.prototype,CharacterData.prototype,DocumentType.prototype].forEach((function(e){e.hasOwnProperty("remove")||Object.defineProperty(e,"remove",{configurable:!0,enumerable:!0,writable:!0,value:function(){this.parentNode.removeChild(this)}})}))},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(39),o=n(41);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(22);e.exports=function(e,t){if(!r(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!r(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e,t,n){var r=n(18),o=n(42),i=n(33),c=n(31),a=Object.defineProperty;t.f=r?a:function(e,t,n){if(i(e),t=c(t,!0),i(n),o)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){var r=n(22);e.exports=function(e){if(!r(e))throw TypeError(String(e)+" is not an object");return e}},function(e,t,n){var r=n(7),o=n(23);e.exports=function(e,t){try{o(r,e,t)}catch(n){r[e]=t}return t}},function(e,t,n){var r=n(7),o=n(37).f,i=n(23),c=n(63),a=n(34),u=n(68),s=n(75);e.exports=function(e,t){var n,d,l,f,p,h=e.target,y=e.global,v=e.stat;if(n=y?r:v?r[h]||a(h,{}):(r[h]||{}).prototype)for(d in t){if(f=t[d],l=e.noTargetGet?(p=o(n,d))&&p.value:n[d],!s(y?d:h+(v?".":"#")+d,e.forced)&&void 0!==l){if(typeof f==typeof l)continue;u(f,l)}(e.sham||l&&l.sham)&&i(f,"sham",!0),c(n,d,f,e)}}},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){var r=n(18),o=n(38),i=n(29),c=n(30),a=n(31),u=n(10),s=n(42),d=Object.getOwnPropertyDescriptor;t.f=r?d:function(e,t){if(e=c(e),t=a(t,!0),s)try{return d(e,t)}catch(e){}if(u(e,t))return i(!o.f.call(e,t),e[t])}},function(e,t,n){"use strict";var r={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!r.call({1:2},1);t.f=i?function(e){var t=o(this,e);return!!t&&t.enumerable}:r},function(e,t,n){var r=n(9),o=n(40),i="".split;e.exports=r((function(){return!Object("z").propertyIsEnumerable(0)}))?function(e){return"String"==o(e)?i.call(e,""):Object(e)}:Object},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(18),o=n(9),i=n(62);e.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(e,t,n){var r=n(44),o=Function.toString;"function"!=typeof r.inspectSource&&(r.inspectSource=function(e){return o.call(e)}),e.exports=r.inspectSource},function(e,t,n){var r=n(7),o=n(34),i=r["__core-js_shared__"]||o("__core-js_shared__",{});e.exports=i},function(e,t,n){var r=n(67),o=n(44);(e.exports=function(e,t){return o[e]||(o[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.6.5",mode:r?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol("+String(void 0===e?"":e)+")_"+(++n+r).toString(36)}},function(e,t){e.exports={}},function(e,t,n){var r=n(10),o=n(30),i=n(73).indexOf,c=n(47);e.exports=function(e,t){var n,a=o(e),u=0,s=[];for(n in a)!r(c,n)&&r(a,n)&&s.push(n);for(;t.length>u;)r(a,n=t[u++])&&(~i(s,n)||s.push(n));return s}},function(e,t,n){var r=n(50),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){var r=n(41);e.exports=function(e){return Object(r(e))}},function(e,t,n){var r=n(9);e.exports=!!Object.getOwnPropertySymbols&&!r((function(){return!String(Symbol())}))},function(e,t){e.exports={}},function(e,t,n){"use strict";(function(e,r){n.d(t,"d",(function(){return p})),n.d(t,"b",(function(){return h})),n.d(t,"a",(function(){return y})),n.d(t,"c",(function(){return m}));var o=n(4),i=n.n(o),c=n(3),a=n.n(c),u=n(1),s=n.n(u),d=n(0);function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function f(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){a()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"payment_intent",r=e(window.eddStripe.cardElement._parent).closest("form");return Object(d.a)("edds_get_intent",{intent_id:t,intent_type:n,form_data:r.serialize()}).then((function(e){return e.intent}))}function h(t){var n=e(window.eddStripe.cardElement._parent).closest("form");return Object(d.a)("edds_confirm_intent",{intent_id:t.id,intent_type:t.object,form_data:n.serialize()}).then((function(e){return e.intent}))}function y(t,n,o){var i=e(window.eddStripe.cardElement._parent).closest("form");if("requires_capture"!==t.status)return r.resolve(t);var c=i.serialize();return o&&(c+="&edd-process-checkout-nonce=".concat(o)),Object(d.a)("edds_capture_intent",f({intent_id:t.id,intent_type:t.object,form_data:c},n)).then((function(e){return e.intent}))}function v(t,n){var r=e(window.eddStripe.cardElement._parent).closest("form");return Object(d.a)("edds_update_intent",f({intent_id:t.id,intent_type:t.object,form_data:r.serialize()},n)).then((function(e){return e.intent}))}function m(e,t){return b.apply(this,arguments)}function b(){return(b=i()(s.a.mark((function e(t,n){var r,o,c;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("requires_confirmation"!==t.status){e.next=7;break}return e.next=3,h(t);case 3:return r=e.sent,e.next=6,m(r);case 6:return e.abrupt("return",e.sent);case 7:if("requires_payment_method"!==t.status&&"requires_source"!==t.status){e.next=14;break}return e.next=10,v(t,n);case 10:return o=e.sent,e.next=13,m(o,n);case 13:return e.abrupt("return",e.sent);case 14:if(!("requires_action"===t.status&&"use_stripe_sdk"===t.next_action.type||"requires_source_action"===t.status&&"use_stripe_sdk"===t.next_action.type)){e.next=18;break}return c="setup_intent"===t.object?"handleCardSetup":"handleCardAction","automatic"===t.confirmation_method&&(c="handleCardPayment"),e.abrupt("return",window.eddStripe[c](t.client_secret).then(function(){var e=i()(s.a.mark((function e(t){var n,r;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!t.error){e.next=2;break}throw t.error;case 2:return n=t.setupIntent,r=t.paymentIntent,e.next=5,m(n||r);case 5:return e.abrupt("return",e.sent);case 6:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()));case 18:return e.abrupt("return",t);case 19:case"end":return e.stop()}}),e)})))).apply(this,arguments)}}).call(this,n(5),n(24))},function(e,t,n){"use strict";(function(e){n.d(t,"a",(function(){return x}));var r,o=n(3),i=n.n(o),c=n(13),a=n.n(c),u=n(4),s=n.n(u),d=n(1),l=n.n(d),f=n(20),p=n(0),h=(n(2),n(6));function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function v(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){i()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function m(){r=!1;var e=document.getElementById("edd-gateway-option-stripe-prb");if(e){e.remove();var t=document.querySelectorAll(".edd-gateway-option"),n=t[0],o=n.querySelector("input");o.checked=!0,n.classList.add("edd-gateway-option-selected"),edd_load_gateway(o.value),1===t.length&&document.getElementById("edd_payment_mode_select_wrap").remove()}}function b(e){var t=document.getElementById("edds-prb-error-wrap"),n=edd_stripe_vars,r=n.checkout_agree_to_terms,o=n.checkout_agree_to_privacy,i=document.getElementById("edd_agree_to_terms");i&&(!1===i.checked?(e.preventDefault(),Object(p.i)({errorMessage:r,errorContainer:t})):Object(p.b)(t));var c=document.getElementById("edd-agree-to-privacy-policy");c&&!1===c.checked&&(!1===c.checked?(e.preventDefault(),Object(p.i)({errorMessage:o,errorContainer:t})):Object(p.b)(t))}function g(e,t){return _.apply(this,arguments)}function _(){return(_=s()(l.a.mark((function e(t,n){var r,o,i;return l.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,Object(p.a)("edds_prb_ajax_get_options");case 3:r=e.sent,o=r["display-items"],i=a()(r,["display-items"]),t.update(v({displayItems:o},i)),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(0),Object(p.i)({errorMessage:"",errorContainer:document.getElementById("edds-prb-checkout"),errorContainerReplace:!1});case 12:case"end":return e.stop()}}),e,null,[[0,9]])})))).apply(this,arguments)}function w(e,t,n){e.complete("success");var r=n.querySelector(".edds-prb-spinner");r&&r.parentNode.removeChild(r),n.classList.remove("loading"),Object(p.i)({errorMessage:t.message,errorContainer:document.getElementById("edds-prb-checkout"),errorContainerReplace:!1})}function O(){return(O=s()(l.a.mark((function t(n,r,o){var i,c,a,u,d,f,y,v,m,b;return l.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,i=o.paymentMethod,o.payerEmail,c=o.payerName,r.classList.add("loading"),a=document.createElement("span"),["edd-loading-ajax","edd-loading","edds-prb-spinner"].forEach((function(e){return a.classList.add(e)})),r.appendChild(a),t.next=9,Object(p.a)("edds_prb_ajax_process_checkout",{name:c,paymentMethod:i,form_data:e("#edd_purchase_form").serialize()});case 9:u=t.sent,d=u.intent,f=u.intent,y=f.client_secret,v=f.object,m=u.nonce,e("#edd-process-checkout-nonce").val(m),o.complete("success"),b="setup_intent"===v?"confirmCardSetup":"confirmCardPayment",eddStripe[b](y,{payment_method:i.id},{handleActions:!1}).then((function(e){var t=e.error;if(t)throw t;eddStripe[b](y).then(function(){var e=s()(l.a.mark((function e(t){var n,i,c,a;return l.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n=t.error,e.prev=1,!n){e.next=4;break}throw n;case 4:return e.next=6,Object(h.b)(d);case 6:return i=e.sent,c=i.intent,a=i.nonce,e.next=11,Object(h.a)(c,a);case 11:window.location.replace(edd_stripe_vars.successPageUri),e.next=17;break;case 14:e.prev=14,e.t0=e.catch(1),w(o,e.t0,r);case 17:case"end":return e.stop()}}),e,null,[[1,14]])})));return function(t){return e.apply(this,arguments)}}())})).catch((function(e){w(o,e,r)})),t.next=24;break;case 21:t.prev=21,t.t0=t.catch(0),w(o,t.t0,r);case 24:case"end":return t.stop()}}),t,null,[[0,21]])})))).apply(this,arguments)}function j(e,t){var n=t.total_plain;!0===r&&0===n&&window.location.reload()}function x(){"1"===edd_scripts.is_checkout&&jQuery(document.body).on("edd_gateway_loaded",(function(e,t){if("stripe-prb"===t){var n=document.querySelector(".edds-prb.edds-prb--checkout");n&&(r=!0,function(e){var t=window.eddStripe,n=document.getElementById("edd_checkout_form_wrap");try{var r=Object(f.a)(e.dataset),o=r["display-items"],i=a()(r,["display-items"]),c=t.paymentRequest(v({requestPayerName:!0,displayItems:o},i)),u=t.elements().create("paymentRequestButton",{paymentRequest:c}),s=document.querySelector("#".concat(e.id));c.canMakePayment().then((function(t){return t?!0===t.applePay&&"true"===edd_stripe_vars.isTestMode?m():(s.style.display="block",n.classList.add("edd-prb--is-active"),u.mount("#".concat(e.id," .edds-prb__button")),function(e,t){var n=jQuery(document.body);n.on("edd_quantity_updated",(function(){return g(e,t)})),n.on("edd_discount_applied",(function(){return g(e,t)})),n.on("edd_discount_removed",(function(){return g(e,t)})),e.on("paymentmethod",(function(n){!function(e,t,n){O.apply(this,arguments)}(e,t,n)})),n.on("edd_discount_applied",j)}(c,n),void u.on("click",b)):m()}))}catch(e){Object(p.i)({errorMessage:e.message,errorContainer:document.querySelector("#edds-prb-checkout"),errorContainerReplace:!1})}}(n))}else r=!1}))}}).call(this,n(5))},function(e,t,n){var r=n(94),o=n(95),i=n(96),c=n(98);e.exports=function(e,t){return r(e)||o(e,t)||i(e,t)||c()},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){"use strict";n.r(t),n(60);var r=n(0),o=n(6),i=n(12),c=n(2);!function(){try{window.eddStripe=new Stripe(edd_stripe_vars.publishable_key),window.eddStripe._plugin={domReady:r.c,apiRequest:r.a,generateNotice:r.f,mountCardElement:c.g,createElementsPaymentForm:c.c,getBillingDetails:c.d,getPaymentMethod:c.e,confirmIntent:c.b,handleIntent:c.f,retrieveIntent:c.h,paymentMethods:i.a},Object(r.c)(o.d,o.h,o.g,o.c,o.f,o.e)}catch(e){alert(e.message)}}()},function(e,t,n){},function(e,t,n){var r=n(35),o=n(76);r({target:"Object",stat:!0,forced:Object.assign!==o},{assign:o})},function(e,t,n){var r=n(7),o=n(22),i=r.document,c=o(i)&&o(i.createElement);e.exports=function(e){return c?i.createElement(e):{}}},function(e,t,n){var r=n(7),o=n(23),i=n(10),c=n(34),a=n(43),u=n(64),s=u.get,d=u.enforce,l=String(String).split("String");(e.exports=function(e,t,n,a){var u=!!a&&!!a.unsafe,s=!!a&&!!a.enumerable,f=!!a&&!!a.noTargetGet;"function"==typeof n&&("string"!=typeof t||i(n,"name")||o(n,"name",t),d(n).source=l.join("string"==typeof t?t:"")),e!==r?(u?!f&&e[t]&&(s=!0):delete e[t],s?e[t]=n:o(e,t,n)):s?e[t]=n:c(t,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&s(this).source||a(this)}))},function(e,t,n){var r,o,i,c=n(65),a=n(7),u=n(22),s=n(23),d=n(10),l=n(66),f=n(47),p=a.WeakMap;if(c){var h=new p,y=h.get,v=h.has,m=h.set;r=function(e,t){return m.call(h,e,t),t},o=function(e){return y.call(h,e)||{}},i=function(e){return v.call(h,e)}}else{var b=l("state");f[b]=!0,r=function(e,t){return s(e,b,t),t},o=function(e){return d(e,b)?e[b]:{}},i=function(e){return d(e,b)}}e.exports={set:r,get:o,has:i,enforce:function(e){return i(e)?o(e):r(e,{})},getterFor:function(e){return function(t){var n;if(!u(t)||(n=o(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){var r=n(7),o=n(43),i=r.WeakMap;e.exports="function"==typeof i&&/native code/.test(o(i))},function(e,t,n){var r=n(45),o=n(46),i=r("keys");e.exports=function(e){return i[e]||(i[e]=o(e))}},function(e,t){e.exports=!1},function(e,t,n){var r=n(10),o=n(69),i=n(37),c=n(32);e.exports=function(e,t){for(var n=o(t),a=c.f,u=i.f,s=0;s<n.length;s++){var d=n[s];r(e,d)||a(e,d,u(t,d))}}},function(e,t,n){var r=n(70),o=n(72),i=n(52),c=n(33);e.exports=r("Reflect","ownKeys")||function(e){var t=o.f(c(e)),n=i.f;return n?t.concat(n(e)):t}},function(e,t,n){var r=n(71),o=n(7),i=function(e){return"function"==typeof e?e:void 0};e.exports=function(e,t){return arguments.length<2?i(r[e])||i(o[e]):r[e]&&r[e][t]||o[e]&&o[e][t]}},function(e,t,n){var r=n(7);e.exports=r},function(e,t,n){var r=n(48),o=n(51).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return r(e,o)}},function(e,t,n){var r=n(30),o=n(49),i=n(74),c=function(e){return function(t,n,c){var a,u=r(t),s=o(u.length),d=i(c,s);if(e&&n!=n){for(;s>d;)if((a=u[d++])!=a)return!0}else for(;s>d;d++)if((e||d in u)&&u[d]===n)return e||d||0;return!e&&-1}};e.exports={includes:c(!0),indexOf:c(!1)}},function(e,t,n){var r=n(50),o=Math.max,i=Math.min;e.exports=function(e,t){var n=r(e);return n<0?o(n+t,0):i(n,t)}},function(e,t,n){var r=n(9),o=/#|\.prototype\./,i=function(e,t){var n=a[c(e)];return n==s||n!=u&&("function"==typeof t?r(t):!!t)},c=i.normalize=function(e){return String(e).replace(o,".").toLowerCase()},a=i.data={},u=i.NATIVE="N",s=i.POLYFILL="P";e.exports=i},function(e,t,n){"use strict";var r=n(18),o=n(9),i=n(77),c=n(52),a=n(38),u=n(53),s=n(39),d=Object.assign,l=Object.defineProperty;e.exports=!d||o((function(){if(r&&1!==d({b:1},d(l({},"a",{enumerable:!0,get:function(){l(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol();return e[n]=7,"abcdefghijklmnopqrst".split("").forEach((function(e){t[e]=e})),7!=d({},e)[n]||"abcdefghijklmnopqrst"!=i(d({},t)).join("")}))?function(e,t){for(var n=u(e),o=arguments.length,d=1,l=c.f,f=a.f;o>d;)for(var p,h=s(arguments[d++]),y=l?i(h).concat(l(h)):i(h),v=y.length,m=0;v>m;)p=y[m++],r&&!f.call(h,p)||(n[p]=h[p]);return n}:d},function(e,t,n){var r=n(48),o=n(51);e.exports=Object.keys||function(e){return r(e,o)}},function(e,t,n){var r=n(35),o=n(79);r({target:"Array",stat:!0,forced:!n(89)((function(e){Array.from(e)}))},{from:o})},function(e,t,n){"use strict";var r=n(80),o=n(53),i=n(82),c=n(83),a=n(49),u=n(85),s=n(86);e.exports=function(e){var t,n,d,l,f,p,h=o(e),y="function"==typeof this?this:Array,v=arguments.length,m=v>1?arguments[1]:void 0,b=void 0!==m,g=s(h),_=0;if(b&&(m=r(m,v>2?arguments[2]:void 0,2)),null==g||y==Array&&c(g))for(n=new y(t=a(h.length));t>_;_++)p=b?m(h[_],_):h[_],u(n,_,p);else for(f=(l=g.call(h)).next,n=new y;!(d=f.call(l)).done;_++)p=b?i(l,m,[d.value,_],!0):d.value,u(n,_,p);return n.length=_,n}},function(e,t,n){var r=n(81);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},function(e,t,n){var r=n(33);e.exports=function(e,t,n,o){try{return o?t(r(n)[0],n[1]):t(n)}catch(t){var i=e.return;throw void 0!==i&&r(i.call(e)),t}}},function(e,t,n){var r=n(19),o=n(55),i=r("iterator"),c=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||c[i]===e)}},function(e,t,n){var r=n(54);e.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(e,t,n){"use strict";var r=n(31),o=n(32),i=n(29);e.exports=function(e,t,n){var c=r(t);c in e?o.f(e,c,i(0,n)):e[c]=n}},function(e,t,n){var r=n(87),o=n(55),i=n(19)("iterator");e.exports=function(e){if(null!=e)return e[i]||e["@@iterator"]||o[r(e)]}},function(e,t,n){var r=n(88),o=n(40),i=n(19)("toStringTag"),c="Arguments"==o(function(){return arguments}());e.exports=r?o:function(e){var t,n,r;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),i))?n:c?o(t):"Object"==(r=o(t))&&"function"==typeof t.callee?"Arguments":r}},function(e,t,n){var r={};r[n(19)("toStringTag")]="z",e.exports="[object z]"===String(r)},function(e,t,n){var r=n(19)("iterator"),o=!1;try{var i=0,c={next:function(){return{done:!!i++}},return:function(){o=!0}};c[r]=function(){return this},Array.from(c,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!o)return!1;var n=!1;try{var i={};i[r]=function(){return{next:function(){return{done:n=!0}}}},e(i)}catch(e){}return n}},function(e,t,n){(function(t,r){var o;o=function(){"use strict";function e(e){return"function"==typeof e}var o=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)},i=0,c=void 0,a=void 0,u=function(e,t){y[i]=e,y[i+1]=t,2===(i+=2)&&(a?a(v):w())},s="undefined"!=typeof window?window:void 0,d=s||{},l=d.MutationObserver||d.WebKitMutationObserver,f="undefined"==typeof self&&void 0!==t&&"[object process]"==={}.toString.call(t),p="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function h(){var e=setTimeout;return function(){return e(v,1)}}var y=new Array(1e3);function v(){for(var e=0;e<i;e+=2)(0,y[e])(y[e+1]),y[e]=void 0,y[e+1]=void 0;i=0}var m,b,g,_,w=void 0;function O(e,t){var n=arguments,r=this,o=new this.constructor(S);void 0===o[x]&&N(o);var i,c=r._state;return c?(i=n[c-1],u((function(){return B(c,o,i,r._result)}))):A(r,o,e,t),o}function j(e){if(e&&"object"==typeof e&&e.constructor===this)return e;var t=new this(S);return L(t,e),t}f?w=function(){return t.nextTick(v)}:l?(b=0,g=new l(v),_=document.createTextNode(""),g.observe(_,{characterData:!0}),w=function(){_.data=b=++b%2}):p?((m=new MessageChannel).port1.onmessage=v,w=function(){return m.port2.postMessage(0)}):w=void 0===s?function(){try{var e=n(92);return c=e.runOnLoop||e.runOnContext,function(){c(v)}}catch(e){return h()}}():h();var x=Math.random().toString(36).substring(16);function S(){}var E=new C;function k(e){try{return e.then}catch(e){return E.error=e,E}}function P(t,n,r){n.constructor===t.constructor&&r===O&&n.constructor.resolve===j?function(e,t){1===t._state?T(e,t._result):2===t._state?M(e,t._result):A(t,void 0,(function(t){return L(e,t)}),(function(t){return M(e,t)}))}(t,n):r===E?M(t,E.error):void 0===r?T(t,n):e(r)?function(e,t,n){u((function(e){var r=!1,o=function(n,o,i,c){try{n.call(o,(function(n){r||(r=!0,t!==n?L(e,n):T(e,n))}),(function(t){r||(r=!0,M(e,t))}))}catch(e){return e}}(n,t,0,0,e._label);!r&&o&&(r=!0,M(e,o))}),e)}(t,n,r):T(t,n)}function L(e,t){var n;e===t?M(e,new TypeError("You cannot resolve a promise with itself")):"function"==typeof(n=t)||"object"==typeof n&&null!==n?P(e,t,k(t)):T(e,t)}function q(e){e._onerror&&e._onerror(e._result),I(e)}function T(e,t){void 0===e._state&&(e._result=t,e._state=1,0!==e._subscribers.length&&u(I,e))}function M(e,t){void 0===e._state&&(e._state=2,e._result=t,u(q,e))}function A(e,t,n,r){var o=e._subscribers,i=o.length;e._onerror=null,o[i]=t,o[i+1]=n,o[i+2]=r,0===i&&e._state&&u(I,e)}function I(e){var t=e._subscribers,n=e._state;if(0!==t.length){for(var r=void 0,o=void 0,i=e._result,c=0;c<t.length;c+=3)r=t[c],o=t[c+n],r?B(n,r,o,i):o(i);e._subscribers.length=0}}function C(){this.error=null}var D=new C;function B(t,n,r,o){var i=e(r),c=void 0,a=void 0,u=void 0,s=void 0;if(i){if((c=function(e,t){try{return e(t)}catch(e){return D.error=e,D}}(r,o))===D?(s=!0,a=c.error,c=null):u=!0,n===c)return void M(n,new TypeError("A promises callback cannot return that same promise."))}else c=o,u=!0;void 0!==n._state||(i&&u?L(n,c):s?M(n,a):1===t?T(n,c):2===t&&M(n,c))}var F=0;function N(e){e[x]=F++,e._state=void 0,e._result=void 0,e._subscribers=[]}function z(e,t){this._instanceConstructor=e,this.promise=new e(S),this.promise[x]||N(this.promise),o(t)?(this._input=t,this.length=t.length,this._remaining=t.length,this._result=new Array(this.length),0===this.length?T(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&T(this.promise,this._result))):M(this.promise,new Error("Array Methods must be provided an Array"))}function R(e){this[x]=F++,this._result=this._state=void 0,this._subscribers=[],S!==e&&("function"!=typeof e&&function(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}(),this instanceof R?function(e,t){try{t((function(t){L(e,t)}),(function(t){M(e,t)}))}catch(t){M(e,t)}}(this,e):function(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}())}function V(){var e=void 0;if(void 0!==r)e=r;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var t=e.Promise;if(t){var n=null;try{n=Object.prototype.toString.call(t.resolve())}catch(e){}if("[object Promise]"===n&&!t.cast)return}e.Promise=R}return z.prototype._enumerate=function(){for(var e=this.length,t=this._input,n=0;void 0===this._state&&n<e;n++)this._eachEntry(t[n],n)},z.prototype._eachEntry=function(e,t){var n=this._instanceConstructor,r=n.resolve;if(r===j){var o=k(e);if(o===O&&void 0!==e._state)this._settledAt(e._state,t,e._result);else if("function"!=typeof o)this._remaining--,this._result[t]=e;else if(n===R){var i=new n(S);P(i,e,o),this._willSettleAt(i,t)}else this._willSettleAt(new n((function(t){return t(e)})),t)}else this._willSettleAt(r(e),t)},z.prototype._settledAt=function(e,t,n){var r=this.promise;void 0===r._state&&(this._remaining--,2===e?M(r,n):this._result[t]=n),0===this._remaining&&T(r,this._result)},z.prototype._willSettleAt=function(e,t){var n=this;A(e,void 0,(function(e){return n._settledAt(1,t,e)}),(function(e){return n._settledAt(2,t,e)}))},R.all=function(e){return new z(this,e).promise},R.race=function(e){var t=this;return o(e)?new t((function(n,r){for(var o=e.length,i=0;i<o;i++)t.resolve(e[i]).then(n,r)})):new t((function(e,t){return t(new TypeError("You must pass an array to race."))}))},R.resolve=j,R.reject=function(e){var t=new this(S);return M(t,e),t},R._setScheduler=function(e){a=e},R._setAsap=function(e){u=e},R._asap=u,R.prototype={constructor:R,then:O,catch:function(e){return this.then(null,e)}},V(),R.polyfill=V,R.Promise=R,R},e.exports=o()}).call(this,n(91),n(36))},function(e,t){var n,r,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function c(){throw new Error("clearTimeout has not been defined")}function a(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:c}catch(e){r=c}}();var u,s=[],d=!1,l=-1;function f(){d&&u&&(d=!1,u.length?s=u.concat(s):l=-1,s.length&&p())}function p(){if(!d){var e=a(f);d=!0;for(var t=s.length;t;){for(u=s,s=[];++l<t;)u&&u[l].run();l=-1,t=s.length}u=null,d=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===c||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function h(e,t){this.fun=e,this.array=t}function y(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];s.push(new h(e,t)),1!==s.length||d||a(p)},h.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=y,o.addListener=y,o.once=y,o.off=y,o.removeListener=y,o.removeAllListeners=y,o.emit=y,o.prependListener=y,o.prependOnceListener=y,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},function(e,t){},function(e,t,n){(function(t){var n=function(e){"use strict";var n=Object.prototype,r=n.hasOwnProperty,o="function"==typeof Symbol?Symbol:{},i=o.iterator||"@@iterator",c=o.asyncIterator||"@@asyncIterator",a=o.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function s(e,t,n,r){var o=t&&t.prototype instanceof f?t:f,i=Object.create(o.prototype),c=new x(r||[]);return i._invoke=function(e,t,n){var r="suspendedStart";return function(o,i){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===o)throw i;return{value:void 0,done:!0}}for(n.method=o,n.arg=i;;){var c=n.delegate;if(c){var a=w(c,n);if(a){if(a===l)continue;return a}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===r)throw r="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r="executing";var u=d(e,t,n);if("normal"===u.type){if(r=n.done?"completed":"suspendedYield",u.arg===l)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r="completed",n.method="throw",n.arg=u.arg)}}}(e,n,c),i}function d(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=s;var l={};function f(){}function p(){}function h(){}var y={};y[i]=function(){return this};var v=Object.getPrototypeOf,m=v&&v(v(S([])));m&&m!==n&&r.call(m,i)&&(y=m);var b=h.prototype=f.prototype=Object.create(y);function g(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function _(e,t){var n;this._invoke=function(o,i){function c(){return new t((function(n,c){!function n(o,i,c,a){var u=d(e[o],e,i);if("throw"!==u.type){var s=u.arg,l=s.value;return l&&"object"==typeof l&&r.call(l,"__await")?t.resolve(l.__await).then((function(e){n("next",e,c,a)}),(function(e){n("throw",e,c,a)})):t.resolve(l).then((function(e){s.value=e,c(s)}),(function(e){return n("throw",e,c,a)}))}a(u.arg)}(o,i,n,c)}))}return n=n?n.then(c,c):c()}}function w(e,t){var n=e.iterator[t.method];if(void 0===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=void 0,w(e,t),"throw"===t.method))return l;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return l}var r=d(n,e.iterator,t.arg);if("throw"===r.type)return t.method="throw",t.arg=r.arg,t.delegate=null,l;var o=r.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,l):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,l)}function O(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function j(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function x(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(O,this),this.reset(!0)}function S(e){if(e){var t=e[i];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,o=function t(){for(;++n<e.length;)if(r.call(e,n))return t.value=e[n],t.done=!1,t;return t.value=void 0,t.done=!0,t};return o.next=o}}return{next:E}}function E(){return{value:void 0,done:!0}}return p.prototype=b.constructor=h,h.constructor=p,p.displayName=u(h,a,"GeneratorFunction"),e.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===p||"GeneratorFunction"===(t.displayName||t.name))},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,h):(e.__proto__=h,u(e,a,"GeneratorFunction")),e.prototype=Object.create(b),e},e.awrap=function(e){return{__await:e}},g(_.prototype),_.prototype[c]=function(){return this},e.AsyncIterator=_,e.async=function(n,r,o,i,c){void 0===c&&(c=t);var a=new _(s(n,r,o,i),c);return e.isGeneratorFunction(r)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},g(b),u(b,a,"Generator"),b[i]=function(){return this},b.toString=function(){return"[object Generator]"},e.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var r=t.pop();if(r in e)return n.value=r,n.done=!1,n}return n.done=!0,n}},e.values=S,x.prototype={constructor:x,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!e)for(var t in this)"t"===t.charAt(0)&&r.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=void 0)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function n(n,r){return c.type="throw",c.arg=e,t.next=n,r&&(t.method="next",t.arg=void 0),!!r}for(var o=this.tryEntries.length-1;o>=0;--o){var i=this.tryEntries[o],c=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var a=r.call(i,"catchLoc"),u=r.call(i,"finallyLoc");if(a&&u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(a){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else{if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&r.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var c=i?i.completion:{};return c.type=e,c.arg=t,i?(this.method="next",this.next=i.finallyLoc,l):this.complete(c)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),l},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),j(n),l}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;j(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:S(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),l}},e}(e.exports);try{regeneratorRuntime=n}catch(e){Function("r","regeneratorRuntime = r")(n)}}).call(this,n(24))},function(e,t){e.exports=function(e){if(Array.isArray(e))return e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],r=!0,o=!1,i=void 0;try{for(var c,a=e[Symbol.iterator]();!(r=(c=a.next()).done)&&(n.push(c.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==a.return||a.return()}finally{if(o)throw i}}return n}},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){var r=n(97);e.exports=function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o},e.exports.default=e.exports,e.exports.__esModule=!0}]);
includes/gateways/stripe/assets/js/build/notices.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=102)}({102:function(e,n,t){(function(e){jQuery((function(){jQuery(".edds-admin-notice").each((function(){var n=e(this),t=n.data("id"),r=n.data("nonce");n.on("click",".notice-dismiss",(function(e){return e.preventDefault(),e.stopPropagation(),wp.ajax.post("edds_admin_notices_dismiss_ajax",{id:t,nonce:r})}))}))}))}).call(this,t(5))},5:function(e,n){e.exports=jQuery}});
includes/gateways/stripe/assets/js/src/admin/index.js ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_stripe_admin */
2
+
3
+ /**
4
+ * Internal dependencies.
5
+ */
6
+ import './../../../css/src/admin.scss';
7
+ import './settings/index.js';
8
+
9
+ let testModeCheckbox;
10
+ let testModeToggleNotice;
11
+
12
+ $( document ).ready( function() {
13
+ testModeCheckbox = document.getElementById( 'edd_settings[test_mode]' );
14
+ if ( testModeCheckbox ) {
15
+ testModeToggleNotice = document.getElementById( 'edd_settings[stripe_connect_test_mode_toggle_notice]' );
16
+ EDD_Stripe_Connect_Scripts.init();
17
+ }
18
+
19
+ // Toggle API keys.
20
+ $( '.edds-api-key-toggle button' ).on( 'click', function( event ) {
21
+ event.preventDefault();
22
+
23
+ $( '.edds-api-key-toggle, .edds-api-key-row' )
24
+ .toggleClass( 'edd-hidden' );
25
+ } );
26
+ } );
27
+
28
+ const EDD_Stripe_Connect_Scripts = {
29
+
30
+ init() {
31
+ this.listeners();
32
+ },
33
+
34
+ listeners() {
35
+ const self = this;
36
+
37
+ testModeCheckbox.addEventListener( 'change', function() {
38
+ // Don't run these events if Stripe is not enabled.
39
+ if ( ! edd_stripe_admin.stripe_enabled ) {
40
+ return;
41
+ }
42
+
43
+ if ( this.checked ) {
44
+ if ( 'false' === edd_stripe_admin.test_key_exists ) {
45
+ self.showNotice( testModeToggleNotice, 'warning' );
46
+ self.addHiddenMarker();
47
+ } else {
48
+ self.hideNotice( testModeToggleNotice );
49
+ const hiddenMarker = document.getElementById( 'edd-test-mode-toggled' );
50
+ if ( hiddenMarker ) {
51
+ hiddenMarker.parentNode.removeChild( hiddenMarker );
52
+ }
53
+ }
54
+ }
55
+
56
+ if ( ! this.checked ) {
57
+ if ( 'false' === edd_stripe_admin.live_key_exists ) {
58
+ self.showNotice( testModeToggleNotice, 'warning' );
59
+ self.addHiddenMarker();
60
+ } else {
61
+ self.hideNotice( testModeToggleNotice );
62
+ const hiddenMarker = document.getElementById( 'edd-test-mode-toggled' );
63
+ if ( hiddenMarker ) {
64
+ hiddenMarker.parentNode.removeChild( hiddenMarker );
65
+ }
66
+ }
67
+ }
68
+ } );
69
+ },
70
+
71
+ addHiddenMarker() {
72
+ const submit = document.getElementById( 'submit' );
73
+
74
+ if ( ! submit ) {
75
+ return;
76
+ }
77
+
78
+ submit.parentNode.insertAdjacentHTML( 'beforeend', '<input type="hidden" class="edd-hidden" id="edd-test-mode-toggled" name="edd-test-mode-toggled" />' );
79
+ },
80
+
81
+ showNotice( element = false, type = 'error' ) {
82
+ if ( ! element ) {
83
+ return;
84
+ }
85
+
86
+ if ( typeof element !== 'object' ) {
87
+ return;
88
+ }
89
+
90
+ element.className = 'notice notice-' + type;
91
+ },
92
+
93
+ hideNotice( element = false ) {
94
+ if ( ! element ) {
95
+ return;
96
+ }
97
+
98
+ if ( typeof element !== 'object' ) {
99
+ return;
100
+ }
101
+
102
+ element.className = 'edd-hidden';
103
+ },
104
+ };
includes/gateways/stripe/assets/js/src/admin/notices.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global wp, jQuery */
2
+
3
+ /**
4
+ * Handle dismissing admin notices.
5
+ */
6
+ jQuery( () => {
7
+ /**
8
+ * Loops through each admin notice on the page for processing.
9
+ *
10
+ * @param {HTMLElement} noticeEl Notice element.
11
+ */
12
+ jQuery( '.edds-admin-notice' ).each( function() {
13
+ const notice = $( this );
14
+ const id = notice.data( 'id' );
15
+ const nonce = notice.data( 'nonce' );
16
+
17
+ /**
18
+ * Listens for a click event on the dismiss button, and dismisses the notice.
19
+ *
20
+ * @param {Event} e Click event.
21
+ * @return {jQuery.Deferred} Deferred object.
22
+ */
23
+ notice.on( 'click', '.notice-dismiss', ( e ) => {
24
+ e.preventDefault();
25
+ e.stopPropagation();
26
+
27
+ return wp.ajax.post(
28
+ 'edds_admin_notices_dismiss_ajax',
29
+ {
30
+ id,
31
+ nonce,
32
+ }
33
+ );
34
+ } );
35
+ } );
36
+ } );
includes/gateways/stripe/assets/js/src/admin/settings/index.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import './requirements.js';
5
+ import './stripe-connect.js';
includes/gateways/stripe/assets/js/src/admin/settings/requirements.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { domReady } from 'utils';
5
+
6
+ /**
7
+ * Hides "Save Changes" button if showing the special settings placeholder.
8
+ */
9
+ domReady( () => {
10
+ const containerEl = document.querySelector( '.edds-requirements-not-met' );
11
+
12
+ if ( ! containerEl ) {
13
+ return;
14
+ }
15
+
16
+ // Hide "Save Changes" button.
17
+ document.querySelector( '.edd-settings-wrap .submit' ).style.display = 'none';
18
+ } );
19
+
20
+ /**
21
+ * Moves "Payment Gateways" notice under Stripe.
22
+ * Disables/unchecks the checkbox.
23
+ */
24
+ domReady( () => {
25
+ const noticeEl = document.getElementById( 'edds-payment-gateways-stripe-unmet-requirements' );
26
+
27
+ if ( ! noticeEl ) {
28
+ return;
29
+ }
30
+
31
+ const stripeLabel = document.querySelector( 'label[for="edd_settings[gateways][stripe]"]' );
32
+ stripeLabel.parentNode.insertBefore( noticeEl, stripeLabel.nextSibling );
33
+
34
+ const stripeCheck = document.getElementById( 'edd_settings[gateways][stripe]' );
35
+ stripeCheck.disabled = true;
36
+ stripeCheck.checked = false;
37
+
38
+ noticeEl.insertBefore( stripeCheck, noticeEl.querySelector( 'p' ) );
39
+ noticeEl.insertBefore( stripeLabel, noticeEl.querySelector( 'p' ) );
40
+ } );
includes/gateways/stripe/assets/js/src/admin/settings/stripe-connect.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { domReady, apiRequest } from 'utils';
5
+
6
+ // Wait for DOM.
7
+ domReady( () => {
8
+ const containerEl = document.getElementById( 'edds-stripe-connect-account' );
9
+ const actionsEl = document.getElementById( 'edds-stripe-disconnect-reconnect' );
10
+
11
+ if ( ! containerEl ) {
12
+ return;
13
+ }
14
+
15
+ return apiRequest( 'edds_stripe_connect_account_info', {
16
+ ...containerEl.dataset,
17
+ } )
18
+ .done( ( response ) => {
19
+ containerEl.innerHTML = response.message;
20
+ containerEl.classList.add( `notice-${ response.status }` );
21
+ if ( response.actions ) {
22
+ actionsEl.innerHTML = response.actions;
23
+ }
24
+ } )
25
+ .fail( ( error ) => {
26
+ containerEl.innerHTML = error.message;
27
+ containerEl.classList.add( 'notice-error' );
28
+ } );
29
+ } );
includes/gateways/stripe/assets/js/src/frontend/components/index.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ export { default as Modal } from './modal';
2
+ export { paymentMethods } from './payment-methods';
includes/gateways/stripe/assets/js/src/frontend/components/modal/index.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+
5
+ // Import Polyfills for MicroModal IE 11 support.
6
+ // https://github.com/Ghosh/micromodal#ie-11-and-below
7
+ // https://github.com/ghosh/Micromodal/issues/49#issuecomment-424213347
8
+ // https://github.com/ghosh/Micromodal/issues/49#issuecomment-517916416
9
+ import 'core-js/modules/es.object.assign';
10
+ import 'core-js/modules/es.array.from';
11
+
12
+ import MicroModal from 'micromodal';
13
+
14
+ const DEFAULT_CONFIG = {
15
+ disableScroll: true,
16
+ awaitOpenAnimation: true,
17
+ awaitCloseAnimation: true,
18
+ };
19
+
20
+ function setup( options ) {
21
+ const config = {
22
+ ...DEFAULT_CONFIG,
23
+ ...options,
24
+ };
25
+
26
+ MicroModal.init( config );
27
+ }
28
+
29
+ function open( modalId, options ) {
30
+ const config = {
31
+ ...DEFAULT_CONFIG,
32
+ ...options,
33
+ };
34
+
35
+ MicroModal.show( modalId, config );
36
+ }
37
+
38
+ function close( modalId ) {
39
+ MicroModal.close( modalId );
40
+ }
41
+
42
+ export default {
43
+ setup,
44
+ open,
45
+ close,
46
+ };
includes/gateways/stripe/assets/js/src/frontend/components/payment-methods/index.js ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $ */
2
+
3
+ /**
4
+ * Internal dependencies.
5
+ */
6
+ import { forEach, getNextSiblings } from 'utils'; // eslint-disable-line @wordpress/dependency-group
7
+
8
+ /**
9
+ *
10
+ */
11
+ export function paymentMethods() {
12
+ // Toggle only shows if using Full Address (for some reason).
13
+ if ( getBillingFieldsToggle() ) {
14
+ // Hide fields initially.
15
+ toggleBillingFields( false );
16
+
17
+ /**
18
+ * Binds change event to "Update billing address" toggle to show/hide address fields.
19
+ *
20
+ * @param {Event} e Change event.
21
+ */
22
+ getBillingFieldsToggle().addEventListener( 'change', function( e ) {
23
+ return toggleBillingFields( e.target.checked );
24
+ } );
25
+ }
26
+
27
+ // Payment method toggles.
28
+ const existingPaymentMethods = document.querySelectorAll( '.edd-stripe-existing-card' );
29
+
30
+ if ( 0 !== existingPaymentMethods.length ) {
31
+ forEach( existingPaymentMethods, function( existingPaymentMethod ) {
32
+ /**
33
+ * Binds change event to credit card toggles.
34
+ *
35
+ * @param {Event} e Change event.
36
+ */
37
+ return existingPaymentMethod.addEventListener( 'change', function( e ) {
38
+ return onPaymentSourceChange( e.target );
39
+ } );
40
+ } );
41
+
42
+ // Simulate change of payment method to populate current fields.
43
+ let currentPaymentMethod = document.querySelector( '.edd-stripe-existing-card:checked' );
44
+
45
+ if ( ! currentPaymentMethod ) {
46
+ currentPaymentMethod = document.querySelector( '.edd-stripe-existing-card:first-of-type' );
47
+ currentPaymentMethod.checked = true;
48
+ }
49
+
50
+ const paymentMethodChangeEvent = document.createEvent( 'Event' );
51
+ paymentMethodChangeEvent.initEvent( 'change', true, false );
52
+ currentPaymentMethod.dispatchEvent( paymentMethodChangeEvent );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Determines if the billing fields can be toggled.
58
+ *
59
+ * @return {Bool} True if the toggle exists.
60
+ */
61
+ function getBillingFieldsToggle() {
62
+ return document.getElementById( 'edd-stripe-update-billing-address' );
63
+ }
64
+
65
+ /**
66
+ * Toggles billing fields visiblity.
67
+ *
68
+ * Assumes the toggle control is the first item in the "Billing Details" fieldset.
69
+ *
70
+ * @param {Bool} isVisible Billing item visibility.
71
+ */
72
+ function toggleBillingFields( isVisible ) {
73
+ const updateAddressWrapperEl = document.querySelector( '.edd-stripe-update-billing-address-wrapper' );
74
+
75
+ if ( ! updateAddressWrapperEl ) {
76
+ return;
77
+ }
78
+
79
+ // Find all elements after the toggle.
80
+ const billingFieldWrappers = getNextSiblings( updateAddressWrapperEl );
81
+ const billingAddressPreview = document.querySelector( '.edd-stripe-update-billing-address-current' );
82
+
83
+ billingFieldWrappers.forEach( function( wrap ) {
84
+ wrap.style.display = isVisible ? 'block' : 'none';
85
+ } );
86
+
87
+ // Hide address preview.
88
+ if ( billingAddressPreview ) {
89
+ billingAddressPreview.style.display = isVisible ? 'none' : 'block';
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Manages UI state when the payment source changes.
95
+ *
96
+ * @param {HTMLElement} paymentSource Selected payment source. (Radio element with data).
97
+ */
98
+ function onPaymentSourceChange( paymentSource ) {
99
+ const isNew = 'new' === paymentSource.value;
100
+ const newCardForm = document.querySelector( '.edd-stripe-new-card' );
101
+ const billingAddressToggle = document.querySelector( '.edd-stripe-update-billing-address-wrapper' );
102
+
103
+ // Toggle card details field.
104
+ newCardForm.style.display = isNew ? 'block' : 'none';
105
+
106
+ if ( billingAddressToggle ) {
107
+ billingAddressToggle.style.display = isNew ? 'none' : 'block';
108
+ }
109
+
110
+ // @todo don't be lazy.
111
+ $( '.edd-stripe-card-radio-item' ).removeClass( 'selected' );
112
+ $( paymentSource ).closest( '.edd-stripe-card-radio-item' ).addClass( 'selected' );
113
+
114
+ const addressFieldMap = {
115
+ card_address: 'address_line1',
116
+ card_address_2: 'address_line2',
117
+ card_city: 'address_city',
118
+ card_state: 'address_state',
119
+ card_zip: 'address_zip',
120
+ billing_country: 'address_country',
121
+ };
122
+
123
+ // New card is being used, show fields and reset them.
124
+ if ( isNew ) {
125
+ // Reset all fields.
126
+ for ( const addressEl in addressFieldMap ) {
127
+ if ( ! addressFieldMap.hasOwnProperty( addressEl ) ) {
128
+ return;
129
+ }
130
+
131
+ const addressField = document.getElementById( addressEl );
132
+
133
+ if ( addressField ) {
134
+ addressField.value = '';
135
+ addressField.selected = '';
136
+ }
137
+ }
138
+
139
+ // Recalculate taxes.
140
+ if ( window.EDD_Checkout.recalculate_taxes ) {
141
+ window.EDD_Checkout.recalculate_taxes();
142
+ }
143
+
144
+ // Show billing fields.
145
+ toggleBillingFields( true );
146
+
147
+ // Existing card is being used.
148
+ // Ensure the billing fields are hidden, and update their values with saved information.
149
+ } else {
150
+ const addressString = [];
151
+ const billingDetailsEl = document.getElementById( paymentSource.id + '-billing-details' );
152
+
153
+ if ( ! billingDetailsEl ) {
154
+ return;
155
+ }
156
+
157
+ // Hide billing fields.
158
+ toggleBillingFields( false );
159
+
160
+ // Uncheck "Update billing address"
161
+ if ( getBillingFieldsToggle() ) {
162
+ getBillingFieldsToggle().checked = false;
163
+ }
164
+
165
+ // Update billing address fields with saved card values.
166
+ const billingDetails = billingDetailsEl.dataset;
167
+
168
+ for ( const addressEl in addressFieldMap ) {
169
+ if ( ! addressFieldMap.hasOwnProperty( addressEl ) ) {
170
+ continue;
171
+ }
172
+
173
+ const addressField = document.getElementById( addressEl );
174
+
175
+ if ( ! addressField ) {
176
+ continue;
177
+ }
178
+
179
+ const value = billingDetails[ addressFieldMap[ addressEl ] ];
180
+
181
+ // Set field value.
182
+ addressField.value = value;
183
+
184
+ // Generate an address string from values.
185
+ if ( '' !== value ) {
186
+ addressString.push( value );
187
+ }
188
+
189
+ // This field is required but does not have a saved value, show all fields.
190
+ if ( addressField.required && '' === value ) {
191
+ // @todo DRY up some of this DOM usage.
192
+ toggleBillingFields( true );
193
+
194
+ if ( getBillingFieldsToggle() ) {
195
+ getBillingFieldsToggle().checked = true;
196
+ }
197
+
198
+ if ( billingAddressToggle ) {
199
+ billingAddressToggle.style.display = 'none';
200
+ }
201
+ }
202
+
203
+ // Trigger change event when the Country field is updated.
204
+ if ( 'billing_country' === addressEl ) {
205
+ const changeEvent = document.createEvent( 'Event' );
206
+ changeEvent.initEvent( 'change', true, true );
207
+ addressField.dispatchEvent( changeEvent );
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Monitor AJAX requests for address changes.
213
+ *
214
+ * Wait for the "State" field to be updated based on the "Country" field's
215
+ * change event. Once there is an AJAX response fill the "State" field with the
216
+ * saved card's State data and recalculate taxes.
217
+ *
218
+ * @since 2.7
219
+ *
220
+ * @param {Object} event
221
+ * @param {Object} xhr
222
+ * @param {Object} options
223
+ */
224
+ $( document ).ajaxSuccess( function( event, xhr, options ) {
225
+ if ( ! options || ! options.data || ! xhr ) {
226
+ return;
227
+ }
228
+
229
+ if (
230
+ options.data.includes( 'action=edd_get_shop_states' ) &&
231
+ options.data.includes( 'field_name=card_state' ) &&
232
+ ( xhr.responseText && xhr.responseText.includes( 'card_state' ) )
233
+ ) {
234
+ const stateField = document.getElementById( 'card_state' );
235
+
236
+ if ( stateField ) {
237
+ stateField.value = billingDetails.address_state;
238
+
239
+ // Recalculate taxes.
240
+ if ( window.EDD_Checkout.recalculate_taxes ) {
241
+ window.EDD_Checkout.recalculate_taxes( stateField.value );
242
+ }
243
+ }
244
+ }
245
+ } );
246
+
247
+ // Update address string summary.
248
+ const billingAddressPreview = document.querySelector( '.edd-stripe-update-billing-address-current' );
249
+
250
+ if ( billingAddressPreview ) {
251
+ billingAddressPreview.innerText = addressString.join( ', ' );
252
+
253
+ const { brand, last4 } = billingDetails;
254
+
255
+ document.querySelector( '.edd-stripe-update-billing-address-brand' ).innerHTML = brand;
256
+ document.querySelector( '.edd-stripe-update-billing-address-last4' ).innerHTML = last4;
257
+ }
258
+ }
259
+ }
includes/gateways/stripe/assets/js/src/frontend/index.js ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global Stripe, edd_stripe_vars */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import './../../../css/src/frontend.scss';
7
+ import { domReady, apiRequest, generateNotice } from 'utils';
8
+
9
+ import {
10
+ setupCheckout,
11
+ setupProfile,
12
+ setupPaymentHistory,
13
+ setupBuyNow,
14
+ setupDownloadPRB,
15
+ setupCheckoutPRB,
16
+ } from 'frontend/payment-forms';
17
+
18
+ import {
19
+ paymentMethods,
20
+ } from 'frontend/components/payment-methods';
21
+
22
+ import {
23
+ mountCardElement,
24
+ createPaymentForm as createElementsPaymentForm,
25
+ getBillingDetails,
26
+ getPaymentMethod,
27
+ confirm as confirmIntent,
28
+ handle as handleIntent,
29
+ retrieve as retrieveIntent,
30
+ } from 'frontend/stripe-elements';
31
+ // eslint-enable @wordpress/dependency-group
32
+
33
+ ( () => {
34
+ try {
35
+ window.eddStripe = new Stripe( edd_stripe_vars.publishable_key );
36
+
37
+ // Alias some functionality for external plugins.
38
+ window.eddStripe._plugin = {
39
+ domReady,
40
+ apiRequest,
41
+ generateNotice,
42
+ mountCardElement,
43
+ createElementsPaymentForm,
44
+ getBillingDetails,
45
+ getPaymentMethod,
46
+ confirmIntent,
47
+ handleIntent,
48
+ retrieveIntent,
49
+ paymentMethods,
50
+ };
51
+
52
+ // Setup frontend components when DOM is ready.
53
+ domReady(
54
+ setupCheckout,
55
+ setupProfile,
56
+ setupPaymentHistory,
57
+ setupBuyNow,
58
+ setupDownloadPRB,
59
+ setupCheckoutPRB,
60
+ );
61
+ } catch ( error ) {
62
+ alert( error.message );
63
+ }
64
+ } )();
includes/gateways/stripe/assets/js/src/frontend/payment-forms/buy-now/index.js ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery, edd_scripts, edd_stripe_vars */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import { forEach, domReady, apiRequest } from 'utils';
7
+ import { Modal, paymentMethods } from 'frontend/components';
8
+ import { paymentForm } from 'frontend/payment-forms/checkout'
9
+
10
+ /**
11
+ * Adds a Download to the Cart.
12
+ *
13
+ * @param {number} downloadId Download ID.
14
+ * @param {number} priceId Price ID.
15
+ * @param {number} quantity Quantity.
16
+ * @param {string} nonce Security nonce.
17
+ *
18
+ * @return {Promise}
19
+ */
20
+ function addToCart( downloadId, priceId, quantity, nonce ) {
21
+ const { ajaxurl } = edd_scripts;
22
+ const data = {
23
+ download_id: downloadId,
24
+ price_id: priceId,
25
+ quantity: quantity,
26
+ nonce,
27
+ };
28
+
29
+ return apiRequest( 'edds_add_to_cart', data );
30
+ }
31
+
32
+ /**
33
+ * Empties the Cart.
34
+ *
35
+ * @return {Promise}
36
+ */
37
+ function emptyCart() {
38
+ return apiRequest( 'edds_empty_cart' );
39
+ }
40
+
41
+ /**
42
+ * Displays the Buy Now modal.
43
+ *
44
+ * @param {Object} args
45
+ */
46
+ function buyNowModal( { downloadId, priceId, quantity, nonce } ) {
47
+ const modalContent = document.querySelector( '#edds-buy-now-modal-content' );
48
+ const modalLoading = '<span class="edd-loading-ajax edd-loading"></span>';
49
+
50
+ // Show modal.
51
+ Modal.open( 'edds-buy-now', {
52
+ /**
53
+ * Adds the item to the Cart when opening.
54
+ */
55
+ onShow() {
56
+ modalContent.innerHTML = modalLoading;
57
+
58
+ addToCart( downloadId, priceId, quantity, nonce )
59
+ .then( ( { checkout } ) => {
60
+ // Show Checkout HTML.
61
+ modalContent.innerHTML = checkout;
62
+
63
+ // Reinitialize core JS.
64
+ window.EDD_Checkout.init();
65
+
66
+ const totalEl = document.querySelector( '#edds-buy-now-modal-content .edd_cart_amount' );
67
+ const total = parseFloat( totalEl.dataset.total );
68
+
69
+ // Reinitialize Stripe JS if a payment is required.
70
+ if ( total > 0 ) {
71
+ paymentForm();
72
+ paymentMethods();
73
+ }
74
+ } )
75
+ .fail( ( { message } ) => {
76
+ // Show error message.
77
+ document.querySelector( '#edds-buy-now-modal-content' ).innerHTML = message;
78
+ } );
79
+ },
80
+ /**
81
+ * Empties Cart on close.
82
+ */
83
+ onClose() {
84
+ emptyCart();
85
+ }
86
+ } );
87
+ }
88
+
89
+ // DOM ready.
90
+ export function setup() {
91
+
92
+ // Find all "Buy Now" links on the page.
93
+ forEach( document.querySelectorAll( '.edds-buy-now' ), ( el ) => {
94
+
95
+ // Don't use modal if "Free Downloads" is active and available for this download.
96
+ // https://easydigitaldownloads.com/downloads/free-downloads/
97
+ if ( el.classList.contains( 'edd-free-download' ) ) {
98
+ return;
99
+ }
100
+
101
+ /**
102
+ * Launches "Buy Now" modal when clicking "Buy Now" link.
103
+ *
104
+ * @param {Object} e Click event.
105
+ */
106
+ el.addEventListener( 'click', ( e ) => {
107
+ const { downloadId, nonce } = e.currentTarget.dataset;
108
+
109
+ // Stop other actions if a Download ID is found.
110
+ if ( ! downloadId ) {
111
+ return;
112
+ }
113
+
114
+ e.preventDefault();
115
+ e.stopImmediatePropagation();
116
+
117
+ // Gather Download information.
118
+ let priceId = 0;
119
+ let quantity = 1;
120
+
121
+ const addToCartForm = e.currentTarget.closest(
122
+ '.edd_download_purchase_form'
123
+ );
124
+
125
+ // Price ID.
126
+ const priceIdEl = addToCartForm.querySelector(
127
+ `.edd_price_option_${downloadId}:checked`
128
+ );
129
+
130
+ if ( priceIdEl ) {
131
+ priceId = priceIdEl.value;
132
+ }
133
+
134
+ // Quantity.
135
+ const quantityEl = addToCartForm.querySelector(
136
+ 'input[name="edd_download_quantity"]'
137
+ );
138
+
139
+ if ( quantityEl ) {
140
+ quantity = quantityEl.value;
141
+ }
142
+
143
+ buyNowModal( {
144
+ downloadId,
145
+ priceId,
146
+ quantity,
147
+ nonce
148
+ } );
149
+ } );
150
+
151
+ } );
152
+
153
+ /**
154
+ * Replaces submit button text after validation errors.
155
+ *
156
+ * If there are no other items in the cart the core javascript will replace
157
+ * the button text with the value for a $0 cart (usually "Free Download")
158
+ * because the script variables were constructed when nothing was in the cart.
159
+ */
160
+ jQuery( document.body ).on( 'edd_checkout_error', () => {
161
+ const submitButtonEl = document.querySelector(
162
+ '#edds-buy-now #edd-purchase-button'
163
+ );
164
+
165
+ if ( ! submitButtonEl ) {
166
+ return;
167
+ }
168
+
169
+ const { i18n: { completePurchase } } = edd_stripe_vars;
170
+
171
+ const amountEl = document.querySelector( '.edd_cart_amount' );
172
+ const { total, totalCurrency } = amountEl.dataset;
173
+
174
+ if ( '0' === total ) {
175
+ return;
176
+ }
177
+
178
+ // For some reason a delay is needed to override the value set by
179
+ // https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/assets/js/edd-ajax.js#L414
180
+ setTimeout( () => {
181
+ submitButtonEl.value = `${ totalCurrency } - ${ completePurchase }`;
182
+ }, 10 );
183
+ } );
184
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/checkout/index.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_scripts */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ // eslint-disable @wordpress/dependency-group
7
+ import { paymentMethods } from 'frontend/components';
8
+ // eslint-enable @wordpress/dependency-group
9
+
10
+ import { paymentForm } from './payment-form.js';
11
+
12
+ export * from './payment-form.js';
13
+
14
+ export function setup() {
15
+ if ( '1' !== edd_scripts.is_checkout ) {
16
+ return;
17
+ }
18
+
19
+ // Initial load for single gateway.
20
+ const singleGateway = document.querySelector( 'input[name="edd-gateway"]' );
21
+
22
+ if ( singleGateway && 'stripe' === singleGateway.value ) {
23
+ paymentForm();
24
+ paymentMethods();
25
+ }
26
+
27
+ // Gateway switch.
28
+ $( document.body ).on( 'edd_gateway_loaded', ( e, gateway ) => {
29
+ if ( 'stripe' !== gateway ) {
30
+ return;
31
+ }
32
+
33
+ paymentForm();
34
+ paymentMethods();
35
+ } );
36
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/checkout/payment-form.js ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_stripe_vars, edd_global_vars */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import {
7
+ createPaymentForm as createElementsPaymentForm,
8
+ getPaymentMethod,
9
+ capture as captureIntent,
10
+ handle as handleIntent,
11
+ } from 'frontend/stripe-elements'; // eslint-disable-line @wordpress/dependency-group
12
+
13
+ import { apiRequest, generateNotice } from 'utils'; // eslint-disable-line @wordpress/dependency-group
14
+
15
+ /**
16
+ * Binds Payment submission functionality.
17
+ *
18
+ * Resets before rebinding to avoid duplicate events
19
+ * during gateway switching.
20
+ */
21
+ export function paymentForm() {
22
+ // Mount Elements.
23
+ createElementsPaymentForm( window.eddStripe.elements() );
24
+
25
+ // Bind form submission.
26
+ // Needs to be jQuery since that is what core submits against.
27
+ $( '#edd_purchase_form' ).off( 'submit', onSubmit );
28
+ $( '#edd_purchase_form' ).on( 'submit', onSubmit );
29
+
30
+ // SUPER ghetto way to watch for core form validation because no events are in place.
31
+ // Called after the purchase form is submitted (via `click` or `submit`)
32
+ $( document ).off( 'ajaxSuccess', watchInitialValidation );
33
+ $( document ).on( 'ajaxSuccess', watchInitialValidation );
34
+ }
35
+
36
+ /**
37
+ * Processes Stripe gateway-specific functionality after core AJAX validation has run.
38
+ */
39
+ async function onSubmitDelay() {
40
+ try {
41
+ // Form data to send to intent requests.
42
+ let formData = $( '#edd_purchase_form' ).serialize();
43
+
44
+ // Retrieve or create a PaymentMethod.
45
+ const paymentMethod = await getPaymentMethod( document.getElementById( 'edd_purchase_form' ), window.eddStripe.cardElement );
46
+
47
+ // Run the modified `_edds_process_purchase_form` and create an Intent.
48
+ const {
49
+ intent: initialIntent,
50
+ nonce: refreshedNonce
51
+ } = await processForm( paymentMethod.id, paymentMethod.exists );
52
+
53
+ // Update existing nonce value in DOM form data in case data is retrieved
54
+ // again directly from the DOM.
55
+ $( '#edd-process-checkout-nonce' ).val( refreshedNonce );
56
+
57
+ // Handle any actions required by the Intent State Machine (3D Secure, etc).
58
+ const handledIntent = await handleIntent(
59
+ initialIntent,
60
+ {
61
+ form_data: formData += `&edd-process-checkout-nonce=${ refreshedNonce }`,
62
+ }
63
+ );
64
+
65
+ // Create an EDD payment record.
66
+ const { intent, nonce } = await createPayment( handledIntent );
67
+
68
+ // Capture any unpcaptured intents.
69
+ const finalIntent = await captureIntent(
70
+ intent,
71
+ {},
72
+ nonce
73
+ );
74
+
75
+ // Attempt to transition payment status and redirect.
76
+ // @todo Maybe confirm payment status as well? Would need to generate a custom
77
+ // response because the private EDD_Payment properties are not available.
78
+ if (
79
+ ( 'succeeded' === finalIntent.status ) ||
80
+ ( 'canceled' === finalIntent.status && 'abandoned' === finalIntent.cancellation_reason )
81
+ ) {
82
+ await completePayment( finalIntent, nonce );
83
+
84
+ window.location.replace( edd_stripe_vars.successPageUri );
85
+ } else {
86
+ window.location.replace( edd_stripe_vars.failurePageUri );
87
+ }
88
+ } catch ( error ) {
89
+ handleException( error );
90
+ enableForm();
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Processes the purchase form.
96
+ *
97
+ * Generates purchase data for the current session and
98
+ * uses the PaymentMethod to generate an Intent based on data.
99
+ *
100
+ * @param {string} paymentMethodId PaymentMethod ID.
101
+ * @param {Bool} paymentMethodExists If the PaymentMethod has already been attached to a customer.
102
+ * @return {Promise} jQuery Promise.
103
+ */
104
+ export function processForm( paymentMethodId, paymentMethodExists ) {
105
+ return apiRequest( 'edds_process_purchase_form', {
106
+ // Send available form data.
107
+ form_data: $( '#edd_purchase_form' ).serialize(),
108
+ payment_method_id: paymentMethodId,
109
+ payment_method_exists: paymentMethodExists,
110
+ } );
111
+ }
112
+
113
+ /**
114
+ * Complete a Payment in EDD.
115
+ *
116
+ * @param {object} intent Intent.
117
+ * @return {Promise} jQuery Promise.
118
+ */
119
+ export function createPayment( intent ) {
120
+ const paymentForm = $( '#edd_purchase_form' );
121
+ let formData = paymentForm.serialize();
122
+
123
+ // Attempt to find the Checkout nonce directly.
124
+ if ( paymentForm.length === 0 ) {
125
+ const nonce = $( '#edd-process-checkout-nonce' ).val();
126
+ formData = `edd-process-checkout-nonce=${ nonce }`
127
+ }
128
+
129
+ return apiRequest( 'edds_create_payment', {
130
+ form_data: formData,
131
+ intent,
132
+ } );
133
+ }
134
+
135
+ /**
136
+ * Complete a Payment in EDD.
137
+ *
138
+ * @param {object} intent Intent.
139
+ * @param {string} refreshedNonce A refreshed nonce that might be needed if the
140
+ * user logged in.
141
+ * @return {Promise} jQuery Promise.
142
+ */
143
+ export function completePayment( intent, refreshedNonce ) {
144
+ const paymentForm = $( '#edd_purchase_form' );
145
+ let formData = paymentForm.serialize();
146
+
147
+ // Attempt to find the Checkout nonce directly.
148
+ if ( paymentForm.length === 0 ) {
149
+ const nonce = $( '#edd-process-checkout-nonce' ).val();
150
+ formData = `edd-process-checkout-nonce=${ nonce }`;
151
+ }
152
+
153
+ // Add the refreshed nonce if available.
154
+ if ( refreshedNonce ) {
155
+ formData += `&edd-process-checkout-nonce=${ refreshedNonce }`;
156
+ }
157
+
158
+ return apiRequest( 'edds_complete_payment', {
159
+ form_data: formData,
160
+ intent,
161
+ } );
162
+ }
163
+
164
+
165
+ /**
166
+ * Listen for initial EDD core validation.
167
+ *
168
+ * @param {Object} event Event.
169
+ * @param {Object} xhr AJAX request.
170
+ * @param {Object} options Request options.
171
+ */
172
+ function watchInitialValidation( event, xhr, options ) {
173
+ if ( ! options || ! options.data || ! xhr ) {
174
+ return;
175
+ }
176
+
177
+ if (
178
+ options.data.includes( 'action=edd_process_checkout' ) &&
179
+ options.data.includes( 'edd-gateway=stripe' ) &&
180
+ ( xhr.responseText && 'success' === xhr.responseText.trim() )
181
+ ) {
182
+ return onSubmitDelay();
183
+ }
184
+ };
185
+
186
+ /**
187
+ * EDD core listens to a a `click` event on the Checkout form submit button.
188
+ *
189
+ * This submit event handler captures true submissions and triggers a `click`
190
+ * event so EDD core can take over as normoal.
191
+ *
192
+ * @param {Object} event submit Event.
193
+ */
194
+ function onSubmit( event ) {
195
+ // Ensure we are dealing with the Stripe gateway.
196
+ if ( ! (
197
+ // Stripe is selected gateway and total is larger than 0.
198
+ $( 'input[name="edd-gateway"]' ).val() === 'stripe' &&
199
+ $( '.edd_cart_total .edd_cart_amount' ).data( 'total' ) > 0
200
+ ) ) {
201
+ return;
202
+ }
203
+
204
+ // While this function is tied to the submit event, block submission.
205
+ event.preventDefault();
206
+
207
+ // Simulate a mouse click on the Submit button.
208
+ //
209
+ // If the form is submitted via the "Enter" key we need to ensure the core
210
+ // validation is run.
211
+ //
212
+ // When that is run and then the form is resubmitted
213
+ // the click event won't do anything because the button will be disabled.
214
+ $( '#edd_purchase_form #edd_purchase_submit [type=submit]' ).trigger( 'click' );
215
+ }
216
+
217
+ /**
218
+ * Enables the Checkout form for further submissions.
219
+ */
220
+ function enableForm() {
221
+ // Update button text.
222
+ document.querySelector( '#edd_purchase_form #edd_purchase_submit [type=submit]' ).value = edd_global_vars.complete_purchase;
223
+
224
+ // Enable form.
225
+ $( '.edd-loading-ajax' ).remove();
226
+ $( '.edd_errors' ).remove();
227
+ $( '.edd-error' ).hide();
228
+ $( '#edd-purchase-button' ).attr( 'disabled', false );
229
+ }
230
+
231
+ /**
232
+ * Handles error output for stripe.js promises, or jQuery AJAX promises.
233
+ *
234
+ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/assets/js/edd-ajax.js#L390
235
+ *
236
+ * @param {Object} error Error data.
237
+ */
238
+ function handleException( error ) {
239
+ const notice = generateNotice( ( error && error.message ) ? error.message : edd_stripe_vars.generic_error );
240
+
241
+ // Hide previous messages.
242
+ // @todo These should all be in a container, but that's not how core works.
243
+ $( '.edd-stripe-alert' ).remove();
244
+ $( edd_global_vars.checkout_error_anchor ).before( notice );
245
+ $( document.body ).trigger( 'edd_checkout_error', [ error ] );
246
+
247
+ if ( window.console && error.responseText ) {
248
+ window.console.error( error.responseText );
249
+ }
250
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/index.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ export { setup as setupCheckout, createPayment, completePayment } from './checkout';
2
+ export { setup as setupProfile } from './profile-editor';
3
+ export { setup as setupPaymentHistory } from './payment-receipt';
4
+ export { setup as setupBuyNow } from './buy-now';
5
+ export {
6
+ setupDownload as setupDownloadPRB,
7
+ setupCheckout as setupCheckoutPRB,
8
+ } from './payment-request';
includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-receipt/index.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ // eslint-disable @wordpress/dependency-group
5
+ import { paymentMethods } from 'frontend/components/payment-methods';
6
+ // eslint-enable @wordpress/dependency-group
7
+
8
+ import { paymentForm } from './payment-form.js';
9
+
10
+ export function setup() {
11
+ if ( ! document.getElementById( 'edds-update-payment-method' ) ) {
12
+ return;
13
+ }
14
+
15
+ paymentForm();
16
+ paymentMethods();
17
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-receipt/payment-form.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global edd_stripe_vars */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ // eslint-disable @wordpress/dependency-group
7
+ import {
8
+ getPaymentMethod,
9
+ createPaymentForm as createElementsPaymentForm,
10
+ handle as handleIntent,
11
+ retrieve as retrieveIntent,
12
+ } from 'frontend/stripe-elements';
13
+
14
+ import { generateNotice, apiRequest } from 'utils';
15
+ // eslint-enable @wordpress/dependency-group
16
+
17
+ /**
18
+ * Binds events and sets up "Update Payment Method" form.
19
+ */
20
+ export function paymentForm() {
21
+ // Mount Elements.
22
+ createElementsPaymentForm( window.eddStripe.elements() );
23
+
24
+ document.getElementById( 'edds-update-payment-method' ).addEventListener( 'submit', onAuthorizePayment );
25
+ }
26
+
27
+ /**
28
+ * Setup PaymentMethods.
29
+ *
30
+ * Moves the active item to the currently authenticating PaymentMethod.
31
+ */
32
+ function setPaymentMethod() {
33
+ const form = document.getElementById( 'edds-update-payment-method' );
34
+ const input = document.getElementById( form.dataset.paymentMethod );
35
+
36
+ // Select the correct PaymentMethod after load.
37
+ if ( input ) {
38
+ const changeEvent = document.createEvent( 'Event' );
39
+
40
+ changeEvent.initEvent( 'change', true, true );
41
+ input.checked = true;
42
+ input.dispatchEvent( changeEvent );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Authorize a PaymentIntent.
48
+ *
49
+ * @param {Event} e submtit event.
50
+ */
51
+ async function onAuthorizePayment( e ) {
52
+ e.preventDefault();
53
+
54
+ const form = document.getElementById( 'edds-update-payment-method' );
55
+
56
+ disableForm();
57
+
58
+ try {
59
+ const paymentMethod = await getPaymentMethod( form, window.eddStripe.cardElement );
60
+
61
+ // Handle PaymentIntent.
62
+ const intent = await retrieveIntent( form.dataset.paymentIntent, 'payment_method' );
63
+
64
+ const handledIntent = await handleIntent( intent, {
65
+ payment_method: paymentMethod.id,
66
+ } );
67
+
68
+ // Attempt to transition payment status and redirect.
69
+ const authorization = await completeAuthorization( handledIntent.id );
70
+
71
+ if ( authorization.payment ) {
72
+ window.location.reload();
73
+ } else {
74
+ throw authorization;
75
+ }
76
+ } catch ( error ) {
77
+ handleException( error );
78
+ enableForm();
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Complete a Payment after the Intent has been authorized.
84
+ *
85
+ * @param {string} intentId Intent ID.
86
+ * @return {Promise} jQuery Promise.
87
+ */
88
+ export function completeAuthorization( intentId ) {
89
+ return apiRequest( 'edds_complete_payment_authorization', {
90
+ intent_id: intentId,
91
+ 'edds-complete-payment-authorization': document.getElementById(
92
+ 'edds-complete-payment-authorization'
93
+ ).value
94
+ } );
95
+ }
96
+
97
+ /**
98
+ * Disables "Add New" form.
99
+ */
100
+ function disableForm() {
101
+ const submit = document.getElementById( 'edds-update-payment-method-submit' );
102
+
103
+ submit.value = submit.dataset.loading;
104
+ submit.disabled = true;
105
+ }
106
+
107
+ /**
108
+ * Enables "Add New" form.
109
+ */
110
+ function enableForm() {
111
+ const submit = document.getElementById( 'edds-update-payment-method-submit' );
112
+
113
+ submit.value = submit.dataset.submit;
114
+ submit.disabled = false;
115
+ }
116
+
117
+ /**
118
+ * Handles a notice (success or error) for authorizing a card.
119
+ *
120
+ * @param {Object} error Error with message to output.
121
+ */
122
+ export function handleException( error ) {
123
+ // Create the new notice.
124
+ const notice = generateNotice(
125
+ ( error && error.message ) ? error.message : edd_stripe_vars.generic_error,
126
+ 'error'
127
+ );
128
+
129
+ const container = document.getElementById( 'edds-update-payment-method-errors' );
130
+
131
+ container.innerHTML = '';
132
+ container.appendChild( notice );
133
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/checkout.js ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global edd_scripts, jQuery */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import { parseDataset } from './';
7
+ import { apiRequest, forEach, outputNotice, clearNotice } from 'utils';
8
+ import { handle as handleIntent } from 'frontend/stripe-elements';
9
+ import { createPayment, completePayment } from 'frontend/payment-forms';
10
+
11
+ let IS_PRB_GATEWAY;
12
+
13
+ /**
14
+ * Disables the "Express Checkout" payment gateway.
15
+ * Switches to the next in the list.
16
+ */
17
+ function hideAndSwitchGateways() {
18
+ IS_PRB_GATEWAY = false;
19
+
20
+ const gatewayRadioEl = document.getElementById( 'edd-gateway-option-stripe-prb' );
21
+
22
+ if ( ! gatewayRadioEl ) {
23
+ return;
24
+ }
25
+
26
+ // Remove radio option.
27
+ gatewayRadioEl.remove();
28
+
29
+ // Recount available gateways and hide selector if needed.
30
+ const gateways = document.querySelectorAll( '.edd-gateway-option' );
31
+ const nextGateway = gateways[0];
32
+ const nextGatewayInput = nextGateway.querySelector( 'input' );
33
+
34
+ // Toggle radio.
35
+ nextGatewayInput.checked = true;
36
+ nextGateway.classList.add( 'edd-gateway-option-selected' );
37
+
38
+ // Load gateway.
39
+ edd_load_gateway( nextGatewayInput.value );
40
+
41
+ // Hide wrapper.
42
+ if ( 1 === gateways.length ) {
43
+ document.getElementById( 'edd_payment_mode_select_wrap' ).remove();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Handles the click event on the Payment Request Button.
49
+ *
50
+ * @param {Event} event Click event.
51
+ */
52
+ function onClick( event ) {
53
+ const errorContainer = document.getElementById( 'edds-prb-error-wrap' );
54
+ const {
55
+ checkout_agree_to_terms,
56
+ checkout_agree_to_privacy,
57
+ } = edd_stripe_vars;
58
+
59
+ const termsEl = document.getElementById( 'edd_agree_to_terms' );
60
+
61
+ if ( termsEl ) {
62
+ if ( false === termsEl.checked ) {
63
+ event.preventDefault();
64
+
65
+ outputNotice( {
66
+ errorMessage: checkout_agree_to_terms,
67
+ errorContainer,
68
+ } );
69
+ } else {
70
+ clearNotice( errorContainer );
71
+ }
72
+ }
73
+
74
+ const privacyEl = document.getElementById( 'edd-agree-to-privacy-policy' );
75
+
76
+ if ( privacyEl && false === privacyEl.checked ) {
77
+ if ( false === privacyEl.checked ) {
78
+ event.preventDefault();
79
+
80
+ outputNotice( {
81
+ errorMessage: checkout_agree_to_privacy,
82
+ errorContainer,
83
+ } );
84
+ } else {
85
+ clearNotice( errorContainer );
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Handles changes to the purchase link form by updating the Payment Request object.
92
+ *
93
+ * @param {PaymentRequest} paymentRequest Payment Request object.
94
+ * @param {HTMLElement} checkoutForm Checkout form.
95
+ */
96
+ async function onChange( paymentRequest, checkoutForm ) {
97
+ try {
98
+ // Calculate and gather price information.
99
+ const {
100
+ 'display-items': displayItems,
101
+ ...paymentRequestData
102
+ } = await apiRequest( 'edds_prb_ajax_get_options' );
103
+
104
+ // Update the Payment Request with server-side data.
105
+ paymentRequest.update( {
106
+ displayItems,
107
+ ...paymentRequestData,
108
+ } )
109
+ } catch ( error ) {
110
+ outputNotice( {
111
+ errorMessage: '',
112
+ errorContainer: document.getElementById( 'edds-prb-checkout' ),
113
+ errorContainerReplace: false,
114
+ } );
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Handles Payment Method errors.
120
+ *
121
+ * @param {Object} event Payment Request event.
122
+ * @param {Object} error Error.
123
+ * @param {HTMLElement} purchaseLink Purchase link form.
124
+ */
125
+ function onPaymentMethodError( event, error, checkoutForm ) {
126
+ // Complete the Payment Request to hide the payment sheet.
127
+ event.complete( 'success' );
128
+
129
+ // Remove spinner.
130
+ const spinner = checkoutForm.querySelector( '.edds-prb-spinner' );
131
+
132
+ if ( spinner ) {
133
+ spinner.parentNode.removeChild( spinner );
134
+ }
135
+
136
+ // Release loading state.
137
+ checkoutForm.classList.remove( 'loading' );
138
+
139
+ // Add notice.
140
+ outputNotice( {
141
+ errorMessage: error.message,
142
+ errorContainer: document.getElementById( 'edds-prb-checkout' ),
143
+ errorContainerReplace: false,
144
+ } );
145
+ }
146
+
147
+ /**
148
+ * Handles recieving a Payment Method from the Payment Request.
149
+ *
150
+ * Adds an item to the cart and processes the Checkout as if we are
151
+ * in normal Checkout context.
152
+ *
153
+ * @param {PaymentRequest} paymentRequest Payment Request object.
154
+ * @param {HTMLElement} checkoutForm Checkout form.
155
+ * @param {Object} event paymentmethod event.
156
+ */
157
+ async function onPaymentMethod( paymentRequest, checkoutForm, event ) {
158
+ try {
159
+ // Retrieve information from the PRB event.
160
+ const { paymentMethod, payerEmail, payerName } = event;
161
+
162
+ // Loading state. Block interaction.
163
+ checkoutForm.classList.add( 'loading' );
164
+
165
+ // Create and append a spinner.
166
+ const spinner = document.createElement( 'span' );
167
+ [ 'edd-loading-ajax', 'edd-loading', 'edds-prb-spinner' ].forEach(
168
+ ( className ) => spinner.classList.add( className )
169
+ );
170
+ checkoutForm.appendChild( spinner );
171
+
172
+ const data = {
173
+ email: payerEmail,
174
+ name: payerName,
175
+ paymentMethod,
176
+ context: 'checkout',
177
+ };
178
+
179
+ // Start the processing.
180
+ //
181
+ // Shims $_POST data to align with the standard Checkout context.
182
+ //
183
+ // This calls `_edds_process_purchase_form()` server-side which
184
+ // creates and returns a PaymentIntent -- just like the first step
185
+ // of a true Checkout.
186
+ const {
187
+ intent,
188
+ intent: {
189
+ client_secret: clientSecret,
190
+ object: intentType,
191
+ },
192
+ nonce: refreshedNonce,
193
+ } = await apiRequest( 'edds_prb_ajax_process_checkout', {
194
+ name: payerName,
195
+ paymentMethod,
196
+ form_data: $( '#edd_purchase_form' ).serialize(),
197
+ } );
198
+
199
+ // Update existing nonce value in DOM form data in case data is retrieved
200
+ // again directly from the DOM.
201
+ $( '#edd-process-checkout-nonce' ).val( refreshedNonce );
202
+
203
+ // Complete the Payment Request to hide the payment sheet.
204
+ event.complete( 'success' );
205
+
206
+ // Confirm the card (SCA, etc).
207
+ const confirmFunc = 'setup_intent' === intentType
208
+ ? 'confirmCardSetup'
209
+ : 'confirmCardPayment';
210
+
211
+ eddStripe[ confirmFunc ](
212
+ clientSecret,
213
+ {
214
+ payment_method: paymentMethod.id
215
+ },
216
+ {
217
+ handleActions: false,
218
+ }
219
+ )
220
+ .then( ( { error } ) => {
221
+ // Something went wrong. Alert the Payment Request.
222
+ if ( error ) {
223
+ throw error;
224
+ }
225
+
226
+ // Confirm again after the Payment Request dialog has been hidden.
227
+ // For cards that do not require further checks this will throw a 400
228
+ // error (in the Stripe API) and a log console error but not throw
229
+ // an actual Exception. This can be ignored.
230
+ //
231
+ // https://github.com/stripe/stripe-payments-demo/issues/133#issuecomment-632593669
232
+ eddStripe[ confirmFunc ]( clientSecret )
233
+ .then( async ( { error } ) => {
234
+ try {
235
+ if ( error ) {
236
+ throw error;
237
+ }
238
+
239
+ // Create an EDD Payment.
240
+ const { intent: updatedIntent, nonce } = await createPayment( intent );
241
+
242
+ // Complete the EDD Payment with the updated PaymentIntent.
243
+ await completePayment( updatedIntent, nonce );
244
+
245
+ // Redirect on completion.
246
+ window.location.replace( edd_stripe_vars.successPageUri );
247
+
248
+ // Something went wrong, output a notice.
249
+ } catch ( error ) {
250
+ onPaymentMethodError( event, error, checkoutForm );
251
+ }
252
+ } );
253
+ } )
254
+ .catch( ( error ) => {
255
+ onPaymentMethodError( event, error, checkoutForm );
256
+ } );
257
+
258
+ // Something went wrong, output a notice.
259
+ } catch ( error ) {
260
+ onPaymentMethodError( event, error, checkoutForm );
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Determines if a full page reload is needed when applying a discount.
266
+ *
267
+ * A 100% discount switches to the "manual" gateway, bypassing the Stripe,
268
+ * however we are still bound to the Payment Request button and a standard
269
+ * Purchase button is not present in the DOM to switch back to.add-new-card
270
+ *
271
+ * @param {Event} e edd_discount_applied event.
272
+ * @param {Object} response Discount application response.
273
+ * @param {int} response.total_plain Cart total after discount.
274
+ */
275
+ function onApplyDiscount( e, { total_plain: total } ) {
276
+ if ( true === IS_PRB_GATEWAY && 0 === total ) {
277
+ window.location.reload();
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Binds purchase link form events.
283
+ *
284
+ * @param {PaymentRequest} paymentRequest Payment Request object.
285
+ * @param {HTMLElement} checkoutForm Checkout form.
286
+ */
287
+ function bindEvents( paymentRequest, checkoutForm ) {
288
+ const $body = jQuery( document.body );
289
+
290
+ // Cart quantities have changed.
291
+ $body.on( 'edd_quantity_updated', () => onChange( paymentRequest, checkoutForm ) );
292
+
293
+ // Discounts have changed.
294
+ $body.on( 'edd_discount_applied', () => onChange( paymentRequest, checkoutForm ) );
295
+ $body.on( 'edd_discount_removed', () => onChange( paymentRequest, checkoutForm ) );
296
+
297
+ // Handle a PaymentMethod when available.
298
+ paymentRequest.on( 'paymentmethod', ( event ) => {
299
+ onPaymentMethod( paymentRequest, checkoutForm, event );
300
+ } );
301
+
302
+ // Handle 100% discounts that require a full gateway refresh.
303
+ $body.on( 'edd_discount_applied', onApplyDiscount );
304
+ }
305
+
306
+ /**
307
+ * Mounts Payment Request buttons (if possible).
308
+ *
309
+ * @param {HTMLElement} element Payment Request button mount wrapper.
310
+ */
311
+ function mount( element ) {
312
+ const { eddStripe } = window;
313
+
314
+ const checkoutForm = document.getElementById( 'edd_checkout_form_wrap' );
315
+
316
+ try {
317
+ // Gather initial data.
318
+ const { 'display-items': displayItems, ...data } = parseDataset( element.dataset );
319
+
320
+ // Create a Payment Request object.
321
+ const paymentRequest = eddStripe.paymentRequest( {
322
+ // Only requested to prompt full address information collection for Apple Pay.
323
+ //
324
+ // On-page name fields are used to update the Easy Digital Downloads Customer.
325
+ // The Payment Request's Payment Method populate the Customer's Billing Details.
326
+ //
327
+ // @link https://stripe.com/docs/js/payment_request/create#stripe_payment_request-options-requestPayerName
328
+ requestPayerName: true,
329
+ displayItems,
330
+ ...data,
331
+ } );
332
+
333
+ // Create a Payment Request button.
334
+ const elements = eddStripe.elements();
335
+ const prButton = elements.create( 'paymentRequestButton', {
336
+ paymentRequest: paymentRequest,
337
+ } );
338
+
339
+ const wrapper = document.querySelector( `#${ element.id }` );
340
+
341
+ // Check the availability of the Payment Request API.
342
+ paymentRequest.canMakePayment()
343
+ // Attempt to mount.
344
+ .then( function( result ) {
345
+ // Hide wrapper if nothing can be mounted.
346
+ if ( ! result ) {
347
+ return hideAndSwitchGateways();
348
+ }
349
+
350
+ // Hide wrapper if using Apple Pay but in Test Mode.
351
+ // The verification for Connected accounts in Test Mode is not reliable.
352
+ if ( true === result.applePay && 'true' === edd_stripe_vars.isTestMode ) {
353
+ return hideAndSwitchGateways();
354
+ }
355
+
356
+ // Mount.
357
+ wrapper.style.display = 'block';
358
+ checkoutForm.classList.add( 'edd-prb--is-active' );
359
+ prButton.mount( `#${ element.id } .edds-prb__button` );
360
+
361
+ // Bind variable pricing/quantity events.
362
+ bindEvents( paymentRequest, checkoutForm );
363
+
364
+ // Handle "Terms of Service" and "Privacy Policy" client validation.
365
+ prButton.on( 'click', onClick );
366
+ } );
367
+ } catch ( error ) {
368
+ outputNotice( {
369
+ errorMessage: error.message,
370
+ errorContainer: document.querySelector( '#edds-prb-checkout' ),
371
+ errorContainerReplace: false,
372
+ } );
373
+ }
374
+ };
375
+
376
+ /**
377
+ * Sets up Payment Request functionality for single purchase links.
378
+ */
379
+ export function setup() {
380
+ if ( '1' !== edd_scripts.is_checkout ) {
381
+ return;
382
+ }
383
+
384
+ /**
385
+ * Mounts PRB when the gateway has loaded.
386
+ *
387
+ * @param {Event} e Gateway loaded event.
388
+ * @param {string} gateway Gateway ID.
389
+ */
390
+ jQuery( document.body ).on( 'edd_gateway_loaded', ( e, gateway ) => {
391
+ if ( 'stripe-prb' !== gateway ) {
392
+ IS_PRB_GATEWAY = false;
393
+
394
+ return;
395
+ }
396
+
397
+ const prbEl = document.querySelector( '.edds-prb.edds-prb--checkout' );
398
+
399
+ if ( ! prbEl ) {
400
+ return;
401
+ }
402
+
403
+ IS_PRB_GATEWAY = true;
404
+
405
+ mount( prbEl );
406
+ } );
407
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/download.js ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global edd_stripe_vars, jQuery */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import { parseDataset } from './';
7
+ import { apiRequest, forEach, outputNotice } from 'utils';
8
+ import { handle as handleIntent } from 'frontend/stripe-elements';
9
+ import { createPayment, completePayment } from 'frontend/payment-forms';
10
+
11
+ /**
12
+ * Finds the Download ID, Price ID, and quantity values for single Download.
13
+ *
14
+ * @param {HTMLElement} purchaseLink Purchase link form.
15
+ * @return {Object}
16
+ */
17
+ function getDownloadData( purchaseLink ) {
18
+ let downloadId, priceId = false, quantity = 1;
19
+
20
+ // Download ID.
21
+ const downloadIdEl = purchaseLink.querySelector( '[name="download_id"]' );
22
+ downloadId = parseFloat( downloadIdEl.value );
23
+
24
+ // Price ID.
25
+ const priceIdEl = purchaseLink.querySelector(
26
+ `.edd_price_option_${downloadId}:checked`
27
+ );
28
+
29
+ if ( priceIdEl ) {
30
+ priceId = parseFloat( priceIdEl.value );
31
+ }
32
+
33
+ // Quantity.
34
+ const quantityEl = purchaseLink.querySelector(
35
+ 'input[name="edd_download_quantity"]'
36
+ );
37
+
38
+ if ( quantityEl ) {
39
+ quantity = parseFloat( quantityEl.value );
40
+ }
41
+
42
+ return {
43
+ downloadId,
44
+ priceId,
45
+ quantity,
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Handles changes to the purchase link form by updating the Payment Request object.
51
+ *
52
+ * @param {PaymentRequest} paymentRequest Payment Request object.
53
+ * @param {HTMLElement} purchaseLink Purchase link form.
54
+ */
55
+ async function onChange( paymentRequest, purchaseLink ) {
56
+ const { downloadId, priceId, quantity } = getDownloadData( purchaseLink );
57
+
58
+ try {
59
+ // Calculate and gather price information.
60
+ const {
61
+ 'display-items': displayItems,
62
+ ...paymentRequestData
63
+ } = await apiRequest( 'edds_prb_ajax_get_options', {
64
+ downloadId,
65
+ priceId,
66
+ quantity,
67
+ } )
68
+
69
+ // Update the Payment Request with server-side data.
70
+ paymentRequest.update( {
71
+ displayItems,
72
+ ...paymentRequestData,
73
+ } )
74
+ } catch ( error ) {
75
+ outputNotice( {
76
+ errorMessage: '',
77
+ errorContainer: purchaseLink,
78
+ errorContainerReplace: false,
79
+ } );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Handles Payment Method errors.
85
+ *
86
+ * @param {Object} event Payment Request event.
87
+ * @param {Object} error Error.
88
+ * @param {HTMLElement} purchaseLink Purchase link form.
89
+ */
90
+ function onPaymentMethodError( event, error, purchaseLink ) {
91
+ // Complete the Payment Request to hide the payment sheet.
92
+ event.complete( 'success' );
93
+
94
+ // Release loading state.
95
+ purchaseLink.classList.remove( 'loading' );
96
+
97
+ outputNotice( {
98
+ errorMessage: error.message,
99
+ errorContainer: purchaseLink,
100
+ errorContainerReplace: false,
101
+ } );
102
+
103
+ // Item is in the cart at this point, so change the Purchase button to Checkout.
104
+ //
105
+ // Using jQuery which will preserve the previously set display value in order
106
+ // to provide better theme compatibility.
107
+ jQuery( 'a.edd-add-to-cart', purchaseLink ).hide();
108
+ jQuery( '.edd_download_quantity_wrapper', purchaseLink ).hide();
109
+ jQuery( '.edd_price_options', purchaseLink ).hide();
110
+ jQuery( '.edd_go_to_checkout', purchaseLink )
111
+ .show().removeAttr( 'data-edd-loading' );
112
+ }
113
+
114
+ /**
115
+ * Handles recieving a Payment Method from the Payment Request.
116
+ *
117
+ * Adds an item to the cart and processes the Checkout as if we are
118
+ * in normal Checkout context.
119
+ *
120
+ * @param {PaymentRequest} paymentRequest Payment Request object.
121
+ * @param {HTMLElement} purchaseLink Purchase link form.
122
+ * @param {Object} event paymentmethod event.
123
+ */
124
+ async function onPaymentMethod( paymentRequest, purchaseLink, event ) {
125
+ try {
126
+ // Retrieve the latest data (price ID, quantity, etc).
127
+ const { downloadId, priceId, quantity } = getDownloadData( purchaseLink );
128
+
129
+ // Retrieve information from the PRB event.
130
+ const { paymentMethod, payerEmail, payerName } = event;
131
+
132
+ // Start the processing.
133
+ //
134
+ // Adds the single Download to the cart and then shims $_POST
135
+ // data to align with the standard Checkout context.
136
+ //
137
+ // This calls `_edds_process_purchase_form()` server-side which
138
+ // creates and returns a PaymentIntent -- just like the first step
139
+ // of a true Checkout.
140
+ const {
141
+ intent,
142
+ intent: {
143
+ client_secret: clientSecret,
144
+ object: intentType,
145
+ }
146
+ } = await apiRequest( 'edds_prb_ajax_process_checkout', {
147
+ email: payerEmail,
148
+ name: payerName,
149
+ paymentMethod,
150
+ downloadId,
151
+ priceId,
152
+ quantity,
153
+ context: 'download',
154
+ } );
155
+
156
+ // Complete the Payment Request to hide the payment sheet.
157
+ event.complete( 'success' );
158
+
159
+ // Loading state. Block interaction.
160
+ purchaseLink.classList.add( 'loading' );
161
+
162
+ // Confirm the card (SCA, etc).
163
+ const confirmFunc = 'setup_intent' === intentType
164
+ ? 'confirmCardSetup'
165
+ : 'confirmCardPayment';
166
+
167
+ eddStripe[ confirmFunc ](
168
+ clientSecret,
169
+ {
170
+ payment_method: paymentMethod.id
171
+ },
172
+ {
173
+ handleActions: false,
174
+ }
175
+ )
176
+ .then( ( { error } ) => {
177
+ // Something went wrong. Alert the Payment Request.
178
+ if ( error ) {
179
+ throw error;
180
+ }
181
+
182
+ // Confirm again after the Payment Request dialog has been hidden.
183
+ // For cards that do not require further checks this will throw a 400
184
+ // error (in the Stripe API) and a log console error but not throw
185
+ // an actual Exception. This can be ignored.
186
+ //
187
+ // https://github.com/stripe/stripe-payments-demo/issues/133#issuecomment-632593669
188
+ eddStripe[ confirmFunc ]( clientSecret )
189
+ .then( async ( { error } ) => {
190
+ try {
191
+ if ( error ) {
192
+ throw error;
193
+ }
194
+
195
+ // Create an EDD Payment.
196
+ const { intent: updatedIntent, nonce } = await createPayment( intent );
197
+
198
+ // Complete the EDD Payment with the updated PaymentIntent.
199
+ await completePayment( updatedIntent, nonce );
200
+
201
+ // Redirect on completion.
202
+ window.location.replace( edd_stripe_vars.successPageUri );
203
+
204
+ // Something went wrong, output a notice.
205
+ } catch ( error ) {
206
+ onPaymentMethodError( event, error, purchaseLink );
207
+ }
208
+ } );
209
+ } )
210
+ .catch( ( error ) => {
211
+ onPaymentMethodError( event, error, purchaseLink );
212
+ } );
213
+
214
+ // Something went wrong, output a notice.
215
+ } catch ( error ) {
216
+ onPaymentMethodError( event, error, purchaseLink );
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Binds purchase link form events.
222
+ *
223
+ * @param {PaymentRequest} paymentRequest Payment Request object.
224
+ * @param {HTMLElement} purchaseLink Purchase link form.
225
+ */
226
+ function bindEvents( paymentRequest, purchaseLink ) {
227
+ // Price option change.
228
+ const priceOptionsEls = purchaseLink.querySelectorAll( '.edd_price_options input[type="radio"]' );
229
+
230
+ forEach( priceOptionsEls, ( priceOption ) => {
231
+ priceOption.addEventListener( 'change', () => onChange( paymentRequest, purchaseLink ) );
232
+ } );
233
+
234
+ // Quantity change.
235
+ const quantityEl = purchaseLink.querySelector( 'input[name="edd_download_quantity"]' );
236
+
237
+ if ( quantityEl ) {
238
+ quantityEl.addEventListener( 'change', () => onChange( paymentRequest, purchaseLink ) );
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Mounts Payment Request buttons (if possible).
244
+ *
245
+ * @param {HTMLElement} element Payment Request button mount wrapper.
246
+ */
247
+ function mount( element ) {
248
+ const { eddStripe } = window;
249
+
250
+ try {
251
+ // Gather initial data.
252
+ const { 'display-items': displayItems, ...data } = parseDataset( element.dataset );
253
+
254
+ // Find the purchase link form.
255
+ const purchaseLink = element.closest(
256
+ '.edd_download_purchase_form'
257
+ );
258
+
259
+ // Create a Payment Request object.
260
+ const paymentRequest = eddStripe.paymentRequest( {
261
+ // Requested to prompt full address information collection for Apple Pay.
262
+ //
263
+ // Collected email address is used to create/update Easy Digital Downloads Customer.
264
+ //
265
+ // @link https://stripe.com/docs/js/payment_request/create#stripe_payment_request-options-requestPayerName
266
+ requestPayerEmail: true,
267
+ displayItems,
268
+ ...data,
269
+ } );
270
+
271
+ // Create a Payment Request button.
272
+ const elements = eddStripe.elements();
273
+ const prButton = elements.create( 'paymentRequestButton', {
274
+ paymentRequest: paymentRequest,
275
+ } );
276
+
277
+ const wrapper = document.querySelector( `#${ element.id }` );
278
+
279
+ // Check the availability of the Payment Request API.
280
+ paymentRequest.canMakePayment()
281
+ // Attempt to mount.
282
+ .then( function( result ) {
283
+ // Hide wrapper if nothing can be mounted.
284
+ if ( ! result ) {
285
+ return;
286
+ }
287
+
288
+ // Hide wrapper if using Apple Pay but in Test Mode.
289
+ // The verification for Connected accounts in Test Mode is not reliable.
290
+ if ( true === result.applePay && 'true' === edd_stripe_vars.isTestMode ) {
291
+ return;
292
+ }
293
+
294
+ // Mount.
295
+ wrapper.style.display = 'block';
296
+ purchaseLink.classList.add( 'edd-prb--is-active' );
297
+ prButton.mount( `#${ element.id } .edds-prb__button` );
298
+
299
+ // Bind variable pricing/quantity events.
300
+ bindEvents( paymentRequest, purchaseLink );
301
+ } );
302
+
303
+ // Handle a PaymentMethod when available.
304
+ paymentRequest.on( 'paymentmethod', ( event ) => {
305
+ onPaymentMethod( paymentRequest, purchaseLink, event );
306
+ } );
307
+ } catch ( error ) {
308
+ outputNotice( {
309
+ errorMessage: error.message,
310
+ errorContainer: purchaseLink,
311
+ errorContainerReplace: false,
312
+ } );
313
+ }
314
+ };
315
+
316
+ /**
317
+ * Sets up Payment Request functionality for single purchase links.
318
+ */
319
+ export function setup() {
320
+ forEach( document.querySelectorAll( '.edds-prb.edds-prb--download' ), mount );
321
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/payment-request/index.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ export { setup as setupDownload } from './download.js';
5
+ export { setup as setupCheckout } from './checkout.js';
6
+
7
+ /**
8
+ * Parses an HTML dataset and decodes JSON values.
9
+ *
10
+ * @param {Object} dataset HTML data attributes.
11
+ * @return {Object}
12
+ */
13
+ export function parseDataset( dataset ) {
14
+ let data = {};
15
+
16
+ for ( const [ key, value ] of Object.entries( dataset ) ) {
17
+ let parsedValue = value;
18
+
19
+ try {
20
+ parsedValue = JSON.parse( value );
21
+ } catch ( e ) {}
22
+
23
+ data[ key ] = parsedValue;
24
+ }
25
+
26
+ return data;
27
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/index.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { paymentMethodActions } from './payment-method-actions.js';
5
+ import { paymentForm } from './payment-form.js';
6
+
7
+ export function setup() {
8
+ if ( ! document.getElementById( 'edd-stripe-manage-cards' ) ) {
9
+ return;
10
+ }
11
+
12
+ paymentMethodActions();
13
+ paymentForm();
14
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/payment-form.js ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global edd_stripe_vars, location */
2
+
3
+ /**
4
+ * Internal dependencies.
5
+ */
6
+ import {
7
+ createPaymentForm as createElementsPaymentForm,
8
+ getBillingDetails
9
+ } from 'frontend/stripe-elements';
10
+
11
+ import {
12
+ apiRequest,
13
+ hasValidInputs,
14
+ triggerBrowserValidation,
15
+ generateNotice,
16
+ forEach
17
+ } from 'utils';
18
+
19
+ /**
20
+ * Binds events and sets up "Add New" form.
21
+ */
22
+ export function paymentForm() {
23
+ // Mount Elements.
24
+ createElementsPaymentForm( window.eddStripe.elements() );
25
+
26
+ // Toggles and submission.
27
+ document.querySelector( '.edd-stripe-add-new' ).addEventListener( 'click', onToggleForm );
28
+ document.getElementById( 'edd-stripe-add-new-cancel' ).addEventListener( 'click', onToggleForm );
29
+ document.getElementById( 'edd-stripe-add-new-card' ).addEventListener( 'submit', onAddPaymentMethod );
30
+
31
+ // Set "Card Name" field as required by HTML5
32
+ document.getElementById( 'card_name' ).required = true;
33
+ }
34
+
35
+ /**
36
+ * Handles toggling of "Add New" form button and submission.
37
+ *
38
+ * @param {Event} e click event.
39
+ */
40
+ function onToggleForm( e ) {
41
+ e.preventDefault();
42
+
43
+ const form = document.getElementById( 'edd-stripe-add-new-card' );
44
+ const formFields = form.querySelector( '.edd-stripe-add-new-card' );
45
+ const isFormVisible = 'block' === formFields.style.display;
46
+
47
+ const cancelButton = form.querySelector( '#edd-stripe-add-new-cancel' );
48
+
49
+ // Trigger a `submit` event.
50
+ if ( isFormVisible && cancelButton !== e.target ) {
51
+ const submitEvent = document.createEvent( 'Event' );
52
+
53
+ submitEvent.initEvent( 'submit', true, true );
54
+ form.dispatchEvent( submitEvent );
55
+ // Toggle form.
56
+ } else {
57
+ formFields.style.display = ! isFormVisible ? 'block' : 'none';
58
+ cancelButton.style.display = ! isFormVisible ? 'inline-block' : 'none';
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Adds a new Source to the Customer.
64
+ *
65
+ * @param {Event} e submit event.
66
+ */
67
+ function onAddPaymentMethod( e ) {
68
+ e.preventDefault();
69
+
70
+ const form = e.target;
71
+
72
+ if ( ! hasValidInputs( form ) ) {
73
+ triggerBrowserValidation( form );
74
+ } else {
75
+ try {
76
+ disableForm();
77
+
78
+ createPaymentMethod( form )
79
+ .then( addPaymentMethod )
80
+ .catch( ( error ) => {
81
+ handleNotice( error );
82
+ enableForm();
83
+ } );
84
+ } catch ( error ) {
85
+ handleNotice( error );
86
+ enableForm();
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Add a PaymentMethod.
93
+ *
94
+ * @param {Object} paymentMethod
95
+ */
96
+ export function addPaymentMethod( paymentMethod ) {
97
+ apiRequest( 'edds_add_payment_method', {
98
+ payment_method_id: paymentMethod.id,
99
+ nonce: document.getElementById( 'edd-stripe-add-card-nonce' ).value,
100
+ } )
101
+ /**
102
+ * Shows an error when the API request fails.
103
+ *
104
+ * @param {Object} response API Request response.
105
+ */
106
+ .fail( handleNotice )
107
+ /**
108
+ * Shows a success notice and automatically redirect.
109
+ *
110
+ * @param {Object} response API Request response.
111
+ */
112
+ .done( function( response ) {
113
+ handleNotice( response, 'success' );
114
+
115
+ // Automatically redirect on success.
116
+ setTimeout( function() {
117
+ location.reload();
118
+ }, 1500 );
119
+ } );
120
+ }
121
+
122
+ /**
123
+ * Creates a PaymentMethod from a card and billing form.
124
+ *
125
+ * @param {HTMLElement} billingForm Form with billing fields to retrieve data from.
126
+ * @return {Object} Stripe PaymentMethod.
127
+ */
128
+ function createPaymentMethod( billingForm ) {
129
+ return window.eddStripe
130
+ // Create a PaymentMethod with stripe.js
131
+ .createPaymentMethod(
132
+ 'card',
133
+ window.eddStripe.cardElement,
134
+ {
135
+ billing_details: getBillingDetails( billingForm ),
136
+ }
137
+ )
138
+ /**
139
+ * Handles PaymentMethod creation response.
140
+ *
141
+ * @param {Object} result PaymentMethod creation result.
142
+ */
143
+ .then( function( result ) {
144
+ if ( result.error ) {
145
+ throw result.error;
146
+ }
147
+
148
+ return result.paymentMethod;
149
+ } );
150
+ }
151
+
152
+ /**
153
+ * Disables "Add New" form.
154
+ */
155
+ function disableForm() {
156
+ const submit = document.querySelector( '.edd-stripe-add-new' );
157
+
158
+ submit.value = submit.dataset.loading;
159
+ submit.disabled = true;
160
+ }
161
+
162
+ /**
163
+ * Enables "Add New" form.
164
+ */
165
+ function enableForm() {
166
+ const submit = document.querySelector( '.edd-stripe-add-new' );
167
+
168
+ submit.value = submit.dataset.submit;
169
+ submit.disabled = false;
170
+ }
171
+
172
+ /**
173
+ * Handles a notice (success or error) for card actions.
174
+ *
175
+ * @param {Object} error Error with message to output.
176
+ * @param {string} type Notice type.
177
+ */
178
+ export function handleNotice( error, type = 'error' ) {
179
+ // Create the new notice.
180
+ const notice = generateNotice(
181
+ ( error && error.message ) ? error.message : edd_stripe_vars.generic_error,
182
+ type
183
+ );
184
+
185
+ // Hide previous notices.
186
+ forEach( document.querySelectorAll( '.edd-stripe-alert' ), function( alert ) {
187
+ alert.remove();
188
+ } );
189
+
190
+ // Show new notice.
191
+ document.querySelector( '.edd-stripe-add-card-actions' )
192
+ .insertBefore( notice, document.querySelector( '.edd-stripe-add-new' ) );
193
+ }
includes/gateways/stripe/assets/js/src/frontend/payment-forms/profile-editor/payment-method-actions.js ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global edd_stripe_vars, location */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import { apiRequest, generateNotice, fieldValueOrNull, forEach } from 'utils'; // eslint-disable-line @wordpress/dependency-group
7
+
8
+ /**
9
+ * Binds events for card actions.
10
+ */
11
+ export function paymentMethodActions() {
12
+ // Update.
13
+ forEach( document.querySelectorAll( '.edd-stripe-update-card' ), function( updateButton ) {
14
+ updateButton.addEventListener( 'click', onToggleUpdateForm );
15
+ } );
16
+
17
+ forEach( document.querySelectorAll( '.edd-stripe-cancel-update' ), function( cancelButton ) {
18
+ cancelButton.addEventListener( 'click', onToggleUpdateForm );
19
+ } );
20
+
21
+ forEach( document.querySelectorAll( '.card-update-form' ), function( updateButton ) {
22
+ updateButton.addEventListener( 'submit', onUpdatePaymentMethod );
23
+ } );
24
+
25
+ // Delete.
26
+ forEach( document.querySelectorAll( '.edd-stripe-delete-card' ), function( deleteButton ) {
27
+ deleteButton.addEventListener( 'click', onDeletePaymentMethod );
28
+ } );
29
+
30
+ // Set Default.
31
+ forEach( document.querySelectorAll( '.edd-stripe-default-card' ), function( setDefaultButton ) {
32
+ setDefaultButton.addEventListener( 'click', onSetDefaultPaymentMethod );
33
+ } );
34
+ }
35
+
36
+ /**
37
+ * Handle a generic Payment Method action (set default, update, delete).
38
+ *
39
+ * @param {string} action Payment action.
40
+ * @param {string} paymentMethodId PaymentMethod ID.
41
+ * @param {null|Object} data Additional AJAX data.
42
+ * @return {Promise} jQuery Promise.
43
+ */
44
+ function paymentMethodAction( action, paymentMethodId, data = {} ) {
45
+ return apiRequest( action, {
46
+ payment_method: paymentMethodId,
47
+ nonce: document.getElementById( 'card_update_nonce_' + paymentMethodId ).value,
48
+ ...data,
49
+ } )
50
+ /**
51
+ * Shows an error when the API request fails.
52
+ *
53
+ * @param {Object} response API Request response.
54
+ */
55
+ .fail( function( response ) {
56
+ handleNotice( paymentMethodId, response );
57
+ } )
58
+ /**
59
+ * Shows a success notice and automatically redirect.
60
+ *
61
+ * @param {Object} response API Request response.
62
+ */
63
+ .done( function( response ) {
64
+ handleNotice( paymentMethodId, response, 'success' );
65
+
66
+ // Automatically redirect on success.
67
+ setTimeout( function() {
68
+ location.reload();
69
+ }, 1500 );
70
+ } );
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @param {Event} e
76
+ */
77
+ function onToggleUpdateForm( e ) {
78
+ e.preventDefault();
79
+
80
+ const source = e.target.dataset.source;
81
+
82
+ const form = document.getElementById( source + '-update-form' );
83
+ const cardActionsEl = document.getElementById( source + '-card-actions' );
84
+ const isFormVisible = 'block' === form.style.display;
85
+
86
+ form.style.display = ! isFormVisible ? 'block' : 'none';
87
+ cardActionsEl.style.display = ! isFormVisible ? 'none' : 'block';
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param {Event} e
93
+ */
94
+ function onUpdatePaymentMethod( e ) {
95
+ e.preventDefault();
96
+
97
+ const form = e.target;
98
+ const data = {};
99
+
100
+ // Gather form data.
101
+ const updateFields = [
102
+ 'address_city',
103
+ 'address_country',
104
+ 'address_line1',
105
+ 'address_line2',
106
+ 'address_zip',
107
+ 'address_state',
108
+ 'exp_month',
109
+ 'exp_year',
110
+ ];
111
+
112
+ updateFields.forEach( function( fieldName ) {
113
+ const field = form.querySelector( '[name="' + fieldName + '"]' );
114
+ data[ fieldName ] = fieldValueOrNull( field );
115
+ } );
116
+
117
+ const submitButton = form.querySelector( 'input[type="submit"]' );
118
+
119
+ submitButton.disabled = true;
120
+ submitButton.value = submitButton.dataset.loading;
121
+
122
+ paymentMethodAction( 'edds_update_payment_method', e.target.dataset.source, data )
123
+ .fail( function( response ) {
124
+ submitButton.disabled = false;
125
+ submitButton.value = submitButton.dataset.submit;
126
+ } );
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @param {Event} e
132
+ */
133
+ function onDeletePaymentMethod( e ) {
134
+ e.preventDefault();
135
+ const loading = '<span class="edd-loading-ajax edd-loading"></span>';
136
+ const linkText = e.target.innerText;
137
+ e.target.innerHTML = loading;
138
+
139
+ paymentMethodAction( 'edds_delete_payment_method', e.target.dataset.source )
140
+ .fail( function( response ) {
141
+ e.target.innerText = linkText;
142
+ } );
143
+ }
144
+
145
+ /**
146
+ *
147
+ * @param {Event} e
148
+ */
149
+ function onSetDefaultPaymentMethod( e ) {
150
+ e.preventDefault();
151
+ const loading = '<span class="edd-loading-ajax edd-loading"></span>';
152
+ const linkText = e.target.innerText;
153
+ e.target.innerHTML = loading;
154
+
155
+ paymentMethodAction( 'edds_set_payment_method_default', e.target.dataset.source )
156
+ .fail( function( response ) {
157
+ e.target.innerText = linkText;
158
+ } );
159
+ }
160
+
161
+ /**
162
+ * Handles a notice (success or error) for card actions.
163
+ *
164
+ * @param {string} paymentMethodId
165
+ * @param {Object} error Error with message to output.
166
+ * @param {string} type Notice type.
167
+ */
168
+ export function handleNotice( paymentMethodId, error, type = 'error' ) {
169
+ // Create the new notice.
170
+ const notice = generateNotice(
171
+ ( error && error.message ) ? error.message : edd_stripe_vars.generic_error,
172
+ type
173
+ );
174
+
175
+ // Hide previous notices.
176
+ forEach( document.querySelectorAll( '.edd-stripe-alert' ), function( alert ) {
177
+ alert.remove();
178
+ } );
179
+
180
+ const item = document.getElementById( paymentMethodId + '_card_item' );
181
+
182
+ // Show new notice.
183
+ item.insertBefore( notice, item.querySelector( '.card-details' ) );
184
+ }
includes/gateways/stripe/assets/js/src/frontend/stripe-elements/index.js ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_stripe_vars */
2
+
3
+ /**
4
+ * Internal dependencies.
5
+ */
6
+ import {
7
+ generateNotice,
8
+ fieldValueOrNull,
9
+ forEach
10
+ } from 'utils'; // eslint-disable-line @wordpress/dependency-group
11
+
12
+ // Intents.
13
+ export * from './intents.js';
14
+
15
+ const DEFAULT_ELEMENTS = {
16
+ 'card': '#edd-stripe-card-element',
17
+ }
18
+
19
+ const DEFAULT_SPLIT_ELEMENTS = {
20
+ 'cardNumber': '#edd-stripe-card-element',
21
+ 'cardExpiry': '#edd-stripe-card-exp-element',
22
+ 'cardCvc': '#edd-stripe-card-cvc-element',
23
+ }
24
+
25
+ let ELEMENTS_OPTIONS = { ...edd_stripe_vars.elementsOptions };
26
+
27
+ /**
28
+ * Mounts Elements based on payment form configuration.
29
+ *
30
+ * Assigns a `cardElement` object to the global `eddStripe` object
31
+ * that can be used to collect card data for tokenization.
32
+ *
33
+ * Integrations (such as Recurring) should pass a configuration of Element
34
+ * types and specific HTML IDs to mount based on settings and form markup
35
+ * to avoid attempting to mount to the same `HTMLElement`.
36
+ *
37
+ * @since 2.8.0
38
+ *
39
+ * @param {Object} elementsInstance Stripe Elements instance.
40
+ * @return {Element} The last Stripe Element to be mounted.
41
+ */
42
+ export function createPaymentForm( elementsInstance, elements ) {
43
+ let mountedEl;
44
+
45
+ if ( ! elements ) {
46
+ elements = ( 'true' === edd_stripe_vars.elementsSplitFields )
47
+ ? DEFAULT_SPLIT_ELEMENTS
48
+ : DEFAULT_ELEMENTS;
49
+ }
50
+
51
+ forEach( elements, ( selector, element ) => {
52
+ mountedEl = createAndMountElement( elementsInstance, selector, element );
53
+ } );
54
+
55
+ // Make at least one Element available globally.
56
+ window.eddStripe.cardElement = mountedEl;
57
+
58
+ return mountedEl;
59
+ }
60
+
61
+ /**
62
+ * Generates and returns an object of styles that can be used to change the appearance
63
+ * of the Stripe Elements iFrame based on existing form styles.
64
+ *
65
+ * Styles that can be applied to the current DOM are injected to the page via
66
+ * a <style> element.
67
+ *
68
+ * @link https://stripe.com/docs/stripe-js/reference#the-elements-object
69
+ *
70
+ * @since 2.8.0
71
+ *
72
+ * @return {Object}
73
+ */
74
+ function generateElementStyles() {
75
+ // Try to mimick existing input styles.
76
+ const cardNameEl = document.querySelector( '.card-name.edd-input' );
77
+
78
+ if ( ! cardNameEl ) {
79
+ return null;
80
+ }
81
+
82
+ const inputStyles = window.getComputedStyle( cardNameEl );
83
+
84
+ // Inject inline CSS instead of applying to the Element so it can be overwritten.
85
+ if ( ! document.getElementById( 'edds-stripe-element-styles' ) ) {
86
+ const styleTag = document.createElement( 'style' );
87
+
88
+ styleTag.innerHTML = `
89
+ .edd-stripe-card-element.StripeElement,
90
+ .edd-stripe-card-exp-element.StripeElement,
91
+ .edd-stripe-card-cvc-element.StripeElement {
92
+ background-color: ${ inputStyles.getPropertyValue( 'background-color' ) };
93
+
94
+ ${
95
+ [ 'top', 'right', 'bottom', 'left' ]
96
+ .map( ( dir ) => (
97
+ `border-${ dir }-color: ${ inputStyles.getPropertyValue( `border-${ dir }-color` ) };
98
+ border-${ dir }-width: ${ inputStyles.getPropertyValue( `border-${ dir }-width` ) };
99
+ border-${ dir }-style: ${ inputStyles.getPropertyValue( `border-${ dir }-style` ) };
100
+ padding-${ dir }: ${ inputStyles.getPropertyValue( `padding-${ dir }` ) };`
101
+ ) )
102
+ .join( '' )
103
+ }
104
+ ${
105
+ [ 'top-right', 'bottom-right', 'bottom-left', 'top-left' ]
106
+ .map( ( dir ) => (
107
+ `border-${ dir }-radius: ${ inputStyles.getPropertyValue( 'border-top-right-radius' ) };`
108
+ ) )
109
+ .join( '' )
110
+ }
111
+ }`
112
+ // Remove whitespace.
113
+ .replace( /\s/g, '' );
114
+
115
+ styleTag.id = 'edds-stripe-element-styles';
116
+
117
+ document.body.appendChild( styleTag );
118
+ }
119
+
120
+ return {
121
+ base: {
122
+ color: inputStyles.getPropertyValue( 'color' ),
123
+ fontFamily: inputStyles.getPropertyValue( 'font-family' ),
124
+ fontSize: inputStyles.getPropertyValue( 'font-size' ),
125
+ fontWeight: inputStyles.getPropertyValue( 'font-weight' ),
126
+ fontSmoothing: inputStyles.getPropertyValue( '-webkit-font-smoothing' ),
127
+ },
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Mounts an Elements Card to the DOM and adds event listeners to submission.
133
+ *
134
+ * @link https://stripe.com/docs/stripe-js/reference#the-elements-object
135
+ *
136
+ * @since 2.8.0
137
+ *
138
+ * @param {Elements} elementsInstance Stripe Elements instance.
139
+ * @param {string} selector Selector to mount Element on.
140
+ * @return {Element|undefined} Stripe Element.
141
+ */
142
+ function createAndMountElement( elementsInstance, selector, element ) {
143
+ const el = document.querySelector( selector );
144
+
145
+ if ( ! el ) {
146
+ return undefined;
147
+ }
148
+
149
+ if ( ! ELEMENTS_OPTIONS.style ) {
150
+ ELEMENTS_OPTIONS.style = generateElementStyles();
151
+ }
152
+
153
+ // Remove hidePostalCode if not using a combined `card` Element.
154
+ if ( 'cardNumber' === element && ELEMENTS_OPTIONS.hasOwnProperty( 'hidePostalCode' ) ) {
155
+ delete ELEMENTS_OPTIONS.hidePostalCode;
156
+ }
157
+
158
+ // Remove unused parameter from options.
159
+ delete ELEMENTS_OPTIONS.i18n;
160
+
161
+ const stripeElement = elementsInstance
162
+ .create( element, ELEMENTS_OPTIONS );
163
+
164
+ stripeElement
165
+ .addEventListener( 'change', ( event ) => {
166
+ handleElementError( event, el );
167
+ handleCardBrandIcon( event );
168
+ } )
169
+ .mount( el );
170
+
171
+ return stripeElement;
172
+ }
173
+
174
+ /**
175
+ * Mounts an Elements Card to the DOM and adds event listeners to submission.
176
+ *
177
+ * @since 2.7.0
178
+ * @since 2.8.0 Deprecated
179
+ *
180
+ * @deprecated Use createPaymentForm() to mount specific elements.
181
+ *
182
+ * @param {Elements} elementsInstance Stripe Elements instance.
183
+ * @param {string} toMount Selector to mount Element on.
184
+ * @return {Element} Stripe Element.
185
+ */
186
+ export function mountCardElement( elementsInstance, toMount = '#edd-stripe-card-element' ) {
187
+ const mountedEl = createPaymentForm( elementsInstance, {
188
+ 'card': toMount,
189
+ } );
190
+
191
+ // Hide split card details fields because any integration that is using this
192
+ // directly has not properly implemented split fields.
193
+ const splitFields = document.getElementById( 'edd-card-details-wrap' );
194
+
195
+ if ( splitFields ) {
196
+ splitFields.style.display = 'none';
197
+ }
198
+
199
+ return mountedEl;
200
+ }
201
+
202
+ /**
203
+ * Handles error output for Elements Card.
204
+ *
205
+ * @param {Event} event Change event on the Card Element.
206
+ * @param {HTMLElement} el HTMLElement the Stripe Element is being mounted on.
207
+ */
208
+ function handleElementError( event, el ) {
209
+ const newCardContainer = el.closest( '.edd-stripe-new-card' );
210
+ const errorsContainer = newCardContainer.querySelector( '#edd-stripe-card-errors' );
211
+
212
+ // Only show one error at once.
213
+ errorsContainer.innerHTML = '';
214
+
215
+ if ( event.error ) {
216
+ const { code, message } = event.error;
217
+ const { elementsOptions: { i18n: { errorMessages } } } = window.edd_stripe_vars;
218
+
219
+ const localizedMessage = errorMessages[ code ] ? errorMessages[ code ] : message;
220
+
221
+ errorsContainer.appendChild( generateNotice( localizedMessage ) );
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Updates card brand icon if using a split form.
227
+ *
228
+ * @since 2.8.0
229
+ *
230
+ * @param {Event} event Change event on the Card Element.
231
+ */
232
+ function handleCardBrandIcon( event ) {
233
+ const {
234
+ brand,
235
+ elementType,
236
+ } = event;
237
+
238
+ if ( 'cardNumber' !== event.elementType ) {
239
+ return;
240
+ }
241
+
242
+ const cardTypeEl = document.querySelector( '.card-type' );
243
+
244
+ if ( 'unknown' === brand ) {
245
+ cardTypeEl.className = 'card-type';
246
+ } else {
247
+ cardTypeEl.classList.add( brand );
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Retrieves (or creates) a PaymentMethod.
253
+ *
254
+ * @param {HTMLElement} billingDetailsForm Form to find data from.
255
+ * @return {Object} PaymentMethod ID and if it previously existed.
256
+ */
257
+ export function getPaymentMethod( billingDetailsForm, cardElement ) {
258
+ const selectedPaymentMethod = $( 'input[name="edd_stripe_existing_card"]:checked' );
259
+
260
+ // An existing PaymentMethod is selected.
261
+ if ( selectedPaymentMethod.length > 0 && 'new' !== selectedPaymentMethod.val() ) {
262
+ return Promise.resolve( {
263
+ id: selectedPaymentMethod.val(),
264
+ exists: true,
265
+ } );
266
+ }
267
+
268
+ // Create a PaymentMethod using the Element data.
269
+ return window.eddStripe
270
+ .createPaymentMethod(
271
+ 'card',
272
+ cardElement,
273
+ {
274
+ billing_details: getBillingDetails( billingDetailsForm ),
275
+ }
276
+ )
277
+ .then( function( result ) {
278
+ if ( result.error ) {
279
+ throw result.error;
280
+ }
281
+
282
+ return {
283
+ id: result.paymentMethod.id,
284
+ exists: false,
285
+ };
286
+ } );
287
+ }
288
+
289
+ /**
290
+ * Retrieves billing details from the Billing Details sections of a form.
291
+ *
292
+ * @param {HTMLElement} form Form to find data from.
293
+ * @return {Object} Billing details
294
+ */
295
+ export function getBillingDetails( form ) {
296
+ return {
297
+ // @todo add Phone
298
+ // @todo add Email
299
+ name: fieldValueOrNull( form.querySelector( '.card-name' ) ),
300
+ address: {
301
+ line1: fieldValueOrNull( form.querySelector( '.card-address' ) ),
302
+ line2: fieldValueOrNull( form.querySelector( '.card-address-2' ) ),
303
+ city: fieldValueOrNull( form.querySelector( '.card-city' ) ),
304
+ state: fieldValueOrNull( form.querySelector( '.card_state' ) ),
305
+ postal_code: fieldValueOrNull( form.querySelector( '.card-zip' ) ),
306
+ country: fieldValueOrNull( form.querySelector( '#billing_country' ) ),
307
+ },
308
+ };
309
+ }
includes/gateways/stripe/assets/js/src/frontend/stripe-elements/intents.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import { apiRequest } from 'utils'; // eslint-disable-line @wordpress/dependency-group
7
+
8
+ /**
9
+ * Retrieve a PaymentIntent.
10
+ *
11
+ * @param {string} intentId Intent ID.
12
+ * @param {string} intentType Intent type. payment_intent or setup_intent.
13
+ * @return {Promise} jQuery Promise.
14
+ */
15
+ export function retrieve( intentId, intentType = 'payment_intent' ) {
16
+ const form = $( window.eddStripe.cardElement._parent ).closest( 'form' );
17
+
18
+ return apiRequest( 'edds_get_intent', {
19
+ intent_id: intentId,
20
+ intent_type: intentType,
21
+ form_data: form.serialize(),
22
+ } )
23
+ // Returns just the PaymentIntent object.
24
+ .then( function( response ) {
25
+ return response.intent;
26
+ } );
27
+ }
28
+
29
+ /**
30
+ * Confirm a PaymentIntent.
31
+ *
32
+ * @param {Object} intent Stripe PaymentIntent or SetupIntent.
33
+ * @return {Promise} jQuery Promise.
34
+ */
35
+ export function confirm( intent ) {
36
+ const form = $( window.eddStripe.cardElement._parent ).closest( 'form' );
37
+
38
+ return apiRequest( 'edds_confirm_intent', {
39
+ intent_id: intent.id,
40
+ intent_type: intent.object,
41
+ form_data: form.serialize(),
42
+ } )
43
+ // Returns just the PaymentIntent object for easier reprocessing.
44
+ .then( function( response ) {
45
+ return response.intent;
46
+ } );
47
+ }
48
+
49
+ /**
50
+ * Capture a PaymentIntent.
51
+ *
52
+ * @param {Object} intent Stripe PaymentIntent or SetupIntent.
53
+ * @param {Object} data Extra data to pass to the intent action.
54
+ * @param {string} refreshedNonce A refreshed nonce that might be needed if the
55
+ * user logged in.
56
+ * @return {Promise} jQuery Promise.
57
+ */
58
+ export function capture( intent, data, refreshedNonce ) {
59
+ const form = $( window.eddStripe.cardElement._parent ).closest( 'form' );
60
+
61
+ if ( 'requires_capture' !== intent.status ) {
62
+ return Promise.resolve( intent );
63
+ }
64
+
65
+ let formData = form.serialize();
66
+
67
+ // Add the refreshed nonce if available.
68
+ if ( refreshedNonce ) {
69
+ formData += `&edd-process-checkout-nonce=${ refreshedNonce }`;
70
+ }
71
+
72
+ return apiRequest( 'edds_capture_intent', {
73
+ intent_id: intent.id,
74
+ intent_type: intent.object,
75
+ form_data: formData,
76
+ ...data,
77
+ } )
78
+ // Returns just the PaymentIntent object for easier reprocessing.
79
+ .then( function( response ) {
80
+ return response.intent;
81
+ } );
82
+ }
83
+
84
+ /**
85
+ * Update a PaymentIntent.
86
+ *
87
+ * @param {Object} intent Stripe PaymentIntent or SetupIntent.
88
+ * @param {Object} data PaymentIntent data to update.
89
+ * @return {Promise} jQuery Promise.
90
+ */
91
+ export function update( intent, data ) {
92
+ const form = $( window.eddStripe.cardElement._parent ).closest( 'form' );
93
+
94
+ return apiRequest( 'edds_update_intent', {
95
+ intent_id: intent.id,
96
+ intent_type: intent.object,
97
+ form_data: form.serialize(),
98
+ ...data,
99
+ } )
100
+ // Returns just the PaymentIntent object for easier reprocessing.
101
+ .then( function( response ) {
102
+ return response.intent;
103
+ } );
104
+ }
105
+
106
+ /**
107
+ * Determines if the PaymentIntent requires further action.
108
+ *
109
+ * @link https://stripe.com/docs/stripe-js/reference
110
+ *
111
+ * @param {Object} intent Stripe PaymentIntent or SetupIntent.
112
+ * @param {Object} data Extra data to pass to the intent action.
113
+ */
114
+ export async function handle( intent, data ) {
115
+ // requires_confirmation
116
+ if ( 'requires_confirmation' === intent.status ) {
117
+ // Attempt to capture.
118
+ const confirmedIntent = await confirm( intent );
119
+
120
+ // Run through again.
121
+ return await handle( confirmedIntent );
122
+ }
123
+
124
+ // requires_payment_method
125
+ // @link https://stripe.com/docs/payments/intents#intent-statuses
126
+ if (
127
+ 'requires_payment_method' === intent.status ||
128
+ 'requires_source' === intent.status
129
+ ) {
130
+ // Attempt to update.
131
+ const updatedIntent = await update( intent, data );
132
+
133
+ // Run through again.
134
+ return await handle( updatedIntent, data );
135
+ }
136
+
137
+ // requires_action
138
+ // @link https://stripe.com/docs/payments/intents#intent-statuses
139
+ if (
140
+ ( 'requires_action' === intent.status && 'use_stripe_sdk' === intent.next_action.type ) ||
141
+ ( 'requires_source_action' === intent.status && 'use_stripe_sdk' === intent.next_action.type )
142
+ ) {
143
+ let cardHandler = 'setup_intent' === intent.object ? 'handleCardSetup' : 'handleCardAction';
144
+
145
+ if ( 'automatic' === intent.confirmation_method ) {
146
+ cardHandler = 'handleCardPayment';
147
+ }
148
+
149
+ return window.eddStripe[ cardHandler ]( intent.client_secret )
150
+ .then( async ( result ) => {
151
+ if ( result.error ) {
152
+ throw result.error;
153
+ }
154
+
155
+ const {
156
+ setupIntent,
157
+ paymentIntent,
158
+ } = result;
159
+
160
+ // Run through again.
161
+ return await handle( setupIntent || paymentIntent );
162
+ } );
163
+ }
164
+
165
+ // Nothing done, return Intent.
166
+ return intent;
167
+ }
includes/gateways/stripe/assets/js/src/utils/api-request.js ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_scripts, ajaxurl */
2
+
3
+ /**
4
+ * Sends an API request to admin-ajax.php
5
+ *
6
+ * @link https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-util.js#L49
7
+ *
8
+ * @param {string} action AJAX action to send to admin-ajax.php
9
+ * @param {Object} data Additional data to send to the action.
10
+ * @return {Promise} jQuery Promise.
11
+ */
12
+ export function apiRequest( action, data ) {
13
+ const options = {
14
+ type: 'POST',
15
+ dataType: 'json',
16
+ xhrFields: {
17
+ withCredentials: true,
18
+ },
19
+ url: ( window.edd_scripts && window.edd_scripts.ajaxurl ) || window.ajaxurl,
20
+ data: {
21
+ action,
22
+ ...data,
23
+ },
24
+ };
25
+
26
+ const deferred = $.Deferred( function( deferred ) {
27
+ // Use with PHP's wp_send_json_success() and wp_send_json_error()
28
+ deferred.jqXHR = $.ajax( options ).done( function( response ) {
29
+ // Treat a response of 1 or 'success' as successful for backward compatibility with existing handlers.
30
+ if ( response === '1' || response === 1 ) {
31
+ response = { success: true };
32
+ }
33
+
34
+ if ( typeof response === 'object' && typeof response.success !== undefined ) {
35
+ deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( this, [ response.data ] );
36
+ } else {
37
+ deferred.rejectWith( this, [ response ] );
38
+ }
39
+ } ).fail( function() {
40
+ deferred.rejectWith( this, arguments );
41
+ } );
42
+ } );
43
+
44
+ const promise = deferred.promise();
45
+ promise.abort = function() {
46
+ deferred.jqXHR.abort();
47
+ return this;
48
+ };
49
+
50
+ return promise;
51
+ }
includes/gateways/stripe/assets/js/src/utils/dom.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies.
3
+ */
4
+ import { forEach } from 'utils'; // eslint-disable-line @wordpress/dependency-group
5
+
6
+ /**
7
+ * forEach implementation that can handle anything.
8
+ */
9
+ export { default as forEach } from 'lodash.foreach';
10
+
11
+ /**
12
+ * DOM ready.
13
+ *
14
+ * Handles multiple callbacks.
15
+ *
16
+ * @param {Function} Callback function to run.
17
+ */
18
+ export function domReady() {
19
+ forEach( arguments, ( callback ) => {
20
+ document.addEventListener( 'DOMContentLoaded', callback );
21
+ } );
22
+ }
23
+
24
+ /**
25
+ * Retrieves all following siblings of an element.
26
+ *
27
+ * @param {HTMLElement} el Starting element.
28
+ * @return {Array} siblings List of sibling elements.
29
+ */
30
+ export function getNextSiblings( el ) {
31
+ const siblings = [];
32
+ let sibling = el.nextElementSibling;
33
+
34
+ while ( sibling ) {
35
+ if ( sibling.nodeType === 1 ) {
36
+ siblings.push( sibling );
37
+ }
38
+
39
+ sibling = sibling.nextElementSibling;
40
+ }
41
+
42
+ return siblings;
43
+ }
includes/gateways/stripe/assets/js/src/utils/form.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies.
3
+ */
4
+ /**
5
+ * External dependencies
6
+ */
7
+ import { forEach } from 'utils';
8
+
9
+ /**
10
+ * Checks is a form passes HTML5 validation.
11
+ *
12
+ * @param {HTMLElement} form Form to trigger validation on.
13
+ * @return {Bool} If the form has valid inputs.
14
+ */
15
+ export function hasValidInputs( form ) {
16
+ let plainInputsValid = true;
17
+
18
+ forEach( form.querySelectorAll( 'input' ), function( input ) {
19
+ if ( input.checkValidity && ! input.checkValidity() ) {
20
+ plainInputsValid = false;
21
+ }
22
+ } );
23
+
24
+ return plainInputsValid;
25
+ }
26
+
27
+ /**
28
+ * Triggers HTML5 browser validation.
29
+ *
30
+ * @param {HTMLElement} form Form to trigger validation on.
31
+ */
32
+ export function triggerBrowserValidation( form ) {
33
+ const submit = document.createElement( 'input' );
34
+ submit.type = 'submit';
35
+ submit.style.display = 'none';
36
+
37
+ form.appendChild( submit );
38
+ submit.click();
39
+ submit.remove();
40
+ }
41
+
42
+ /**
43
+ * Returns an input's value, or null.
44
+ *
45
+ * @param {HTMLElement} field Field to retrieve value from.
46
+ * @return {null|string} Value if the field has a value.
47
+ */
48
+ export function fieldValueOrNull( field ) {
49
+ if ( ! field ) {
50
+ return null;
51
+ }
52
+
53
+ if ( '' === field.value ) {
54
+ return null;
55
+ }
56
+
57
+ return field.value;
58
+ }
includes/gateways/stripe/assets/js/src/utils/index.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ import './polyfill-includes.js';
2
+ import './polyfill-closest.js';
3
+ import './polyfill-object-entries.js';
4
+ import './polyfill-remove.js';
5
+
6
+ export * from './api-request.js';
7
+ export * from './dom.js';
8
+ export * from './notice.js';
9
+ export * from './form.js';
includes/gateways/stripe/assets/js/src/utils/notice.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global $, edd_stripe_vars */
2
+
3
+ /**
4
+ * Generates a notice element.
5
+ *
6
+ * @param {string} message The notice text.
7
+ * @param {string} type The type of notice. error or success. Default error.
8
+ * @return {Element} HTML element containing errors.
9
+ */
10
+ export function generateNotice( message, type = 'error' ) {
11
+ const notice = document.createElement( 'p' );
12
+ notice.classList.add( 'edd-alert' );
13
+ notice.classList.add( 'edd-stripe-alert' );
14
+ notice.style.clear = 'both';
15
+
16
+ if ( 'error' === type ) {
17
+ notice.classList.add( 'edd-alert-error' );
18
+ } else {
19
+ notice.classList.add( 'edd-alert-success' );
20
+ }
21
+
22
+ notice.innerHTML = message || edd_stripe_vars.generic_error;
23
+
24
+ return notice;
25
+ }
26
+
27
+ /**
28
+ * Outputs a notice.
29
+ *
30
+ *
31
+ * @param {object} args Output arguments.
32
+ * @param {string} args.errorType The type of notice. error or success
33
+ * @param {string} args.errorMessasge The notice text.
34
+ * @param {HTMLElement} args.errorContainer HTML element containing errors.
35
+ * @param {bool} args.errorContainerReplace If true Appends the notice before
36
+ * the container.
37
+ */
38
+ export function outputNotice( {
39
+ errorType,
40
+ errorMessage,
41
+ errorContainer,
42
+ errorContainerReplace = true,
43
+ } ) {
44
+ const $errorContainer = $( errorContainer );
45
+ const notice = generateNotice( errorMessage, errorType );
46
+
47
+ if ( true === errorContainerReplace ) {
48
+ $errorContainer.html( notice );
49
+ } else {
50
+ $errorContainer.before( notice );
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Clears a notice.
56
+ *
57
+ * @param {HTMLElement} errorContainer HTML element containing errors.
58
+ */
59
+ export function clearNotice( errorContainer ) {
60
+ $( errorContainer ).html( '' );
61
+ }
includes/gateways/stripe/assets/js/src/utils/polyfill-closest.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Polyfill .closest
2
+ // @link https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
3
+ if ( ! Element.prototype.matches ) {
4
+ Element.prototype.matches =
5
+ Element.prototype.msMatchesSelector ||
6
+ Element.prototype.webkitMatchesSelector;
7
+ }
8
+
9
+ if ( ! Element.prototype.closest ) {
10
+ Element.prototype.closest = function( s ) {
11
+ let el = this;
12
+
13
+ do {
14
+ if ( Element.prototype.matches.call( el, s ) ) return el;
15
+
16
+ el = el.parentElement || el.parentNode;
17
+ } while ( el !== null && el.nodeType === 1 );
18
+
19
+ return null;
20
+ };
21
+ }
includes/gateways/stripe/assets/js/src/utils/polyfill-includes.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Polyfill string.contains
2
+ // @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill
3
+ if ( ! String.prototype.includes ) {
4
+ String.prototype.includes = function( search, start ) {
5
+ 'use strict';
6
+
7
+ if ( typeof start !== 'number' ) {
8
+ start = 0;
9
+ }
10
+
11
+ if ( start + search.length > this.length ) {
12
+ return false;
13
+ } else {
14
+ return this.indexOf( search, start ) !== -1;
15
+ }
16
+ };
17
+ }
includes/gateways/stripe/assets/js/src/utils/polyfill-object-entries.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Polyfill Object.entries
2
+ // @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Polyfill
3
+ if ( ! Object.entries ) {
4
+ Object.entries = function( obj ) {
5
+ var ownProps = Object.keys( obj ),
6
+ i = ownProps.length,
7
+ resArray = new Array( i ); // preallocate the Array
8
+
9
+ while ( i-- ) {
10
+ resArray[ i ] = [ ownProps[ i ], obj[ ownProps[ i ] ] ];
11
+ }
12
+
13
+ return resArray;
14
+ };
15
+ }
includes/gateways/stripe/assets/js/src/utils/polyfill-remove.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Polyfill .remove
2
+ // @link https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove#Polyfill
3
+ ( function ( arr ) {
4
+ arr.forEach( function( item ) {
5
+ if ( item.hasOwnProperty( 'remove' ) ) {
6
+ return;
7
+ }
8
+
9
+ Object.defineProperty( item, 'remove', {
10
+ configurable: true,
11
+ enumerable: true,
12
+ writable: true,
13
+ value: function remove() {
14
+ this.parentNode.removeChild( this );
15
+ }
16
+ } );
17
+ } );
18
+ } )( [ Element.prototype, CharacterData.prototype, DocumentType.prototype ] );
includes/gateways/stripe/edd-stripe.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Easy Digital Downloads - Stripe Payment Gateway
4
+ * Plugin URL: https://easydigitaldownloads.com/downloads/stripe-gateway/
5
+ * Description: Adds a payment gateway for Stripe.com
6
+ * Version: 2.8.2
7
+ * Author: Sandhills Development, LLC
8
+ * Author URI: https://sandhillsdev.com
9
+ * Text Domain: edds
10
+ * Domain Path: languages
11
+ */
12
+
13
+ /**
14
+ * Returns the one true instance of EDD_Stripe
15
+ *
16
+ * @since 2.8.1
17
+ *
18
+ * @return void|\EDD_Stripe EDD_Stripe instance or void if Easy Digital
19
+ * Downloads is not active.
20
+ */
21
+ function edd_stripe_core_bootstrap() {
22
+ // Easy Digital Downloads is not active, do nothing.
23
+ if ( ! function_exists( 'EDD' ) ) {
24
+ return;
25
+ }
26
+
27
+ // Stripe is already active, do nothing.
28
+ if ( class_exists( 'EDD_Stripe' ) ) {
29
+ return;
30
+ }
31
+
32
+ if ( ! defined( 'EDDS_PLUGIN_DIR' ) ) {
33
+ define( 'EDDS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
34
+ }
35
+
36
+ if ( ! defined( 'EDDSTRIPE_PLUGIN_URL' ) ) {
37
+ define( 'EDDSTRIPE_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
38
+ }
39
+
40
+ if ( ! defined( 'EDD_STRIPE_VERSION' ) ) {
41
+ define( 'EDD_STRIPE_VERSION', '2.8.2' );
42
+ }
43
+
44
+ if ( ! defined( 'EDD_STRIPE_API_VERSION' ) ) {
45
+ define( 'EDD_STRIPE_API_VERSION', '2020-03-02' );
46
+ }
47
+
48
+ if ( ! defined( 'EDD_STRIPE_PARTNER_ID' ) ) {
49
+ define( 'EDD_STRIPE_PARTNER_ID', 'pp_partner_DKh7NDe3Y5G8XG' );
50
+ }
51
+
52
+ include_once __DIR__ . '/includes/class-edd-stripe.php';
53
+
54
+ // Initial instantiation.
55
+ EDD_Stripe::instance();
56
+ }
57
+ add_action( 'plugins_loaded', 'edd_stripe_core_bootstrap' );
58
+
includes/gateways/stripe/includes/admin/admin-actions.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Trigger preapproved payment charge
5
+ *
6
+ * @since 1.6
7
+ * @return void
8
+ */
9
+ function edds_process_preapproved_charge() {
10
+
11
+ if( empty( $_GET['nonce'] ) )
12
+ return;
13
+
14
+ if( ! wp_verify_nonce( $_GET['nonce'], 'edds-process-preapproval' ) )
15
+ return;
16
+
17
+ $payment_id = absint( $_GET['payment_id'] );
18
+ $charge = edds_charge_preapproved( $payment_id );
19
+
20
+ if ( $charge ) {
21
+ wp_redirect( esc_url_raw( add_query_arg( array( 'edd-message' => 'preapproval-charged' ), admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ) ); exit;
22
+ } else {
23
+ wp_redirect( esc_url_raw( add_query_arg( array( 'edd-message' => 'preapproval-failed' ), admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ) ); exit;
24
+ }
25
+
26
+ }
27
+ add_action( 'edd_charge_stripe_preapproval', 'edds_process_preapproved_charge' );
28
+
29
+
30
+ /**
31
+ * Cancel a preapproved payment
32
+ *
33
+ * @since 1.6
34
+ * @return void
35
+ */
36
+ function edds_process_preapproved_cancel() {
37
+ global $edd_options;
38
+
39
+ if( empty( $_GET['nonce'] ) )
40
+ return;
41
+
42
+ if( ! wp_verify_nonce( $_GET['nonce'], 'edds-process-preapproval' ) )
43
+ return;
44
+
45
+ $payment_id = absint( $_GET['payment_id'] );
46
+
47
+ if ( empty( $payment_id ) ) {
48
+ return;
49
+ }
50
+
51
+ $payment = edd_get_payment( $payment_id );
52
+ $customer_id = $payment->get_meta( '_edds_stripe_customer_id', true );
53
+ $status = $payment->status;
54
+
55
+ if ( empty( $customer_id ) ) {
56
+ return;
57
+ }
58
+
59
+ if ( 'preapproval' !== $status ) {
60
+ return;
61
+ }
62
+
63
+ edd_insert_payment_note( $payment_id, __( 'Preapproval cancelled', 'easy-digital-downloads' ) );
64
+ edd_update_payment_status( $payment_id, 'cancelled' );
65
+ $payment->delete_meta( '_edds_stripe_customer_id' );
66
+
67
+ wp_redirect( esc_url_raw( add_query_arg( array( 'edd-message' => 'preapproval-cancelled' ), admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ) ); exit;
68
+ }
69
+ add_action( 'edd_cancel_stripe_preapproval', 'edds_process_preapproved_cancel' );
70
+
71
+ /**
72
+ * Admin Messages
73
+ *
74
+ * @since 1.6
75
+ * @return void
76
+ */
77
+ function edds_admin_messages() {
78
+
79
+ if ( isset( $_GET['edd-message'] ) && 'preapproval-charged' == $_GET['edd-message'] ) {
80
+ add_settings_error( 'edds-notices', 'edds-preapproval-charged', __( 'The preapproved payment was successfully charged.', 'easy-digital-downloads' ), 'updated' );
81
+ }
82
+ if ( isset( $_GET['edd-message'] ) && 'preapproval-failed' == $_GET['edd-message'] ) {
83
+ add_settings_error( 'edds-notices', 'edds-preapproval-charged', __( 'The preapproved payment failed to be charged. View order details for further details.', 'easy-digital-downloads' ), 'error' );
84
+ }
85
+ if ( isset( $_GET['edd-message'] ) && 'preapproval-cancelled' == $_GET['edd-message'] ) {
86
+ add_settings_error( 'edds-notices', 'edds-preapproval-cancelled', __( 'The preapproved payment was successfully cancelled.', 'easy-digital-downloads' ), 'updated' );
87
+ }
88
+
89
+ if( isset( $_GET['edd_gateway_connect_error'], $_GET['edd-message'] ) ) {
90
+ /* translators: %1$s Stripe Connect error message. %2$s Retry URL. */
91
+ echo '<div class="notice notice-error"><p>' . sprintf( __( 'There was an error connecting your Stripe account. Message: %1$s. Please <a href="%2$s">try again</a>.', 'easy-digital-downloads' ), esc_html( urldecode( $_GET['edd-message'] ) ), esc_url( admin_url( 'edit.php?post_type=download&page=edd-settings&tab=gateways&section=edd-stripe' ) ) ) . '</p></div>';
92
+ add_filter( 'wp_parse_str', function( $ar ) {
93
+ if( isset( $ar['edd_gateway_connect_error'] ) ) {
94
+ unset( $ar['edd_gateway_connect_error'] );
95
+ }
96
+
97
+ if( isset( $ar['edd-message'] ) ) {
98
+ unset( $ar['edd-message'] );
99
+ }
100
+ return $ar;
101
+ });
102
+ }
103
+
104
+ settings_errors( 'edds-notices' );
105
+ }
106
+ add_action( 'admin_notices', 'edds_admin_messages' );
107
+
108
+ /**
109
+ * Add payment meta item to payments that used an existing card
110
+ *
111
+ * @since 2.6
112
+ * @param $payment_id
113
+ * @return void
114
+ */
115
+ function edds_show_existing_card_meta( $payment_id ) {
116
+ $payment = new EDD_Payment( $payment_id );
117
+ $existing_card = $payment->get_meta( '_edds_used_existing_card' );
118
+ if ( ! empty( $existing_card ) ) {
119
+ ?>
120
+ <div class="edd-order-stripe-existing-card edd-admin-box-inside">
121
+ <p>
122
+ <span class="label"><?php _e( 'Used Existing Card:', 'easy-digital-downloads' ); ?></span>&nbsp;
123
+ <span><?php _e( 'Yes', 'easy-digital-downloads' ); ?></span>
124
+ </p>
125
+ </div>
126
+ <?php
127
+ }
128
+ }
129
+ add_action( 'edd_view_order_details_payment_meta_after', 'edds_show_existing_card_meta', 10, 1 );
130
+
131
+ /**
132
+ * Handles redirects to the Stripe settings page under certain conditions.
133
+ *
134
+ * @since 2.6.14
135
+ */
136
+ function edds_stripe_connect_test_mode_toggle_redirect() {
137
+
138
+ // Check for our marker
139
+ if( ! isset( $_POST['edd-test-mode-toggled'] ) ) {
140
+ return;
141
+ }
142
+
143
+ if( ! current_user_can( 'manage_shop_settings' ) ) {
144
+ return;
145
+ }
146
+
147
+ if ( false === edds_is_gateway_active() ) {
148
+ return;
149
+ }
150
+
151
+ /**
152
+ * Filter the redirect that happens when options are saved and
153
+ * add query args to redirect to the Stripe settings page
154
+ * and to show a notice about connecting with Stripe.
155
+ */
156
+ add_filter( 'wp_redirect', function( $location ) {
157
+ if( false !== strpos( $location, 'page=edd-settings' ) && false !== strpos( $location, 'settings-updated=true' ) ) {
158
+ $location = add_query_arg(
159
+ array(
160
+ 'edd-message' => 'connect-to-stripe',
161
+ ),
162
+ $location
163
+ );
164
+ }
165
+ return $location;
166
+ } );
167
+
168
+ }
169
+ add_action( 'admin_init', 'edds_stripe_connect_test_mode_toggle_redirect' );
includes/gateways/stripe/includes/admin/admin-filters.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Given a Payment ID, extract the transaction ID from Stripe
5
+ *
6
+ * @param string $payment_id Payment ID
7
+ * @return string Transaction ID
8
+ */
9
+ function edds_get_payment_transaction_id( $payment_id ) {
10
+
11
+ $txn_id = '';
12
+ $notes = edd_get_payment_notes( $payment_id );
13
+
14
+ foreach ( $notes as $note ) {
15
+ if ( preg_match( '/^Stripe Charge ID: ([^\s]+)/', $note->comment_content, $match ) ) {
16
+ $txn_id = $match[1];
17
+ continue;
18
+ }
19
+ }
20
+
21
+ return apply_filters( 'edds_set_payment_transaction_id', $txn_id, $payment_id );
22
+ }
23
+ add_filter( 'edd_get_payment_transaction_id-stripe', 'edds_get_payment_transaction_id', 10, 1 );
24
+
25
+ /**
26
+ * Given a transaction ID, generate a link to the Stripe transaction ID details
27
+ *
28
+ * @since 1.9.1
29
+ * @param string $transaction_id The Transaction ID
30
+ * @param int $payment_id The payment ID for this transaction
31
+ * @return string A link to the Stripe transaction details
32
+ */
33
+ function edd_stripe_link_transaction_id( $transaction_id, $payment_id ) {
34
+
35
+ $test = edd_get_payment_meta( $payment_id, '_edd_payment_mode' ) === 'test' ? 'test/' : '';
36
+ $url = '<a href="https://dashboard.stripe.com/' . $test . 'payments/' . $transaction_id . '" target="_blank">' . $transaction_id . '</a>';
37
+
38
+ return apply_filters( 'edd_stripe_link_payment_details_transaction_id', $url );
39
+
40
+ }
41
+ add_filter( 'edd_payment_details_transaction_id-stripe', 'edd_stripe_link_transaction_id', 10, 2 );
42
+
43
+
44
+ /**
45
+ * Display the payment status filters
46
+ *
47
+ * @since 1.6
48
+ * @return array
49
+ */
50
+ function edds_payment_status_filters( $views ) {
51
+ $payment_count = wp_count_posts( 'edd_payment' );
52
+ $preapproval_count = '&nbsp;<span class="count">(' . $payment_count->preapproval . ')</span>';
53
+ $preapproval_pending_count = '&nbsp;<span class="count">(' . $payment_count->preapproval_pending . ')</span>';
54
+ $cancelled_count = '&nbsp;<span class="count">(' . $payment_count->cancelled . ')</span>';
55
+ $current = isset( $_GET['status'] ) ? $_GET['status'] : '';
56
+
57
+ $views['preapproval'] = sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( 'status', 'preapproval', admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ), $current === 'preapproval' ? ' class="current"' : '', __( 'Preapproved', 'easy-digital-downloads' ) . $preapproval_count );
58
+ $views['pending_preapproval'] = sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( 'status', 'preapproval_pending', admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ), $current === 'preapproval_pending' ? ' class="current"' : '', __( 'Preapproval Pending', 'easy-digital-downloads' ) . $preapproval_pending_count );
59
+ $views['cancelled'] = sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( 'status', 'cancelled', admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ), $current === 'cancelled' ? ' class="current"' : '', __( 'Cancelled', 'easy-digital-downloads' ) . $cancelled_count );
60
+
61
+ return $views;
62
+ }
63
+ add_filter( 'edd_payments_table_views', 'edds_payment_status_filters' );
64
+
65
+ /**
66
+ * Show the Process / Cancel buttons for preapproved payments
67
+ *
68
+ * @since 1.6
69
+ * @return string
70
+ */
71
+ function edds_payments_column_data( $value, $payment_id, $column_name ) {
72
+ if ( $column_name == 'status' ) {
73
+ $payment = edd_get_payment( $payment_id );
74
+
75
+ if ( empty( $payment ) ) {
76
+ return $value;
77
+ }
78
+
79
+ $status = $payment->status;
80
+ $customer_id = $payment->get_meta( '_edds_stripe_customer_id', true );
81
+
82
+ if ( empty( $customer_id ) ) {
83
+ return $value;
84
+ }
85
+
86
+ $nonce = wp_create_nonce( 'edds-process-preapproval' );
87
+
88
+ $preapproval_args = array(
89
+ 'payment_id' => $payment_id,
90
+ 'nonce' => $nonce,
91
+ 'edd-action' => 'charge_stripe_preapproval'
92
+ );
93
+
94
+ $cancel_args = array(
95
+ 'preapproval_key' => $customer_id,
96
+ 'payment_id' => $payment_id,
97
+ 'nonce' => $nonce,
98
+ 'edd-action' => 'cancel_stripe_preapproval'
99
+ );
100
+
101
+ $actions = array();
102
+
103
+ $value .= '<p class="row-actions">';
104
+
105
+ if ( in_array( $status, array( 'preapproval', 'preapproval_pending' ), true ) ) {
106
+ $actions[] = '<a href="' . esc_url( add_query_arg( $preapproval_args, admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ) . '">' . __( 'Process', 'easy-digital-downloads' ) . '</a>';
107
+
108
+ if ( 'cancelled' !== $status ) {
109
+ $actions[] = '<span class="delete"><a href="' . esc_url( add_query_arg( $cancel_args, admin_url( 'edit.php?post_type=download&page=edd-payment-history' ) ) ) . '">' . __( 'Cancel', 'easy-digital-downloads' ) . '</a></span>';
110
+ }
111
+ }
112
+
113
+ $value .= implode( ' | ', $actions );
114
+
115
+ $value .= '</p>';
116
+ }
117
+ return $value;
118
+ }
119
+ add_filter( 'edd_payments_table_column', 'edds_payments_column_data', 20, 3 );
includes/gateways/stripe/includes/admin/class-notices-registry.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notices registry.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Implements a registry for notices.
11
+ *
12
+ * @since 2.6.19
13
+ */
14
+ class EDD_Stripe_Admin_Notices_Registry extends EDD_Stripe_Utils_Registry implements EDD_Stripe_Utils_Static_Registry {
15
+
16
+ /**
17
+ * Item error label.
18
+ *
19
+ * @since 2.6.19
20
+ * @var string
21
+ */
22
+ public static $item_error_label = 'admin notice';
23
+
24
+ /**
25
+ * The one true Notices_Registry instance.
26
+ *
27
+ * @since 2.6.19
28
+ * @var EDD_Stripe_Notices_Registry
29
+ */
30
+ public static $instance;
31
+
32
+ /**
33
+ * Retrieves the one true Admin Notices registry instance.
34
+ *
35
+ * @since 2.6.19
36
+ *
37
+ * @return EDD_Stripe_Admin_Notices_Registry Report registry instance.
38
+ */
39
+ public static function instance() {
40
+ if ( is_null( self::$instance ) ) {
41
+ self::$instance = new EDD_Stripe_Admin_Notices_Registry();
42
+ }
43
+
44
+ return self::$instance;
45
+ }
46
+
47
+ /**
48
+ * Initializes the notices registry.
49
+ *
50
+ * @since 2.6.19
51
+ */
52
+ public function init() {
53
+ /**
54
+ * Fires during instantiation of the notices registry.
55
+ *
56
+ * @since 2.6.19
57
+ *
58
+ * @param EDD_Stripe_Notices_Registry $this Registry instance.
59
+ */
60
+ do_action( 'edds_admin_notices_registry_init', $this );
61
+ }
62
+
63
+ /**
64
+ * Adds a new notice.
65
+ *
66
+ * @since 2.6.19
67
+ *
68
+ * @throws Exception
69
+ *
70
+ * @param string $notice_id Unique notice ID.
71
+ * @param array $notice_args {
72
+ * Arguments for adding a new notice.
73
+ *
74
+ * @type string|callable $message Notice message or a callback to retrieve it.
75
+ * @type string $type Notice type. Accepts 'success', 'info', 'warning', 'error'.
76
+ * Default 'success'.
77
+ * @type bool $dismissible Detrmines if the notice can be hidden for the current install.
78
+ * Default true
79
+ * }
80
+ * @return true
81
+ * @throws Exception
82
+ */
83
+ public function add( $notice_id, $notice_args ) {
84
+ $defaults = array(
85
+ 'type' => 'success',
86
+ 'dismissible' => true,
87
+ );
88
+
89
+ $notice_args = array_merge( $defaults, $notice_args );
90
+
91
+ if ( empty( $notice_args['message'] ) ) {
92
+ throw new Exception( esc_html__( 'A message must be specified for each notice.', 'easy-digital-downloads' ) );
93
+ }
94
+
95
+ if ( ! in_array( $notice_args['type'], array( 'success', 'info', 'warning', 'error' ), true ) ) {
96
+ $notice_args['type'] = 'success';
97
+ }
98
+
99
+ return $this->add_item( $notice_id, $notice_args );
100
+ }
101
+
102
+ }
includes/gateways/stripe/includes/admin/class-notices.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manage the notices registry.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Implements logic for displaying notifications.
11
+ *
12
+ * @since 2.6.19
13
+ */
14
+ class EDD_Stripe_Admin_Notices {
15
+
16
+ /**
17
+ * Registry.
18
+ *
19
+ * @since 2.6.19
20
+ * @var EDD_Stripe_Notices_Registry
21
+ */
22
+ protected $registry;
23
+
24
+ /**
25
+ * EDD_Stripe_Admin_Notices
26
+ *
27
+ * @param EDD_Stripe_Notices_Registry $registry Notices registry.
28
+ */
29
+ public function __construct( $registry ) {
30
+ $this->registry = $registry;
31
+ }
32
+
33
+ /**
34
+ * Retrieves the name of the option to manage the status of the notice.
35
+ *
36
+ * @since 2.6.19
37
+ *
38
+ * @param string $notice_id ID of the notice to generate the name with.
39
+ * @return string
40
+ */
41
+ public function get_dismissed_option_name( $notice_id ) {
42
+ // Ensures backwards compatibility for notices dismissed before 2.6.19
43
+ switch ( $notice_id ) {
44
+ case 'stripe-connect':
45
+ $option_name = 'edds_stripe_connect_intro_notice_dismissed';
46
+ break;
47
+ default:
48
+ $option_name = sprintf( 'edds_notice_%1$s_dismissed', $notice_id );
49
+ }
50
+
51
+ return $option_name;
52
+ }
53
+
54
+ /**
55
+ * Dismisses a notice.
56
+ *
57
+ * @since 2.6.19
58
+ *
59
+ * @param string $notice_id ID of the notice to dismiss.
60
+ * @return bool True if notice is successfully dismissed. False on failure.
61
+ */
62
+ public function dismiss( $notice_id ) {
63
+ return update_option( $this->get_dismissed_option_name( $notice_id ), true );
64
+ }
65
+
66
+ /**
67
+ * Restores a notice.
68
+ *
69
+ * @since 2.6.19
70
+ *
71
+ * @param string $notice_id ID of the notice to restore.
72
+ * @return bool True if notice is successfully restored. False on failure.
73
+ */
74
+ public function restore( $notice_id ) {
75
+ return delete_option( $this->get_dismissed_option_name( $notice_id ) );
76
+ }
77
+
78
+ /**
79
+ * Determine if a notice has been permanently dismissed.
80
+ *
81
+ * @since 2.6.19
82
+ *
83
+ * @param int $notice_id Notice ID.
84
+ * @return bool True if the notice is dismissed.
85
+ */
86
+ public function is_dismissed( $notice_id ) {
87
+ return (bool) get_option( $this->get_dismissed_option_name( $notice_id ), false );
88
+ }
89
+
90
+ /**
91
+ * Builds a given notice's output.
92
+ *
93
+ * @since 2.6.19
94
+ *
95
+ * @param string $notice_id ID of the notice to build.
96
+ */
97
+ public function build( $notice_id ) {
98
+ $output = '';
99
+ $notice = $this->registry->get_item( $notice_id );
100
+
101
+ if ( empty( $notice ) ) {
102
+ return $output;
103
+ }
104
+
105
+ if ( true === $this->is_dismissed( $notice_id ) ) {
106
+ return $output;
107
+ }
108
+
109
+ if ( is_callable( $notice['message'] ) ) {
110
+ $message = call_user_func( $notice['message'] );
111
+ } else {
112
+ $message = $notice['message'];
113
+ }
114
+
115
+ $classes = array(
116
+ 'edds-admin-notice',
117
+ 'notice',
118
+ 'notice-' . $notice['type'],
119
+ );
120
+
121
+ if ( $notice['dismissible'] ) {
122
+ $classes[] = 'is-dismissible';
123
+ }
124
+
125
+ $output = sprintf(
126
+ '<div id="edds-%1$s-notice" class="%2$s" data-id="%1$s" data-nonce="%3$s" role="alert">%4$s</div>',
127
+ esc_attr( $notice_id ),
128
+ esc_attr( implode( ' ', $classes ) ),
129
+ wp_create_nonce( "edds-dismiss-{$notice_id}-nonce" ),
130
+ $message
131
+ );
132
+
133
+ return $output;
134
+ }
135
+
136
+ /**
137
+ * Outputs a given notice.
138
+ *
139
+ * @since 2.6.19
140
+ */
141
+ public function output( $notice_id ) {
142
+ echo $this->build( $notice_id );
143
+ }
144
+
145
+ }
includes/gateways/stripe/includes/admin/notices.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bootstraps and outputs notices.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Registers scripts to manage dismissing notices.
11
+ *
12
+ * @since 2.6.19
13
+ */
14
+ function edds_admin_notices_scripts() {
15
+ wp_register_script(
16
+ 'edds-admin-notices',
17
+ EDDSTRIPE_PLUGIN_URL . 'assets/js/build/notices.min.js',
18
+ array(
19
+ 'wp-util',
20
+ 'jquery',
21
+ ),
22
+ EDD_STRIPE_VERSION,
23
+ true
24
+ );
25
+ }
26
+ add_action( 'admin_enqueue_scripts', 'edds_admin_notices_scripts' );
27
+
28
+ /**
29
+ * Registers admin notices.
30
+ *
31
+ * @since 2.6.19
32
+ *
33
+ * @return true|WP_Error True if all notices are registered, otherwise WP_Error.
34
+ */
35
+ function edds_admin_notices_register() {
36
+ $registry = edds_get_registry( 'admin-notices' );
37
+
38
+ if ( ! $registry ) {
39
+ return new WP_Error( 'edds-invalid-registry', esc_html__( 'Unable to locate registry', 'easy-digital-downloads' ) );
40
+ }
41
+
42
+ try {
43
+ // PHP
44
+ $registry->add(
45
+ 'php-requirement',
46
+ array(
47
+ 'message' => function() {
48
+ ob_start();
49
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/notices/php-requirement.php';
50
+ return ob_get_clean();
51
+ },
52
+ 'type' => 'error',
53
+ 'dismissible' => false,
54
+ )
55
+ );
56
+
57
+ // EDD 2.9
58
+ $registry->add(
59
+ 'edd-requirement',
60
+ array(
61
+ 'message' => function() {
62
+ ob_start();
63
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/notices/edd-requirement.php';
64
+ return ob_get_clean();
65
+ },
66
+ 'type' => 'error',
67
+ 'dismissible' => false,
68
+ )
69
+ );
70
+
71
+ // Recurring requirement.
72
+ $registry->add(
73
+ 'edd-recurring-requirement',
74
+ array(
75
+ 'message' => function() {
76
+ ob_start();
77
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/notices/edd-recurring-requirement.php';
78
+ return ob_get_clean();
79
+ },
80
+ 'type' => 'error',
81
+ 'dismissible' => false,
82
+ )
83
+ );
84
+
85
+ // Enable gateway.
86
+ $registry->add(
87
+ 'edd-stripe-core',
88
+ array(
89
+ 'message' => function() {
90
+ ob_start();
91
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/notices/edd-stripe-core.php';
92
+ return ob_get_clean();
93
+ },
94
+ 'type' => 'info',
95
+ 'dismissible' => true,
96
+ )
97
+ );
98
+ } catch ( Exception $e ) {
99
+ return new WP_Error(
100
+ 'edds-invalid-notices-registration',
101
+ esc_html( $e->getMessage() )
102
+ );
103
+ };
104
+
105
+ return true;
106
+ }
107
+ add_action( 'admin_init', 'edds_admin_notices_register' );
108
+
109
+ /**
110
+ * Conditionally prints registered notices.
111
+ *
112
+ * @since 2.6.19
113
+ */
114
+ function edds_admin_notices_print() {
115
+ // Current user needs capability to dismiss notices.
116
+ if ( ! current_user_can( 'manage_options' ) ) {
117
+ return;
118
+ }
119
+
120
+ $registry = edds_get_registry( 'admin-notices' );
121
+
122
+ if ( ! $registry ) {
123
+ return;
124
+ }
125
+
126
+ $notices = new EDD_Stripe_Admin_Notices( $registry );
127
+
128
+ wp_enqueue_script( 'edds-admin-notices' );
129
+
130
+ try {
131
+ // PHP 5.6 requirement.
132
+ if (
133
+ false === edds_has_met_requirements( 'php' ) &&
134
+ true === edds_is_pro()
135
+ ) {
136
+ $notices->output( 'php-requirement' );
137
+ }
138
+
139
+ // EDD 2.9 requirement.
140
+ if ( false === edds_has_met_requirements( 'edd' ) ) {
141
+ $notices->output( 'edd-requirement' );
142
+ }
143
+
144
+ // Recurring 2.10.0 requirement.
145
+ if ( false === edds_has_met_requirements( 'recurring' ) ) {
146
+ $notices->output( 'edd-recurring-requirement' );
147
+ }
148
+
149
+ // Stripe in Core notice.
150
+ if ( false === edds_is_pro() && false === edd_is_gateway_active( 'stripe' ) ) {
151
+ $notices->output( 'edd-stripe-core' );
152
+ }
153
+ } catch( Exception $e ) {}
154
+ }
155
+ add_action( 'admin_notices', 'edds_admin_notices_print' );
156
+
157
+ /**
158
+ * Handles AJAX dismissal of notices.
159
+ *
160
+ * WordPress automatically removes the notices, so the response here is arbitrary.
161
+ * If the notice cannot be dismissed it will simply reappear when the page is refreshed.
162
+ *
163
+ * @since 2.6.19
164
+ */
165
+ function edds_admin_notices_dismiss_ajax() {
166
+ $notice_id = isset( $_REQUEST[ 'id' ] ) ? esc_attr( $_REQUEST['id'] ) : false;
167
+ $nonce = isset( $_REQUEST[ 'nonce' ] ) ? esc_attr( $_REQUEST['nonce'] ) : false;
168
+
169
+ if ( ! ( $notice_id && $nonce ) ) {
170
+ return wp_send_json_error();
171
+ }
172
+
173
+ if ( ! wp_verify_nonce( $nonce, "edds-dismiss-{$notice_id}-nonce" ) ) {
174
+ return wp_send_json_error();
175
+ }
176
+
177
+ $registry = edds_get_registry( 'admin-notices' );
178
+
179
+ if ( ! $registry ) {
180
+ return wp_send_json_error();
181
+ }
182
+
183
+ $notices = new EDD_Stripe_Admin_Notices( $registry );
184
+ $dismissed = $notices->dismiss( $notice_id );
185
+
186
+ if ( true === $dismissed ) {
187
+ return wp_send_json_success();
188
+ } else {
189
+ return wp_send_json_error();
190
+ }
191
+ }
192
+ add_action( 'wp_ajax_edds_admin_notices_dismiss_ajax', 'edds_admin_notices_dismiss_ajax' );
includes/gateways/stripe/includes/admin/notices/edd-recurring-requirement.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notice: edd-recurring-requirement
4
+ *
5
+ * @package EDD_Stripe\Admin\Notices
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+ ?>
16
+
17
+ <p>
18
+ <strong><?php esc_html_e( 'Credit card payments with Stripe are currently disabled.', 'easy-digital-downloads' ); ?></strong>
19
+ </p>
20
+
21
+ <p>
22
+ <?php
23
+ echo wp_kses(
24
+ sprintf(
25
+ /* translators: %1$s Opening strong tag, do not translate. %2$s Closing strong tag, do not translate. %3$s Opening code tag, do not translate. %4$s Closing code tag, do not translate. */
26
+ __( 'To continue accepting credit card payments with Stripe please update %1$sEasy Digital Downloads - Recurring Payments%2$s to version %3$s2.10%4$s or higher.', 'easy-digital-downloads' ),
27
+ '<strong>',
28
+ '</strong>',
29
+ '<code>',
30
+ '</code>'
31
+ ),
32
+ array(
33
+ 'code' => true,
34
+ 'strong' => true,
35
+ )
36
+ );
37
+ ?>
38
+ </p>
includes/gateways/stripe/includes/admin/notices/edd-requirement.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notice: edd-requirement
4
+ *
5
+ * @package EDD_Stripe\Admin\Notices
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+ ?>
16
+
17
+ <p>
18
+ <strong><?php esc_html_e( 'Credit card payments with Stripe are currently disabled.', 'easy-digital-downloads' ); ?></strong>
19
+ </p>
20
+
21
+ <p>
22
+ <?php
23
+ echo wp_kses(
24
+ sprintf(
25
+ /* translators: %1$s Opening strong tag, do not translate. %2$s Closing strong tag, do not translate. %3$s Opening code tag, do not translate. %4$s Closing code tag, do not translate. */
26
+ __( 'To continue accepting credit card payments with Stripe please update %1$sEasy Digital Downloads%2$s to version %3$s2.9%4$s or higher.', 'easy-digital-downloads' ),
27
+ '<strong>',
28
+ '</strong>',
29
+ '<code>',
30
+ '</code>'
31
+ ),
32
+ array(
33
+ 'code' => true,
34
+ 'strong' => true,
35
+ )
36
+ );
37
+ ?>
38
+ </p>
includes/gateways/stripe/includes/admin/notices/edd-stripe-core.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notice: edd-stripe-core
4
+ *
5
+ * @package EDD_Stripe\Admin\Notices
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ $gateways_url = add_query_arg(
17
+ array(
18
+ 'post_type' => 'download',
19
+ 'page' => 'edd-settings',
20
+ 'tab' => 'gateways',
21
+ ),
22
+ admin_url( 'edit.php' )
23
+ );
24
+ ?>
25
+
26
+ <p>
27
+ <strong>
28
+ <?php esc_html_e( 'Accept credit card payments with Stripe', 'easy-digital-downloads' ); ?>
29
+ </strong> <br />
30
+ <?php
31
+ echo wp_kses(
32
+ sprintf(
33
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. %3$s Opening anchor tag, do not translate. %4$s Closing anchor tag, do not translate. */
34
+ __( 'Easy Digital Downloads now lets you accept credit card payments using Stripe, including Apple Pay and Google Pay support. %1$sEnable Stripe%2$s now or %3$slearn more%4$s about the benefits of using Stripe.', 'easy-digital-downloads' ),
35
+ '<a href="' . esc_url( $gateways_url ) . '">',
36
+ '</a>',
37
+ '<a href="https://easydigitaldownloads.com/edd-stripe-integration" target="_blank" rel="noopener noreferrer">',
38
+ '</a>'
39
+ ),
40
+ array(
41
+ 'a' => array(
42
+ 'href' => true,
43
+ 'rel' => true,
44
+ 'target' => true,
45
+ ),
46
+ )
47
+ );
48
+ ?>
49
+ </p>
includes/gateways/stripe/includes/admin/notices/php-requirement.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notice: php-requirement
4
+ *
5
+ * @package EDD_Stripe\Admin\Notices
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ $required_version = 5.6;
17
+ $current_version = phpversion();
18
+ ?>
19
+
20
+ <p>
21
+ <strong><?php esc_html_e( 'Credit card payments with Stripe are currently disabled.', 'easy-digital-downloads' ); ?></strong>
22
+ </p>
23
+
24
+ <p>
25
+ <?php
26
+ echo wp_kses(
27
+ sprintf(
28
+ /* translators: %1$s Future PHP version requirement. %2$s Current PHP version. %3$s Opening strong tag, do not translate. %4$s Closing strong tag, do not translate. %5$s Opening anchor tag, do not translate. %6$s Closing anchor tag, do not translate. */
29
+ __( 'Easy Digital Downloads Stripe Payment Gateway requires PHP version %1$s or higher. It looks like you\'re using version %2$s, which means you will need to %3$supgrade your version of PHP to allow the plugin to continue to function%4$s. Newer versions of PHP are both faster and more secure. The version you\'re using %5$sno longer receives security updates%6$s, which is another great reason to update.', 'easy-digital-downloads' ),
30
+ '<code>' . $required_version . '</code>',
31
+ '<code>' . $current_version . '</code>',
32
+ '<strong>',
33
+ '</strong>',
34
+ '<a href="http://php.net/eol.php" rel="noopener noreferrer" target="_blank">',
35
+ '</a>'
36
+ ),
37
+ array(
38
+ 'code' => true,
39
+ 'strong' => true,
40
+ 'a' => array(
41
+ 'href' => true,
42
+ 'rel' => true,
43
+ 'target' => true,
44
+ )
45
+ )
46
+ );
47
+ ?>
48
+ </p>
49
+
50
+ <p>
51
+ <button id="edds-php-read-more" class="button button-secondary button-small"><?php esc_html_e( 'Read More', 'easy-digital-downloads' ); ?></button>
52
+
53
+ <script>
54
+ document.getElementById( 'edds-php-read-more' ).addEventListener( 'click', function( e ) {
55
+ e.preventDefault();
56
+ var wrapperEl = e.target.parentNode.nextElementSibling;
57
+ wrapperEl.style.display = 'block' === wrapperEl.style.display ? 'none' : 'block';
58
+ } );
59
+ </script>
60
+ </p>
61
+
62
+ <div style="display: none;">
63
+
64
+ <p>
65
+ <strong><?php esc_html_e( 'Which version should I upgrade to?', 'easy-digital-downloads' ); ?></strong>
66
+ </p>
67
+
68
+ <p>
69
+ <?php
70
+ echo wp_kses(
71
+ sprintf(
72
+ /* translators: %1$s Future PHP version requirement. */
73
+ __( 'In order to be compatible with future versions of the Stripe payment gateway, you should update your PHP version to at least %1$s; however we recommend using version <code>7.4</code> if possible to receive the full speed and security benefits provided to more modern and fully supported versions of PHP. However, some plugins may not be fully compatible with PHP <code>7.4</code>, so more testing may be required.', 'easy-digital-downloads' ),
74
+ '<code>' . $required_version . '</code>'
75
+ ),
76
+ array(
77
+ 'code' => true,
78
+ )
79
+ );
80
+ ?>
81
+ </p>
82
+
83
+ <p>
84
+ <strong><?php esc_html_e( 'Need help upgrading? Ask your web host!', 'easy-digital-downloads' ); ?></strong>
85
+ </p>
86
+
87
+ <p>
88
+ <?php
89
+ echo wp_kses(
90
+ sprintf(
91
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
92
+ __( 'Many web hosts can give you instructions on how/where to upgrade your version of PHP through their control panel, or may even be able to do it for you. %1$sRead more about updating PHP%2$s.', 'easy-digital-downloads' ),
93
+ '<a href="https://wordpress.org/support/update-php/" target="_blank" rel="noopener noreferrer">',
94
+ '</a>'
95
+ ),
96
+ array(
97
+ 'a' => array(
98
+ 'href' => true,
99
+ 'rel' => true,
100
+ 'target' => true,
101
+ )
102
+ )
103
+ );
104
+ ?>
105
+ </p>
106
+
107
+ </div>
includes/gateways/stripe/includes/admin/reporting/class-stripe-reports.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reporting: Stripe
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6
7
+ */
8
+
9
+ /**
10
+ * Class EDD_Stripe_Reports
11
+ *
12
+ * Do nothing in 2.8.0
13
+ * The reports have not collected data since 2.7.0 and provide no tangible value.
14
+ *
15
+ * @since 2.6
16
+ * @deprecated 2.8.0
17
+ */
18
+ class EDD_Stripe_Reports {
19
+ public function __construct() {
20
+ _doing_it_wrong(
21
+ __CLASS__,
22
+ __( 'Stripe-specific reports have been removed.', 'easy-digital-downloads' ),
23
+ '2.8.0'
24
+ );
25
+ }
26
+ }
includes/gateways/stripe/includes/admin/settings.php ADDED
@@ -0,0 +1,454 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register our settings section
5
+ *
6
+ * @return array
7
+ */
8
+ function edds_settings_section( $sections ) {
9
+ $sections['edd-stripe'] = __( 'Stripe', 'easy-digital-downloads' );
10
+
11
+ return $sections;
12
+ }
13
+ add_filter( 'edd_settings_sections_gateways', 'edds_settings_section' );
14
+
15
+ /**
16
+ * Register the gateway settings
17
+ *
18
+ * @access public
19
+ * @since 1.0
20
+ * @return array
21
+ */
22
+ function edds_add_settings( $settings ) {
23
+ // Output a placeholder setting to help promote Stripe
24
+ // for non-Pro installs that do not meet PHP requirements.
25
+ if (
26
+ false === edds_has_met_requirements( 'php' ) &&
27
+ false === edds_is_pro()
28
+ ) {
29
+ return array_merge(
30
+ $settings,
31
+ array(
32
+ 'edd-stripe' => array(
33
+ 'edds-requirements-not-met' => array(
34
+ 'id' => 'edds-requirements-not-met',
35
+ 'name' => __( 'Unmet Requirements', 'easy-digital-downloads' ),
36
+ 'type' => 'stripe_requirements_not_met',
37
+ 'class' => 'edds-requirements-not-met',
38
+ ),
39
+ ),
40
+ )
41
+ );
42
+ }
43
+
44
+ $stripe_settings = array(
45
+ 'stripe_connect_button' => array(
46
+ 'id' => 'stripe_connect_button',
47
+ 'name' => __( 'Connection Status', 'easy-digital-downloads' ),
48
+ 'desc' => edds_stripe_connect_setting_field(),
49
+ 'type' => 'descriptive_text',
50
+ 'class' => 'edd-stripe-connect-row',
51
+ ),
52
+ 'test_publishable_key' => array(
53
+ 'id' => 'test_publishable_key',
54
+ 'name' => __( 'Test Publishable Key', 'easy-digital-downloads' ),
55
+ 'desc' => __( 'Enter your test publishable key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
56
+ 'type' => 'text',
57
+ 'size' => 'regular',
58
+ 'class' => 'edd-hidden edds-api-key-row',
59
+ ),
60
+ 'test_secret_key' => array(
61
+ 'id' => 'test_secret_key',
62
+ 'name' => __( 'Test Secret Key', 'easy-digital-downloads' ),
63
+ 'desc' => __( 'Enter your test secret key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
64
+ 'type' => 'text',
65
+ 'size' => 'regular',
66
+ 'class' => 'edd-hidden edds-api-key-row',
67
+ ),
68
+ 'live_publishable_key' => array(
69
+ 'id' => 'live_publishable_key',
70
+ 'name' => __( 'Live Publishable Key', 'easy-digital-downloads' ),
71
+ 'desc' => __( 'Enter your live publishable key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
72
+ 'type' => 'text',
73
+ 'size' => 'regular',
74
+ 'class' => 'edd-hidden edds-api-key-row',
75
+ ),
76
+ 'live_secret_key' => array(
77
+ 'id' => 'live_secret_key',
78
+ 'name' => __( 'Live Secret Key', 'easy-digital-downloads' ),
79
+ 'desc' => __( 'Enter your live secret key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
80
+ 'type' => 'text',
81
+ 'size' => 'regular',
82
+ 'class' => 'edd-hidden edds-api-key-row',
83
+ ),
84
+ 'stripe_webhook_description' => array(
85
+ 'id' => 'stripe_webhook_description',
86
+ 'type' => 'descriptive_text',
87
+ 'name' => __( 'Webhooks', 'easy-digital-downloads' ),
88
+ 'desc' =>
89
+ '<p>' . sprintf(
90
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
91
+ __( 'In order for Stripe to function completely, you must configure your Stripe webhooks. Visit your %1$saccount dashboard%2$s to configure them. Please add a webhook endpoint for the URL below.', 'easy-digital-downloads' ),
92
+ '<a href="https://dashboard.stripe.com/account/webhooks" target="_blank" rel="noopener noreferrer">',
93
+ '</a>'
94
+ ) . '</p>' .
95
+ '<p><strong>' . sprintf(
96
+ /* translators: %s Webhook URL. Do not translate. */
97
+ __( 'Webhook URL: %s', 'easy-digital-downloads' ),
98
+ home_url( 'index.php?edd-listener=stripe' )
99
+ ) . '</strong></p>' .
100
+ '<p>' . sprintf(
101
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
102
+ __( 'See our %1$sdocumentation%2$s for more information.', 'easy-digital-downloads' ),
103
+ '<a href="' . esc_url( edds_documentation_route( 'stripe-webhooks' ) ) . '" target="_blank" rel="noopener noreferrer">',
104
+ '</a>'
105
+ ) . '</p>'
106
+ ),
107
+ 'stripe_billing_fields' => array(
108
+ 'id' => 'stripe_billing_fields',
109
+ 'name' => __( 'Billing Address Display', 'easy-digital-downloads' ),
110
+ 'desc' => __( 'Select how you would like to display the billing address fields on the checkout form. <p><strong>Notes</strong>:</p><p>If taxes are enabled, this option cannot be changed from "Full address".</p><p>If set to "No address fields", you <strong>must</strong> disable "zip code verification" in your Stripe account.</p>', 'easy-digital-downloads' ),
111
+ 'type' => 'select',
112
+ 'options' => array(
113
+ 'full' => __( 'Full address', 'easy-digital-downloads' ),
114
+ 'zip_country' => __( 'Zip / Postal Code and Country only', 'easy-digital-downloads' ),
115
+ 'none' => __( 'No address fields', 'easy-digital-downloads' )
116
+ ),
117
+ 'std' => 'full'
118
+ ),
119
+ 'stripe_statement_descriptor' => array(
120
+ 'id' => 'stripe_statement_descriptor',
121
+ 'name' => __( 'Statement Descriptor', 'easy-digital-downloads' ),
122
+ 'desc' => __( 'Choose how charges will appear on customer\'s credit card statements. <em>Max 22 characters</em>', 'easy-digital-downloads' ),
123
+ 'type' => 'text',
124
+ ),
125
+ 'stripe_use_existing_cards' => array(
126
+ 'id' => 'stripe_use_existing_cards',
127
+ 'name' => __( 'Show Previously Used Cards', 'easy-digital-downloads' ),
128
+ 'desc' => __( 'Provides logged in customers with a list of previous used payment methods for faster checkout.', 'easy-digital-downloads' ),
129
+ 'type' => 'checkbox'
130
+ ),
131
+ 'stripe_allow_prepaid' => array(
132
+ 'id' => 'stripe_allow_prepaid',
133
+ 'name' => __( 'Prepaid Cards', 'easy-digital-downloads' ),
134
+ 'desc' => __( 'Allow prepaid cards as valid payment method.', 'easy-digital-downloads' ),
135
+ 'type' => 'checkbox',
136
+ ),
137
+ 'stripe_split_payment_fields' => array(
138
+ 'id' => 'stripe_split_payment_fields',
139
+ 'name' => __( 'Split Credit Card Form', 'easy-digital-downloads' ),
140
+ 'desc' => __( 'Use separate card number, expiration, and CVC fields in payment forms.', 'easy-digital-downloads' ),
141
+ 'type' => 'checkbox',
142
+ ),
143
+ 'stripe_restrict_assets' => array(
144
+ 'id' => 'stripe_restrict_assets',
145
+ 'name' => ( __( 'Restrict Stripe Assets', 'easy-digital-downloads' ) ),
146
+ 'desc' => ( __( 'Only load Stripe.com hosted assets on pages that specifically utilize Stripe functionality.', 'easy-digital-downloads' ) ),
147
+ 'type' => 'checkbox',
148
+ 'tooltip_title' => __( 'Loading Javascript from Stripe', 'easy-digital-downloads' ),
149
+ 'tooltip_desc' => __( 'Stripe advises that their Javascript library be loaded on every page to take advantage of their advanced fraud detection rules. If you are not concerned with this, enable this setting to only load the Javascript when necessary. Read more about Stripe\'s recommended setup here: https://stripe.com/docs/web/setup.', 'easy-digital-downloads' ),
150
+ )
151
+ );
152
+
153
+ if ( edd_get_option( 'stripe_checkout' ) ) {
154
+ $stripe_settings['stripe_checkout'] = array(
155
+ 'id' => 'stripe_checkout',
156
+ 'name' => '<strong>' . __( 'Stripe Checkout', 'easy-digital-downloads' ) . '</strong>',
157
+ 'type' => 'stripe_checkout_notice',
158
+ 'desc' => wp_kses(
159
+ sprintf(
160
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
161
+ esc_html__( 'To ensure your website is compliant with the new %1$sStrong Customer Authentication%2$s (SCA) regulations, the legacy Stripe Checkout modal is no longer supported. Payments are still securely accepted through through Stripe on the standard Easy Digital Downloads checkout page. "Buy Now" buttons will also automatically redirect to the standard checkout page.', 'easy-digital-downloads' ),
162
+ '<a href="https://stripe.com/en-ca/guides/strong-customer-authentication" target="_blank" rel="noopener noreferrer">',
163
+ '</a>'
164
+ ),
165
+ array(
166
+ 'a' => array(
167
+ 'href' => true,
168
+ 'rel' => true,
169
+ 'target' => true,
170
+ )
171
+ )
172
+ ),
173
+ );
174
+ }
175
+
176
+ if ( version_compare( EDD_VERSION, 2.5, '>=' ) ) {
177
+ $stripe_settings = array( 'edd-stripe' => $stripe_settings );
178
+
179
+ // Set up the new setting field for the Test Mode toggle notice
180
+ $notice = array(
181
+ 'stripe_connect_test_mode_toggle_notice' => array(
182
+ 'id' => 'stripe_connect_test_mode_toggle_notice',
183
+ 'desc' => '<p>' . __( 'You have disabled the "Test Mode" option. Once you have saved your changes, please verify your Stripe connection, especially if you have not previously connected in with "Test Mode" disabled.', 'easy-digital-downloads' ) . '</p>',
184
+ 'type' => 'stripe_connect_notice',
185
+ 'field_class' => 'edd-hidden',
186
+ )
187
+ );
188
+
189
+ // Insert the new setting after the Test Mode checkbox
190
+ $position = array_search( 'test_mode', array_keys( $settings['main'] ), true );
191
+ $settings = array_merge(
192
+ array_slice( $settings['main'], $position, 1, true ),
193
+ $notice,
194
+ $settings
195
+ );
196
+ }
197
+
198
+ return array_merge( $settings, $stripe_settings );
199
+ }
200
+ add_filter( 'edd_settings_gateways', 'edds_add_settings' );
201
+
202
+ /**
203
+ * Force full billing address display when taxes are enabled
204
+ *
205
+ * @access public
206
+ * @since 2.5
207
+ * @return string
208
+ */
209
+ function edd_stripe_sanitize_stripe_billing_fields_save( $value, $key ) {
210
+
211
+ if( 'stripe_billing_fields' == $key && edd_use_taxes() ) {
212
+
213
+ $value = 'full';
214
+
215
+ }
216
+
217
+ return $value;
218
+
219
+ }
220
+ add_filter( 'edd_settings_sanitize_select', 'edd_stripe_sanitize_stripe_billing_fields_save', 10, 2 );
221
+
222
+ /**
223
+ * Filter the output of the statement descriptor option to add a max length to the text string
224
+ *
225
+ * @since 2.6
226
+ * @param $html string The full html for the setting output
227
+ * @param $args array The original arguments passed in to output the html
228
+ *
229
+ * @return string
230
+ */
231
+ function edd_stripe_max_length_statement_descriptor( $html, $args ) {
232
+ if ( 'stripe_statement_descriptor' !== $args['id'] ) {
233
+ return $html;
234
+ }
235
+
236
+ $html = str_replace( '<input type="text"', '<input type="text" maxlength="22"', $html );
237
+
238
+ return $html;
239
+ }
240
+ add_filter( 'edd_after_setting_output', 'edd_stripe_max_length_statement_descriptor', 10, 2 );
241
+
242
+ /**
243
+ * Callback for the stripe_connect_notice field type.
244
+ *
245
+ * @since 2.6.14
246
+ *
247
+ * @param array $args The setting field arguments
248
+ */
249
+ function edd_stripe_connect_notice_callback( $args ) {
250
+
251
+ $value = isset( $args['desc'] ) ? $args['desc'] : '';
252
+
253
+ $class = edd_sanitize_html_class( $args['field_class'] );
254
+
255
+ $html = '<div class="'.$class.'" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']">' . $value . '</div>';
256
+
257
+ echo $html;
258
+ }
259
+
260
+ /**
261
+ * Callback for the stripe_checkout_notice field type.
262
+ *
263
+ * @since 2.7.0
264
+ *
265
+ * @param array $args The setting field arguments
266
+ */
267
+ function edd_stripe_checkout_notice_callback( $args ) {
268
+ $value = isset( $args['desc'] ) ? $args['desc'] : '';
269
+
270
+ $html = '<div class="notice notice-warning inline' . edd_sanitize_html_class( $args['field_class'] ) . '" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']">' . wpautop( $value ) . '</div>';
271
+
272
+ echo $html;
273
+ }
274
+
275
+ /**
276
+ * Outputs information when Stripe has been activated but application requirements are not met.
277
+ *
278
+ * @since 2.8.1
279
+ */
280
+ function edd_stripe_requirements_not_met_callback() {
281
+ $required_version = 5.6;
282
+ $current_version = phpversion();
283
+
284
+ echo '<div class="notice inline notice-warning">';
285
+ echo '<p>';
286
+ echo wp_kses(
287
+ sprintf(
288
+ /* translators: %1$s Future PHP version requirement. %2$s Current PHP version. %3$s Opening strong tag, do not translate. %4$s Closing strong tag, do not translate. */
289
+ __(
290
+ 'Processing credit cards with Stripe requires PHP version %1$s or higher. It looks like you\'re using version %2$s, which means you will need to %3$supgrade your version of PHP before acceping credit card payments%4$s.',
291
+ 'easy-digital-downloads'
292
+ ),
293
+ '<code>' . $required_version . '</code>',
294
+ '<code>' . $current_version . '</code>',
295
+ '<strong>',
296
+ '</strong>'
297
+ ),
298
+ array(
299
+ 'code' => true,
300
+ 'strong' => true
301
+ )
302
+ );
303
+ echo '</p>';
304
+ echo '<p>';
305
+
306
+ echo '<strong>';
307
+ esc_html_e( 'Need help upgrading? Ask your web host!', 'easy-digital-downloads' );
308
+ echo '</strong><br />';
309
+
310
+ echo wp_kses(
311
+ sprintf(
312
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
313
+ __(
314
+ 'Many web hosts can give you instructions on how/where to upgrade your version of PHP through their control panel, or may even be able to do it for you. If you need to change hosts, please see %1$sour hosting recommendations%2$s.',
315
+ 'easy-digital-downloads'
316
+ ),
317
+ '<a href="https://easydigitaldownloads.com/recommended-wordpress-hosting/" target="_blank" rel="noopener noreferrer">',
318
+ '</a>'
319
+ ),
320
+ array(
321
+ 'a' => array(
322
+ 'href' => true,
323
+ 'target' => true,
324
+ 'rel' => true,
325
+ ),
326
+ )
327
+ );
328
+ echo '</p>';
329
+ echo '</div>';
330
+ }
331
+
332
+ /**
333
+ * Adds a notice to the "Payment Gateways" selector if Stripe has been activated but does
334
+ * not meet application requirements.
335
+ *
336
+ * @since 2.8.1
337
+ *
338
+ * @param string $html Setting HTML.
339
+ * @param array $args Setting arguments.
340
+ * @return string
341
+ */
342
+ function edds_payment_gateways_notice( $html, $args ) {
343
+ if ( 'gateways' !== $args['id'] ) {
344
+ return $html;
345
+ }
346
+
347
+ if (
348
+ true === edds_is_pro() ||
349
+ true === edds_has_met_requirements( 'php' )
350
+ ) {
351
+ return $html;
352
+ }
353
+
354
+ $required_version = 5.6;
355
+ $current_version = phpversion();
356
+
357
+ $html .= '<div id="edds-payment-gateways-stripe-unmet-requirements" class="notice inline notice-info"><p>' .
358
+ wp_kses(
359
+ sprintf(
360
+ /* translators: %1$s PHP version requirement. %2$s Current PHP version. %3$s Opening strong tag, do not translate. %4$s Closing strong tag, do not translate. */
361
+ __(
362
+ 'Processing credit cards with Stripe requires PHP version %1$s or higher. It looks like you\'re using version %2$s, which means you will need to %3$supgrade your version of PHP before acceping credit card payments%4$s.',
363
+ 'easy-digital-downloads'
364
+ ),
365
+ '<code>' . $required_version . '</code>',
366
+ '<code>' . $current_version . '</code>',
367
+ '<strong>',
368
+ '</strong>'
369
+ ),
370
+ array(
371
+ 'code' => true,
372
+ 'strong' => true
373
+ )
374
+ ) .
375
+ '</p><p><strong>' .
376
+ esc_html__( 'Need help upgrading? Ask your web host!', 'easy-digital-downloads' ) .
377
+ '</strong><br />' .
378
+ wp_kses(
379
+ sprintf(
380
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
381
+ __(
382
+ 'Many web hosts can give you instructions on how/where to upgrade your version of PHP through their control panel, or may even be able to do it for you. If you need to change hosts, please see %1$sour hosting recommendations%2$s.',
383
+ 'easy-digital-downloads'
384
+ ),
385
+ '<a href="https://easydigitaldownloads.com/recommended-wordpress-hosting/" target="_blank" rel="noopener noreferrer">',
386
+ '</a>'
387
+ ),
388
+ array(
389
+ 'a' => array(
390
+ 'href' => true,
391
+ 'target' => true,
392
+ 'rel' => true,
393
+ ),
394
+ )
395
+ ) . '</p></div>';
396
+
397
+ return $html;
398
+ }
399
+ add_filter( 'edd_after_setting_output', 'edds_payment_gateways_notice', 10, 2 );
400
+
401
+ /**
402
+ * Listens for Stripe Connect completion requests and saves the Stripe API keys.
403
+ *
404
+ * @since 2.6.14
405
+ */
406
+ function edds_process_gateway_connect_completion() {
407
+
408
+ if( ! isset( $_GET['edd_gateway_connect_completion'] ) || 'stripe_connect' !== $_GET['edd_gateway_connect_completion'] || ! isset( $_GET['state'] ) ) {
409
+ return;
410
+ }
411
+
412
+ if( ! current_user_can( 'manage_shop_settings' ) ) {
413
+ return;
414
+ }
415
+
416
+ if( headers_sent() ) {
417
+ return;
418
+ }
419
+
420
+ $edd_credentials_url = add_query_arg( array(
421
+ 'live_mode' => (int) ! edd_is_test_mode(),
422
+ 'state' => sanitize_text_field( $_GET['state'] ),
423
+ 'customer_site_url' => admin_url( 'edit.php?post_type=download' ),
424
+ ), 'https://easydigitaldownloads.com/?edd_gateway_connect_credentials=stripe_connect' );
425
+
426
+ $response = wp_remote_get( esc_url_raw( $edd_credentials_url ) );
427
+
428
+ if( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
429
+ $message = '<p>' . sprintf(
430
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
431
+ __( 'There was an error getting your Stripe credentials. Please %1$stry again%2$s. If you continue to have this problem, please contact support.', 'easy-digital-downloads' ),
432
+ '<a href="' . esc_url( admin_url( 'edit.php?post_type=download&page=edd-settings&tab=gateways&section=edd-stripe' ) ) . '" target="_blank" rel="noopener noreferrer">',
433
+ '</a>'
434
+ ) . '</p>';
435
+ wp_die( $message );
436
+ }
437
+
438
+ $data = json_decode( $response['body'], true );
439
+ $data = $data['data'];
440
+
441
+ if( edd_is_test_mode() ) {
442
+ edd_update_option( 'test_publishable_key', sanitize_text_field( $data['publishable_key'] ) );
443
+ edd_update_option( 'test_secret_key', sanitize_text_field( $data['secret_key'] ) );
444
+ } else {
445
+ edd_update_option( 'live_publishable_key', sanitize_text_field( $data['publishable_key'] ) );
446
+ edd_update_option( 'live_secret_key', sanitize_text_field( $data['secret_key'] ) );
447
+ }
448
+
449
+ edd_update_option( 'stripe_connect_account_id', sanitize_text_field( $data['stripe_user_id'] ) );
450
+ wp_redirect( esc_url_raw( admin_url( 'edit.php?post_type=download&page=edd-settings&tab=gateways&section=edd-stripe' ) ) );
451
+ exit;
452
+
453
+ }
454
+ add_action( 'admin_init', 'edds_process_gateway_connect_completion' );
includes/gateways/stripe/includes/admin/settings/stripe-connect.php ADDED
@@ -0,0 +1,636 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Admin Settings: Stripe Connect
4
+ *
5
+ * @package EDD_Stripe\Admin\Settings\Stripe_Connect
6
+ * @copyright Copyright (c) 2019, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.0
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * Determines if the Stripe API keys can be managed manually.
18
+ *
19
+ * @since 2.8.0
20
+ *
21
+ * @return bool
22
+ */
23
+ function edds_stripe_connect_can_manage_keys() {
24
+ $can_manage = false;
25
+
26
+ /**
27
+ * Filters the ability to override the ability to manually manage
28
+ * Stripe API keys.
29
+ *
30
+ * @since 2.8.0
31
+ *
32
+ * @param bool $can_manage If the current user can manage API keys.
33
+ */
34
+ $can_manage = apply_filters( 'edds_stripe_connect_can_manage_keys', $can_manage );
35
+
36
+ return $can_manage;
37
+ }
38
+
39
+ /**
40
+ * Retrieves a URL to allow Stripe Connect via oAuth.
41
+ *
42
+ * @since 2.8.0
43
+ *
44
+ * @return string
45
+ */
46
+ function edds_stripe_connect_url() {
47
+ $return_url = add_query_arg(
48
+ array(
49
+ 'post_type' => 'download',
50
+ 'page' => 'edd-settings',
51
+ 'tab' => 'gateways',
52
+ 'section' => 'edd-stripe',
53
+ ),
54
+ admin_url( 'edit.php' )
55
+ );
56
+
57
+ /**
58
+ * Filters the URL users are returned to after using Stripe Connect oAuth.
59
+ *
60
+ * @since 2.8.0
61
+ *
62
+ * @param $return_url URL to return to.
63
+ */
64
+ $return_url = apply_filters( 'edds_stripe_connect_return_url', $return_url );
65
+
66
+ $stripe_connect_url = add_query_arg(
67
+ array(
68
+ 'live_mode' => (int) ! edd_is_test_mode(),
69
+ 'state' => str_pad( wp_rand( wp_rand(), PHP_INT_MAX ), 100, wp_rand(), STR_PAD_BOTH ),
70
+ 'customer_site_url' => $return_url,
71
+ ),
72
+ 'https://easydigitaldownloads.com/?edd_gateway_connect_init=stripe_connect'
73
+ );
74
+
75
+ /**
76
+ * Filters the URL to start the Stripe Connect oAuth flow.
77
+ *
78
+ * @since 2.8.0
79
+ *
80
+ * @param $stripe_connect_url URL to oAuth proxy.
81
+ */
82
+ $stripe_connect_url = apply_filters( 'edds_stripe_connect_url', $stripe_connect_url );
83
+
84
+ return $stripe_connect_url;
85
+ }
86
+
87
+ /**
88
+ * Returns a URL to disconnect the current Stripe Connect account ID and keys.
89
+ *
90
+ * @since 2.8.0
91
+ *
92
+ * @return string $stripe_connect_disconnect_url URL to disconnect an account ID and keys.
93
+ */
94
+ function edds_stripe_connect_disconnect_url() {
95
+ $stripe_connect_disconnect_url = add_query_arg(
96
+ array(
97
+ 'post_type' => 'download',
98
+ 'page' => 'edd-settings',
99
+ 'tab' => 'gateways',
100
+ 'section' => 'edd-stripe',
101
+ 'edds-stripe-disconnect' => true,
102
+ ),
103
+ admin_url( 'edit.php' )
104
+ );
105
+
106
+ /**
107
+ * Filters the URL to "disconnect" the Stripe Account.
108
+ *
109
+ * @since 2.8.0
110
+ *
111
+ * @param $stripe_connect_disconnect_url URL to remove the associated Account ID.
112
+ */
113
+ $stripe_connect_disconnect_url = apply_filters(
114
+ 'edds_stripe_connect_disconnect_url',
115
+ $stripe_connect_disconnect_url
116
+ );
117
+
118
+ $stripe_connect_disconnect_url = wp_nonce_url( $stripe_connect_disconnect_url, 'edds-stripe-connect-disconnect' );
119
+
120
+ return $stripe_connect_disconnect_url;
121
+ }
122
+
123
+ /**
124
+ * Removes the associated Stripe Connect Account ID and keys.
125
+ *
126
+ * This does not revoke application permissions from the Stripe Dashboard,
127
+ * it simply allows the "Connect with Stripe" flow to run again for a different account.
128
+ *
129
+ * @since 2.8.0
130
+ */
131
+ function edds_stripe_connect_process_disconnect() {
132
+ // Current user cannot handle this request, bail.
133
+ if ( ! current_user_can( 'manage_options' ) ) {
134
+ return;
135
+ }
136
+
137
+ // No nonce, bail.
138
+ if ( isset( $_GET['_wpnonce'] ) && ! wp_verify_nonce( $_GET['_wpnonce'], 'edds-stripe-connect-disconnect' ) ) {
139
+ return;
140
+ }
141
+
142
+ // Do not need to handle this request, bail.
143
+ if (
144
+ ! ( isset( $_GET['page'] ) && 'edd-settings' === $_GET['page'] ) ||
145
+ ! isset( $_GET['edds-stripe-disconnect'] )
146
+ ) {
147
+ return;
148
+ }
149
+
150
+ $options = array(
151
+ 'stripe_connect_account_id',
152
+ 'test_publishable_key',
153
+ 'test_secret_key',
154
+ 'live_publishable_key',
155
+ 'live_secret_key',
156
+ );
157
+
158
+ foreach ( $options as $option ) {
159
+ edd_delete_option( $option );
160
+ }
161
+
162
+ $redirect = remove_query_arg(
163
+ array(
164
+ '_wpnonce',
165
+ 'edds-stripe-disconnect',
166
+ )
167
+ );
168
+
169
+ return wp_redirect( esc_url_raw( $redirect ) );
170
+ }
171
+ add_action( 'admin_init', 'edds_stripe_connect_process_disconnect' );
172
+
173
+ /**
174
+ * Renders custom HTML for the "Stripe Connect" setting field in the Stripe Payment Gateway
175
+ * settings subtab.
176
+ *
177
+ * Provides a way to use Stripe Connect and manually manage API keys.
178
+ *
179
+ * @since 2.8.0
180
+ */
181
+ function edds_stripe_connect_setting_field() {
182
+ $stripe_connect_url = edds_stripe_connect_url();
183
+ $stripe_disconnect_url = edds_stripe_connect_disconnect_url();
184
+
185
+ $stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
186
+
187
+ $api_key = edd_is_test_mode()
188
+ ? edd_get_option( 'test_publishable_key' )
189
+ : edd_get_option( 'live_publishable_key' );
190
+
191
+ ob_start();
192
+ ?>
193
+
194
+ <?php if ( empty( $api_key ) ) : ?>
195
+
196
+ <a href="<?php echo esc_url( $stripe_connect_url ); ?>" class="edd-stripe-connect">
197
+ <span><?php esc_html_e( 'Connect with Stripe', 'easy-digital-downloads' ); ?></span>
198
+ </a>
199
+
200
+ <p>
201
+ <?php
202
+ /** This filter is documented in includes/admin/settings/stripe-connect.php */
203
+ $show_fee_message = apply_filters( 'edds_show_stripe_connect_fee_message', true );
204
+
205
+ $fee_message = true === $show_fee_message
206
+ ? (
207
+ __(
208
+ 'Connect with Stripe for pay as you go pricing: 2% per-transaction fee + Stripe fees.',
209
+ 'easy-digital-downloads'
210
+ ) . ' '
211
+ )
212
+ : '';
213
+
214
+ echo esc_html( $fee_message );
215
+ echo wp_kses(
216
+ sprintf(
217
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
218
+ __( 'Have questions about connecting with Stripe? See the %1$sdocumentation%2$s.', 'easy-digital-downloads' ),
219
+ '<a href="' . esc_url( edds_documentation_route( 'stripe-connect' ) ) . '" target="_blank" rel="noopener noreferrer">',
220
+ '</a>'
221
+ ),
222
+ array(
223
+ 'a' => array(
224
+ 'href' => true,
225
+ 'target' => true,
226
+ 'rel' => true,
227
+ )
228
+ )
229
+ );
230
+ ?>
231
+ </p>
232
+
233
+ <?php endif; ?>
234
+
235
+ <?php if ( ! empty( $api_key ) ) : ?>
236
+
237
+ <div
238
+ id="edds-stripe-connect-account"
239
+ class="edds-stripe-connect-acount-info notice inline"
240
+ data-account-id="<?php echo esc_attr( $stripe_connect_account_id ); ?>"
241
+ data-nonce="<?php echo wp_create_nonce( 'edds-stripe-connect-account-information' ); ?>"
242
+ >
243
+ <p><span class="spinner is-active"></span>
244
+ <em><?php esc_html_e( 'Retrieving account information...', 'easy-digital-downloads' ); ?></em>
245
+ </div>
246
+ <div id="edds-stripe-disconnect-reconnect">
247
+ </div>
248
+
249
+ <?php endif; ?>
250
+
251
+ <?php if ( true === edds_stripe_connect_can_manage_keys() ) : ?>
252
+
253
+ <div class="edds-api-key-toggle">
254
+ <p>
255
+ <button type="button" class="button-link">
256
+ <small>
257
+ <?php esc_html_e( 'Manage API keys manually', 'easy-digital-downloads' ); ?>
258
+ </small>
259
+ </button>
260
+ </p>
261
+ </div>
262
+
263
+ <div class="edds-api-key-toggle edd-hidden">
264
+ <p>
265
+ <button type="button" class="button-link">
266
+ <small>
267
+ <?php esc_html_e( 'Hide API keys', 'easy-digital-downloads' ); ?>
268
+ </small>
269
+ </button>
270
+ </p>
271
+
272
+ <div class="notice inline notice-warning" style="margin: 15px 0 -10px;">
273
+ <?php echo wpautop( esc_html__( 'Although you can add your API keys manually, we recommend using Stripe Connect: an easier and more secure way of connecting your Stripe account to your website. Stripe Connect prevents issues that can arise when copying and pasting account details from Stripe into your Easy Digital Downloads payment gateway settings. With Stripe Connect you\'ll be ready to go with just a few clicks.', 'easy-digital-downloads' ) ); ?>
274
+ </div>
275
+ </div>
276
+
277
+ <?php endif; ?>
278
+
279
+ <?php
280
+ return ob_get_clean();
281
+ }
282
+
283
+ /**
284
+ * Responds to an AJAX request about the current Stripe connection status.
285
+ *
286
+ * @since 2.8.0
287
+ */
288
+ function edds_stripe_connect_account_info_ajax_response() {
289
+ // Generic error.
290
+ $unknown_error = array(
291
+ 'message' => wpautop( esc_html__( 'Unable to retrieve account information.', 'easy-digital-downloads' ) ),
292
+ );
293
+
294
+ // Current user can't manage settings.
295
+ if ( ! current_user_can( 'manage_shop_settings' ) ) {
296
+ return wp_send_json_error( $unknown_error );
297
+ }
298
+
299
+ // Nonce validation, show error on fail.
300
+ if ( ! wp_verify_nonce( $_POST['nonce'], 'edds-stripe-connect-account-information' ) ) {
301
+ return wp_send_json_error( $unknown_error );
302
+ }
303
+
304
+ $account_id = isset( $_POST['accountId'] )
305
+ ? sanitize_text_field( $_POST['accountId'] )
306
+ : '';
307
+
308
+ $mode = edd_is_test_mode()
309
+ ? _x( 'test', 'Stripe Connect mode', 'easy-digital-downloads' )
310
+ : _x( 'live', 'Stripe Connect mode', 'easy-digital-downloads' );
311
+
312
+ // Provides general reconnect and disconnect action URLs.
313
+ $reconnect_disconnect_actions = wp_kses(
314
+ sprintf(
315
+ /* translators: %1$s Stripe payment mode. %2$s Opening anchor tag for reconnecting to Stripe, do not translate. %3$s Opening anchor tag for disconnecting Stripe, do not translate. %4$s Closing anchor tag, do not translate. */
316
+ __( 'Your Stripe account is connected in %1$s mode. %2$sReconnect in %1$s mode%4$s, or %3$sdisconnect this account%4$s.', 'easy-digital-downloads' ),
317
+ '<strong>' . $mode . '</strong>',
318
+ '<a href="' . esc_url( edds_stripe_connect_url() ) . '" rel="noopener noreferrer">',
319
+ '<a href="' . esc_url( edds_stripe_connect_disconnect_url() ) . '">',
320
+ '</a>'
321
+ ),
322
+ array(
323
+ 'strong' => true,
324
+ 'a' => array(
325
+ 'href' => true,
326
+ 'rel' => true,
327
+ )
328
+ )
329
+ );
330
+
331
+ // If connecting in Test Mode Stripe gives you the opportunity to create a
332
+ // temporary account. Alert the user of the limitations associated with
333
+ // this type of account.
334
+ $dev_account_error = array(
335
+ 'message' => wp_kses(
336
+ wpautop(
337
+ sprintf(
338
+ __(
339
+ /* translators: %1$s Opening bold tag, do not translate. %2$s Closing bold tag, do not translate. */
340
+ 'You are currently connected to a %1$stemporary%2$s Stripe test account, which can only be used for testing purposes. You cannot manage this account in Stripe.',
341
+ 'easy-digital-downloads'
342
+ ),
343
+ '<strong>',
344
+ '</strong>'
345
+ ) . ' ' .
346
+ (
347
+ class_exists( 'EDD_Recurring' )
348
+ ? __(
349
+ 'Webhooks cannot be configured for recurring purchases with this account.',
350
+ 'easy-digital-downloads'
351
+ )
352
+ : ''
353
+ ) . ' ' .
354
+ sprintf(
355
+ __(
356
+ /* translators: %1$s Opening link tag, do not translate. %2$s Closing link tag, do not translate. */
357
+ '%1$sRegister a Stripe account%2$s for full access.',
358
+ 'easy-digital-downloads'
359
+ ),
360
+ '<a href="https://dashboard.stripe.com/register" target="_blank" rel="noopener noreferrer">',
361
+ '</a>'
362
+ ) . ' ' .
363
+ '<br /><br />' .
364
+ sprintf(
365
+ /* translators: %1$s Opening anchor tag for disconnecting Stripe, do not translate. %2$s Closing anchor tag, do not translate. */
366
+ __( '%1$sDisconnect this account%2$s.', 'easy-digital-downloads' ),
367
+ '<a href="' . esc_url( edds_stripe_connect_disconnect_url() ) . '">',
368
+ '</a>'
369
+ )
370
+ ),
371
+ array(
372
+ 'p' => true,
373
+ 'strong' => true,
374
+ 'a' => array(
375
+ 'href' => true,
376
+ 'rel' => true,
377
+ 'target' => true,
378
+ )
379
+ )
380
+ ),
381
+ 'status' => 'warning',
382
+ );
383
+
384
+ // Attempt to show account information from Stripe Connect account.
385
+ if ( ! empty( $account_id ) ) {
386
+ try {
387
+ $account = edds_api_request( 'Account', 'retrieve', $account_id );
388
+
389
+ // Find the email.
390
+ $email = isset( $account->email )
391
+ ? esc_html( $account->email )
392
+ : '';
393
+
394
+ // Find a Display Name.
395
+ $display_name = isset( $account->display_name )
396
+ ? esc_html( $account->display_name )
397
+ : '';
398
+
399
+ if (
400
+ empty( $display_name ) &&
401
+ isset( $account->settings ) &&
402
+ isset( $account->settings->dashboard ) &&
403
+ isset( $account->settings->dashboard->display_name )
404
+ ) {
405
+ $display_name = esc_html( $account->settings->dashboard->display_name );
406
+ }
407
+
408
+ // Unsaved/unactivated accounts do not have an email or display name.
409
+ if ( empty( $email ) && empty( $display_name ) ) {
410
+ return wp_send_json_success( $dev_account_error );
411
+ }
412
+
413
+ if ( ! empty( $display_name ) ) {
414
+ $display_name = '<strong>' . $display_name . '</strong><br/ >';
415
+ }
416
+
417
+ if ( ! empty( $email ) ) {
418
+ $email = $email . ' &mdash; ';
419
+ }
420
+
421
+ /**
422
+ * Filters if the Stripe Connect fee messaging should show.
423
+ *
424
+ * @since 2.8.1
425
+ *
426
+ * @param bool $show_fee_message Show fee message, or not.
427
+ */
428
+ $show_fee_message = apply_filters( 'edds_show_stripe_connect_fee_message', true );
429
+
430
+ $fee_message = true === $show_fee_message
431
+ ? wpautop(
432
+ esc_html__(
433
+ 'Pay as you go pricing: 2% per-transaction fee + Stripe fees.',
434
+ 'easy-digital-downloads'
435
+ )
436
+ )
437
+ : '';
438
+
439
+ // Return a message with name, email, and reconnect/disconnect actions.
440
+ return wp_send_json_success(
441
+ array(
442
+ 'message' => wpautop(
443
+ // $display_name is already escaped
444
+ $display_name . esc_html( $email ) . esc_html__( 'Administrator (Owner)', 'easy-digital-downloads' ) . $fee_message
445
+ ),
446
+ 'actions' => $reconnect_disconnect_actions,
447
+ 'status' => 'success',
448
+ )
449
+ );
450
+ } catch ( \Stripe\Exception\AuthenticationException $e ) {
451
+ // API keys were changed after using Stripe Connect.
452
+ return wp_send_json_error(
453
+ array(
454
+ 'message' => wpautop(
455
+ esc_html__( 'The API keys provided do not match the Stripe Connect account associated with this installation. If you have manually modified these values after connecting your account, please reconnect below or update your API keys.', 'easy-digital-downloads' ) .
456
+ '<br /><br />' .
457
+ $reconnect_disconnect_actions
458
+ ),
459
+ )
460
+ );
461
+ } catch ( \EDD_Stripe_Utils_Exceptions_Stripe_API_Unmet_Requirements $e ) {
462
+ return wp_send_json_error(
463
+ array(
464
+ 'message' => wpautop(
465
+ $e->getMessage()
466
+ ),
467
+ )
468
+ );
469
+ } catch ( \Exception $e ) {
470
+ // General error.
471
+ return wp_send_json_error( $unknown_error );
472
+ }
473
+ // Manual API key management.
474
+ } else {
475
+ $connect_button = sprintf(
476
+ '<a href="%s" class="edd-stripe-connect"><span>%s</span></a>',
477
+ esc_url( edds_stripe_connect_url() ),
478
+ esc_html__( 'Connect with Stripe', 'easy-digital-downloads' )
479
+ );
480
+
481
+ $connect = esc_html__( 'It is highly recommended to Connect with Stripe for easier setup and improved security.', 'easy-digital-downloads' );
482
+
483
+ // See if the keys are valid.
484
+ try {
485
+ // While we could show similar account information, leave it blank to help
486
+ // push people towards Stripe Connect.
487
+ $account = edds_api_request( 'Account', 'retrieve' );
488
+
489
+ return wp_send_json_success(
490
+ array(
491
+ 'message' => wpautop(
492
+ sprintf(
493
+ /* translators: %1$s Stripe payment mode.*/
494
+ __( 'Your manually managed %1$s mode API keys are valid.', 'easy-digital-downloads' ),
495
+ '<strong>' . $mode . '</strong>'
496
+ ) .
497
+ '<br /><br />' .
498
+ $connect . '<br /><br />' . $connect_button
499
+ ),
500
+ 'status' => 'success',
501
+ )
502
+ );
503
+ // Show invalid keys.
504
+ } catch ( \Exception $e ) {
505
+ return wp_send_json_error(
506
+ array(
507
+ 'message' => wpautop(
508
+ sprintf(
509
+ /* translators: %1$s Stripe payment mode.*/
510
+ __( 'Your manually managed %1$s mode API keys are invalid.', 'easy-digital-downloads' ),
511
+ '<strong>' . $mode . '</strong>'
512
+ ) .
513
+ '<br /><br />' .
514
+ $connect . '<br /><br />' . $connect_button
515
+ ),
516
+ )
517
+ );
518
+ }
519
+ }
520
+ }
521
+ add_action( 'wp_ajax_edds_stripe_connect_account_info', 'edds_stripe_connect_account_info_ajax_response' );
522
+
523
+ /**
524
+ * Registers admin notices for Stripe Connect.
525
+ *
526
+ * @since 2.8.0
527
+ *
528
+ * @return true|WP_Error True if all notices are registered, otherwise WP_Error.
529
+ */
530
+ function edds_stripe_connect_admin_notices_register() {
531
+ $registry = edds_get_registry( 'admin-notices' );
532
+
533
+ if ( ! $registry ) {
534
+ return new WP_Error( 'edds-invalid-registry', esc_html__( 'Unable to locate registry', 'easy-digital-downloads' ) );
535
+ }
536
+
537
+ $connect_button = sprintf(
538
+ '<a href="%s" class="edd-stripe-connect"><span>%s</span></a>',
539
+ esc_url( edds_stripe_connect_url() ),
540
+ esc_html__( 'Connect with Stripe', 'easy-digital-downloads' )
541
+ );
542
+
543
+ try {
544
+ // Stripe Connect.
545
+ $registry->add(
546
+ 'stripe-connect',
547
+ array(
548
+ 'message' => sprintf(
549
+ '<p>%s</p><p>%s</p>',
550
+ esc_html__( 'Start accepting payments with Stripe by connecting your account. Stripe Connect helps ensure easier setup and improved security.', 'easy-digital-downloads' ),
551
+ $connect_button
552
+ ),
553
+ 'type' => 'info',
554
+ 'dismissible' => true,
555
+ )
556
+ );
557
+
558
+ // Stripe Connect reconnect.
559
+ /** translators: %s Test mode status. */
560
+ $test_mode_status = edd_is_test_mode()
561
+ ? _x( 'enabled', 'gateway test mode status', 'easy-digital-downloads' )
562
+ : _x( 'disabled', 'gateway test mode status', 'easy-digital-downloads' );
563
+
564
+ $registry->add(
565
+ 'stripe-connect-reconnect',
566
+ array(
567
+ 'message' => sprintf(
568
+ '<p>%s</p><p>%s</p>',
569
+ sprintf(
570
+ /* translators: %s Test mode status. Enabled or disabled. */
571
+ __( '"Test Mode" has been %s. Please verify your Stripe connection status.', 'easy-digital-downloads' ),
572
+ $test_mode_status
573
+ ),
574
+ $connect_button
575
+ ),
576
+ 'type' => 'warning',
577
+ 'dismissible' => true,
578
+ )
579
+ );
580
+ } catch( Exception $e ) {
581
+ return new WP_Error( 'edds-invalid-notices-registration', esc_html__( $e->getMessage() ) );
582
+ };
583
+
584
+ return true;
585
+ }
586
+ add_action( 'admin_init', 'edds_stripe_connect_admin_notices_register' );
587
+
588
+ /**
589
+ * Conditionally prints registered notices.
590
+ *
591
+ * @since 2.6.19
592
+ */
593
+ function edds_stripe_connect_admin_notices_print() {
594
+ // Current user needs capability to dismiss notices.
595
+ if ( ! current_user_can( 'manage_options' ) ) {
596
+ return;
597
+ }
598
+
599
+ $registry = edds_get_registry( 'admin-notices' );
600
+
601
+ if ( ! $registry ) {
602
+ return;
603
+ }
604
+
605
+ $notices = new EDD_Stripe_Admin_Notices( $registry );
606
+
607
+ wp_enqueue_script( 'edds-admin-notices' );
608
+
609
+ try {
610
+ $enabled_gateways = edd_get_enabled_payment_gateways();
611
+
612
+ $api_key = true === edd_is_test_mode()
613
+ ? edd_get_option( 'test_secret_key' )
614
+ : edd_get_option( 'live_secret_key' );
615
+
616
+ $mode_toggle = isset( $_GET['edd-message'] ) && 'connect-to-stripe' === $_GET['edd-message'];
617
+
618
+ if ( array_key_exists( 'stripe', $enabled_gateways ) && empty( $api_key ) ) {
619
+ wp_enqueue_style(
620
+ 'edd-stripe-admin-styles',
621
+ EDDSTRIPE_PLUGIN_URL . 'assets/css/build/admin.min.css',
622
+ array(),
623
+ EDD_STRIPE_VERSION
624
+ );
625
+
626
+ // Stripe Connect.
627
+ if ( false === $mode_toggle ) {
628
+ $notices->output( 'stripe-connect' );
629
+ // Stripe Connect reconnect.
630
+ } else {
631
+ $notices->output( 'stripe-connect-reconnect' );
632
+ }
633
+ }
634
+ } catch( Exception $e ) {}
635
+ }
636
+ add_action( 'admin_notices', 'edds_stripe_connect_admin_notices_print' );
includes/gateways/stripe/includes/admin/upgrade-functions.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Stripe Upgrade Notices
5
+ *
6
+ * @since 2.6
7
+ *
8
+ */
9
+ function edd_stripe_upgrade_notices() {
10
+
11
+ global $wpdb;
12
+
13
+ // Don't show notices on the upgrades page
14
+ if ( isset( $_GET['page'] ) && $_GET['page'] == 'edd-upgrades' ) {
15
+ return;
16
+ }
17
+
18
+ if ( ! edd_has_upgrade_completed( 'stripe_customer_id_migration' ) ) {
19
+
20
+ $has_stripe_customers = $wpdb->get_var( "SELECT count(user_id) FROM $wpdb->usermeta WHERE meta_key IN ( '_edd_stripe_customer_id', '_edd_stripe_customer_id_test' ) LIMIT 1" );
21
+ $needs_upgrade = ! empty( $has_stripe_customers );
22
+
23
+ if( ! $needs_upgrade ) {
24
+ edd_set_upgrade_complete( 'stripe_customer_id_migration' );
25
+ return;
26
+ }
27
+
28
+ printf(
29
+ '<div class="updated">' .
30
+ '<p>' .
31
+ /* translators: %s Upgrade link. */
32
+ __( 'Easy Digital Downloads - Stripe Gateway needs to upgrade the customers database; <a href="%s">click here to start the upgrade</a>. <a href="#" onClick="jQuery(this).parent().next(\'p\').slideToggle()">Learn more about this upgrade</a>', 'easy-digital-downloads' ) .
33
+ '</p>' .
34
+ '<p style="display: none;">' .
35
+ __( '<strong>About this upgrade:</strong><br />This upgrade will improve the reliability of associating purchase records with your existing customer records in Stripe by changing their Stripe Customer IDs to be stored locally on their EDD customer record, instead of their user record.', 'easy-digital-downloads' ) .
36
+ '<br /><br />' .
37
+ __( '<strong>Advanced User?</strong><br />This upgrade can also be run via WPCLI with the following command:<br /><code>wp edd-stripe migrate_customer_ids</code>', 'easy-digital-downloads' ) .
38
+ '</p>' .
39
+ '</div>',
40
+ esc_url( admin_url( 'index.php?page=edd-upgrades&edd-upgrade=stripe_customer_id_migration' ) )
41
+ );
42
+ }
43
+
44
+ }
45
+ add_action( 'admin_notices', 'edd_stripe_upgrade_notices' );
46
+
47
+ /**
48
+ * Migrates Stripe Customer IDs from the usermeta table to the edd_customermeta table.
49
+ *
50
+ * @since 2.6
51
+ * @return void
52
+ */
53
+ function edd_stripe_customer_id_migration() {
54
+ global $wpdb;
55
+
56
+ if ( ! current_user_can( 'manage_shop_settings' ) ) {
57
+ wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
58
+ }
59
+
60
+ ignore_user_abort( true );
61
+
62
+ $step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
63
+ $number = isset( $_GET['number'] ) ? absint( $_GET['number'] ) : 10;
64
+ $offset = $step == 1 ? 0 : ( $step - 1 ) * $number;
65
+
66
+ $total = isset( $_GET['total'] ) ? absint( $_GET['total'] ) : false;
67
+ if ( empty( $total ) || $total <= 1 ) {
68
+ $total_sql = "SELECT COUNT(user_id) as total_users FROM $wpdb->usermeta WHERE meta_key IN ( '_edd_stripe_customer_id', '_edd_stripe_customer_id_test' )";
69
+ $results = $wpdb->get_row( $total_sql, 0 );
70
+ $total = $results->total_users;
71
+ }
72
+
73
+ $stripe_user_meta = $wpdb->get_results(
74
+ $wpdb->prepare(
75
+ "SELECT * FROM $wpdb->usermeta WHERE meta_key IN ( '_edd_stripe_customer_id', '_edd_stripe_customer_id_test' ) ORDER BY umeta_id ASC LIMIT %d,%d;",
76
+ $offset,
77
+ $number
78
+ )
79
+ );
80
+
81
+ if ( $stripe_user_meta ) {
82
+
83
+ foreach ( $stripe_user_meta as $stripe_user ) {
84
+
85
+ $user = get_userdata( $stripe_user->user_id );
86
+ $email = $user->user_email;
87
+
88
+ $customer = new EDD_Customer( $email );
89
+
90
+ // If we don't have a customer on this site, just move along.
91
+ if ( ! $customer->id > 0 ) {
92
+ continue;
93
+ }
94
+
95
+ $stripe_customer_id = $stripe_user->meta_value;
96
+
97
+ // We should try and use a recurring ID if one exists for this user
98
+ if ( class_exists( 'EDD_Recurring_Subscriber' ) ) {
99
+ $subscriber = new EDD_Recurring_Subscriber( $customer->id );
100
+ $stripe_customer_id = $subscriber->get_recurring_customer_id( 'stripe' );
101
+ }
102
+
103
+ $customer->update_meta( $stripe_user->meta_key, $stripe_customer_id );
104
+
105
+ }
106
+
107
+ $step ++;
108
+ $redirect = add_query_arg( array(
109
+ 'page' => 'edd-upgrades',
110
+ 'edd-upgrade' => 'stripe_customer_id_migration',
111
+ 'step' => $step,
112
+ 'number' => $number,
113
+ 'total' => $total
114
+ ), admin_url( 'index.php' ) );
115
+
116
+ wp_redirect( $redirect );
117
+ exit;
118
+
119
+ } else {
120
+
121
+ update_option( 'edds_stripe_version', preg_replace( '/[^0-9.].*/', '', EDD_STRIPE_VERSION ) );
122
+ edd_set_upgrade_complete( 'stripe_customer_id_migration' );
123
+ delete_option( 'edd_doing_upgrade' );
124
+
125
+ wp_redirect( admin_url() );
126
+ exit;
127
+
128
+ }
129
+
130
+ }
131
+ add_action( 'edd_stripe_customer_id_migration', 'edd_stripe_customer_id_migration' );
includes/gateways/stripe/includes/card-actions.php ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Card actions.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Process the card update actions from the manage card form.
11
+ *
12
+ * @since 2.6
13
+ * @return void
14
+ */
15
+ function edd_stripe_process_card_update() {
16
+ $enabled = edd_stripe_existing_cards_enabled();
17
+
18
+ // Feature not enabled.
19
+ if ( ! $enabled ) {
20
+ wp_send_json_error(
21
+ array(
22
+ 'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
23
+ )
24
+ );
25
+ }
26
+
27
+ // Source can't be found.
28
+ $payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
29
+
30
+ if ( empty( $payment_method ) ) {
31
+ wp_send_json_error(
32
+ array(
33
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
34
+ )
35
+ );
36
+ }
37
+
38
+ // Nonce failed.
39
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], $payment_method . '_update' ) ) {
40
+ wp_send_json_error(
41
+ array(
42
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
43
+ )
44
+ );
45
+ }
46
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
47
+ if ( empty( $stripe_customer_id ) ) {
48
+ wp_send_json_error(
49
+ array(
50
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
51
+ )
52
+ );
53
+ }
54
+
55
+ try {
56
+ $card_args = array();
57
+ $card_fields = array(
58
+ 'address_city',
59
+ 'address_country',
60
+ 'address_line1',
61
+ 'address_line2',
62
+ 'address_zip',
63
+ 'address_state',
64
+ 'exp_month',
65
+ 'exp_year',
66
+ );
67
+
68
+ foreach ( $card_fields as $card_field ) {
69
+ $card_args[ $card_field ] = ( isset( $_POST[ $card_field ] ) && '' !== $_POST[ $card_field ] )
70
+ ? sanitize_text_field( $_POST[ $card_field ] )
71
+ : null;
72
+ }
73
+
74
+ // Update a PaymentMethod.
75
+ if ( 'pm_' === substr( $payment_method, 0, 3 ) ) {
76
+ $address_args = array(
77
+ 'city' => $card_args['address_city'],
78
+ 'country' => $card_args['address_country'],
79
+ 'line1' => $card_args['address_line1'],
80
+ 'line2' => $card_args['address_line2'],
81
+ 'postal_code' => $card_args['address_zip'],
82
+ 'state' => $card_args['address_state'],
83
+ );
84
+
85
+ edds_api_request(
86
+ 'PaymentMethod',
87
+ 'update',
88
+ $payment_method,
89
+ array(
90
+ 'billing_details' => array(
91
+ 'address' => $address_args,
92
+ ),
93
+ 'card' => array(
94
+ 'exp_month' => $card_args['exp_month'],
95
+ 'exp_year' => $card_args['exp_year'],
96
+ ),
97
+ )
98
+ );
99
+
100
+ // Update a legacy Card.
101
+ } else {
102
+ edds_api_request( 'Customer', 'updateSource', $stripe_customer_id, $payment_method, $card_args );
103
+ }
104
+
105
+ // Check if customer has default card.
106
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
107
+ $default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
108
+ // If there is no default card, make updated card default.
109
+ if ( null === $default_payment_method ) {
110
+ edds_customer_set_default_payment_method( $stripe_customer_id, current( $existing_cards )['source']->id );
111
+ }
112
+
113
+ wp_send_json_success(
114
+ array(
115
+ 'message' => esc_html__( 'Card successfully updated.', 'easy-digital-downloads' ),
116
+ )
117
+ );
118
+ } catch ( \Exception $e ) {
119
+ wp_send_json_error(
120
+ array(
121
+ 'message' => esc_html( $e->getMessage() ),
122
+ )
123
+ );
124
+ }
125
+ }
126
+ add_action( 'wp_ajax_edds_update_payment_method', 'edd_stripe_process_card_update' );
127
+
128
+ /**
129
+ * Process the set default card action from the manage card form.
130
+ *
131
+ * @since 2.6
132
+ * @return void
133
+ */
134
+ function edd_stripe_process_card_default() {
135
+ $enabled = edd_stripe_existing_cards_enabled();
136
+
137
+ // Feature not enabled.
138
+ if ( ! $enabled ) {
139
+ wp_send_json_error(
140
+ array(
141
+ 'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
142
+ )
143
+ );
144
+ }
145
+
146
+ // Source can't be found.
147
+ $payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
148
+
149
+ if ( empty( $payment_method ) ) {
150
+ wp_send_json_error(
151
+ array(
152
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
153
+ )
154
+ );
155
+ }
156
+
157
+ // Nonce failed.
158
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], $payment_method . '_update' ) ) {
159
+ wp_send_json_error(
160
+ array(
161
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
162
+ )
163
+ );
164
+ }
165
+
166
+ // Customer can't be found.
167
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
168
+
169
+ if ( empty( $stripe_customer_id ) ) {
170
+ wp_send_json_error(
171
+ array(
172
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
173
+ )
174
+ );
175
+ }
176
+
177
+ try {
178
+ edds_customer_set_default_payment_method( $stripe_customer_id, $payment_method );
179
+
180
+ wp_send_json_success(
181
+ array(
182
+ 'message' => esc_html__( 'Card successfully set as default.', 'easy-digital-downloads' ),
183
+ )
184
+ );
185
+ } catch ( \Exception $e ) {
186
+ wp_send_json_error(
187
+ array(
188
+ 'message' => esc_html( $e->getMessage() ),
189
+ )
190
+ );
191
+ }
192
+ }
193
+ add_action( 'wp_ajax_edds_set_payment_method_default', 'edd_stripe_process_card_default' );
194
+
195
+ /**
196
+ * Process the delete card action from the manage card form.
197
+ *
198
+ * @since 2.6
199
+ * @return void
200
+ */
201
+ function edd_stripe_process_card_delete() {
202
+ $enabled = edd_stripe_existing_cards_enabled();
203
+
204
+ // Feature not enabled.
205
+ if ( ! $enabled ) {
206
+ wp_send_json_error(
207
+ array(
208
+ 'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
209
+ )
210
+ );
211
+ }
212
+
213
+ // Source can't be found.
214
+ $payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
215
+
216
+ if ( empty( $payment_method ) ) {
217
+ wp_send_json_error(
218
+ array(
219
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
220
+ )
221
+ );
222
+ }
223
+
224
+ // Nonce failed.
225
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], $payment_method . '_update' ) ) {
226
+ wp_send_json_error(
227
+ array(
228
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
229
+ )
230
+ );
231
+ }
232
+
233
+ // Customer can't be found.
234
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
235
+
236
+ if ( empty( $stripe_customer_id ) ) {
237
+ wp_send_json_error(
238
+ array(
239
+ 'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
240
+ )
241
+ );
242
+ }
243
+
244
+ // Removal is disabled for this card.
245
+ $should_remove = apply_filters(
246
+ 'edd_stripe_should_remove_card',
247
+ array(
248
+ 'remove' => true,
249
+ 'message' => '',
250
+ ),
251
+ $payment_method,
252
+ $stripe_customer_id
253
+ );
254
+
255
+ if ( ! $should_remove['remove'] ) {
256
+ wp_send_json_error(
257
+ array(
258
+ 'message' => esc_html__( 'This feature is not available at this time.', 'easy-digital-downloads' ),
259
+ )
260
+ );
261
+ }
262
+
263
+ try {
264
+ // Detach a PaymentMethod.
265
+ if ( 'pm_' === substr( $payment_method, 0, 3 ) ) {
266
+ $payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method );
267
+ $payment_method->detach();
268
+
269
+ // Delete a Card.
270
+ } else {
271
+ edds_api_request( 'Customer', 'deleteSource', $stripe_customer_id, $payment_method );
272
+ }
273
+
274
+ // Retrieve saved cards before checking for default.
275
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
276
+ $default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
277
+
278
+ // If there is no default card, make updated card default.
279
+ if ( null === $default_payment_method && ! empty( $existing_cards ) ) {
280
+ edds_customer_set_default_payment_method( $stripe_customer_id, current( $existing_cards )['source']->id );
281
+ }
282
+
283
+ wp_send_json_success(
284
+ array(
285
+ 'message' => esc_html__( 'Card successfully removed.', 'easy-digital-downloads' ),
286
+ )
287
+ );
288
+ } catch ( \Exception $e ) {
289
+ wp_send_json_error(
290
+ array(
291
+ 'message' => esc_html( $e->getMessage() ),
292
+ )
293
+ );
294
+ }
295
+ }
296
+ add_action( 'wp_ajax_edds_delete_payment_method', 'edd_stripe_process_card_delete' );
297
+
298
+ /**
299
+ * Handles adding a new PaymentMethod (via AJAX).
300
+ *
301
+ * @since 2.6
302
+ * @return void
303
+ */
304
+ function edds_add_payment_method() {
305
+ $enabled = edd_stripe_existing_cards_enabled();
306
+
307
+ // Feature not enabled.
308
+ if ( ! $enabled ) {
309
+ wp_send_json_error(
310
+ array(
311
+ 'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
312
+ )
313
+ );
314
+ }
315
+
316
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
317
+ // Increase the card error count.
318
+ edd_stripe()->rate_limiting->increment_card_error_count();
319
+
320
+ wp_send_json_error(
321
+ array(
322
+ 'message' => __( 'Unable to update your account at this time, please try again later', 'easy-digital-downloads' ),
323
+ )
324
+ );
325
+ }
326
+
327
+ // PaymentMethod can't be found.
328
+ $payment_method_id = isset( $_POST['payment_method_id'] ) ? sanitize_text_field( $_POST['payment_method_id'] ) : false;
329
+
330
+ if ( ! $payment_method_id ) {
331
+ wp_send_json_error(
332
+ array(
333
+ 'message' => __( 'Missing card ID.', 'easy-digital-downloads' ),
334
+ )
335
+ );
336
+ }
337
+
338
+ // Nonce failed.
339
+ if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'edd-stripe-add-card' ) ) {
340
+ wp_send_json_error(
341
+ array(
342
+ 'message' => __( 'Error adding card.', 'easy-digital-downloads' ),
343
+ )
344
+ );
345
+ }
346
+
347
+ $edd_customer = new \EDD_Customer( get_current_user_id(), true );
348
+ if ( 0 === $edd_customer->id ) {
349
+ wp_send_json_error(
350
+ array(
351
+ 'message' => __(
352
+ 'Unable to retrieve customer.',
353
+ 'easy-digital-downloads'
354
+ ),
355
+ )
356
+ );
357
+ }
358
+
359
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
360
+ $stripe_customer = edds_get_stripe_customer(
361
+ $stripe_customer_id,
362
+ array(
363
+ 'email' => $edd_customer->email,
364
+ 'description' => $edd_customer->email,
365
+ )
366
+ );
367
+ if ( false === $stripe_customer ) {
368
+ wp_send_json_error(
369
+ array(
370
+ 'message' => __(
371
+ 'Unable to create customer in Stripe.',
372
+ 'easy-digital-downloads'
373
+ ),
374
+ )
375
+ );
376
+ }
377
+
378
+ // Ensure the EDD Customer is has a link to the most up to date Stripe Customer ID.
379
+ $edd_customer->update_meta( edd_stripe_get_customer_key(), $stripe_customer->id );
380
+
381
+ try {
382
+ $payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method_id );
383
+ $payment_method->attach(
384
+ array(
385
+ 'customer' => $stripe_customer->id,
386
+ )
387
+ );
388
+ // Check if customer has default card.
389
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
390
+ $default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
391
+ // If there is no default card, make updated card default.
392
+ if ( null === $default_payment_method ) {
393
+ edds_customer_set_default_payment_method( $stripe_customer->id, current( $existing_cards )['source']->id );
394
+ }
395
+
396
+ wp_send_json_success(
397
+ array(
398
+ 'message' => esc_html__( 'Card successfully added.', 'easy-digital-downloads' ),
399
+ )
400
+ );
401
+ } catch ( \Exception $e ) {
402
+ // Increase the card error count.
403
+ edd_stripe()->rate_limiting->increment_card_error_count();
404
+
405
+ wp_send_json_error(
406
+ array(
407
+ 'message' => esc_html( $e->getMessage() ),
408
+ )
409
+ );
410
+ }
411
+ }
412
+ add_action( 'wp_ajax_edds_add_payment_method', 'edds_add_payment_method' );
413
+
414
+ /**
415
+ * Sets default payment method if none.
416
+ *
417
+ * @since 2.8
418
+ * @param string $stripe_customer_id Stripe Customer ID. Usually starts with cus_ .
419
+ * @param string $payment_method_id Stripe Payment ID. Usually starts with pm_ .
420
+ * @return \Stripe\Customer $customer Stripe Customer.
421
+ */
422
+ function edds_customer_set_default_payment_method( $stripe_customer_id, $payment_method_id ) {
423
+ $customer = edds_api_request(
424
+ 'Customer',
425
+ 'update',
426
+ $stripe_customer_id,
427
+ array(
428
+ 'invoice_settings' => array(
429
+ 'default_payment_method' => $payment_method_id,
430
+ ),
431
+ )
432
+ );
433
+ return $customer;
434
+ }
435
+
436
+ /**
437
+ * Checks if customer has default payment method.
438
+ *
439
+ * @since 2.8
440
+ * @param int $user_id WordPress user ID.
441
+ * @param array $payment_methods Array of payment methods for user, default = false will fetch payment methods.
442
+ * @return null|string Payment Method ID if found, else null
443
+ */
444
+ function edds_customer_get_default_payment_method( $user_id, $payment_methods = false ) {
445
+ // Retrieve saved cards before checking for default.
446
+ if ( false === $payment_methods ) {
447
+ $payment_methods = edd_stripe_get_existing_cards( $user_id );
448
+ }
449
+ $default_payment_method = null;
450
+ if ( count( $payment_methods ) >= 1 ) {
451
+ // Loop through existing cards for default.
452
+ foreach ( $payment_methods as $card ) {
453
+ if ( true === $card['default'] ) {
454
+ $default_payment_method = $card['source']->id;
455
+ break;
456
+ }
457
+ }
458
+ }
459
+ return $default_payment_method;
460
+ }
461
+
462
+ /**
463
+ * Checks if customer Stripe Customer object exists.
464
+ *
465
+ * @since 2.8
466
+ * @param string $stripe_customer_id Stripe Customer ID. Usually starts with cus_ .
467
+ * @param array $customer_args {
468
+ * Arguments to create a Stripe Customer.
469
+ *
470
+ * @link https://stripe.com/docs/api/customers/create
471
+ * }
472
+ * @return \Stripe\Customer|false $customer Stripe Customer if found or false on error.
473
+ */
474
+ function edds_get_stripe_customer( $stripe_customer_id, $customer_args ) {
475
+ $customer = false;
476
+ if ( ! empty( $stripe_customer_id ) ) {
477
+ try {
478
+ $customer = edds_api_request( 'Customer', 'retrieve', $stripe_customer_id );
479
+ if ( isset( $customer->deleted ) && $customer->deleted ) { // If customer was deleted in Stripe, try to create a new one.
480
+ $customer = edds_create_stripe_customer( $customer_args );
481
+ }
482
+ } catch ( \Stripe\Error\Base $e ) {
483
+ $error_code = $e->getStripeCode();
484
+ if ( 'resource_missing' === $error_code ) { // If Stripe returns an error of 'resource_missing', try to create a new Stripe Customer.
485
+ try {
486
+ $customer = edds_create_stripe_customer( $customer_args );
487
+ } catch ( \Exception $e ) {
488
+ // No further actions to take if something causes error.
489
+ }
490
+ }
491
+ }
492
+ } else {
493
+ try {
494
+ $customer = edds_create_stripe_customer( $customer_args );
495
+ } catch ( \Exception $e ) {
496
+ // No further actions to take if something causes error.
497
+ }
498
+ }
499
+ return $customer;
500
+ }
501
+
502
+ /**
503
+ * Creates a new Stripe Customer
504
+ *
505
+ * @since 2.8
506
+ * @param array $customer_args {
507
+ * Arguments to create a Stripe Customer.
508
+ *
509
+ * @link https://stripe.com/docs/api/customers/create
510
+ * }
511
+ * @return \Stripe\Customer|false $customer Stripe Customer if one is created or false on error.
512
+ */
513
+ function edds_create_stripe_customer( $customer_args = array() ) {
514
+ /**
515
+ * Filters the arguments used to create a Customer in Stripe.
516
+ *
517
+ * @since unknown
518
+ *
519
+ * @param array $customer_args {
520
+ * Arguments to create a Stripe Customer.
521
+ *
522
+ * @link https://stripe.com/docs/api/customers/create
523
+ * }
524
+ * @param array $purchase_data {
525
+ * Cart purchase data if in the checkout context. Empty otherwise.
526
+ * }
527
+ */
528
+ $customer_args = apply_filters( 'edds_create_customer_args', $customer_args, array() );
529
+ if ( empty( $customer_args['email'] ) || ! is_email( $customer_args['email'] ) ) {
530
+ return false;
531
+ }
532
+ if ( empty( $customer_args['description'] ) ) {
533
+ $customer_args['description'] = $customer_args['email'];
534
+ }
535
+
536
+ try {
537
+ $customer = edds_api_request( 'Customer', 'create', $customer_args );
538
+ } catch ( \Exception $e ) {
539
+ $customer = false;
540
+ }
541
+
542
+ return $customer;
543
+
544
+ }
includes/gateways/stripe/includes/class-edd-stripe-rate-limiting.php ADDED
@@ -0,0 +1,369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class EDD_Stripe_Rate_Limiting
5
+ */
6
+ class EDD_Stripe_Rate_Limiting {
7
+
8
+ /**
9
+ * Is the file writable.
10
+ *
11
+ * @var bool
12
+ */
13
+ public $is_writable = true;
14
+
15
+ /**
16
+ * The rate limiting log file.
17
+ *
18
+ * @var string
19
+ */
20
+ private $filename = '';
21
+
22
+ /**
23
+ * The file path to the log file.
24
+ *
25
+ * @var string
26
+ */
27
+ private $file = '';
28
+
29
+ /**
30
+ * Set up the EDD Logging Class
31
+ *
32
+ * @since 2.6.19
33
+ */
34
+ public function __construct() {
35
+ $this->actions();
36
+ $this->filters();
37
+ }
38
+
39
+ /**
40
+ * Register any actions we need to use.
41
+ *
42
+ * @since 2.6.19
43
+ */
44
+ private function actions() {
45
+
46
+ // Setup the log file.
47
+ add_action( 'plugins_loaded', array( $this, 'setup_log_file' ), 11 );
48
+
49
+ // Catch any recurring errors as they don't run through the main Stripe extension.
50
+ add_action( 'edd_before_purchase_form', array( $this, 'listen_for_recurring_card_errors' ), 0 );
51
+
52
+ }
53
+
54
+ /**
55
+ * Register any filters we need to use.
56
+ *
57
+ * @since 2.6.19
58
+ */
59
+ private function filters() {
60
+
61
+ // Hide the purchase button if the visitor has hit the limit of errors.
62
+ add_filter( 'edd_checkout_button_purchase', array( $this, 'maybe_hide_purchase_button' ) );
63
+
64
+ }
65
+
66
+ /**
67
+ * Sets up the log file if it is writable
68
+ *
69
+ * @since 2.6.19
70
+ * @return void
71
+ */
72
+ public function setup_log_file() {
73
+
74
+ $upload_dir = wp_upload_dir();
75
+ $this->filename = wp_hash( home_url( '/' ) ) . '-edd-stripe-rate-limiting.log';
76
+ $this->file = trailingslashit( $upload_dir['basedir'] ) . $this->filename;
77
+
78
+ if ( ! is_writeable( $upload_dir['basedir'] ) ) {
79
+ $this->is_writable = false;
80
+ }
81
+
82
+ }
83
+
84
+ /**
85
+ * Checks if the current session has hit the card error limit.
86
+ *
87
+ * @since 2.6.19
88
+ *
89
+ * @return bool
90
+ */
91
+ public function has_hit_card_error_limit() {
92
+ if ( ! $this->card_error_checks_enabled() ) {
93
+ return false;
94
+ }
95
+
96
+ $blocking_id = $this->get_card_error_id();
97
+ $entry = $this->get_rate_limiting_entry( $blocking_id );
98
+ $expiration = ! empty( $entry['timeout'] ) ? $entry['timeout'] : 0;
99
+ $card_errors = ! empty( $entry['count'] ) ? $entry['count'] : 0;
100
+
101
+ if ( $expiration < current_time( 'timestamp' ) ) {
102
+ $this->remove_log_entry( $this->get_card_error_id() );
103
+ return false;
104
+ }
105
+
106
+ $max_error_count = 5;
107
+
108
+ /**
109
+ * Filters the number of times checkout errors can occur before blocking future attempts.
110
+ *
111
+ * @since 2.6.19
112
+ *
113
+ * @param bool $max_error_count The maximum failed checkouts before blocking future attempts. Default 5.
114
+ */
115
+ $max_error_count = apply_filters( 'edds_max_card_error_count', $max_error_count );
116
+
117
+ return $max_error_count <= $card_errors;
118
+ }
119
+
120
+ /**
121
+ * Remove an entry from the rate limiting log.
122
+ *
123
+ * @since 2.6.19
124
+ *
125
+ * @param string $blocking_id The blocking ID for the rate limiting.
126
+ */
127
+ public function remove_log_entry( $blocking_id = '' ) {
128
+ $current_logs = $this->get_decoded_file();
129
+ unset( $current_logs[ $blocking_id ] );
130
+
131
+ $this->write_to_log( $current_logs );
132
+ }
133
+
134
+ /**
135
+ * Get a specific entry from the rate limiting log.
136
+ *
137
+ * @since 2.6.19
138
+ *
139
+ * @param string $blocking_id The blocking ID to get the entry for.
140
+ *
141
+ * @return array
142
+ */
143
+ public function get_rate_limiting_entry( $blocking_id = '' ) {
144
+ $current_logs = $this->get_decoded_file();
145
+ $entry = array();
146
+
147
+ if ( array_key_exists( $blocking_id, $current_logs ) ) {
148
+ $entry = $current_logs[ $blocking_id ];
149
+ }
150
+
151
+ return $entry;
152
+ }
153
+
154
+
155
+ /**
156
+ * Retrieves the number of times an IP address has generated card errors.
157
+ *
158
+ * @since 2.6.19
159
+ *
160
+ * @return int
161
+ */
162
+ public function get_card_error_count() {
163
+ $blocking_id = $this->get_card_error_id();
164
+ $count = 0;
165
+
166
+ $current_blocks = $this->get_decoded_file();
167
+ if ( array_key_exists( $blocking_id, $current_blocks ) ) {
168
+ $count = $current_blocks[ $blocking_id ]['count'];
169
+ }
170
+
171
+ return $count;
172
+ }
173
+
174
+ /**
175
+ * Increments the Stripe card error counter.
176
+ *
177
+ * @since 2.6.19
178
+ *
179
+ * @return int
180
+ */
181
+ public function increment_card_error_count() {
182
+ $current_count = $this->get_card_error_count();
183
+ $blocking_id = $this->get_card_error_id();
184
+
185
+ if ( empty( $current_count ) ) {
186
+ $current_count = 1;
187
+ } else {
188
+ $current_count++;
189
+ }
190
+
191
+ $this->update_rate_limiting_count( $blocking_id, $current_count );
192
+
193
+ return absint( $current_count );
194
+ }
195
+
196
+ /**
197
+ * Update an entry in the rate limiting array.
198
+ *
199
+ * @since 2.6.19
200
+ *
201
+ * @param string $blocking_id The blocking ID.
202
+ * @param int $current_count The count to update to.
203
+ */
204
+ protected function update_rate_limiting_count( $blocking_id = '', $current_count = 0 ) {
205
+
206
+ $expiration_in_seconds = HOUR_IN_SECONDS;
207
+
208
+ /**
209
+ * Filters the length of time before checkout card error counts are reset.
210
+ *
211
+ * @since 2.6.19
212
+ *
213
+ * @param int $expiration_in_seconds The length in seconds before card error counts are reset. Default 60.
214
+ */
215
+ $expiration_in_seconds = apply_filters( 'edds_card_error_timeout', $expiration_in_seconds );
216
+
217
+ $current_log = $this->get_decoded_file();
218
+
219
+ $current_log[ $blocking_id ]['count'] = $current_count;
220
+ $current_log[ $blocking_id ]['timeout'] = current_time( 'timestamp' ) + $expiration_in_seconds;
221
+
222
+ $this->write_to_log( $current_log );
223
+
224
+ }
225
+
226
+ /**
227
+ * Determines if we should check for Stripe card errors and track them.
228
+ *
229
+ * @since 2.6.19
230
+ *
231
+ * @return bool
232
+ */
233
+ public function card_error_checks_enabled() {
234
+ $checks_enabled = true;
235
+
236
+ /**
237
+ * Filters if card errors should be checked and tracked during checkout.
238
+ *
239
+ * @since 2.6.19
240
+ *
241
+ * @param bool $checks_enabled Enables or disables card error checking on checkout. Default true.
242
+ */
243
+ $checks_enabled = apply_filters( 'edds_card_error_checking_enabled', true );
244
+
245
+ return true === $checks_enabled;
246
+ }
247
+
248
+ /**
249
+ * Generates the card error tracking ID.
250
+ *
251
+ * ID is the IP address of the visitor. Prepends the value with `edds_card_errors_` for use with the transient system.
252
+ * Uses IP tracking in an attempt to mitigate the amount of bogus WordPress user accounts being created.
253
+ *
254
+ * @since 2.6.19
255
+ *
256
+ * @return string
257
+ */
258
+ public function get_card_error_id() {
259
+ return edd_get_ip();
260
+ }
261
+
262
+ /**
263
+ * Determines if we should hide the purchase button.
264
+ *
265
+ * When someone has hit the card error limit, the purchase button is hidden.
266
+ *
267
+ * @since 2.6.19
268
+ *
269
+ * @param string $purchase_button_markup The markup for the purchase button.
270
+ *
271
+ * @return string
272
+ */
273
+ public function maybe_hide_purchase_button( $purchase_button_markup = '' ) {
274
+ if ( $this->has_hit_card_error_limit() ) {
275
+ $purchase_button_markup = '';
276
+ }
277
+
278
+ return $purchase_button_markup;
279
+
280
+ }
281
+
282
+ /**
283
+ * When the purchase form errors are displayed, see if any were related to Stripe failures and increase the card error
284
+ * counter.
285
+ *
286
+ * @since 2.6.19
287
+ */
288
+ public function listen_for_recurring_card_errors() {
289
+
290
+ // Get all of our EDD errors.
291
+ $errors = edd_get_errors();
292
+
293
+ // If any of our errors are Stripe card errors from recurring, increment the card error counter.
294
+ if ( isset( $errors['edd_recurring_stripe_error'] ) && ! empty( $errors['edd_recurring_stripe_error'] ) ) {
295
+ $this->increment_card_error_count();
296
+ }
297
+
298
+ }
299
+
300
+ /**
301
+ * Retrieve the log data
302
+ *
303
+ * @since 2.6.19
304
+ * @return string
305
+ */
306
+ protected function get_file_contents() {
307
+ return $this->get_file();
308
+ }
309
+
310
+ /**
311
+ * Get the decoded array of rate limiting from the log file.
312
+ *
313
+ * @since 2.6.19
314
+ *
315
+ * @return array
316
+ */
317
+ protected function get_decoded_file() {
318
+ $decoded_contents = json_decode( $this->get_file_contents(), true );
319
+ if ( is_null( $decoded_contents ) ) {
320
+ $decoded_contents = array();
321
+ }
322
+
323
+ return (array) $decoded_contents;
324
+ }
325
+
326
+ /**
327
+ * Retrieve the file data is written to
328
+ *
329
+ * @since 2.6.19
330
+ * @return string
331
+ */
332
+ protected function get_file() {
333
+
334
+ $file = json_encode( array() );
335
+
336
+ if ( @file_exists( $this->file ) ) {
337
+
338
+ if ( ! is_writeable( $this->file ) ) {
339
+ $this->is_writable = false;
340
+ }
341
+
342
+ $file = @file_get_contents( $this->file );
343
+ } else {
344
+
345
+ @file_put_contents( $this->file, $file );
346
+ @chmod( $this->file, 0664 );
347
+ }
348
+
349
+ return $file;
350
+ }
351
+
352
+ /**
353
+ * Write the log message
354
+ *
355
+ * @since 2.6.19
356
+ *
357
+ * @param array $content The content of the rate limiting.
358
+ *
359
+ * @return void
360
+ */
361
+ public function write_to_log( $content = array() ) {
362
+ $content = json_encode( $content );
363
+
364
+ if ( $this->is_writable ) {
365
+ @file_put_contents( $this->file, $content );
366
+ }
367
+ }
368
+
369
+ }
includes/gateways/stripe/includes/class-edd-stripe.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main plugin class.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * EDD_Stripe class.
18
+ *
19
+ * @since 2.6.0
20
+ */
21
+ class EDD_Stripe {
22
+
23
+ /**
24
+ * Singleton instance.
25
+ *
26
+ * @since 2.6.0
27
+ * @var EDD_Stripe
28
+ */
29
+ private static $instance;
30
+
31
+ /**
32
+ * Rate limiting component.
33
+ *
34
+ * @since 2.6.19
35
+ * @var EDD_Stripe_Rate_Limiting
36
+ */
37
+ public $rate_limiting;
38
+
39
+ /**
40
+ * Instantiates or returns the singleton instance.
41
+ *
42
+ * @since 2.6.0
43
+ *
44
+ * @return EDD_Stripe
45
+ */
46
+ public static function instance() {
47
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof EDD_Stripe ) ) {
48
+ self::$instance = new EDD_Stripe;
49
+ self::$instance->includes();
50
+ self::$instance->setup_classes();
51
+ self::$instance->actions();
52
+ self::$instance->filters();
53
+
54
+ if ( class_exists( 'EDD_License' ) && is_admin() ) {
55
+ new EDD_License(
56
+ __FILE__,
57
+ 'Stripe Payment Gateway',
58
+ EDD_STRIPE_VERSION,
59
+ 'Sandhills Development, LLC',
60
+ 'stripe_license_key',
61
+ null,
62
+ 167
63
+ );
64
+ }
65
+ }
66
+
67
+ return self::$instance;
68
+ }
69
+
70
+ /**
71
+ * Includes files.
72
+ *
73
+ * @since 2.6.0
74
+ */
75
+ private function includes() {
76
+ if ( ! class_exists( 'Stripe\Stripe' ) ) {
77
+ require_once EDDS_PLUGIN_DIR . '/vendor/autoload.php';
78
+ }
79
+
80
+ require_once EDDS_PLUGIN_DIR . '/includes/class-stripe-api.php';
81
+
82
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/exceptions/class-stripe-api-unmet-requirements.php';
83
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/exceptions/class-attribute-not-found.php';
84
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/exceptions/class-stripe-object-not-found.php';
85
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/exceptions/class-gateway-exception.php';
86
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/interface-static-registry.php';
87
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/class-registry.php';
88
+ require_once EDDS_PLUGIN_DIR . '/includes/utils/modal.php';
89
+
90
+ require_once EDDS_PLUGIN_DIR . '/includes/functions.php';
91
+ require_once EDDS_PLUGIN_DIR . '/includes/deprecated.php';
92
+ require_once EDDS_PLUGIN_DIR . '/includes/compat.php';
93
+ require_once EDDS_PLUGIN_DIR . '/includes/i18n.php';
94
+ require_once EDDS_PLUGIN_DIR . '/includes/emails.php';
95
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-receipt.php';
96
+ require_once EDDS_PLUGIN_DIR . '/includes/card-actions.php';
97
+ require_once EDDS_PLUGIN_DIR . '/includes/gateway-actions.php';
98
+ require_once EDDS_PLUGIN_DIR . '/includes/gateway-filters.php';
99
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-actions.php';
100
+ require_once EDDS_PLUGIN_DIR . '/includes/webhooks.php';
101
+ require_once EDDS_PLUGIN_DIR . '/includes/elements.php';
102
+ require_once EDDS_PLUGIN_DIR . '/includes/scripts.php';
103
+ require_once EDDS_PLUGIN_DIR . '/includes/template-functions.php';
104
+ require_once EDDS_PLUGIN_DIR . '/includes/class-edd-stripe-rate-limiting.php';
105
+
106
+ // Payment Methods.
107
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/index.php';
108
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/index.php';
109
+
110
+ if ( is_admin() ) {
111
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/class-notices-registry.php';
112
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/class-notices.php';
113
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/notices.php';
114
+
115
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/admin-actions.php';
116
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/admin-filters.php';
117
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/settings/stripe-connect.php';
118
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/settings.php';
119
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/upgrade-functions.php';
120
+ require_once EDDS_PLUGIN_DIR . '/includes/admin/reporting/class-stripe-reports.php';
121
+ }
122
+
123
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
124
+ require_once EDDS_PLUGIN_DIR . '/includes/integrations/wp-cli.php';
125
+ }
126
+
127
+ if ( defined( 'EDD_ALL_ACCESS_VER' ) && EDD_ALL_ACCESS_VER ) {
128
+ require_once EDDS_PLUGIN_DIR . '/includes/integrations/edd-all-access.php';
129
+ }
130
+
131
+ if ( class_exists( 'EDD_Auto_Register' ) ) {
132
+ require_once EDDS_PLUGIN_DIR . '/includes/integrations/edd-auto-register.php';
133
+ }
134
+
135
+ // Pro.
136
+ $pro = EDDS_PLUGIN_DIR . '/includes/pro/index.php';
137
+
138
+ if ( file_exists( $pro ) ) {
139
+ require_once $pro;
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Applies various hooks.
145
+ *
146
+ * @since 2.6.0
147
+ */
148
+ private function actions() {
149
+ add_action( 'init', array( self::$instance, 'load_textdomain' ) );
150
+ add_action( 'admin_init', array( self::$instance, 'database_upgrades' ) );
151
+ }
152
+
153
+ /**
154
+ * Applies various filters.
155
+ *
156
+ * @since 2.6.0
157
+ */
158
+ private function filters() {
159
+ add_filter( 'edd_payment_gateways', array( self::$instance, 'register_gateway' ) );
160
+ }
161
+
162
+ /**
163
+ * Configures core components.
164
+ *
165
+ * @since 2.6.19
166
+ */
167
+ private function setup_classes() {
168
+ $this->rate_limiting = new EDD_Stripe_Rate_Limiting();
169
+ }
170
+
171
+ /**
172
+ * Performs database upgrades.
173
+ *
174
+ * @since 2.6.0
175
+ */
176
+ public function database_upgrades() {
177
+ $did_upgrade = false;
178
+ $version = get_option( 'edds_stripe_version' );
179
+
180
+ if ( ! $version || version_compare( $version, EDD_STRIPE_VERSION, '<' ) ) {
181
+ $did_upgrade = true;
182
+
183
+ switch ( EDD_STRIPE_VERSION ) {
184
+ case '2.5.8' :
185
+ edd_update_option( 'stripe_checkout_remember', true );
186
+ break;
187
+ case '2.8.0':
188
+ edd_update_option( 'stripe_allow_prepaid', true );
189
+ break;
190
+ }
191
+
192
+ }
193
+
194
+ if ( $did_upgrade ) {
195
+ update_option( 'edds_stripe_version', EDD_STRIPE_VERSION );
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Loads the plugin text domain.
201
+ *
202
+ * @since 2.6.0
203
+ */
204
+ public function load_textdomain() {
205
+ // Set filter for language directory
206
+ $lang_dir = EDDS_PLUGIN_DIR . '/languages/';
207
+
208
+ // Traditional WordPress plugin locale filter
209
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'edds' );
210
+ $mofile = sprintf( '%1$s-%2$s.mo', 'edds', $locale );
211
+
212
+ // Setup paths to current locale file
213
+ $mofile_local = $lang_dir . $mofile;
214
+ $mofile_global = WP_LANG_DIR . '/edd-stripe/' . $mofile;
215
+
216
+ // Look in global /wp-content/languages/edd-stripe/ folder
217
+ if( file_exists( $mofile_global ) ) {
218
+ load_textdomain( 'edds', $mofile_global );
219
+
220
+ // Look in local /wp-content/plugins/edd-stripe/languages/ folder
221
+ } elseif( file_exists( $mofile_local ) ) {
222
+ load_textdomain( 'edds', $mofile_local );
223
+
224
+ } else {
225
+ // Load the default language files
226
+ load_plugin_textdomain( 'edds', false, $lang_dir );
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Registers the gateway.
232
+ *
233
+ * @param array $gateways Payment gateways.
234
+ * @return array
235
+ */
236
+ public function register_gateway( $gateways ) {
237
+ // Format: ID => Name
238
+ $gateways['stripe'] = array(
239
+ 'admin_label' => 'Stripe',
240
+ 'checkout_label' => __( 'Credit Card', 'easy-digital-downloads' ),
241
+ 'supports' => array(
242
+ 'buy_now'
243
+ )
244
+ );
245
+ return $gateways;
246
+ }
247
+
248
+ }
includes/gateways/stripe/includes/class-stripe-api.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manage the Stripe API PHP bindings usage.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ use \Stripe\Stripe;
10
+
11
+ /**
12
+ * Implements a wrapper for the Stripe API PHP bindings.
13
+ *
14
+ * @since 2.7.0
15
+ */
16
+ class EDD_Stripe_API {
17
+
18
+ /**
19
+ * Configures the Stripe API before each request.
20
+ *
21
+ * @since 2.7.0
22
+ */
23
+ public function __construct() {
24
+ add_action( 'edds_pre_stripe_api_request', array( $this, 'set_api_key' ) );
25
+ add_action( 'edds_pre_stripe_api_request', array( $this, 'set_app_info' ) );
26
+ add_action( 'edds_pre_stripe_api_request', array( $this, 'set_api_version' ) );
27
+ }
28
+
29
+ /**
30
+ * Makes an API request.
31
+ *
32
+ * Requires a Stripe object and method, with optional additional arguments.
33
+ *
34
+ * @since 2.7.0
35
+ *
36
+ * @link https://github.com/stripe/stripe-php
37
+ *
38
+ * @throws \EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found When attempting to call an object or method that is not available.
39
+ * @throws \Stripe\Exception
40
+ *
41
+ * @param string $object Stripe object, such as Customer, Subscription, PaymentMethod, etc.
42
+ * @param string $method Method to call on the object, such as update, retrieve, etc.
43
+ * @param mixed ...$args Additional arguments to pass to the request.
44
+ * @return \Stripe\StripeObject
45
+ */
46
+ public function request( $object, $method ) {
47
+ // Nothing should be executing API requests if the application requirements
48
+ // have not been met. However, a final safety net is added here.
49
+ if ( false === edds_has_met_requirements() ) {
50
+ throw new EDD_Stripe_Utils_Exceptions_Stripe_API_Unmet_Requirements(
51
+ __( 'Unable to process request: Unmet Stripe payment gateway requirements. Please contact the website administrator.', 'easy-digital-downloads' )
52
+ );
53
+ }
54
+
55
+ $classname = 'Stripe\\' . $object;
56
+
57
+ // Retrieve additional arguments.
58
+ $args = func_get_args();
59
+ unset( $args[0] ); // Removes $object.
60
+ unset( $args[1] ); // Removes $method.
61
+
62
+ // Reset keys.
63
+ $args = array_values( $args );
64
+
65
+ if ( ! is_callable( array( $classname, $method ) ) ) {
66
+ throw new EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found(
67
+ sprintf(
68
+ /* translators: %1$s Stripe API class name. %2$s Stripe API method name. */
69
+ esc_html__( 'Unable to call %1$s::%2$s', 'easy-digital-downloads' ),
70
+ $classname,
71
+ $method
72
+ )
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Allows action to be taken before a Stripe API request is made.
78
+ *
79
+ * @since 2.8.0
80
+ *
81
+ * @param EDD_Stripe_API $this EDD_Stripe_API class.
82
+ * @param string $object Stripe object, such as Customer, Subscription, PaymentMethod, etc.
83
+ * @param string $method Method to call on the object, such as update, retrieve, etc.
84
+ * @param mixed $args Additional arguments to pass to the request.
85
+ */
86
+ do_action( 'edds_pre_stripe_api_request', $this, $object, $method, $args );
87
+
88
+ // @todo Filter arguments and per-request options?
89
+ //
90
+ // Need to account for:
91
+ //
92
+ // ::retrieve( array() );
93
+ // ::retrieve( array(), array() );
94
+ // ::retrieve( '123' );
95
+ // ::retrieve( '123', array() );
96
+ // ::update( '123', array() );
97
+ // ::update( '123', array(), array() );
98
+
99
+ return call_user_func_array( array( $classname, $method ), $args );
100
+ }
101
+
102
+ /**
103
+ * Sets API key for all proceeding requests.
104
+ *
105
+ * @since 2.7.0
106
+ */
107
+ public function set_api_key() {
108
+ $secret_key = edd_get_option( ( edd_is_test_mode() ? 'test' : 'live' ) . '_secret_key' );
109
+
110
+ Stripe::setApiKey( trim( $secret_key ) );
111
+ }
112
+
113
+ /**
114
+ * Sets application info for all proceeding requests.
115
+ *
116
+ * @link https://stripe.com/docs/building-plugins#setappinfo
117
+ *
118
+ * @since 2.7.0
119
+ */
120
+ public function set_app_info() {
121
+ Stripe::setAppInfo(
122
+ 'WordPress Easy Digital Downloads - Stripe',
123
+ EDD_STRIPE_VERSION,
124
+ esc_url( site_url() ),
125
+ EDD_STRIPE_PARTNER_ID
126
+ );
127
+ }
128
+
129
+ /**
130
+ * Sets API version for all proceeding requests.
131
+ *
132
+ * @link https://stripe.com/docs/building-plugins#set-api-version
133
+ *
134
+ * @since 2.7.0
135
+ */
136
+ public function set_api_version() {
137
+ Stripe::setApiVersion( EDD_STRIPE_API_VERSION );
138
+ }
139
+ }
includes/gateways/stripe/includes/compat.php ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Rewritten core functions to provide compatibility with a full AJAX checkout.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Maps serialized form data to global $_POST and $_REQUEST variables.
11
+ *
12
+ * This ensures any custom code that hooks in to actions inside an
13
+ * AJAX processing step can utilize form field data.
14
+ *
15
+ * @since 2.7.3
16
+ *
17
+ * @param array $post_data $_POST data containing serialized form data.
18
+ */
19
+ function _edds_map_form_data_to_request( $post_data ) {
20
+ if ( ! isset( $post_data['form_data'] ) ) {
21
+ return;
22
+ }
23
+
24
+ parse_str( $post_data['form_data'], $form_data );
25
+
26
+ $_POST = array_merge( $_POST, $form_data );
27
+ $_REQUEST = array_merge( $_REQUEST, $_POST );
28
+ }
29
+
30
+ /**
31
+ * When dealing with payments certain aspects only work if the payment
32
+ * is being created inside the `edd_process_purchase_form()` function.
33
+ *
34
+ * Since this gateway uses multiple steps via AJAX requests this context gets lost.
35
+ * Calling this function "fakes" that we are still in this process when creating
36
+ * a new payment.
37
+ *
38
+ * Mainly this prevents `edd_insert_payment()` from creating multiple customers for
39
+ * the same user by ensuring the checkout email address is added to the existing customer.
40
+ *
41
+ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/includes/payments/class-edd-payment.php#L2754
42
+ *
43
+ * @since 2.7.0
44
+ */
45
+ function _edds_fake_process_purchase_step() {
46
+ // Save current errors.
47
+ $errors = edd_get_errors();
48
+
49
+ // Clear any errors that might be used as a reason to attempt a redirect in the following action.
50
+ edd_clear_errors();
51
+
52
+ // Don't run any attached actions twice.
53
+ remove_all_actions( 'edd_pre_process_purchase' );
54
+
55
+ // Pretend we are about to process a purchase.
56
+ do_action( 'edd_pre_process_purchase' );
57
+
58
+ // Clear any errors that may have been set in the previous action.
59
+ edd_clear_errors();
60
+
61
+ // Restore original errors.
62
+ if ( ! empty( $errors ) ) {
63
+ foreach ( $errors as $error_id => $error_message ) {
64
+ edd_set_error( $error_id, $error_message );
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * A rewritten version of `edds_get_purchase_form_user()` that can be run during AJAX.
71
+ *
72
+ * @since 2.7.0
73
+ *
74
+ * @return array
75
+ */
76
+ function _edds_get_purchase_form_user( $valid_data = array() ) {
77
+ // Initialize user
78
+ $user = false;
79
+
80
+ if ( is_user_logged_in() ) {
81
+
82
+ // Set the valid user as the logged in collected data.
83
+ $user = $valid_data['logged_in_user'];
84
+
85
+ } elseif ( true === $valid_data['need_new_user'] || true === $valid_data['need_user_login'] ) {
86
+
87
+ // Ensure $_COOKIE is available without a new HTTP request.
88
+ add_action( 'set_logged_in_cookie', 'edds_set_logged_in_cookie_global' );
89
+
90
+ // New user registration.
91
+ if ( true === $valid_data['need_new_user'] ) {
92
+
93
+ // Set user.
94
+ $user = $valid_data['new_user_data'];
95
+
96
+ // Register and login new user.
97
+ $user['user_id'] = edd_register_and_login_new_user( $user );
98
+
99
+ } elseif ( true === $valid_data['need_user_login'] ) { // User login.
100
+
101
+ /*
102
+ * The login form is now processed in the edd_process_purchase_login() function.
103
+ * This is still here for backwards compatibility.
104
+ * This also allows the old login process to still work if a user removes the
105
+ * checkout login submit button.
106
+ *
107
+ * This also ensures that the customer is logged in correctly if they click "Purchase"
108
+ * instead of submitting the login form, meaning the customer is logged in during the purchase process.
109
+ */
110
+
111
+ // Set user.
112
+ $user = $valid_data['login_user_data'];
113
+
114
+ // Login user.
115
+ if ( empty( $user ) || -1 === $user['user_id'] ) {
116
+ edd_set_error( 'invalid_user', __( 'The user information is invalid', 'easy-digital-downloads' ) );
117
+ return false;
118
+ } else {
119
+ edd_log_user_in( $user['user_id'], $user['user_login'], $user['user_pass'] );
120
+ }
121
+ }
122
+
123
+ remove_action( 'set_logged_in_cookie', 'edds_set_logged_in_cookie_global' );
124
+ }
125
+
126
+ // Check guest checkout.
127
+ if ( false === $user && false === edd_no_guest_checkout() ) {
128
+ // Set user.
129
+ $user = $valid_data['guest_user_data'];
130
+ }
131
+
132
+ // Verify we have an user.
133
+ if ( false === $user || empty( $user ) ) {
134
+ return false;
135
+ }
136
+
137
+ // Get user first name.
138
+ if ( ! isset( $user['user_first'] ) || strlen( trim( $user['user_first'] ) ) < 1 ) {
139
+ $user['user_first'] = isset( $_POST["edd_first"] ) ? strip_tags( trim( $_POST["edd_first"] ) ) : '';
140
+ }
141
+
142
+ // Get user last name.
143
+ if ( ! isset( $user['user_last'] ) || strlen( trim( $user['user_last'] ) ) < 1 ) {
144
+ $user['user_last'] = isset( $_POST["edd_last"] ) ? strip_tags( trim( $_POST["edd_last"] ) ) : '';
145
+ }
146
+
147
+ // Get the user's billing address details.
148
+ $user['address'] = array();
149
+ $user['address']['line1'] = ! empty( $_POST['card_address'] ) ? sanitize_text_field( $_POST['card_address'] ) : '';
150
+ $user['address']['line2'] = ! empty( $_POST['card_address_2'] ) ? sanitize_text_field( $_POST['card_address_2'] ) : '';
151
+ $user['address']['city'] = ! empty( $_POST['card_city'] ) ? sanitize_text_field( $_POST['card_city'] ) : '';
152
+ $user['address']['state'] = ! empty( $_POST['card_state'] ) ? sanitize_text_field( $_POST['card_state'] ) : '';
153
+ $user['address']['country'] = ! empty( $_POST['billing_country'] ) ? sanitize_text_field( $_POST['billing_country'] ) : '';
154
+ $user['address']['zip'] = ! empty( $_POST['card_zip'] ) ? sanitize_text_field( $_POST['card_zip'] ) : '';
155
+
156
+ if ( empty( $user['address']['country'] ) ) {
157
+ $user['address'] = false; // Country will always be set if address fields are present.
158
+ }
159
+
160
+ if ( ! empty( $user['user_id'] ) && $user['user_id'] > 0 && ! empty( $user['address'] ) ) {
161
+ // EDD3: Add the customer address if it doesn't already exist.
162
+ if ( function_exists( 'edd_maybe_add_customer_address' ) ) {
163
+ $customer = edd_get_customer_by( 'user_id', $user['user_id'] );
164
+ if ( $customer ) {
165
+ edd_maybe_add_customer_address( $customer->id, $user['address'] );
166
+ }
167
+ } else {
168
+ // Store the address in the user's meta so the cart can be pre-populated with it on return purchases.
169
+ update_user_meta( $user['user_id'], '_edd_user_address', $user['address'] );
170
+ }
171
+ }
172
+
173
+ // Return valid user.
174
+ return $user;
175
+ }
176
+
177
+ /**
178
+ * A rewritten version of `edd_process_purchase_form()` that allows for full AJAX processing.
179
+ *
180
+ * `edd_process_purchase_form()` is run up until:
181
+ *
182
+ * if ( $is_ajax ) {
183
+ * echo 'success';
184
+ * edd_die();
185
+ * }
186
+ *
187
+ * Then this function is called which reruns the start of `edd_process_purchase_form()` and
188
+ * continues the rest of the processing.
189
+ *
190
+ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/includes/process-purchase.php
191
+ *
192
+ * @since 2.7.0
193
+ */
194
+ function _edds_process_purchase_form() {
195
+ // Catch exceptions at a high level.
196
+ try {
197
+ // `edd_process_purchase_form()` and subsequent code executions are written
198
+ // expecting form processing to happen via a POST request from a client form.
199
+ //
200
+ // This version is called from an AJAX POST request, so the form data is sent
201
+ // in a serialized string to ensure all fields are available.
202
+ //
203
+ // Map and merge formData to $_POST so it's accessible in other functions.
204
+ parse_str( $_POST['form_data'], $form_data );
205
+ $_POST = array_merge( $_POST, $form_data );
206
+ $_REQUEST = array_merge( $_REQUEST, $_POST );
207
+
208
+ /**
209
+ * @since unknown
210
+ * @todo document
211
+ */
212
+ do_action( 'edd_pre_process_purchase' );
213
+
214
+ // Make sure the cart isn't empty.
215
+ if ( ! edd_get_cart_contents() && ! edd_cart_has_fees() ) {
216
+ throw new \Exception( esc_html__( 'Your cart is empty.', 'easy-digital-downloads' ) );
217
+ }
218
+
219
+ if ( ! isset( $_POST['edd-process-checkout-nonce'] ) ) {
220
+ edd_debug_log( __( 'Missing nonce when processing checkout. Please read the following for more information: https://easydigitaldownloads.com/development/2018/07/05/important-update-to-ajax-requests-in-easy-digital-downloads-2-9-4', 'easy-digital-downloads' ), true );
221
+ }
222
+
223
+ $nonce = isset( $_POST['edd-process-checkout-nonce'] ) ? sanitize_text_field( $_POST['edd-process-checkout-nonce'] ) : '';
224
+ $nonce_verified = wp_verify_nonce( $nonce, 'edd-process-checkout' );
225
+
226
+ if ( false === $nonce_verified ) {
227
+ throw new \Exception( esc_html__( 'Error processing purchase. Please reload the page and try again.', 'easy-digital-downloads' ) );
228
+ }
229
+
230
+ // Validate the form $_POST data.
231
+ $valid_data = edd_purchase_form_validate_fields();
232
+
233
+ // Allow themes and plugins to hook to errors.
234
+ //
235
+ // In the future these should throw exceptions, existing `edd_set_error()` usage will be caught below.
236
+ do_action( 'edd_checkout_error_checks', $valid_data, $_POST );
237
+
238
+ // Validate the user.
239
+ $user = _edds_get_purchase_form_user( $valid_data );
240
+
241
+ // Let extensions validate fields after user is logged in if user has used login/registration form
242
+ do_action( 'edd_checkout_user_error_checks', $user, $valid_data, $_POST );
243
+
244
+ if ( false === $valid_data || edd_get_errors() || ! $user ) {
245
+ $errors = edd_get_errors();
246
+
247
+ if ( is_array( $errors ) ) {
248
+ throw new \Exception( current( $errors ) );
249
+ }
250
+ }
251
+
252
+ // Setup user information.
253
+ $user_info = array(
254
+ 'id' => $user['user_id'],
255
+ 'email' => $user['user_email'],
256
+ 'first_name' => $user['user_first'],
257
+ 'last_name' => $user['user_last'],
258
+ 'discount' => $valid_data['discount'],
259
+ 'address' => ! empty( $user['address'] ) ? $user['address'] : array(),
260
+ );
261
+
262
+ // Update a customer record if they have added/updated information.
263
+ $customer = new EDD_Customer( $user_info['email'] );
264
+
265
+ $name = $user_info['first_name'] . ' ' . $user_info['last_name'];
266
+
267
+ if ( empty( $customer->name ) || $name != $customer->name ) {
268
+ $update_data = array(
269
+ 'name' => $name
270
+ );
271
+
272
+ // Update the customer's name and update the user record too.
273
+ $customer->update( $update_data );
274
+
275
+ wp_update_user( array(
276
+ 'ID' => get_current_user_id(),
277
+ 'first_name' => $user_info['first_name'],
278
+ 'last_name' => $user_info['last_name']
279
+ ) );
280
+ }
281
+
282
+ // Update the customer's address if different to what's in the database
283
+ $address = wp_parse_args( $user_info['address'], array(
284
+ 'line1' => '',
285
+ 'line2' => '',
286
+ 'city' => '',
287
+ 'state' => '',
288
+ 'country' => '',
289
+ 'zip' => '',
290
+ ) );
291
+
292
+ $address = array(
293
+ 'address' => $address['line1'],
294
+ 'address2' => $address['line2'],
295
+ 'city' => $address['city'],
296
+ 'region' => $address['state'],
297
+ 'country' => $address['country'],
298
+ 'postal_code' => $address['zip'],
299
+ );
300
+
301
+ if ( ! empty( $user['user_id'] ) && $user['user_id'] > 0 && ! empty( $address ) ) {
302
+ // EDD3: Add the customer address if it doesn't already exist.
303
+ if ( function_exists( 'edd_maybe_add_customer_address' ) ) {
304
+ $customer = edd_get_customer_by( 'user_id', $user['user_id'] );
305
+ if ( $customer ) {
306
+ edd_maybe_add_customer_address( $customer->id, $user['address'] );
307
+ }
308
+ } else {
309
+ // Store the address in the user's meta so the cart can be pre-populated with it on return purchases.
310
+ update_user_meta( $user['user_id'], '_edd_user_address', $user['address'] );
311
+ }
312
+ }
313
+
314
+ $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
315
+
316
+ $card_country = isset( $valid_data['cc_info']['card_country'] ) ? $valid_data['cc_info']['card_country'] : false;
317
+ $card_state = isset( $valid_data['cc_info']['card_state'] ) ? $valid_data['cc_info']['card_state'] : false;
318
+ $card_zip = isset( $valid_data['cc_info']['card_zip'] ) ? $valid_data['cc_info']['card_zip'] : false;
319
+
320
+ // Set up the unique purchase key. If we are resuming a payment, we'll overwrite this with the existing key.
321
+ $purchase_key = strtolower( md5( $user['user_email'] . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'edd', true ) ) );
322
+ $existing_payment = EDD()->session->get( 'edd_resume_payment' );
323
+
324
+ if ( ! empty( $existing_payment ) ) {
325
+ $payment = new EDD_Payment( $existing_payment );
326
+
327
+ if( $payment->is_recoverable() && ! empty( $payment->key ) ) {
328
+ $purchase_key = $payment->key;
329
+ }
330
+ }
331
+
332
+ // Setup purchase information.
333
+ $purchase_data = array(
334
+ 'downloads' => edd_get_cart_contents(),
335
+ 'fees' => edd_get_cart_fees(), // Any arbitrary fees that have been added to the cart
336
+ 'subtotal' => edd_get_cart_subtotal(), // Amount before taxes and discounts
337
+ 'discount' => edd_get_cart_discounted_amount(), // Discounted amount
338
+ 'tax' => edd_get_cart_tax(), // Taxed amount
339
+ 'tax_rate' => edd_use_taxes() ? edd_get_cart_tax_rate( $card_country, $card_state, $card_zip ) : 0, // Tax rate
340
+ 'price' => edd_get_cart_total(), // Amount after taxes
341
+ 'purchase_key' => $purchase_key,
342
+ 'user_email' => $user['user_email'],
343
+ 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
344
+ 'user_info' => stripslashes_deep( $user_info ),
345
+ 'post_data' => $_POST,
346
+ 'cart_details' => edd_get_cart_content_details(),
347
+ 'gateway' => $valid_data['gateway'],
348
+ 'card_info' => $valid_data['cc_info']
349
+ );
350
+
351
+ // Add the user data for hooks
352
+ $valid_data['user'] = $user;
353
+
354
+ // Allow themes and plugins to hook before the gateway
355
+ do_action( 'edd_checkout_before_gateway', $_POST, $user_info, $valid_data );
356
+
357
+ // Store payment method data.
358
+ $purchase_data['gateway_nonce'] = wp_create_nonce( 'edd-gateway' );
359
+
360
+ // Allow the purchase data to be modified before it is sent to the gateway
361
+ $purchase_data = apply_filters(
362
+ 'edd_purchase_data_before_gateway',
363
+ $purchase_data,
364
+ $valid_data
365
+ );
366
+
367
+ // Setup the data we're storing in the purchase session
368
+ $session_data = $purchase_data;
369
+
370
+ // Used for showing download links to non logged-in users after purchase, and for other plugins needing purchase data.
371
+ edd_set_purchase_session( $session_data );
372
+
373
+ /**
374
+ * Allows further processing...
375
+ */
376
+ do_action( 'edd_gateway_' . $purchase_data['gateway'], $purchase_data );
377
+ } catch( \Exception $e ) {
378
+ return wp_send_json_error( array(
379
+ 'message' => $e->getMessage(),
380
+ ) );
381
+ }
382
+ }
383
+ add_action( 'wp_ajax_edds_process_purchase_form', '_edds_process_purchase_form' );
384
+ add_action( 'wp_ajax_nopriv_edds_process_purchase_form', '_edds_process_purchase_form' );
385
+
386
+ if ( ! function_exists( 'edd_is_dev_environment' ) ) {
387
+ /**
388
+ * Check the network site URL for signs of being a development environment.
389
+ *
390
+ * @since 3.0
391
+ *
392
+ * @return bool $retval True if dev, false if not.
393
+ */
394
+ function edd_is_dev_environment() {
395
+
396
+ // Assume not a development environment
397
+ $retval = false;
398
+
399
+ // Get this one time and use it below
400
+ $network_url = network_site_url( '/' );
401
+
402
+ // Possible strings
403
+ $strings = array(
404
+
405
+ // Popular port suffixes
406
+ ':8888', // This is common with MAMP on OS X
407
+
408
+ // Popular development TLDs
409
+ '.dev', // VVV
410
+ '.local', // Local
411
+ '.test', // IETF
412
+ '.example', // IETF
413
+ '.invalid', // IETF
414
+ '.localhost', // IETF
415
+
416
+ // Popular development subdomains
417
+ 'dev.',
418
+
419
+ // Popular development domains
420
+ 'localhost',
421
+ 'example.com',
422
+ );
423
+
424
+ // Loop through all strings
425
+ foreach ( $strings as $string ) {
426
+ if ( stristr( $network_url, $string ) ) {
427
+ $retval = $string;
428
+ break;
429
+ }
430
+ }
431
+
432
+ // Filter & return
433
+ return apply_filters( 'edd_is_dev_environment', $retval );
434
+ }
435
+ }
includes/gateways/stripe/includes/deprecated.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manage deprecations.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Process stripe checkout submission
11
+ *
12
+ * @access public
13
+ * @since 1.0
14
+ * @return void
15
+ */
16
+ function edds_process_stripe_payment( $purchase_data ) {
17
+ _edd_deprecated_function( 'edds_process_stripe_payment', '2.7.0', 'edds_process_purchase_form', debug_backtrace() );
18
+
19
+ return edds_process_purchase_form( $purchase_data );
20
+ }
21
+
22
+ /**
23
+ * Database Upgrade actions
24
+ *
25
+ * @access public
26
+ * @since 2.5.8
27
+ * @return void
28
+ */
29
+ function edds_plugin_database_upgrades() {
30
+ _edd_deprecated_function(
31
+ __FUNCTION__,
32
+ '2.8.1',
33
+ null,
34
+ debug_backtrace()
35
+ );
36
+
37
+ edd_stripe()->database_upgrades();
38
+ }
39
+
40
+ /**
41
+ * Internationalization
42
+ *
43
+ * @since 1.6.6
44
+ * @return void
45
+ */
46
+ function edds_textdomain() {
47
+ _edd_deprecated_function(
48
+ __FUNCTION__,
49
+ '2.8.1',
50
+ null,
51
+ debug_backtrace()
52
+ );
53
+
54
+ edd_stripe()->load_textdomain();
55
+ }
56
+
57
+ /**
58
+ * Register our payment gateway
59
+ *
60
+ * @since 1.0
61
+ * @return array
62
+ */
63
+ function edds_register_gateway( $gateways ) {
64
+ _edd_deprecated_function(
65
+ __FUNCTION__,
66
+ '2.8.1',
67
+ null,
68
+ debug_backtrace()
69
+ );
70
+
71
+ return edd_stripe()->register_gateway( $gateways );
72
+ }
includes/gateways/stripe/includes/elements.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Stripe Elements functionality.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Retrieves the styles passed to the Stripe Elements instance.
11
+ *
12
+ * @since 2.7.0
13
+ *
14
+ * @link https://stripe.com/docs/stripe-js
15
+ * @link https://stripe.com/docs/stripe-js/reference#elements-create
16
+ * @link https://stripe.com/docs/stripe-js/reference#element-options
17
+ *
18
+ * @return array
19
+ */
20
+ function edds_get_stripe_elements_styles() {
21
+ $elements_styles = array();
22
+
23
+ /**
24
+ * Filters the styles used to create the Stripe Elements card field.
25
+ *
26
+ * @since 2.7.0
27
+ *
28
+ * @link https://stripe.com/docs/stripe-js/reference#element-options
29
+ *
30
+ * @param array $elements_styles Styles used to create Stripe Elements card field.
31
+ */
32
+ $elements_styles = apply_filters( 'edds_stripe_elements_styles', $elements_styles );
33
+
34
+ return $elements_styles;
35
+ }
36
+
37
+ /**
38
+ * Retrieves the options passed to the Stripe Elements instance.
39
+ *
40
+ * @since 2.7.0
41
+ *
42
+ * @link https://stripe.com/docs/stripe-js
43
+ * @link https://stripe.com/docs/stripe-js/reference#elements-create
44
+ * @link https://stripe.com/docs/stripe-js/reference#element-options
45
+ *
46
+ * @return array
47
+ */
48
+ function edds_get_stripe_elements_options() {
49
+ $elements_options = array(
50
+ 'hidePostalCode' => true,
51
+ 'i18n' => array(
52
+ 'errorMessages' => edds_get_localized_error_messages(),
53
+ ),
54
+ );
55
+ $elements_styles = edds_get_stripe_elements_styles();
56
+
57
+ if ( ! empty( $elements_styles ) ) {
58
+ $elements_options['style'] = $styles;
59
+ }
60
+
61
+ /**
62
+ * Filters the options used to create the Stripe Elements card field.
63
+ *
64
+ * @since 2.7.0
65
+ *
66
+ * @link https://stripe.com/docs/stripe-js/reference#element-options
67
+ *
68
+ * @param array $elements_options Options used to create Stripe Elements card field.
69
+ */
70
+ $elements_options = apply_filters( 'edds_stripe_elements_options', $elements_options );
71
+
72
+ // Elements doesn't like an empty array (which won't be converted to an object in JS).
73
+ if ( empty( $elements_options ) ) {
74
+ return null;
75
+ }
76
+
77
+ return $elements_options;
78
+ }
includes/gateways/stripe/includes/emails.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment emails.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Notify a customer that a Payment needs further action.
11
+ *
12
+ * @since 2.7.0
13
+ *
14
+ * @param int $payment_id EDD Payment ID.
15
+ */
16
+ function edds_preapproved_payment_needs_action_notification( $payment_id ) {
17
+ $payment = edd_get_payment( $payment_id );
18
+ $payment_data = $payment->get_meta( '_edd_payment_meta', true );
19
+
20
+ $from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
21
+ $from_name = apply_filters( 'edd_purchase_from_name', $from_name, $payment_id, $payment_data );
22
+ $from_email = edd_get_option( 'from_email', get_bloginfo( 'admin_email' ) );
23
+ $from_email = apply_filters( 'edd_purchase_from_address', $from_email, $payment_id, $payment_data );
24
+
25
+ if ( empty( $to_email ) ) {
26
+ $to_email = $payment->email;
27
+ }
28
+
29
+ $subject = esc_html__( 'Your Preapproved Payment Requires Action', 'easy-digital-downloads' );
30
+ $heading = edd_do_email_tags( esc_html__( 'Payment Requires Action', 'easy-digital-downloads' ), $payment_id );
31
+
32
+ $message = esc_html__( 'Dear {name},', 'easy-digital-downloads' ) . "\n\n";
33
+ $message .= esc_html__( 'Your preapproved payment requires further action before your purchase can be completed. Please click the link below to take finalize your purchase', 'easy-digital-downloads' ) . "\n\n";
34
+ $message .= esc_url( add_query_arg( 'payment_key', $payment->key, edd_get_success_page_uri() ) );
35
+ $message = edd_do_email_tags( $message, $payment_id );
36
+
37
+ /** This filter is documented in easy-digital-downloads/includes/emails/template.php */
38
+ $message = apply_filters( 'edd_email_template_wpautop', true ) ? wpautop( $message ) : $message;
39
+
40
+ $emails = EDD()->emails;
41
+
42
+ $emails->__set( 'from_name', $from_name );
43
+ $emails->__set( 'from_email', $from_email );
44
+ $emails->__set( 'heading', $heading );
45
+
46
+ $headers = $emails->get_headers();
47
+ $emails->__set( 'headers', $headers );
48
+
49
+ $emails->send( $to_email, $subject, $message );
50
+ }
51
+ add_action( 'edds_preapproved_payment_needs_action', 'edds_preapproved_payment_needs_action_notification' );
includes/gateways/stripe/includes/functions.php ADDED
@@ -0,0 +1,550 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since unknown
7
+ */
8
+
9
+ /**
10
+ * Returns the one true instance of EDD_Stripe
11
+ *
12
+ * @since 2.6
13
+ *
14
+ * @return void|\EDD_Stripe EDD_Stripe instance or void if Easy Digital
15
+ * Downloads is not active.
16
+ */
17
+ function edd_stripe() {
18
+ // Easy Digital Downloads is not active, do nothing.
19
+ if ( ! function_exists( 'EDD' ) ) {
20
+ return;
21
+ }
22
+
23
+ return EDD_Stripe::instance();
24
+ }
25
+
26
+ /**
27
+ * Determines if the current execution of Stripe is being loaded from the
28
+ * "Pro" version of the gateway.
29
+ *
30
+ * (Currently) when Stripe is packaged with EDD core the bootstrap file is
31
+ * renamed to `edds_stripe_bootstrap_core()` to prevent collision.
32
+ *
33
+ * @since 2.8.1
34
+ *
35
+ * @return bool True if the "Pro" version of the gateway is loaded.
36
+ */
37
+ function edds_is_pro() {
38
+ return function_exists( 'edd_stripe_bootstrap' );
39
+ }
40
+
41
+ /**
42
+ * Determines if the Stripe gateway is active.
43
+ *
44
+ * This checks both application requirements being met as
45
+ * well as the gateway being enabled via Payment Gateways settings.
46
+ *
47
+ * @since 2.8.1
48
+ *
49
+ * @return bool
50
+ */
51
+ function edds_is_gateway_active() {
52
+ if ( false === edds_has_met_requirements() ) {
53
+ return false;
54
+ }
55
+
56
+ if ( false === edd_is_gateway_active( 'stripe' ) ) {
57
+ return false;
58
+ }
59
+
60
+ return true;
61
+ }
62
+
63
+ /**
64
+ * Determines of the application requirements have been met.
65
+ *
66
+ * @since 2.8.1
67
+ *
68
+ * @param false|string $requirement Specific requirement to check for.
69
+ * False ensures all requirements are met.
70
+ * Default false.
71
+ * @return bool True if the requirement(s) is met.
72
+ */
73
+ function edds_has_met_requirements( $requirement = false ) {
74
+ $requirements = array(
75
+ 'php' => (
76
+ version_compare( PHP_VERSION, '5.6.0', '>' )
77
+ ),
78
+ 'edd' => (
79
+ defined( 'EDD_VERSION' )
80
+ ? version_compare( EDD_VERSION, '2.8.99', '>' )
81
+ : true
82
+ ),
83
+ 'recurring' => (
84
+ defined( 'EDD_RECURRING_VERSION' )
85
+ ? version_compare( EDD_RECURRING_VERSION, '2.9.99', '>' )
86
+ : true
87
+ ),
88
+ );
89
+
90
+ if ( false === $requirement ) {
91
+ return false === in_array( false, $requirements, true );
92
+ } else {
93
+ return isset( $requirements[ $requirement ] )
94
+ ? $requirements[ $requirement ]
95
+ : true;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Allows preconfigured Stripe API requests to be made.
101
+ *
102
+ * @since 2.7.0
103
+ *
104
+ * @throws \EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found When attempting to call an object or method that is not available.
105
+ * @throws \Stripe\Exception
106
+ *
107
+ * @param string $object Name of the Stripe object to request.
108
+ * @param string $method Name of the API operation to perform during the request.
109
+ * @param mixed ...$args Additional arguments to pass to the request.
110
+ * @return \Stripe\StripeObject
111
+ */
112
+ function edds_api_request( $object, $method, $args = null ) {
113
+ $api = new EDD_Stripe_API();
114
+
115
+ return call_user_func_array( array( $api, 'request' ), func_get_args() );
116
+ }
117
+
118
+ /**
119
+ * Converts a truthy value (e.g. '1', 'yes') to a bool.
120
+ *
121
+ * @since 2.8.0
122
+ *
123
+ * @param mixed $truthy_value Truthy value.
124
+ * @return bool
125
+ */
126
+ function edds_truthy_to_bool( $truthy_value ) {
127
+ $truthy = array(
128
+ 'yes',
129
+ 1,
130
+ '1',
131
+ 'true',
132
+ );
133
+
134
+ return is_bool( $truthy_value )
135
+ ? $truthy_value
136
+ : in_array( strtolower( $truthy_value ), $truthy, true );
137
+ }
138
+
139
+ /**
140
+ * Retrieve the exsting cards setting.
141
+ * @return bool
142
+ */
143
+ function edd_stripe_existing_cards_enabled() {
144
+ $use_existing_cards = edd_get_option( 'stripe_use_existing_cards', false );
145
+ return ! empty( $use_existing_cards );
146
+ }
147
+
148
+ /**
149
+ * Given a user ID, retrieve existing cards within stripe.
150
+ *
151
+ * @since 2.6
152
+ * @param int $user_id
153
+ *
154
+ * @return array
155
+ */
156
+ function edd_stripe_get_existing_cards( $user_id = 0 ) {
157
+ if ( empty( $user_id ) ) {
158
+ return array();
159
+ }
160
+
161
+ $enabled = edd_stripe_existing_cards_enabled();
162
+
163
+ if ( ! $enabled ) {
164
+ return array();
165
+ }
166
+
167
+ static $existing_cards;
168
+
169
+ if ( ! is_null( $existing_cards ) && array_key_exists( $user_id, $existing_cards ) ) {
170
+ return $existing_cards[ $user_id ];
171
+ }
172
+
173
+ // Check if the user has existing cards
174
+ $customer_cards = array();
175
+ $stripe_customer_id = edds_get_stripe_customer_id( $user_id );
176
+
177
+ if ( ! empty( $stripe_customer_id ) ) {
178
+ try {
179
+ $stripe_customer = edds_api_request( 'Customer', 'retrieve', $stripe_customer_id );
180
+
181
+ if ( isset( $stripe_customer->deleted ) && $stripe_customer->deleted ) {
182
+ return $customer_cards;
183
+ }
184
+
185
+ $payment_methods = edds_api_request( 'PaymentMethod', 'all', array(
186
+ 'type' => 'card',
187
+ 'customer' => $stripe_customer->id,
188
+ 'limit' => 100,
189
+ ) );
190
+
191
+ $cards = edds_api_request( 'Customer', 'allSources', $stripe_customer->id, array(
192
+ 'limit' => 100,
193
+ ) );
194
+
195
+ $sources = array_merge( $payment_methods->data, $cards->data );
196
+
197
+ foreach ( $sources as $source ) {
198
+ if ( ! in_array( $source->object, array( 'payment_method', 'card' ), true ) ) {
199
+ continue;
200
+ }
201
+
202
+ $source_data = new stdClass();
203
+ $source_data->id = $source->id;
204
+
205
+ switch( $source->object ) {
206
+ case 'payment_method':
207
+ $source_data->brand = ucwords( $source->card->brand );
208
+ $source_data->last4 = $source->card->last4;
209
+ $source_data->exp_month = $source->card->exp_month;
210
+ $source_data->exp_year = $source->card->exp_year;
211
+ $source_data->fingerprint = $source->card->fingerprint;
212
+ $source_data->address_line1 = $source->billing_details->address->line1;
213
+ $source_data->address_line2 = $source->billing_details->address->line2;
214
+ $source_data->address_city = $source->billing_details->address->city;
215
+ $source_data->address_zip = $source->billing_details->address->postal_code;
216
+ $source_data->address_state = $source->billing_details->address->state;
217
+ $source_data->address_country = $source->billing_details->address->country;
218
+
219
+ $customer_cards[ $source->id ]['default'] = $source->id === $stripe_customer->invoice_settings->default_payment_method;
220
+ break;
221
+ case 'card':
222
+ $source_data->brand = $source->brand;
223
+ $source_data->last4 = $source->last4;
224
+ $source_data->exp_month = $source->exp_month;
225
+ $source_data->exp_year = $source->exp_year;
226
+ $source_data->fingerprint = $source->fingerprint;
227
+ $source_data->address_line1 = $source->address_line1;
228
+ $source_data->address_line2 = $source->address_line2;
229
+ $source_data->address_city = $source->address_city;
230
+ $source_data->address_zip = $source->address_zip;
231
+ $source_data->address_state = $source->address_state;
232
+ $source_data->address_country = $source->address_country;
233
+ break;
234
+ }
235
+
236
+ $customer_cards[ $source->id ]['source'] = $source_data;
237
+ }
238
+ } catch ( Exception $e ) {
239
+ return $customer_cards;
240
+ }
241
+ }
242
+
243
+ // Show only the latest version of card for duplicates.
244
+ $fingerprints = array();
245
+ foreach ( $customer_cards as $key => $customer_card ) {
246
+ $fingerprint = $customer_card['source']->fingerprint;
247
+ if ( ! in_array( $fingerprint, $fingerprints ) ) {
248
+ $fingerprints[] = $fingerprint;
249
+ } else {
250
+ unset( $customer_cards[ $key ] );
251
+ }
252
+ }
253
+
254
+ // Put default card first.
255
+ usort(
256
+ $customer_cards,
257
+ function( $a, $b ) {
258
+ return $a['default'] ? 1 : -1;
259
+ }
260
+ );
261
+
262
+ $existing_cards[ $user_id ] = $customer_cards;
263
+
264
+ return $existing_cards[ $user_id ];
265
+ }
266
+
267
+ /**
268
+ * Look up the stripe customer id in user meta, and look to recurring if not found yet
269
+ *
270
+ * @since 2.4.4
271
+ * @since 2.6 Added lazy load for moving to customer meta and ability to look up by customer ID.
272
+ * @param int $id_or_email The user ID, customer ID or email to look up.
273
+ * @param bool $by_user_id If the lookup is by user ID or not.
274
+ *
275
+ * @return string Stripe customer ID
276
+ */
277
+ function edds_get_stripe_customer_id( $id_or_email, $by_user_id = true ) {
278
+ $stripe_customer_id = '';
279
+ $meta_key = edd_stripe_get_customer_key();
280
+
281
+ if ( is_email( $id_or_email ) ) {
282
+ $by_user_id = false;
283
+ }
284
+
285
+ $customer = new EDD_Customer( $id_or_email, $by_user_id );
286
+ if ( $customer->id > 0 ) {
287
+ $stripe_customer_id = $customer->get_meta( $meta_key );
288
+ }
289
+
290
+ if ( empty( $stripe_customer_id ) ) {
291
+ $user_id = 0;
292
+ if ( ! empty( $customer->user_id ) ) {
293
+ $user_id = $customer->user_id;
294
+ } else if ( $by_user_id && is_numeric( $id_or_email ) ) {
295
+ $user_id = $id_or_email;
296
+ } else if ( is_email( $id_or_email ) ) {
297
+ $user = get_user_by( 'email', $id_or_email );
298
+ if ( $user ) {
299
+ $user_id = $user->ID;
300
+ }
301
+ }
302
+
303
+ if ( ! isset( $user ) ) {
304
+ $user = get_user_by( 'id', $user_id );
305
+ }
306
+
307
+ if ( $user ) {
308
+
309
+ $customer = new EDD_Customer( $user->user_email );
310
+
311
+ if ( ! empty( $user_id ) ) {
312
+ $stripe_customer_id = get_user_meta( $user_id, $meta_key, true );
313
+
314
+ // Lazy load migrating data over to the customer meta from Stripe issue #113
315
+ $customer->update_meta( $meta_key, $stripe_customer_id );
316
+ }
317
+
318
+ }
319
+
320
+ }
321
+
322
+ if ( empty( $stripe_customer_id ) && class_exists( 'EDD_Recurring_Subscriber' ) ) {
323
+
324
+ $subscriber = new EDD_Recurring_Subscriber( $id_or_email, $by_user_id );
325
+
326
+ if ( $subscriber->id > 0 ) {
327
+
328
+ $verified = false;
329
+
330
+ if ( ( $by_user_id && $id_or_email == $subscriber->user_id ) ) {
331
+ // If the user ID given, matches that of the subscriber
332
+ $verified = true;
333
+ } else {
334
+ // If the email used is the same as the primary email
335
+ if ( $subscriber->email == $id_or_email ) {
336
+ $verified = true;
337
+ }
338
+
339
+ // If the email is in the EDD 2.6 Additional Emails
340
+ if ( property_exists( $subscriber, 'emails' ) && in_array( $id_or_email, $subscriber->emails ) ) {
341
+ $verified = true;
342
+ }
343
+ }
344
+
345
+ if ( $verified ) {
346
+ $stripe_customer_id = $subscriber->get_recurring_customer_id( 'stripe' );
347
+ }
348
+
349
+ }
350
+
351
+ if ( ! empty( $stripe_customer_id ) ) {
352
+ $customer->update_meta( $meta_key, $stripe_customer_id );
353
+ }
354
+
355
+ }
356
+
357
+ return $stripe_customer_id;
358
+ }
359
+
360
+ /**
361
+ * Get the meta key for storing Stripe customer IDs in
362
+ *
363
+ * @access public
364
+ * @since 1.6.7
365
+ * @return string
366
+ */
367
+ function edd_stripe_get_customer_key() {
368
+
369
+ $key = '_edd_stripe_customer_id';
370
+ if( edd_is_test_mode() ) {
371
+ $key .= '_test';
372
+ }
373
+ return $key;
374
+ }
375
+
376
+ /**
377
+ * Determines if the shop is using a zero-decimal currency
378
+ *
379
+ * @access public
380
+ * @since 1.8.4
381
+ * @return bool
382
+ */
383
+ function edds_is_zero_decimal_currency() {
384
+
385
+ $ret = false;
386
+ $currency = edd_get_currency();
387
+
388
+ switch( $currency ) {
389
+
390
+ case 'BIF' :
391
+ case 'CLP' :
392
+ case 'DJF' :
393
+ case 'GNF' :
394
+ case 'JPY' :
395
+ case 'KMF' :
396
+ case 'KRW' :
397
+ case 'MGA' :
398
+ case 'PYG' :
399
+ case 'RWF' :
400
+ case 'VND' :
401
+ case 'VUV' :
402
+ case 'XAF' :
403
+ case 'XOF' :
404
+ case 'XPF' :
405
+
406
+ $ret = true;
407
+ break;
408
+
409
+ }
410
+
411
+ return $ret;
412
+ }
413
+
414
+ /**
415
+ * Retrieves a sanitized statement descriptor.
416
+ *
417
+ * @since 2.6.19
418
+ *
419
+ * @return string $statement_descriptor Sanitized statement descriptor.
420
+ */
421
+ function edds_get_statement_descriptor() {
422
+ $statement_descriptor = edd_get_option( 'stripe_statement_descriptor', '' );
423
+ $statement_descriptor = edds_sanitize_statement_descriptor( $statement_descriptor );
424
+
425
+ return $statement_descriptor;
426
+ }
427
+
428
+ /**
429
+ * Retrieves a list of unsupported characters for Stripe statement descriptors.
430
+ *
431
+ * @since 2.6.19
432
+ *
433
+ * @return array $unsupported_characters List of unsupported characters.
434
+ */
435
+ function edds_get_statement_descriptor_unsupported_characters() {
436
+ $unsupported_characters = array(
437
+ '<',
438
+ '>',
439
+ '"',
440
+ '\'',
441
+ '\\',
442
+ '*',
443
+ );
444
+
445
+ /**
446
+ * Filters the list of unsupported characters for Stripe statement descriptors.
447
+ *
448
+ * @since 2.6.19
449
+ *
450
+ * @param array $unsupported_characters List of unsupported characters.
451
+ */
452
+ $unsupported_characters = apply_filters( 'edds_get_statement_descriptor_unsupported_characters', $unsupported_characters );
453
+
454
+ return $unsupported_characters;
455
+ }
456
+
457
+ /**
458
+ * Sanitizes a string to be used for a statement descriptor.
459
+ *
460
+ * @since 2.6.19
461
+ *
462
+ * @link https://stripe.com/docs/connect/statement-descriptors#requirements
463
+ *
464
+ * @param string $statement_descriptor Statement descriptor to sanitize.
465
+ * @return string $statement_descriptor Sanitized statement descriptor.
466
+ */
467
+ function edds_sanitize_statement_descriptor( $statement_descriptor ) {
468
+ $unsupported_characters = edds_get_statement_descriptor_unsupported_characters();
469
+
470
+ $statement_descriptor = trim( str_replace( $unsupported_characters, '', $statement_descriptor ) );
471
+ $statement_descriptor = substr( $statement_descriptor, 0, 22 );
472
+
473
+ return $statement_descriptor;
474
+ }
475
+
476
+ /**
477
+ * Retrieves a given registry instance by name.
478
+ *
479
+ * @since 2.6.19
480
+ *
481
+ * @param string $name Registry name.
482
+ * @return null|EDD_Stripe_Registry Null if the registry doesn't exist, otherwise the object instance.
483
+ */
484
+ function edds_get_registry( $name ) {
485
+ switch( $name ) {
486
+ case 'admin-notices':
487
+ $registry = EDD_Stripe_Admin_Notices_Registry::instance();
488
+ break;
489
+ default:
490
+ $registry = null;
491
+ break;
492
+ }
493
+
494
+ return $registry;
495
+ }
496
+
497
+ /**
498
+ * Attempts to verify a nonce from various payment forms when the origin
499
+ * of the action isn't explicitly known.
500
+ *
501
+ * This could be coming from the Checkout, Payment Authorization,
502
+ * or Update Payment Method (Recurring) form.
503
+ *
504
+ * @since 2.8.0
505
+ *
506
+ * @return bool
507
+ */
508
+ function edds_verify_payment_form_nonce() {
509
+ // Checkout.
510
+ $nonce = isset( $_POST['edd-process-checkout-nonce'] )
511
+ ? sanitize_text_field( $_POST['edd-process-checkout-nonce'] )
512
+ : '';
513
+
514
+ if ( ! empty( $nonce ) ) {
515
+ return wp_verify_nonce( $nonce, 'edd-process-checkout' );
516
+ }
517
+
518
+ // Update Payment Method.
519
+ $nonce = isset( $_POST['edd_recurring_update_nonce'] )
520
+ ? sanitize_text_field( $_POST['edd_recurring_update_nonce'] )
521
+ : '';
522
+
523
+ if ( ! empty( $nonce ) ) {
524
+ return wp_verify_nonce( $nonce, 'update-payment' );
525
+ }
526
+
527
+ return false;
528
+ }
529
+
530
+ /**
531
+ * Routes user to correct support documentation, depending on whether they are using Standard or Pro version of Stripe
532
+ *
533
+ * @since 2.8.1
534
+ * @param string $type The type of Stripe documentation.
535
+ * @return string
536
+ */
537
+ function edds_documentation_route( $type ) {
538
+ $base_url = 'https://docs.easydigitaldownloads.com/standard';
539
+
540
+ /**
541
+ * Filter to change EDD-Stripe support url.
542
+ *
543
+ * @since 2.8.1
544
+ * @param string $base_url The url string for EDD-Stripe standard.
545
+ */
546
+ $base_url = apply_filters( 'edds_documentation_route_base', $base_url );
547
+
548
+ return trailingslashit( $base_url ) . $type;
549
+
550
+ }
includes/gateways/stripe/includes/gateway-actions.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register payment statuses for preapproval
5
+ *
6
+ * @since 1.6
7
+ * @return void
8
+ */
9
+ function edds_register_post_statuses() {
10
+ register_post_status( 'preapproval_pending', array(
11
+ 'label' => _x( 'Preapproval Pending', 'Pending preapproved payment', 'easy-digital-downloads' ),
12
+ 'public' => true,
13
+ 'exclude_from_search' => false,
14
+ 'show_in_admin_all_list' => true,
15
+ 'show_in_admin_status_list' => true,
16
+ /* translators: %s Payment status count */
17
+ 'label_count' => _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'easy-digital-downloads' )
18
+ ) );
19
+ register_post_status( 'preapproval', array(
20
+ 'label' => _x( 'Preapproved', 'Preapproved payment', 'easy-digital-downloads' ),
21
+ 'public' => true,
22
+ 'exclude_from_search' => false,
23
+ 'show_in_admin_all_list' => true,
24
+ 'show_in_admin_status_list' => true,
25
+ /* translators: %s Payment status count */
26
+ 'label_count' => _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'easy-digital-downloads' )
27
+ ) );
28
+ register_post_status( 'cancelled', array(
29
+ 'label' => _x( 'Cancelled', 'Cancelled payment', 'easy-digital-downloads' ),
30
+ 'public' => true,
31
+ 'exclude_from_search' => false,
32
+ 'show_in_admin_all_list' => true,
33
+ 'show_in_admin_status_list' => true,
34
+ /* translators: %s Payment status count */
35
+ 'label_count' => _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'easy-digital-downloads' )
36
+ ) );
37
+ }
38
+ add_action( 'init', 'edds_register_post_statuses', 110 );
39
+
40
+ /**
41
+ * Register the statement_descriptor email tag.
42
+ *
43
+ * @since 2.6
44
+ * @return void
45
+ */
46
+ function edd_stripe_register_email_tags() {
47
+ $statement_descriptor = edds_get_statement_descriptor();
48
+ if ( ! empty( $statement_descriptor ) ) {
49
+ edd_add_email_tag( 'stripe_statement_descriptor', __( 'Outputs a line stating what charges will appear as on customer\'s credit card statements.', 'easy-digital-downloads' ), 'edd_stripe_statement_descriptor_template_tag' );
50
+ }
51
+ }
52
+ add_action( 'edd_add_email_tags', 'edd_stripe_register_email_tags' );
53
+
54
+ /**
55
+ * Swap the {statement_descriptor} email tag with the string from the option
56
+ *
57
+ * @since 2.6
58
+ * @param $payment_id
59
+ *
60
+ * @return mixed
61
+ */
62
+ function edd_stripe_statement_descriptor_template_tag( $payment_id ) {
63
+ $payment = new EDD_Payment( $payment_id );
64
+ if ( 'stripe' !== $payment->gateway ) {
65
+ return '';
66
+ }
67
+
68
+ $statement_descriptor = edds_get_statement_descriptor();
69
+ if ( empty( $statement_descriptor ) ) {
70
+ return '';
71
+ }
72
+
73
+ // If you want to filter this, use the %s to define where you want the actual statement descriptor to show in your message.
74
+ $email_tag_output = __( apply_filters( 'edd_stripe_statement_descriptor_email_tag', 'Charges will appear on your card statement as %s' ), 'easy-digital-downloads' );
75
+
76
+ return sprintf( $email_tag_output, $statement_descriptor );
77
+ }
includes/gateways/stripe/includes/gateway-filters.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Removes Stripe from active gateways if application requirements are not met.
5
+ *
6
+ * @since 2.8.1
7
+ *
8
+ * @param array $enabled_gateways Enabled gateways that allow purchasing.
9
+ * @return array
10
+ */
11
+ function edds_validate_gateway_requirements( $enabled_gateways ) {
12
+ if ( false === edds_has_met_requirements() ) {
13
+ unset( $enabled_gateways['stripe'] );
14
+ }
15
+
16
+ return $enabled_gateways;
17
+ }
18
+ add_filter( 'edd_enabled_payment_gateways', 'edds_validate_gateway_requirements', 20 );
19
+
20
+ /**
21
+ * Register our new payment status labels for EDD
22
+ *
23
+ * @since 1.6
24
+ * @return array
25
+ */
26
+ function edds_payment_status_labels( $statuses ) {
27
+ $statuses['preapproval'] = __( 'Preapproved', 'easy-digital-downloads' );
28
+ $statuses['preapproval_pending'] = __( 'Preapproval Pending', 'easy-digital-downloads' );
29
+ $statuses['cancelled'] = __( 'Cancelled', 'easy-digital-downloads' );
30
+ return $statuses;
31
+ }
32
+ add_filter( 'edd_payment_statuses', 'edds_payment_status_labels' );
33
+
34
+ /**
35
+ * Injects the Stripe token and customer email into the pre-gateway data
36
+ *
37
+ * @since 2.0
38
+ *
39
+ * @param array $purchase_data
40
+ * @return array
41
+ */
42
+ function edd_stripe_straight_to_gateway_data( $purchase_data ) {
43
+
44
+ $gateways = edd_get_enabled_payment_gateways();
45
+
46
+ if ( isset( $gateways['stripe'] ) ) {
47
+ $_REQUEST['edd-gateway'] = 'stripe';
48
+ $purchase_data['gateway'] = 'stripe';
49
+ }
50
+
51
+ return $purchase_data;
52
+ }
53
+ add_filter( 'edd_straight_to_gateway_purchase_data', 'edd_stripe_straight_to_gateway_data' );
54
+
55
+ /**
56
+ * Process the POST Data for the Credit Card Form, if a token wasn't supplied
57
+ *
58
+ * @since 2.2
59
+ * @return array The credit card data from the $_POST
60
+ */
61
+ function edds_process_post_data( $purchase_data ) {
62
+ if ( ! isset( $purchase_data['gateway'] ) || 'stripe' !== $purchase_data['gateway'] ) {
63
+ return;
64
+ }
65
+
66
+ if ( isset( $_POST['edd_stripe_existing_card'] ) && 'new' !== $_POST['edd_stripe_existing_card'] ) {
67
+ return;
68
+ }
69
+
70
+ // Require a name for new cards.
71
+ if ( ! isset( $_POST['card_name'] ) || strlen( trim( $_POST['card_name'] ) ) === 0 ) {
72
+ edd_set_error( 'no_card_name', __( 'Please enter a name for the credit card.', 'easy-digital-downloads' ) );
73
+ }
74
+ }
75
+ add_action( 'edd_checkout_error_checks', 'edds_process_post_data' );
76
+
77
+ /**
78
+ * Retrieves the locale used for Checkout modal window
79
+ *
80
+ * @since 2.5
81
+ * @return string The locale to use
82
+ */
83
+ function edds_get_stripe_checkout_locale() {
84
+ return apply_filters( 'edd_stripe_checkout_locale', 'auto' );
85
+ }
86
+
87
+ /**
88
+ * Sets the $_COOKIE global when a logged in cookie is available.
89
+ *
90
+ * We need the global to be immediately available so calls to wp_create_nonce()
91
+ * within the same session will use the newly available data.
92
+ *
93
+ * @since 2.8.0
94
+ *
95
+ * @link https://wordpress.stackexchange.com/a/184055
96
+ *
97
+ * @param string $logged_in_cookie The logged-in cookie value.
98
+ */
99
+ function edds_set_logged_in_cookie_global( $logged_in_cookie ) {
100
+ $_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie;
101
+ }
includes/gateways/stripe/includes/i18n.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Internationalization
4
+ *
5
+ * @package EDD_Stripe
6
+ * @copyright Copyright (c) 2020, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.0
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * Returns a list of error codes and corresponding localized error messages.
18
+ *
19
+ * @since 2.8.0
20
+ *
21
+ * @return array $error_list List of error codes and corresponding error messages.
22
+ */
23
+ function edds_get_localized_error_messages() {
24
+ $error_list = array(
25
+ 'invalid_number' => __( 'The card number is not a valid credit card number.', 'easy-digital-downloads' ),
26
+ 'invalid_expiry_month' => __( 'The card\'s expiration month is invalid.', 'easy-digital-downloads' ),
27
+ 'invalid_expiry_year' => __( 'The card\'s expiration year is invalid.', 'easy-digital-downloads' ),
28
+ 'invalid_cvc' => __( 'The card\'s security code is invalid.', 'easy-digital-downloads' ),
29
+ 'incorrect_number' => __( 'The card number is incorrect.', 'easy-digital-downloads' ),
30
+ 'incomplete_number' => __( 'The card number is incomplete.', 'easy-digital-downloads' ),
31
+ 'incomplete_cvc' => __( 'The card\'s security code is incomplete.', 'easy-digital-downloads' ),
32
+ 'incomplete_expiry' => __( 'The card\'s expiration date is incomplete.', 'easy-digital-downloads' ),
33
+ 'expired_card' => __( 'The card has expired.', 'easy-digital-downloads' ),
34
+ 'incorrect_cvc' => __( 'The card\'s security code is incorrect.', 'easy-digital-downloads' ),
35
+ 'incorrect_zip' => __( 'The card\'s zip code failed validation.', 'easy-digital-downloads' ),
36
+ 'invalid_expiry_year_past' => __( 'The card\'s expiration year is in the past', 'easy-digital-downloads' ),
37
+ 'card_declined' => __( 'The card was declined.', 'easy-digital-downloads' ),
38
+ 'processing_error' => __( 'An error occurred while processing the card.', 'easy-digital-downloads' ),
39
+ 'invalid_request_error' => __( 'Unable to process this payment, please try again or use alternative method.', 'easy-digital-downloads' ),
40
+ 'email_invalid' => __( 'Invalid email address, please correct and try again.', 'easy-digital-downloads' ),
41
+ );
42
+
43
+ /**
44
+ * Filters the list of available error codes and corresponding error messages.
45
+ *
46
+ * @since 2.8.0
47
+ *
48
+ * @param array $error_list List of error codes and corresponding error messages.
49
+ */
50
+ $error_list = apply_filters( 'edds_get_localized_error_list', $error_list );
51
+
52
+ return $error_list;
53
+ }
54
+
55
+ /**
56
+ * Returns a localized error message for a corresponding Stripe
57
+ * error code.
58
+ *
59
+ * @link https://stripe.com/docs/error-codes
60
+ *
61
+ * @since 2.8.0
62
+ *
63
+ * @param string $error_code Error code.
64
+ * @param string $error_message Original error message to return if a localized version does not exist.
65
+ * @return string $error_message Potentially localized error message.
66
+ */
67
+ function edds_get_localized_error_message( $error_code, $error_message ) {
68
+ $error_list = edds_get_localized_error_messages();
69
+
70
+ if ( ! empty( $error_list[ $error_code ] ) ) {
71
+ return $error_list[ $error_code ];
72
+ }
73
+
74
+ return $error_message;
75
+ }
includes/gateways/stripe/includes/integrations/edd-all-access.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Integrations: All Access Pass
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Disables Payment Request Button output if Download has been unlocked with a pass.
11
+ *
12
+ * @since 2.8.0
13
+ *
14
+ * @param bool $enabled If the Payment Request Button is enabled.
15
+ * @param int $download_id Current Download ID.
16
+ * @return bool
17
+ */
18
+ function edds_all_access_prb_purchase_link_enabled( $enabled, $download_id ) {
19
+ $all_access = edd_all_access_check(
20
+ array(
21
+ 'download_id' => $download_id,
22
+ )
23
+ );
24
+
25
+ return false === $all_access['success'];
26
+ }
27
+ add_filter( 'edds_prb_purchase_link_enabled', 'edds_all_access_prb_purchase_link_enabled', 10, 2 );
includes/gateways/stripe/includes/integrations/edd-auto-register.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Integration: Auto Register
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Checks if the payment being created is by the Stripe gateway.
11
+ * Ensures the registered user is logged in automatically if so.
12
+ *
13
+ * Added slightly early to not override anything more specific.
14
+ *
15
+ * @since 2.8.0
16
+ *
17
+ * @param bool $maybe_login Determines if the user should be logged in after registration.
18
+ * @return bool
19
+ */
20
+ function edds_auto_register_login_user( $maybe_login ) {
21
+
22
+ if ( false === edd_is_gateway_active( 'stripe' ) ) {
23
+ return $maybe_login;
24
+ }
25
+ // If the request originated from the Stripe gateway on the Checkout log inthe registered user.
26
+ if ( isset( $_POST['action'] ) && 'edds_create_payment' === $_POST['action'] ) {
27
+ return true;
28
+ }
29
+
30
+ return $maybe_login;
31
+ }
32
+ add_filter( 'edd_auto_register_login_user', 'edds_auto_register_login_user', 5 );
includes/gateways/stripe/includes/integrations/wp-cli.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Easy Digital Downloads WP-CLI Tools for Stripe
4
+ *
5
+ * This class provides an integration point with the WP-CLI plugin allowing
6
+ * access to EDD from the command line.
7
+ *
8
+ * @package EDD
9
+ * @subpackage Classes/CLI
10
+ * @copyright Copyright (c) 2015, Chris Klosowski
11
+ * @license http://opensource.org/license/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) exit;
17
+
18
+ WP_CLI::add_command( 'edd-stripe', 'EDD_Stripe_CLI' );
19
+
20
+ /**
21
+ * Work with EDD through WP-CLI
22
+ *
23
+ * EDD_CLI Class
24
+ *
25
+ * Adds CLI support to EDD through WP-CL
26
+ *
27
+ * @since 1.0
28
+ */
29
+ class EDD_Stripe_CLI extends EDD_CLI {
30
+ /**
31
+ * Migrate the Stripe customer IDs from the usermeta table to the edd_customermeta table.
32
+ *
33
+ * ## OPTIONS
34
+ *
35
+ * --force=<boolean>: If the routine should be run even if the upgrade routine has been run already
36
+ *
37
+ * ## EXAMPLES
38
+ *
39
+ * wp edd-stripe migrate_customer_ids
40
+ * wp edd-stripe migrate_customer_ids --force
41
+ */
42
+ public function migrate_customer_ids( $args, $assoc_args ) {
43
+ global $wpdb;
44
+ $force = isset( $assoc_args['force'] ) ? true : false;
45
+
46
+ $upgrade_completed = edd_has_upgrade_completed( 'stripe_customer_id_migration' );
47
+
48
+ if ( ! $force && $upgrade_completed ) {
49
+ WP_CLI::error( __( 'The Stripe customer ID migration has already been run. To do this anyway, use the --force argument.', 'easy-digital-downloads' ) );
50
+ }
51
+
52
+ $sql = "SELECT user_id, meta_key, meta_value FROM $wpdb->usermeta WHERE meta_key IN ( '_edd_stripe_customer_id', '_edd_stripe_customer_id_test' )";
53
+ $results = $wpdb->get_results( $sql );
54
+ $total = count( $results );
55
+
56
+ if ( ! empty( $total ) ) {
57
+
58
+ $progress = new \cli\progress\Bar( 'Processing user meta', $total );
59
+
60
+ foreach ( $results as $result ) {
61
+ $user_data = get_userdata( $result->user_id );
62
+ $customer = new EDD_Customer( $user_data->user_email );
63
+
64
+ if ( ! $customer->id > 0 ) {
65
+ $customer = new EDD_Customer( $result->user_id, true );
66
+
67
+ if ( ! $customer->id > 0 ) {
68
+ continue;
69
+ }
70
+ }
71
+
72
+ $stripe_customer_id = $result->meta_value;
73
+
74
+ // We should try and use a recurring ID if one exists for this user
75
+ if ( class_exists( 'EDD_Recurring_Subscriber' ) ) {
76
+ $subscriber = new EDD_Recurring_Subscriber( $customer->id );
77
+ $stripe_customer_id = $subscriber->get_recurring_customer_id( 'stripe' );
78
+ }
79
+
80
+ $customer->update_meta( $result->meta_key, $stripe_customer_id );
81
+
82
+ $progress->tick();
83
+ }
84
+
85
+ $progress->finish();
86
+ WP_CLI::line( __( 'Migration complete.', 'easy-digital-downloads' ) );
87
+ } else {
88
+ WP_CLI::line( __( 'No user records were found that needed to be migrated.', 'easy-digital-downloads' ) );
89
+ }
90
+
91
+ update_option( 'edds_stripe_version', preg_replace( '/[^0-9.].*/', '', EDD_STRIPE_VERSION ) );
92
+ edd_set_upgrade_complete( 'stripe_customer_id_migration' );
93
+
94
+ }
95
+ }
includes/gateways/stripe/includes/payment-actions.php ADDED
@@ -0,0 +1,1440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment actions.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Starts the process of completing a purchase with Stripe.
11
+ *
12
+ * Generates an intent that can require user authorization before proceeding.
13
+ *
14
+ * @link https://stripe.com/docs/payments/intents
15
+ * @since 2.7.0
16
+ *
17
+ * @param array $purchase_data {
18
+ * Purchase form data.
19
+ *
20
+ * }
21
+ */
22
+ function edds_process_purchase_form( $purchase_data ) {
23
+ // Catch a straight to gateway request.
24
+ // Remove the error set by the "gateway mismatch" and allow the redirect.
25
+ if ( isset( $_REQUEST['edd_action'] ) && 'straight_to_gateway' === $_REQUEST['edd_action'] ) {
26
+ foreach ( $purchase_data['downloads'] as $download ) {
27
+ $options = isset( $download['options'] ) ? $download['options'] : array();
28
+ $options['quantity'] = isset( $download['quantity'] ) ? $download['quantity'] : 1;
29
+
30
+ edd_add_to_cart( $download['id'], $options );
31
+ }
32
+
33
+ edd_unset_error( 'edd-straight-to-gateway-error' );
34
+ edd_send_back_to_checkout();
35
+
36
+ return;
37
+ }
38
+
39
+ try {
40
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
41
+ throw new \EDD_Stripe_Gateway_Exception(
42
+ esc_html__(
43
+ 'We are unable to process your payment at this time, please try again later or contact support.',
44
+ 'easy-digital-downloads'
45
+ )
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Allows processing before an Intent is created.
51
+ *
52
+ * @since 2.7.0
53
+ *
54
+ * @param array $purchase_data Purchase data.
55
+ */
56
+ do_action( 'edds_pre_process_purchase_form', $purchase_data );
57
+
58
+ $payment_method_id = isset( $_POST['payment_method_id'] ) ? sanitize_text_field( $_POST['payment_method_id'] ) : false;
59
+ $payment_method_exists = isset( $_POST['payment_method_exists'] ) ? 'true' == $_POST['payment_method_exists'] : false;
60
+
61
+ if ( ! $payment_method_id ) {
62
+ throw new \EDD_Stripe_Gateway_Exception(
63
+ esc_html__(
64
+ 'Unable to locate payment method. Please try again with a new payment method.',
65
+ 'easy-digital-downloads'
66
+ )
67
+ );
68
+ }
69
+
70
+ // Ensure Payment Method is still valid.
71
+ $payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method_id );
72
+ $card = isset( $payment_method->card ) ? $payment_method->card : null;
73
+
74
+ // ...block prepaid cards if option is not enabled.
75
+ if (
76
+ $card &&
77
+ 'prepaid' === $card->funding &&
78
+ false === (bool) edd_get_option( 'stripe_allow_prepaid' )
79
+ ) {
80
+ throw new \EDD_Stripe_Gateway_Exception(
81
+ esc_html__(
82
+ 'Prepaid cards are not a valid payment method. Please try again with a new payment method.',
83
+ 'easy-digital-downloads'
84
+ )
85
+ );
86
+ }
87
+
88
+ if ( edds_is_zero_decimal_currency() ) {
89
+ $amount = $purchase_data['price'];
90
+ } else {
91
+ $amount = round( $purchase_data['price'] * 100, 0 );
92
+ }
93
+
94
+ // Retrieves or creates a Stripe Customer.
95
+ $customer = edds_checkout_setup_customer( $purchase_data );
96
+
97
+ if ( ! $customer ) {
98
+ throw new \EDD_Stripe_Gateway_Exception(
99
+ esc_html__(
100
+ 'Unable to create customer. Please try again.',
101
+ 'easy-digital-downloads'
102
+ )
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Allows processing before an Intent is created, but
108
+ * after a \Stripe\Customer is available.
109
+ *
110
+ * @since 2.7.0
111
+ *
112
+ * @param array $purchase_data Purchase data.
113
+ * @param \Stripe\Customer $customer Stripe Customer object.
114
+ */
115
+ do_action( 'edds_process_purchase_form_before_intent', $purchase_data, $customer );
116
+
117
+ // Flag if this is the first card being attached to the Customer.
118
+ $existing_payment_methods = edd_stripe_get_existing_cards( $purchase_data['user_info']['id'] );
119
+ $is_first_payment_method = empty( $existing_payment_methods );
120
+
121
+ $address_info = $purchase_data['user_info']['address'];
122
+
123
+ // Update PaymentMethod details if necessary.
124
+ if ( $payment_method_exists && ! empty( $_POST['edd_stripe_update_billing_address'] ) ) {
125
+ $billing_address = array();
126
+
127
+ foreach ( $address_info as $key => $value ) {
128
+ // Adjusts address data keys to work with PaymentMethods.
129
+ switch( $key ) {
130
+ case 'zip':
131
+ $key = 'postal_code';
132
+ break;
133
+ }
134
+
135
+ $billing_address[ $key ] = ! empty( $value ) ? sanitize_text_field( $value ) : '';
136
+ }
137
+
138
+ edds_api_request( 'PaymentMethod', 'update', $payment_method_id, array(
139
+ 'billing_details' => array(
140
+ 'address' => $billing_address,
141
+ ),
142
+ ) );
143
+ }
144
+
145
+ // Create a list of {$download_id}_{$price_id}
146
+ $payment_items = array();
147
+
148
+ foreach ( $purchase_data['cart_details'] as $item ) {
149
+ $price_id = isset( $item['item_number']['options']['price_id'] )
150
+ ? $item['item_number']['options']['price_id']
151
+ : null;
152
+
153
+ $payment_items[] = $item['id'] . ( ! empty( $price_id ) ? ( '_' . $price_id ) : '' );
154
+ }
155
+
156
+ // Shared Intent arguments.
157
+ $intent_args = array(
158
+ 'confirm' => true,
159
+ 'payment_method' => $payment_method_id,
160
+ 'customer' => $customer->id,
161
+ 'metadata' => array(
162
+ 'email' => esc_html( $purchase_data['user_info']['email'] ),
163
+ 'edd_payment_subtotal' => esc_html( $purchase_data['subtotal'] ),
164
+ 'edd_payment_discount' => esc_html( $purchase_data['discount'] ),
165
+ 'edd_payment_tax' => esc_html( $purchase_data['tax'] ),
166
+ 'edd_payment_tax_rate' => esc_html( $purchase_data['tax_rate'] ),
167
+ 'edd_payment_fees' => esc_html( edd_get_cart_fee_total() ),
168
+ 'edd_payment_total' => esc_html( $purchase_data['price'] ),
169
+ 'edd_payment_items' => esc_html( implode( ', ', $payment_items ) ),
170
+ ),
171
+ );
172
+
173
+ // Attempt to map existing charge arguments to PaymentIntents.
174
+ if ( has_filter( 'edds_create_charge_args' ) ) {
175
+ /**
176
+ * @deprecated 2.7.0 In favor of `edds_create_payment_intent_args`.
177
+ *
178
+ * @param array $intent_args
179
+ */
180
+ $old_charge_args = apply_filters_deprecated(
181
+ 'edds_create_charge_args',
182
+ array(
183
+ $intent_args,
184
+ ),
185
+ '2.7.0',
186
+ 'edds_create_payment_intent_args'
187
+ );
188
+
189
+ // Grab a few compatible arguments from the old charges filter.
190
+ $compatible_keys = array(
191
+ 'amount',
192
+ 'currency',
193
+ 'customer',
194
+ 'description',
195
+ 'metadata',
196
+ 'application_fee',
197
+ );
198
+
199
+ foreach ( $compatible_keys as $compatible_key ) {
200
+ if ( ! isset( $old_charge_args[ $compatible_key ] ) ) {
201
+ continue;
202
+ }
203
+
204
+ $value = $old_charge_args[ $compatible_key ];
205
+
206
+ switch ( $compatible_key ) {
207
+ case 'application_fee' :
208
+ $intent_args['application_fee_amount'] = $value;
209
+ break;
210
+
211
+ default:
212
+ // If a legacy value is an array merge it with the existing values to avoid overriding completely.
213
+ $intent_args[ $compatible_key ] = is_array( $value ) && is_array( $intent_args[ $compatible_key ] )
214
+ ? wp_parse_args( $value, $intent_args[ $compatible_key ] )
215
+ : $value;
216
+ }
217
+
218
+ edd_debug_log( __( 'Charges are no longer directly created in Stripe. Please read the following for more information: https://easydigitaldownloads.com/development/', 'easy-digital-downloads' ), true );
219
+ }
220
+ }
221
+
222
+ // Create a SetupIntent for a non-payment carts.
223
+ if ( edd_get_option( 'stripe_preapprove_only' ) || 0 === $amount ) {
224
+ $intent_args = array_merge(
225
+ array(
226
+ 'usage' => 'off_session',
227
+ 'description' => edds_get_payment_description( $purchase_data['cart_details'] ),
228
+ ),
229
+ $intent_args
230
+ );
231
+
232
+ /**
233
+ * Filters the arguments used to create a SetupIntent.
234
+ *
235
+ * @since 2.7.0
236
+ *
237
+ * @param array $intent_args SetupIntent arguments.
238
+ * @param array $purchase_data {
239
+ * Purchase form data.
240
+ *
241
+ * }
242
+ */
243
+ $intent_args = apply_filters( 'edds_create_setup_intent_args', $intent_args, $purchase_data );
244
+
245
+ $intent = edds_api_request( 'SetupIntent', 'create', $intent_args );
246
+
247
+ // Manually attach PaymentMethod to the Customer.
248
+ if ( ! $payment_method_exists && edd_stripe_existing_cards_enabled() ) {
249
+ $payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method_id );
250
+ $payment_method->attach( array(
251
+ 'customer' => $customer->id,
252
+ ) );
253
+ }
254
+
255
+ // Create a PaymentIntent for an immediate charge.
256
+ } else {
257
+ $purchase_summary = edds_get_payment_description( $purchase_data['cart_details'] );
258
+ $statement_descriptor = edds_get_statement_descriptor();
259
+
260
+ if ( empty( $statement_descriptor ) ) {
261
+ $statement_descriptor = substr( $purchase_summary, 0, 22 );
262
+ }
263
+
264
+ $statement_descriptor = apply_filters( 'edds_statement_descriptor', $statement_descriptor, $purchase_data );
265
+ $statement_descriptor = edds_sanitize_statement_descriptor( $statement_descriptor );
266
+
267
+ if ( empty( $statement_descriptor ) ) {
268
+ $statement_descriptor = null;
269
+ }
270
+
271
+ $intent_args = array_merge(
272
+ array(
273
+ 'amount' => $amount,
274
+ 'currency' => edd_get_currency(),
275
+ 'setup_future_usage' => 'off_session',
276
+ 'confirmation_method' => 'manual',
277
+ 'save_payment_method' => true,
278
+ 'description' => $purchase_summary,
279
+ 'statement_descriptor' => $statement_descriptor,
280
+ ),
281
+ $intent_args
282
+ );
283
+
284
+ $stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
285
+
286
+ if ( ! empty( $stripe_connect_account_id ) ) {
287
+ $intent_args['application_fee_amount'] = round( $amount * 0.02 );
288
+ }
289
+
290
+ /**
291
+ * Filters the arguments used to create a SetupIntent.
292
+ *
293
+ * @since 2.7.0
294
+ *
295
+ * @param array $intent_args SetupIntent arguments.
296
+ * @param array $purchase_data {
297
+ * Purchase form data.
298
+ *
299
+ * }
300
+ */
301
+ $intent_args = apply_filters( 'edds_create_payment_intent_args', $intent_args, $purchase_data );
302
+
303
+ $intent = edds_api_request( 'PaymentIntent', 'create', $intent_args );
304
+ }
305
+
306
+ // Set the default payment method when attaching the first one.
307
+ if ( $is_first_payment_method ) {
308
+ edds_api_request( 'Customer', 'update', $customer->id, array(
309
+ 'invoice_settings' => array(
310
+ 'default_payment_method' => $payment_method_id,
311
+ ),
312
+ ) );
313
+ }
314
+
315
+ /**
316
+ * Allows further processing after an Intent is created.
317
+ *
318
+ * @since 2.7.0
319
+ *
320
+ * @param array $purchase_data Purchase data.
321
+ * @param \Stripe\PaymentIntent|\Stripe\SetupIntent $intent Created Stripe Intent.
322
+ * @param int $payment_id EDD Payment ID.
323
+ */
324
+ do_action( 'edds_process_purchase_form', $purchase_data, $intent );
325
+
326
+ return wp_send_json_success( array(
327
+ 'intent' => $intent,
328
+ // Send back a new nonce because the user might have logged in.
329
+ 'nonce' => wp_create_nonce( 'edd-process-checkout' ),
330
+ ) );
331
+
332
+ // Catch card-specific errors to handle rate limiting.
333
+ } catch ( \Stripe\Exception\CardException $e ) {
334
+ // Increase the card error count.
335
+ edd_stripe()->rate_limiting->increment_card_error_count();
336
+
337
+ $error = $e->getJsonBody()['error'];
338
+
339
+ // Record error in log.
340
+ edd_record_gateway_error(
341
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
342
+ sprintf(
343
+ esc_html__( 'There was an error while processing a Stripe payment. Payment data: %s', 'easy-digital-downloads' ),
344
+ wp_json_encode( $error )
345
+ ),
346
+ 0
347
+ );
348
+
349
+ return wp_send_json_error( array(
350
+ 'message' => esc_html(
351
+ edds_get_localized_error_message( $error['code'], $error['message'] )
352
+ ),
353
+ ) );
354
+
355
+ // Catch Stripe-specific errors.
356
+ } catch ( \Stripe\Exception\ApiErrorException $e ) {
357
+ $error = $e->getJsonBody()['error'];
358
+
359
+ // Record error in log.
360
+ edd_record_gateway_error(
361
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
362
+ sprintf(
363
+ esc_html__( 'There was an error while processing a Stripe payment. Payment data: %s', 'easy-digital-downloads' ),
364
+ wp_json_encode( $error )
365
+ ),
366
+ 0
367
+ );
368
+
369
+ return wp_send_json_error( array(
370
+ 'message' => esc_html(
371
+ edds_get_localized_error_message( $error['code'], $error['message'] )
372
+ ),
373
+ ) );
374
+
375
+ // Catch gateway processing errors.
376
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
377
+ if ( true === $e->hasLogMessage() ) {
378
+ edd_record_gateway_error(
379
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
380
+ $e->getLogMessage(),
381
+ 0
382
+ );
383
+ }
384
+
385
+ return wp_send_json_error( array(
386
+ 'message' => esc_html( $e->getMessage() ),
387
+ ) );
388
+
389
+ // Catch any remaining error.
390
+ } catch( \Exception $e ) {
391
+
392
+ // Safety precaution in case the payment form is submitted directly.
393
+ // Redirects back to the Checkout.
394
+ if ( isset( $_POST['edd_email'] ) && ! isset( $_POST['payment_method_id'] ) ) {
395
+ edd_set_error( $e->getCode(), $e->getMessage() );
396
+ edd_send_back_to_checkout( '?payment-mode=' . $purchase_data['gateway'] );
397
+ }
398
+
399
+ return wp_send_json_error( array(
400
+ 'message' => esc_html( $e->getMessage() ),
401
+ ) );
402
+ }
403
+ }
404
+ add_action( 'edd_gateway_stripe', 'edds_process_purchase_form' );
405
+
406
+ /**
407
+ * Retrieves an Intent.
408
+ *
409
+ * @since 2.7.0
410
+ */
411
+ function edds_get_intent() {
412
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
413
+ _edds_map_form_data_to_request( $_POST );
414
+
415
+ $intent_id = isset( $_REQUEST['intent_id'] ) ? sanitize_text_field( $_REQUEST['intent_id'] ) : null;
416
+ $intent_type = isset( $_REQUEST['intent_type'] ) ? sanitize_text_field( $_REQUEST['intent_type'] ) : 'payment_intent';
417
+
418
+ try {
419
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
420
+ throw new \EDD_Stripe_Gateway_Exception(
421
+ esc_html__(
422
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
423
+ 'easy-digital-downloads'
424
+ ),
425
+ 'Rate limit reached during Intent retrieval.'
426
+ );
427
+ }
428
+
429
+ if ( false === edds_verify_payment_form_nonce() ) {
430
+ throw new \EDD_Stripe_Gateway_Exception(
431
+ esc_html__(
432
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
433
+ 'easy-digital-downloads'
434
+ ),
435
+ 'Nonce verification failed during Intent retrieval.'
436
+ );
437
+ }
438
+
439
+ if ( 'setup_intent' === $intent_type ) {
440
+ $intent = edds_api_request( 'SetupIntent', 'retrieve', $intent_id );
441
+ } else {
442
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent_id );
443
+ }
444
+
445
+ return wp_send_json_success( array(
446
+ 'intent' => $intent,
447
+ ) );
448
+ // Catch gateway processing errors.
449
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
450
+ // Increase the rate limit if an exception occurs mid-process.
451
+ edd_stripe()->rate_limiting->increment_card_error_count();
452
+
453
+ if ( true === $e->hasLogMessage() ) {
454
+ edd_record_gateway_error(
455
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
456
+ $e->getLogMessage(),
457
+ 0
458
+ );
459
+ }
460
+
461
+ return wp_send_json_error( array(
462
+ 'message' => esc_html( $e->getMessage() ),
463
+ ) );
464
+
465
+ // Catch any remaining error.
466
+ } catch( \Exception $e ) {
467
+ return wp_send_json_error( array(
468
+ 'message' => esc_html( $e->getMessage() ),
469
+ ) );
470
+ }
471
+ }
472
+ add_action( 'wp_ajax_edds_get_intent', 'edds_get_intent' );
473
+ add_action( 'wp_ajax_nopriv_edds_get_intent', 'edds_get_intent' );
474
+
475
+ /**
476
+ * Confirms a PaymentIntent.
477
+ *
478
+ * @since 2.7.0
479
+ */
480
+ function edds_confirm_intent() {
481
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
482
+ _edds_map_form_data_to_request( $_POST );
483
+
484
+ $intent_id = isset( $_REQUEST['intent_id'] ) ? sanitize_text_field( $_REQUEST['intent_id'] ) : null;
485
+ $intent_type = isset( $_REQUEST['intent_type'] ) ? sanitize_text_field( $_REQUEST['intent_type'] ) : 'payment_intent';
486
+
487
+ try {
488
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
489
+ throw new \EDD_Stripe_Gateway_Exception(
490
+ esc_html__(
491
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
492
+ 'easy-digital-downloads'
493
+ ),
494
+ 'Rate limit reached during Intent confirmation.'
495
+ );
496
+ }
497
+
498
+ if ( false === edds_verify_payment_form_nonce() ) {
499
+ throw new \EDD_Stripe_Gateway_Exception(
500
+ esc_html__(
501
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
502
+ 'easy-digital-downloads'
503
+ ),
504
+ 'Nonce verification failed during Intent confirmation.'
505
+ );
506
+ }
507
+
508
+ // SetupIntent was used if the cart total is $0.
509
+ if ( 'setup_intent' === $intent_type ) {
510
+ $intent = edds_api_request( 'SetupIntent', 'retrieve', $intent_id );
511
+ } else {
512
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent_id );
513
+ $intent->confirm();
514
+ }
515
+
516
+ /**
517
+ * Allows further processing after an Intent is confirmed.
518
+ * Runs for all calls to confirm(), regardless of action needed.
519
+ *
520
+ * @since 2.7.0
521
+ *
522
+ * @param \Stripe\PaymentIntent|\Stripe\SetupIntent $intent Stripe intent.
523
+ */
524
+ do_action( 'edds_confirm_payment_intent', $intent );
525
+
526
+ return wp_send_json_success( array(
527
+ 'intent' => $intent,
528
+ ) );
529
+
530
+ // Catch gateway processing errors.
531
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
532
+ // Increase the rate limit if an exception occurs mid-process.
533
+ edd_stripe()->rate_limiting->increment_card_error_count();
534
+
535
+ if ( true === $e->hasLogMessage() ) {
536
+ edd_record_gateway_error(
537
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
538
+ $e->getLogMessage(),
539
+ 0
540
+ );
541
+ }
542
+
543
+ return wp_send_json_error( array(
544
+ 'message' => esc_html( $e->getMessage() ),
545
+ ) );
546
+
547
+ // Catch any remaining error.
548
+ } catch( Exception $e ) {
549
+ return wp_send_json_error( array(
550
+ 'message' => esc_html( $e->getMessage() ),
551
+ ) );
552
+ }
553
+ }
554
+ add_action( 'wp_ajax_edds_confirm_intent', 'edds_confirm_intent' );
555
+ add_action( 'wp_ajax_nopriv_edds_confirm_intent', 'edds_confirm_intent' );
556
+
557
+ /**
558
+ * Capture a PaymentIntent.
559
+ *
560
+ * @since 2.7.0
561
+ */
562
+ function edds_capture_intent() {
563
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
564
+ _edds_map_form_data_to_request( $_POST );
565
+
566
+ $intent_id = isset( $_REQUEST['intent_id'] ) ? sanitize_text_field( $_REQUEST['intent_id'] ) : null;
567
+
568
+ try {
569
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
570
+ throw new \EDD_Stripe_Gateway_Exception(
571
+ esc_html__(
572
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
573
+ 'easy-digital-downloads'
574
+ ),
575
+ 'Rate limit reached during Intent capture.'
576
+ );
577
+ }
578
+
579
+ // This must happen in the Checkout flow, so validate the Checkout nonce.
580
+ $nonce = isset( $_POST['edd-process-checkout-nonce'] )
581
+ ? sanitize_text_field( $_POST['edd-process-checkout-nonce'] )
582
+ : '';
583
+
584
+ $nonce_verified = wp_verify_nonce( $nonce, 'edd-process-checkout' );
585
+
586
+ if ( false === $nonce_verified ) {
587
+ throw new \EDD_Stripe_Gateway_Exception(
588
+ esc_html__(
589
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
590
+ 'easy-digital-downloads'
591
+ ),
592
+ 'Nonce verification failed during Intent capture.'
593
+ );
594
+ }
595
+
596
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent_id );
597
+
598
+ /**
599
+ * Allows processing before a PaymentIntent is captured.
600
+ *
601
+ * @since 2.7.0
602
+ *
603
+ * @param \Stripe\PaymentIntent $payment_intent Stripe PaymentIntent.
604
+ */
605
+ do_action( 'edds_capture_payment_intent', $intent );
606
+
607
+ // Capture capturable amount if nothing else has captured the intent.
608
+ if ( 'requires_capture' === $intent->status ) {
609
+ $intent->capture( array(
610
+ 'amount_to_capture' => $intent->amount_capturable,
611
+ ) );
612
+ }
613
+
614
+ return wp_send_json_success( array(
615
+ 'intent' => $intent,
616
+ ) );
617
+
618
+ // Catch gateway processing errors.
619
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
620
+ // Increase the rate limit if an exception occurs mid-process.
621
+ edd_stripe()->rate_limiting->increment_card_error_count();
622
+
623
+ if ( true === $e->hasLogMessage() ) {
624
+ edd_record_gateway_error(
625
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
626
+ $e->getLogMessage(),
627
+ 0
628
+ );
629
+ }
630
+
631
+ return wp_send_json_error( array(
632
+ 'message' => esc_html( $e->getMessage() ),
633
+ ) );
634
+
635
+ // Catch any remaining error.
636
+ } catch( Exception $e ) {
637
+ return wp_send_json_error( array(
638
+ 'message' => esc_html( $e->getMessage() ),
639
+ ) );
640
+ }
641
+ }
642
+ add_action( 'wp_ajax_edds_capture_intent', 'edds_capture_intent' );
643
+ add_action( 'wp_ajax_nopriv_edds_capture_intent', 'edds_capture_intent' );
644
+
645
+ /**
646
+ * Update a PaymentIntent.
647
+ *
648
+ * @since 2.7.0
649
+ */
650
+ function edds_update_intent() {
651
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
652
+ _edds_map_form_data_to_request( $_POST );
653
+
654
+ $intent_id = isset( $_REQUEST['intent_id'] ) ? sanitize_text_field( $_REQUEST['intent_id'] ) : null;
655
+
656
+ try {
657
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
658
+ throw new \EDD_Stripe_Gateway_Exception(
659
+ esc_html__(
660
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
661
+ 'easy-digital-downloads'
662
+ ),
663
+ 'Rate limit reached during Intent update.'
664
+ );
665
+ }
666
+
667
+ if ( false === edds_verify_payment_form_nonce() ) {
668
+ throw new \EDD_Stripe_Gateway_Exception(
669
+ esc_html__(
670
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
671
+ 'easy-digital-downloads'
672
+ ),
673
+ 'Nonce verification failed during Intent update.'
674
+ );
675
+ }
676
+
677
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent_id );
678
+
679
+ /**
680
+ * Allows processing before a PaymentIntent is updated.
681
+ *
682
+ * @since 2.7.0
683
+ *
684
+ * @param string $intent_id Stripe PaymentIntent ID.
685
+ */
686
+ do_action( 'edds_update_payment_intent', $intent_id );
687
+
688
+ $intent_args = array();
689
+ $intent_args_whitelist = array(
690
+ 'payment_method',
691
+ );
692
+
693
+ foreach ( $intent_args_whitelist as $intent_arg ) {
694
+ if ( isset( $_POST[ $intent_arg ] ) ) {
695
+ $intent_args[ $intent_arg ] = sanitize_text_field( $_POST[ $intent_arg ] );
696
+ }
697
+ }
698
+
699
+ $intent = edds_api_request( 'PaymentIntent', 'update', $intent_id, $intent_args );
700
+
701
+ return wp_send_json_success( array(
702
+ 'intent' => $intent,
703
+ ) );
704
+
705
+ // Catch gateway processing errors.
706
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
707
+ // Increase the rate limit if an exception occurs mid-process.
708
+ edd_stripe()->rate_limiting->increment_card_error_count();
709
+
710
+ if ( true === $e->hasLogMessage() ) {
711
+ edd_record_gateway_error(
712
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
713
+ $e->getLogMessage(),
714
+ 0
715
+ );
716
+ }
717
+
718
+ return wp_send_json_error( array(
719
+ 'message' => esc_html( $e->getMessage() ),
720
+ ) );
721
+
722
+ // Catch any remaining error.
723
+ } catch( Exception $e ) {
724
+ return wp_send_json_error( array(
725
+ 'message' => esc_html( $e->getMessage() ),
726
+ ) );
727
+ }
728
+ }
729
+ add_action( 'wp_ajax_edds_update_intent', 'edds_update_intent' );
730
+ add_action( 'wp_ajax_nopriv_edds_update_intent', 'edds_update_intent' );
731
+
732
+ /**
733
+ * Create an \EDD_Payment.
734
+ *
735
+ * @since 2.7.0
736
+ */
737
+ function edds_create_payment() {
738
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
739
+ _edds_map_form_data_to_request( $_POST );
740
+
741
+ // Simulate being in an `edd_process_purchase_form()` request.
742
+ _edds_fake_process_purchase_step();
743
+
744
+ try {
745
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
746
+ throw new \EDD_Stripe_Gateway_Exception(
747
+ esc_html__(
748
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
749
+ 'easy-digital-downloads'
750
+ ),
751
+ 'Rate limit reached during payment creation.'
752
+ );
753
+ }
754
+
755
+ // This must happen in the Checkout flow, so validate the Checkout nonce.
756
+ $nonce = isset( $_POST['edd-process-checkout-nonce'] )
757
+ ? sanitize_text_field( $_POST['edd-process-checkout-nonce'] )
758
+ : '';
759
+
760
+ $nonce_verified = wp_verify_nonce( $nonce, 'edd-process-checkout' );
761
+
762
+ if ( false === $nonce_verified ) {
763
+ throw new \EDD_Stripe_Gateway_Exception(
764
+ esc_html__(
765
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
766
+ 'easy-digital-downloads'
767
+ ),
768
+ 'Nonce verification failed during payment creation.'
769
+ );
770
+ }
771
+
772
+ $intent = isset( $_REQUEST['intent'] ) ? $_REQUEST['intent'] : array();
773
+
774
+ if ( ! isset( $intent['id'] ) ) {
775
+ throw new \EDD_Stripe_Gateway_Exception(
776
+ esc_html__(
777
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
778
+ 'easy-digital-downloads'
779
+ ),
780
+ 'Unable to retrieve Intent data during payment creation.'
781
+ );
782
+ }
783
+
784
+ $purchase_data = edd_get_purchase_session();
785
+
786
+ if ( false === $purchase_data ) {
787
+ throw new \EDD_Stripe_Gateway_Exception(
788
+ esc_html__(
789
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
790
+ 'easy-digital-downloads'
791
+ ),
792
+ 'Unable to retrieve purchase data during payment creation.'
793
+ );
794
+ }
795
+
796
+ // Ensure Intent has transitioned to the correct status.
797
+ if ( 'setup_intent' === $intent['object'] ) {
798
+ $intent = edds_api_request( 'SetupIntent', 'retrieve', $intent['id'] );
799
+ } else {
800
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent['id'] );
801
+ }
802
+
803
+ if ( ! in_array( $intent->status, array( 'succeeded', 'requires_capture' ), true ) ) {
804
+ throw new \EDD_Stripe_Gateway_Exception(
805
+ esc_html__(
806
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
807
+ 'easy-digital-downloads'
808
+ ),
809
+ 'Invalid Intent status ' . $intent->status . ' during payment creation.'
810
+ );
811
+ }
812
+
813
+ $payment_data = array(
814
+ 'price' => $purchase_data['price'],
815
+ 'date' => $purchase_data['date'],
816
+ 'user_email' => $purchase_data['user_email'],
817
+ 'purchase_key' => $purchase_data['purchase_key'],
818
+ 'currency' => edd_get_currency(),
819
+ 'downloads' => $purchase_data['downloads'],
820
+ 'cart_details' => $purchase_data['cart_details'],
821
+ 'user_info' => $purchase_data['user_info'],
822
+ 'status' => 'pending',
823
+ 'gateway' => 'stripe',
824
+ );
825
+
826
+ // Ensure $_COOKIE is available without a new HTTP request.
827
+ if ( class_exists( 'EDD_Auto_Register' ) ) {
828
+ add_action( 'set_logged_in_cookie', 'edds_set_logged_in_cookie_global' );
829
+ }
830
+
831
+ // Record the pending payment.
832
+ $payment_id = edd_insert_payment( $payment_data );
833
+
834
+ if ( class_exists( 'EDD_Auto_Register' ) ) {
835
+ remove_action( 'set_logged_in_cookie', 'edds_set_logged_in_cookie_global' );
836
+ }
837
+
838
+ if ( false === $payment_id ) {
839
+ throw new \EDD_Stripe_Gateway_Exception(
840
+ esc_html__(
841
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
842
+ 'easy-digital-downloads'
843
+ ),
844
+ 'Unable to insert payment record.'
845
+ );
846
+ }
847
+
848
+ // Retrieve created payment.
849
+ $payment = edd_get_payment( $payment_id );
850
+
851
+ // Retrieve the relevant Intent.
852
+ if ( 'setup_intent' === $intent->object ) {
853
+ $intent = edds_api_request( 'SetupIntent', 'update', $intent->id, array(
854
+ 'metadata' => array(
855
+ 'edd_payment_id' => $payment_id,
856
+ ),
857
+ ) );
858
+
859
+ $payment->add_note( 'Stripe SetupIntent ID: ' . $intent->id );
860
+ $payment->update_meta( '_edds_stripe_setup_intent_id', $intent->id );
861
+ } else {
862
+ $intent = edds_api_request( 'PaymentIntent', 'update', $intent->id, array(
863
+ 'metadata' => array(
864
+ 'edd_payment_id' => $payment_id,
865
+ ),
866
+ ) );
867
+
868
+ $payment->add_note( 'Stripe PaymentIntent ID: ' . $intent->id );
869
+ $payment->update_meta( '_edds_stripe_payment_intent_id', $intent->id );
870
+ }
871
+
872
+ // Use Intent ID for temporary transaction ID.
873
+ // It will be updated when a charge is available.
874
+ $payment->transaction_id = $intent->id;
875
+
876
+ // Retrieves or creates a Stripe Customer.
877
+ $payment->update_meta( '_edds_stripe_customer_id', $intent->customer );
878
+ $payment->add_note( 'Stripe Customer ID: ' . $intent->customer );
879
+
880
+ // Attach the \Stripe\Customer ID to the \EDD_Customer meta if one exists.
881
+ $edd_customer = new EDD_Customer( $purchase_data['user_email'] );
882
+
883
+ if ( $edd_customer->id > 0 ) {
884
+ $edd_customer->update_meta( edd_stripe_get_customer_key(), $intent->customer );
885
+ }
886
+
887
+ if ( $payment->save() ) {
888
+ /**
889
+ * Allows further processing after a payment is created.
890
+ *
891
+ * @since 2.7.0
892
+ *
893
+ * @param \EDD_Payment $payment EDD Payment.
894
+ * @param \Stripe\PaymentIntent|\Stripe\SetupIntent $intent Created Stripe Intent.
895
+ */
896
+ do_action( 'edds_payment_created', $payment, $intent );
897
+
898
+ return wp_send_json_success( array(
899
+ 'intent' => $intent,
900
+ 'payment' => $payment,
901
+ // Send back a new nonce because the user might have logged in via Auto Register.
902
+ 'nonce' => wp_create_nonce( 'edd-process-checkout' ),
903
+ ) );
904
+ } else {
905
+ throw new \EDD_Stripe_Gateway_Exception(
906
+ esc_html__(
907
+ 'Unable to create payment.',
908
+ 'easy-digital-downloads'
909
+ ),
910
+ 'Unable to save payment record.'
911
+ );
912
+ }
913
+
914
+ // Catch gateway processing errors.
915
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
916
+ // Increase the rate limit count when something goes wrong mid-process.
917
+ edd_stripe()->rate_limiting->increment_card_error_count();
918
+
919
+ if ( true === $e->hasLogMessage() ) {
920
+ edd_record_gateway_error(
921
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
922
+ $e->getLogMessage(),
923
+ 0
924
+ );
925
+ }
926
+
927
+ return wp_send_json_error( array(
928
+ 'message' => esc_html( $e->getMessage() ),
929
+ ) );
930
+
931
+ // Catch any remaining error.
932
+ } catch( \Exception $e ) {
933
+ return wp_send_json_error( array(
934
+ 'message' => esc_html( $e->getMessage() ),
935
+ ) );
936
+ }
937
+ }
938
+ add_action( 'wp_ajax_edds_create_payment', 'edds_create_payment' );
939
+ add_action( 'wp_ajax_nopriv_edds_create_payment', 'edds_create_payment' );
940
+
941
+ /**
942
+ * Completes an \EDD_Payment (via AJAX)
943
+ *
944
+ * @since 2.7.0
945
+ */
946
+ function edds_complete_payment() {
947
+ // Map and merge serialized `form_data` to $_POST so it's accessible to other functions.
948
+ _edds_map_form_data_to_request( $_POST );
949
+
950
+ $intent = isset( $_REQUEST['intent'] ) ? $_REQUEST['intent'] : array();
951
+
952
+ try {
953
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
954
+ throw new \EDD_Stripe_Gateway_Exception(
955
+ esc_html__(
956
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
957
+ 'easy-digital-downloads'
958
+ ),
959
+ 'Rate limit reached during payment completion.'
960
+ );
961
+ }
962
+
963
+ // This must happen in the Checkout flow, so validate the Checkout nonce.
964
+ $nonce = isset( $_POST['edd-process-checkout-nonce'] )
965
+ ? sanitize_text_field( $_POST['edd-process-checkout-nonce'] )
966
+ : '';
967
+
968
+ $nonce_verified = wp_verify_nonce( $nonce, 'edd-process-checkout' );
969
+
970
+ if ( false === $nonce_verified ) {
971
+ throw new \EDD_Stripe_Gateway_Exception(
972
+ esc_html__(
973
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
974
+ 'easy-digital-downloads'
975
+ ),
976
+ 'Nonce verification failed during payment completion.'
977
+ );
978
+ }
979
+
980
+ if ( ! isset( $intent['id'] ) ) {
981
+ throw new \EDD_Stripe_Gateway_Exception(
982
+ esc_html__(
983
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
984
+ 'easy-digital-downloads'
985
+ ),
986
+ 'Unable to retrieve Intent during payment completion.'
987
+ );
988
+ }
989
+
990
+ // Retrieve the intent from Stripe again to verify linked payment.
991
+ if ( 'setup_intent' === $intent['object'] ) {
992
+ $intent = edds_api_request( 'SetupIntent', 'retrieve', $intent['id'] );
993
+ } else {
994
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent['id'] );
995
+ }
996
+
997
+ $payment = edd_get_payment( $intent->metadata->edd_payment_id );
998
+
999
+ if ( ! $payment ) {
1000
+ throw new \EDD_Stripe_Gateway_Exception(
1001
+ esc_html__(
1002
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1003
+ 'easy-digital-downloads'
1004
+ ),
1005
+ 'Unable to retrieve pending payment record.'
1006
+ );
1007
+ }
1008
+
1009
+ if ( 'setup_intent' !== $intent['object'] ) {
1010
+ $charge_id = sanitize_text_field( current( $intent['charges']['data'] )['id'] );
1011
+
1012
+ $payment->add_note( 'Stripe Charge ID: ' . $charge_id );
1013
+ $payment->transaction_id = sanitize_text_field( $charge_id );
1014
+ }
1015
+
1016
+ // Mark payment as Preapproved.
1017
+ if ( edd_get_option( 'stripe_preapprove_only' ) ) {
1018
+ $payment->status = 'preapproval';
1019
+
1020
+ // Complete payment and transition the Transaction ID to the actual Charge ID.
1021
+ } else {
1022
+ $payment->status = 'publish';
1023
+ }
1024
+
1025
+ if ( $payment->save() ) {
1026
+ /**
1027
+ * Allows further processing after a payment is completed.
1028
+ *
1029
+ * Sends back just the Intent ID to avoid needing always retrieve
1030
+ * the intent in this step, which has been transformed via JSON,
1031
+ * and is no longer a \Stripe\PaymentIntent
1032
+ *
1033
+ * @since 2.7.0
1034
+ *
1035
+ * @param \EDD_Payment $payment EDD Payment.
1036
+ * @param string $intent_id Stripe Intent ID.
1037
+ */
1038
+ do_action( 'edds_payment_complete', $payment, $intent['id'] );
1039
+
1040
+ // Empty cart.
1041
+ edd_empty_cart();
1042
+
1043
+ return wp_send_json_success( array(
1044
+ 'payment' => $payment,
1045
+ 'intent' => $intent,
1046
+ ) );
1047
+ } else {
1048
+ throw new \EDD_Stripe_Gateway_Exception(
1049
+ esc_html__(
1050
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1051
+ 'easy-digital-downloads'
1052
+ ),
1053
+ 'Unable to update payment record to completion.'
1054
+ );
1055
+ }
1056
+
1057
+ // Catch gateway processing errors.
1058
+ } catch ( \EDD_Stripe_Gateway_Exception $e ) {
1059
+ // Increase the rate limit count when something goes wrong mid-process.
1060
+ edd_stripe()->rate_limiting->increment_card_error_count();
1061
+
1062
+ if ( true === $e->hasLogMessage() ) {
1063
+ edd_record_gateway_error(
1064
+ esc_html__( 'Stripe Error', 'easy-digital-downloads' ),
1065
+ $e->getLogMessage(),
1066
+ 0
1067
+ );
1068
+ }
1069
+
1070
+ return wp_send_json_error( array(
1071
+ 'message' => esc_html( $e->getMessage() ),
1072
+ ) );
1073
+
1074
+ // Catch any remaining error.
1075
+ } catch( \Exception $e ) {
1076
+ return wp_send_json_error( array(
1077
+ 'message' => esc_html( $e->getMessage() ),
1078
+ ) );
1079
+ }
1080
+ }
1081
+ add_action( 'wp_ajax_edds_complete_payment', 'edds_complete_payment' );
1082
+ add_action( 'wp_ajax_nopriv_edds_complete_payment', 'edds_complete_payment' );
1083
+
1084
+ /**
1085
+ * Completes a Payment authorization.
1086
+ *
1087
+ * @since 2.7.0
1088
+ */
1089
+ function edds_complete_payment_authorization() {
1090
+ $intent_id = isset( $_REQUEST['intent_id'] ) ? sanitize_text_field( $_REQUEST['intent_id'] ) : null;
1091
+
1092
+ try {
1093
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
1094
+ throw new \EDD_Stripe_Gateway_Exception(
1095
+ esc_html__(
1096
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1097
+ 'easy-digital-downloads'
1098
+ ),
1099
+ 'Rate limit reached during payment authorization.'
1100
+ );
1101
+ }
1102
+
1103
+ $nonce = isset( $_POST['edds-complete-payment-authorization'] )
1104
+ ? sanitize_text_field( $_POST['edds-complete-payment-authorization'] )
1105
+ : '';
1106
+
1107
+ $nonce_verified = wp_verify_nonce( $nonce, 'edds-complete-payment-authorization' );
1108
+
1109
+ if ( false === $nonce_verified ) {
1110
+ throw new \EDD_Stripe_Gateway_Exception(
1111
+ esc_html__(
1112
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1113
+ 'easy-digital-downloads'
1114
+ ),
1115
+ 'Nonce verification failed during payment authorization.'
1116
+ );
1117
+ }
1118
+
1119
+ $intent = edds_api_request( 'PaymentIntent', 'retrieve', $intent_id );
1120
+ $edd_payment_id = $intent->metadata->edd_payment_id ? $intent->metadata->edd_payment_id : false;
1121
+
1122
+ if ( ! $edd_payment_id ) {
1123
+ throw new \EDD_Stripe_Gateway_Exception(
1124
+ esc_html__(
1125
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1126
+ 'easy-digital-downloads'
1127
+ ),
1128
+ 'Unable to retrieve payment record ID from Stripe metadata.'
1129
+ );
1130
+ }
1131
+
1132
+ $payment = edd_get_payment( $edd_payment_id );
1133
+ $charge_id = current( $intent->charges->data )->id;
1134
+
1135
+ $payment->add_note( 'Stripe Charge ID: ' . $charge_id );
1136
+ $payment->transaction_id = $charge_id;
1137
+ $payment->status = 'publish';
1138
+
1139
+
1140
+ if ( $payment->save() ) {
1141
+
1142
+ /**
1143
+ * Allows further processing after a payment authorization is completed.
1144
+ *
1145
+ * @since 2.7.0
1146
+ *
1147
+ * @param \Stripe\PaymentIntent $intent Created Stripe Intent.
1148
+ * @param EDD_Payment $payment EDD Payment.
1149
+ */
1150
+ do_action( 'edds_payment_authorization_complete', $intent, $payment );
1151
+
1152
+ return wp_send_json_success( array(
1153
+ 'intent' => $intent,
1154
+ 'payment' => $payment,
1155
+ ) );
1156
+ } else {
1157
+ throw new \EDD_Stripe_Gateway_Exception(
1158
+ esc_html__(
1159
+ 'An error occurred, but your payment may have gone through. Please contact the site administrator.',
1160
+ 'easy-digital-downloads'
1161
+ ),
1162
+ 'Unable to save payment record during authorization.'
1163
+ );
1164
+ }
1165
+ } catch( \Exception $e ) {
1166
+ return wp_send_json_error( array(
1167
+ 'message' => esc_html( $e->getMessage() ),
1168
+ ) );
1169
+ }
1170
+ }
1171
+ add_action( 'wp_ajax_edds_complete_payment_authorization', 'edds_complete_payment_authorization' );
1172
+ add_action( 'wp_ajax_nopriv_edds_complete_payment_authorization', 'edds_complete_payment_authorization' );
1173
+
1174
+ /**
1175
+ * Sets up a \Stripe\Customer object based on the current purchase data.
1176
+ *
1177
+ * @param array $purchase_data {
1178
+ *
1179
+ * }
1180
+ * @return \Stripe\Customer|false $customer Stripe Customer if one is created or false on error.
1181
+ */
1182
+ function edds_checkout_setup_customer( $purchase_data ) {
1183
+ $customer = false;
1184
+ $stripe_customer_id = '';
1185
+ if ( is_user_logged_in() ) {
1186
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
1187
+ }
1188
+ if ( empty( $stripe_customer_id ) ) {
1189
+ // No customer ID found, let's look one up based on the email.
1190
+ $stripe_customer_id = edds_get_stripe_customer_id( $purchase_data['user_email'], false );
1191
+ }
1192
+ $customer_args = array(
1193
+ 'email' => $purchase_data['user_email'],
1194
+ 'description' => $purchase_data['user_email'],
1195
+ );
1196
+ /**
1197
+ * Filters the arguments used to create a Customer in Stripe.
1198
+ *
1199
+ * @since unknown
1200
+ *
1201
+ * @param array $customer_args {
1202
+ * Arguments to create a Stripe Customer.
1203
+ *
1204
+ * @link https://stripe.com/docs/api/customers/create
1205
+ * }
1206
+ * @param array $purchase_data {
1207
+ * Cart purchase data if in the checkout context. Empty otherwise.
1208
+ * }
1209
+ */
1210
+ $customer_args = apply_filters( 'edds_create_customer_args', $customer_args, $purchase_data );
1211
+ $customer = edds_get_stripe_customer( $stripe_customer_id, $customer_args );
1212
+
1213
+ return $customer;
1214
+ }
1215
+
1216
+ /**
1217
+ * Generates a description based on the cart details.
1218
+ *
1219
+ * @param array $cart_details {
1220
+ *
1221
+ * }
1222
+ * @return string
1223
+ */
1224
+ function edds_get_payment_description( $cart_details ) {
1225
+ $purchase_summary = '';
1226
+
1227
+ if( is_array( $cart_details ) && ! empty( $cart_details ) ) {
1228
+ foreach( $cart_details as $item ) {
1229
+ $purchase_summary .= $item['name'];
1230
+ $price_id = isset( $item['item_number']['options']['price_id'] )
1231
+ ? absint( $item['item_number']['options']['price_id'] )
1232
+ : false;
1233
+
1234
+ if ( false !== $price_id ) {
1235
+ $purchase_summary .= ' - ' . edd_get_price_option_name( $item['id'], $item['item_number']['options']['price_id'] );
1236
+ }
1237
+
1238
+ $purchase_summary .= ', ';
1239
+ }
1240
+
1241
+ $purchase_summary = rtrim( $purchase_summary, ', ' );
1242
+ } else {
1243
+ $purchase_summary = edd_get_purchase_summary( $purchase_data, false );
1244
+ }
1245
+
1246
+ // Stripe has a maximum of 999 characters in the charge description
1247
+ $purchase_summary = substr( $purchase_summary, 0, 1000 );
1248
+
1249
+ return html_entity_decode( $purchase_summary, ENT_COMPAT, 'UTF-8' );
1250
+ }
1251
+
1252
+ /**
1253
+ * Charge a preapproved payment
1254
+ *
1255
+ * @since 1.6
1256
+ * @return bool
1257
+ */
1258
+ function edds_charge_preapproved( $payment_id = 0 ) {
1259
+ $retval = false;
1260
+
1261
+ if ( empty( $payment_id ) ) {
1262
+ return $retval;
1263
+ }
1264
+
1265
+ $payment = edd_get_payment( $payment_id );
1266
+ $customer_id = $payment->get_meta( '_edds_stripe_customer_id' );
1267
+
1268
+ if ( empty( $customer_id ) ) {
1269
+ return $retval;
1270
+ }
1271
+
1272
+ if ( ! in_array( $payment->status, array( 'preapproval', 'preapproval_pending' ), true ) ) {
1273
+ return $retval;
1274
+ }
1275
+
1276
+ $setup_intent_id = $payment->get_meta( '_edds_stripe_setup_intent_id' );
1277
+
1278
+ try {
1279
+ if ( edds_is_zero_decimal_currency() ) {
1280
+ $amount = edd_get_payment_amount( $payment->ID );
1281
+ } else {
1282
+ $amount = edd_get_payment_amount( $payment->ID ) * 100;
1283
+ }
1284
+
1285
+ $cart_details = edd_get_payment_meta_cart_details( $payment->ID );
1286
+ $purchase_summary = edds_get_payment_description( $cart_details );
1287
+ $statement_descriptor = edds_get_statement_descriptor();
1288
+
1289
+ if ( empty( $statement_descriptor ) ) {
1290
+ $statement_descriptor = substr( $purchase_summary, 0, 22 );
1291
+ }
1292
+
1293
+ $statement_descriptor = apply_filters( 'edds_preapproved_statement_descriptor', $statement_descriptor, $payment->ID );
1294
+ $statement_descriptor = edds_sanitize_statement_descriptor( $statement_descriptor );
1295
+
1296
+ if ( empty( $statement_descriptor ) ) {
1297
+ $statement_descriptor = null;
1298
+ }
1299
+
1300
+ // Create a PaymentIntent using SetupIntent data.
1301
+ if ( ! empty( $setup_intent_id ) ) {
1302
+ $setup_intent = edds_api_request( 'SetupIntent', 'retrieve', $setup_intent_id );
1303
+ $intent_args = array(
1304
+ 'amount' => $amount,
1305
+ 'currency' => edd_get_currency(),
1306
+ 'payment_method' => $setup_intent->payment_method,
1307
+ 'customer' => $setup_intent->customer,
1308
+ 'off_session' => true,
1309
+ 'confirm' => true,
1310
+ 'description' => $purchase_summary,
1311
+ 'metadata' => $setup_intent->metadata->toArray(),
1312
+ 'statement_descriptor' => $statement_descriptor,
1313
+ );
1314
+ // Process a legacy preapproval. Uses the Customer's default source.
1315
+ } else {
1316
+ $customer = \Stripe\Customer::retrieve( $customer_id );
1317
+ $intent_args = array(
1318
+ 'amount' => $amount,
1319
+ 'currency' => edd_get_currency(),
1320
+ 'payment_method' => $customer->default_source,
1321
+ 'customer' => $customer->id,
1322
+ 'off_session' => true,
1323
+ 'confirm' => true,
1324
+ 'description' => $purchase_summary,
1325
+ 'metadata' => array(
1326
+ 'email' => edd_get_payment_user_email( $payment->ID ),
1327
+ 'edd_payment_id' => $payment->ID,
1328
+ ),
1329
+ 'statement_descriptor' => $statement_descriptor,
1330
+ );
1331
+ }
1332
+
1333
+ /** This filter is documented in includes/payment-actions.php */
1334
+ $intent_args = apply_filters( 'edds_create_payment_intent_args', $intent_args, array() );
1335
+
1336
+ $payment_intent = edds_api_request( 'PaymentIntent', 'create', $intent_args );
1337
+
1338
+ if ( 'succeeded' === $payment_intent->status ) {
1339
+ $charge_id = current( $payment_intent->charges->data )->id;
1340
+
1341
+ $payment->status = 'publish';
1342
+ $payment->add_note( 'Stripe Charge ID: ' . $charge_id );
1343
+ $payment->add_note( 'Stripe PaymentIntent ID: ' . $payment_intent->id );
1344
+ $payment->add_meta( '_edds_stripe_payment_intent_id', $payment_intent->id );
1345
+ $payment->transaction_id = $charge_id;
1346
+
1347
+ $retval = $payment->save();
1348
+ }
1349
+ } catch( \Stripe\Exception\ApiErrorException $e ) {
1350
+ $error = $e->getJsonBody()['error'];
1351
+
1352
+ $payment->status = 'preapproval_pending';
1353
+ $payment->add_note( esc_html(
1354
+ edds_get_localized_error_message( $error['code'], $error['message'] )
1355
+ ) );
1356
+ $payment->add_note( 'Stripe PaymentIntent ID: ' . $error['payment_intent']['id'] );
1357
+ $payment->add_meta( '_edds_stripe_payment_intent_id', $error['payment_intent']['id'] );
1358
+ $payment->save();
1359
+
1360
+ /**
1361
+ * Allows further processing when a Preapproved payment needs further action.
1362
+ *
1363
+ * @since 2.7.0
1364
+ *
1365
+ * @param int $payment_id ID of the payment.
1366
+ */
1367
+ do_action( 'edds_preapproved_payment_needs_action', $payment_id );
1368
+ } catch( \Exception $e ) {
1369
+ $payment->add_note( esc_html( $e->getMessage() ) );
1370
+ }
1371
+
1372
+ return $retval;
1373
+ }
1374
+
1375
+ /**
1376
+ * Process refund in Stripe
1377
+ *
1378
+ * @access public
1379
+ * @since 1.8
1380
+ * @return void
1381
+ */
1382
+ function edd_stripe_process_refund( $payment_id, $new_status, $old_status ) {
1383
+ if ( empty( $_POST['edd_refund_in_stripe'] ) ) {
1384
+ return;
1385
+ }
1386
+
1387
+ $should_process_refund = 'publish' != $old_status && 'revoked' != $old_status ? false : true;
1388
+ $should_process_refund = apply_filters( 'edds_should_process_refund', $should_process_refund, $payment_id, $new_status, $old_status );
1389
+
1390
+ if ( false === $should_process_refund ) {
1391
+ return;
1392
+ }
1393
+
1394
+ if ( 'refunded' != $new_status ) {
1395
+ return;
1396
+ }
1397
+
1398
+ $charge_id = edd_get_payment_transaction_id( $payment_id );
1399
+
1400
+ if ( empty( $charge_id ) || $charge_id == $payment_id ) {
1401
+ $notes = edd_get_payment_notes( $payment_id );
1402
+
1403
+ foreach ( $notes as $note ) {
1404
+ if ( preg_match( '/^Stripe Charge ID: ([^\s]+)/', $note->comment_content, $match ) ) {
1405
+ $charge_id = $match[1];
1406
+ break;
1407
+ }
1408
+ }
1409
+ }
1410
+
1411
+ // Bail if no charge ID was found.
1412
+ if ( empty( $charge_id ) ) {
1413
+ return;
1414
+ }
1415
+
1416
+ try {
1417
+ $args = apply_filters( 'edds_create_refund_args', array(
1418
+ 'charge' => $charge_id,
1419
+ ) );
1420
+
1421
+ $sec_args = apply_filters( 'edds_create_refund_secondary_args', array() );
1422
+
1423
+ $refund = edds_api_request( 'Refund', 'create', $args, $sec_args );
1424
+
1425
+ edd_insert_payment_note(
1426
+ $payment_id,
1427
+ sprintf(
1428
+ /* translators: %s Stripe Refund ID */
1429
+ __( 'Charge refunded in Stripe. Refund ID %s', 'easy-digital-downloads' ),
1430
+ $refund->id
1431
+ )
1432
+ );
1433
+
1434
+ } catch ( Exception $e ) {
1435
+ wp_die( $e->getMessage(), __( 'Error', 'easy-digital-downloads' ) , array( 'response' => 400 ) );
1436
+ }
1437
+
1438
+ do_action( 'edds_payment_refunded', $payment_id );
1439
+ }
1440
+ add_action( 'edd_update_payment_status', 'edd_stripe_process_refund', 200, 3 );
includes/gateways/stripe/includes/payment-methods/buy-now/ajax.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now: AJAX
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Adds a Download to the Cart on the `edds_add_to_cart` AJAX action.
11
+ *
12
+ * @since 2.8.0
13
+ */
14
+ function edds_buy_now_ajax_add_to_cart() {
15
+ $data = $_POST;
16
+
17
+ if ( ! isset( $data['download_id'] ) || ! isset( $data['nonce'] ) ) {
18
+ return wp_send_json_error( array(
19
+ 'message' => __( 'Unable to add item to cart.', 'easy-digital-downloads' ),
20
+ ) );
21
+ }
22
+
23
+ $download_id = absint( $data['download_id'] );
24
+ $price_id = absint( $data['price_id'] );
25
+ $quantity = absint( $data['quantity'] );
26
+
27
+ $nonce = sanitize_text_field( $data['nonce'] );
28
+ $valid_nonce = wp_verify_nonce( $nonce, 'edd-add-to-cart-' . $download_id );
29
+
30
+ if ( false === $valid_nonce ) {
31
+ return wp_send_json_error( array(
32
+ 'message' => __( 'Unable to add item to cart.', 'easy-digital-downloads' ),
33
+ ) );
34
+ }
35
+
36
+ // Empty cart.
37
+ edd_empty_cart();
38
+
39
+ // Add individual item.
40
+ edd_add_to_cart( $download_id, array(
41
+ 'quantity' => $quantity,
42
+ 'price_id' => $price_id,
43
+ ) );
44
+
45
+ return wp_send_json_success( array(
46
+ 'checkout' => edds_buy_now_checkout(),
47
+ ) );
48
+ }
49
+ add_action( 'wp_ajax_edds_add_to_cart', 'edds_buy_now_ajax_add_to_cart' );
50
+ add_action( 'wp_ajax_nopriv_edds_add_to_cart', 'edds_buy_now_ajax_add_to_cart' );
51
+
52
+ /**
53
+ * Empties the cart on the `edds_buy_now_empty_cart` AJAX action.
54
+ *
55
+ * @since 2.8.0
56
+ */
57
+ function edds_buy_now_ajax_empty_cart() {
58
+ edd_empty_cart();
59
+
60
+ return wp_send_json_success();
61
+ }
62
+ add_action( 'wp_ajax_edds_empty_cart', 'edds_buy_now_ajax_empty_cart' );
63
+ add_action( 'wp_ajax_nopriv_edds_empty_cart', 'edds_buy_now_ajax_empty_cart' );
includes/gateways/stripe/includes/payment-methods/buy-now/checkout.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now: Checkout
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ // Hook in global card validation to this flow.
10
+ add_action( 'edds_buy_now_checkout_error_checks', 'edds_process_post_data' );
11
+
12
+ /**
13
+ * Adds Buy Now-specific overrides when processing a Buy Now purchase.
14
+ *
15
+ * @since 2.8.0
16
+ */
17
+ function edds_buy_now_process_overrides() {
18
+ if ( ! isset( $_POST ) ) {
19
+ return;
20
+ }
21
+
22
+ if ( ! isset( $_POST['edds-gateway'] ) ) {
23
+ return;
24
+ }
25
+
26
+ if ( 'buy-now' !== $_POST['edds-gateway'] ) {
27
+ return;
28
+ }
29
+
30
+ // Ensure Billing Address and Name Fields are not required.
31
+ add_filter( 'edd_require_billing_address', '__return_false' );
32
+
33
+ // Require email address.
34
+ add_filter( 'edd_purchase_form_required_fields', 'edds_buy_now_purchase_form_required_fields', 9999 );
35
+
36
+ // Remove 3rd party validations.
37
+ remove_all_actions( 'edd_checkout_error_checks' );
38
+ remove_all_actions( 'edd_checkout_user_error_checks' );
39
+
40
+ // Validate the form $_POST data.
41
+ $valid_data = edd_purchase_form_validate_fields();
42
+
43
+ /**
44
+ * Allows Buy Now-specific checkout validations.
45
+ *
46
+ * @since 2.8.0
47
+ *
48
+ * @param array $valid_data Validated checkout data.
49
+ * @param array $_POST Global $_POST data.
50
+ */
51
+ do_action( 'edds_buy_now_checkout_error_checks', $valid_data, $_POST );
52
+
53
+ // Validate the user
54
+ $user = edd_get_purchase_form_user( $valid_data );
55
+
56
+ /**
57
+ * Allows Buy Now-specific user validations.
58
+ *
59
+ * @since 2.8.0
60
+ *
61
+ * @param array $user Validated user data.
62
+ * @param array $valid_data Validated checkout data.
63
+ * @param array $_POST Global $_POST data.
64
+ */
65
+ do_action( 'edds_buy_now_checkout_user_error_checks', $user, $valid_data, $_POST );
66
+ }
67
+ add_action( 'edd_pre_process_purchase', 'edds_buy_now_process_overrides' );
68
+
69
+ /**
70
+ * Filters the purchase form's required field to only
71
+ * require an email address.
72
+ *
73
+ * @since 2.8.0
74
+ *
75
+ * @return array
76
+ */
77
+ function edds_buy_now_purchase_form_required_fields() {
78
+ return array(
79
+ 'edd_email' => array(
80
+ 'error_id' => 'invalid_email',
81
+ 'error_message' => __( 'Please enter a valid email address', 'easy-digital-downloads' )
82
+ ),
83
+ );
84
+ }
includes/gateways/stripe/includes/payment-methods/buy-now/functions.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now: Functions
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Checks to see if "Buy Now" is enabled.
11
+ *
12
+ * @since 2.8
13
+ * @return boolean
14
+ */
15
+ function edds_buy_now_is_enabled() {
16
+ // Check if the shop supports Buy Now.
17
+ $shop_supports = edd_shop_supports_buy_now();
18
+
19
+ if ( false === $shop_supports ) {
20
+ return false;
21
+ }
22
+
23
+ // Check if guest checkout is disabled and the user is not logged in.
24
+ if ( edd_logged_in_only() && ! is_user_logged_in() ) {
25
+ return false;
26
+ }
27
+
28
+ return true;
29
+ }
30
+
31
+ /**
32
+ * Allows "Buy Now" support if `stripe` and `stripe-prb` (Express Checkout) are
33
+ * the only two active gateways and taxes are not enabled.
34
+ *
35
+ * @since 2.8
36
+ * @param boolean $supports Whether the shop supports Buy Now, as determined by EDD.
37
+ * @return boolean
38
+ */
39
+ function edds_shop_supports_buy_now( $supports ) {
40
+
41
+ if ( edd_use_taxes() ) {
42
+ return false;
43
+ }
44
+
45
+ $gateways = edd_get_enabled_payment_gateways();
46
+ $stripe_gateways = array( 'stripe', 'stripe-prb' );
47
+ if ( empty( array_diff( array_keys( $gateways ), $stripe_gateways ) ) ) {
48
+ return true;
49
+ }
50
+
51
+ return $supports;
52
+ }
53
+ add_filter( 'edd_shop_supports_buy_now', 'edds_shop_supports_buy_now' );
includes/gateways/stripe/includes/payment-methods/buy-now/index.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/functions.php';
10
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/ajax.php';
11
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/checkout.php';
12
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/template.php';
13
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/buy-now/shortcode.php';
includes/gateways/stripe/includes/payment-methods/buy-now/shortcode.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now: Shortcode
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Sets the stripe-checkout parameter if the direct parameter is present in the [purchase_link] short code.
11
+ *
12
+ * @since 2.0
13
+ *
14
+ * @param array $out
15
+ * @param array $pairs
16
+ * @param array $atts
17
+ * @return array
18
+ */
19
+ function edd_stripe_purchase_link_shortcode_atts( $out, $pairs, $atts ) {
20
+
21
+ if ( ! edds_buy_now_is_enabled() ) {
22
+ return $out;
23
+ }
24
+
25
+ $direct = false;
26
+
27
+ // [purchase_link direct=true]
28
+ if ( isset( $atts['direct'] ) && true === edds_truthy_to_bool( $atts['direct'] ) ) {
29
+ $direct = true;
30
+
31
+ // [purchase_link stripe-checkout]
32
+ } else if ( isset( $atts['stripe-checkout'] ) || false !== array_search( 'stripe-checkout', $atts, true ) ) {
33
+ $direct = true;
34
+ }
35
+
36
+ $out['direct'] = $direct;
37
+
38
+ if ( true === $direct ) {
39
+ $out['stripe-checkout'] = $direct;
40
+ } else {
41
+ unset( $out['stripe-checkout'] );
42
+ }
43
+
44
+ return $out;
45
+ }
46
+ add_filter( 'shortcode_atts_purchase_link', 'edd_stripe_purchase_link_shortcode_atts', 10, 3 );
47
+
48
+ /**
49
+ * Sets the stripe-checkout parameter if the direct parameter is present in edd_get_purchase_link()
50
+ *
51
+ * @since 2.0
52
+ * @since 2.8.0 Adds `.edds-buy-now` to the class list.
53
+ *
54
+ * @param array $arg Purchase link shortcode attributes.
55
+ * @return array
56
+ */
57
+ function edd_stripe_purchase_link_atts( $args ) {
58
+ global $edds_has_buy_now;
59
+
60
+ if ( ! edds_buy_now_is_enabled() ) {
61
+ return $args;
62
+ }
63
+
64
+ // Don't use modal if "Free Downloads" is active and available for this download.
65
+ // https://easydigitaldownloads.com/downloads/free-downloads/
66
+ if ( function_exists( 'edd_free_downloads_use_modal' ) ) {
67
+ if ( edd_free_downloads_use_modal( $args['download_id'] ) && ! edd_has_variable_prices( $args['download_id'] ) ) {
68
+ return $args;
69
+ }
70
+ }
71
+
72
+ $direct = edds_truthy_to_bool( $args['direct'] );
73
+
74
+ $args['direct'] = $direct;
75
+
76
+ if ( true === $direct ) {
77
+ $args['stripe-checkout'] = true;
78
+ $args['class'] .= ' edds-buy-now';
79
+
80
+ if ( false === edd_item_in_cart( $args['download_id'] ) ) {
81
+ $edds_has_buy_now = $direct;
82
+ }
83
+ } else {
84
+ unset( $args['stripe-checkout'] );
85
+ }
86
+
87
+ return $args;
88
+ }
89
+ add_filter( 'edd_purchase_link_args', 'edd_stripe_purchase_link_atts', 10 );
90
+
91
+ /**
92
+ * Disables the Buy Now button behavior if Stripe's "Buy Now" is not supported.
93
+ *
94
+ * @since 2.8
95
+ * @param string $button_behavior The current cart button behavior.
96
+ * @return string
97
+ */
98
+ function edds_maybe_disable_buy_now_button( $button_behavior ) {
99
+ if ( ! edds_buy_now_is_enabled() ) {
100
+ return 'add_to_cart';
101
+ }
102
+
103
+ return $button_behavior;
104
+ }
105
+ add_filter( 'edd_get_download_button_behavior', 'edds_maybe_disable_buy_now_button' );
includes/gateways/stripe/includes/payment-methods/buy-now/template.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Buy Now: Template
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Adds "Buy Now" modal markup to the bottom of the page.
11
+ *
12
+ * @since 2.8.0
13
+ */
14
+ function edds_buy_now_modal() {
15
+ // Check if Stripe Buy Now is enabled.
16
+ global $edds_has_buy_now;
17
+
18
+ if ( true !== $edds_has_buy_now ) {
19
+ return;
20
+ }
21
+
22
+ if ( ! edds_buy_now_is_enabled() ) {
23
+ return;
24
+ }
25
+
26
+ // Enqueue core scripts.
27
+ add_filter( 'edd_is_checkout', '__return_true' );
28
+
29
+ if ( function_exists( 'edd_enqueue_scripts' ) ) {
30
+ // https://github.com/easydigitaldownloads/easy-digital-downloads/issues/7847
31
+ edd_enqueue_scripts();
32
+ edd_localize_scripts();
33
+ } else {
34
+ edd_load_scripts();
35
+ }
36
+
37
+ edd_agree_to_terms_js();
38
+
39
+ remove_filter( 'edd_is_checkout', '__return_true' );
40
+
41
+ // Enqueue scripts.
42
+ edd_stripe_js( true );
43
+ edd_stripe_css( true );
44
+
45
+ echo edds_modal( array(
46
+ 'id' => 'edds-buy-now',
47
+ 'title' => __( 'Buy Now', 'easy-digital-downloads' ),
48
+ 'class' => array(
49
+ 'edds-buy-now-modal',
50
+ ),
51
+ 'content' => '<span class="edd-loading-ajax edd-loading"></span>',
52
+ ) ); // WPCS: XSS okay.
53
+ }
54
+ add_action( 'wp_print_footer_scripts', 'edds_buy_now_modal', 0 );
55
+
56
+ /**
57
+ * Outputs a custom "Buy Now"-specific Checkout form.
58
+ *
59
+ * @since 2.8.0
60
+ */
61
+ function edds_buy_now_checkout() {
62
+ $total = (int) edd_get_cart_total();
63
+
64
+ $form_mode = $total > 0
65
+ ? 'payment-mode=stripe'
66
+ : 'payment-mode=manual';
67
+ $form_action = edd_get_checkout_uri( $form_mode );
68
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
69
+
70
+ $customer = EDD()->session->get( 'customer' );
71
+ $customer = wp_parse_args(
72
+ $customer,
73
+ array(
74
+ 'email' => '',
75
+ )
76
+ );
77
+
78
+ if ( is_user_logged_in() ) {
79
+ $user_data = get_userdata( get_current_user_id() );
80
+
81
+ foreach( $customer as $key => $field ) {
82
+ if ( 'email' == $key && empty( $field ) ) {
83
+ $customer[ $key ] = $user_data->user_email;
84
+ } elseif ( empty( $field ) ) {
85
+ $customer[ $key ] = $user_data->$key;
86
+ }
87
+ }
88
+ }
89
+
90
+ $customer = array_map( 'sanitize_text_field', $customer );
91
+
92
+ remove_action( 'edd_after_cc_fields', 'edd_default_cc_address_fields', 10 );
93
+ remove_action( 'edd_purchase_form_before_submit', 'edd_checkout_final_total', 999 );
94
+
95
+ // Filter purchase button label.
96
+ add_filter( 'edd_get_checkout_button_purchase_label', 'edds_buy_now_checkout_purchase_label' );
97
+
98
+ ob_start();
99
+ ?>
100
+
101
+ <div id="edd_checkout_form_wrap">
102
+ <form
103
+ id="edd_purchase_form"
104
+ class="edd_form edds-buy-now-form"
105
+ action="<?php echo esc_url( $form_action ); ?>"
106
+ method="POST"
107
+ >
108
+ <p>
109
+ <label class="edd-label" for="edd-email">
110
+ <?php esc_html_e( 'Email Address', 'easy-digital-downloads' ); ?>
111
+ <?php if ( edd_field_is_required( 'edd_email' ) ) : ?>
112
+ <span class="edd-required-indicator">*</span>
113
+ <?php endif ?>
114
+ </label>
115
+
116
+ <input
117
+ id="edd-email"
118
+ class="edd-input required"
119
+ type="email"
120
+ name="edd_email"
121
+ value="<?php echo esc_attr( $customer['email'] ); ?>"
122
+ <?php if ( edd_field_is_required( 'edd_email' ) ) : ?>
123
+ required
124
+ <?php endif; ?>
125
+ />
126
+ </p>
127
+
128
+ <?php if ( $total > 0 ) : ?>
129
+
130
+ <?php if ( ! empty( $existing_cards ) ) : ?>
131
+ <?php edd_stripe_existing_card_field_radio( get_current_user_id() ); ?>
132
+ <?php endif; ?>
133
+
134
+ <div
135
+ class="edd-stripe-new-card"
136
+ <?php if ( ! empty( $existing_cards ) ) : ?>
137
+ style="display: none;"
138
+ <?php endif; ?>
139
+ >
140
+ <?php do_action( 'edd_stripe_new_card_form' ); ?>
141
+ <?php do_action( 'edd_after_cc_expiration' ); ?>
142
+ </div>
143
+
144
+ <?php endif; ?>
145
+
146
+ <?php
147
+ edd_terms_agreement();
148
+ edd_privacy_agreement();
149
+ edd_checkout_hidden_fields();
150
+ ?>
151
+
152
+ <div id="edd_purchase_submit">
153
+ <?php echo edd_checkout_button_purchase(); // WPCS: XSS okay. ?>
154
+ </div>
155
+
156
+ <div class="edd_cart_total" style="display: none;">
157
+ <div
158
+ class="edd_cart_amount"
159
+ data-total="<?php echo edd_get_cart_total(); ?>"
160
+ data-total-currency="<?php echo edd_currency_filter( edd_format_amount( edd_get_cart_total() ) ); ?>"
161
+ >
162
+ </div>
163
+ </div>
164
+
165
+ <input type="hidden" name="edds-gateway" value="buy-now" />
166
+ </form>
167
+ </div>
168
+
169
+ <?php
170
+ return ob_get_clean();
171
+ }
172
+
173
+ /**
174
+ * Filters the label of the of the "Purchase" button in the "Buy Now" modal.
175
+ *
176
+ * @since 2.8.0
177
+ *
178
+ * @param string $label Purchase label.
179
+ * @return string
180
+ */
181
+ function edds_buy_now_checkout_purchase_label( $label ) {
182
+ $total = edd_get_cart_total();
183
+
184
+ if ( 0 === (int) $total ) {
185
+ return $label;
186
+ }
187
+
188
+ return sprintf(
189
+ '%s - %s',
190
+ edd_currency_filter(
191
+ edd_format_amount( $total )
192
+ ),
193
+ $label
194
+ );
195
+ }
196
+
197
+ /**
198
+ * Adds additional script variables needed for the Buy Now flow.
199
+ *
200
+ * @since 2.8.0
201
+ *
202
+ * @param array $vars Script variables.
203
+ * @return array
204
+ */
205
+ function edds_buy_now_vars( $vars ) {
206
+ if ( ! isset( $vars['i18n'] ) ) {
207
+ $vars['i18n'] = array();
208
+ }
209
+
210
+ // Non-zero amount.
211
+ $label = edd_get_option( 'checkout_label', '' );
212
+ $complete_purchase = ! empty( $label )
213
+ ? $label
214
+ : esc_html__( 'Purchase', 'easy-digital-downloads' );
215
+
216
+ /* This filter is documented in easy-digital-downloads/includes/checkout/template.php */
217
+ $complete_purchase = apply_filters(
218
+ 'edd_get_checkout_button_purchase_label',
219
+ $complete_purchase,
220
+ $label
221
+ );
222
+
223
+ $vars['i18n']['completePurchase'] = $complete_purchase;
224
+
225
+ return $vars;
226
+ }
227
+ add_filter( 'edd_stripe_js_vars', 'edds_buy_now_vars' );
includes/gateways/stripe/includes/payment-methods/payment-request/admin/settings.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button: Settings
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Adds settings to the Stripe subtab.
11
+ *
12
+ * @since 2.8.0
13
+ *
14
+ * @param array $settings Gateway settings.
15
+ * @return array Filtered gateway settings.
16
+ */
17
+ function edds_prb_add_settings( $settings ) {
18
+ // Prevent adding the extra settings if the requirements are not met.
19
+ // The `edd_settings_gateways` filter runs regardless of the short circuit
20
+ // inside of `edds_add_settings()`
21
+ if (
22
+ false === edds_has_met_requirements( 'php' ) &&
23
+ false === edds_is_pro()
24
+ ) {
25
+ return $settings;
26
+ }
27
+
28
+ $prb_settings = array(
29
+ array(
30
+ 'id' => 'stripe_prb',
31
+ 'name' => __( 'Apple Pay/Google Pay', 'easy-digital-downloads' ),
32
+ 'desc' => wp_kses(
33
+ (
34
+ sprintf(
35
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Opening anchor tag, do not translate. %3$s Closing anchor tag, do not translate. */
36
+ __( '"Express Checkout" via Apple Pay, Google Pay, or Microsoft Pay digital wallets. By using Apple Pay, you agree to %1$sStripe%3$s and %2$sApple\'s%3$s terms of service.', 'easy-digital-downloads' ),
37
+ '<a href="https://stripe.com/apple-pay/legal" target="_blank" rel="noopener noreferrer">',
38
+ '<a href="https://developer.apple.com/apple-pay/acceptable-use-guidelines-for-websites/" target="_blank" rel="noopener noreferrer">',
39
+ '</a>'
40
+ ) . (
41
+ edd_use_taxes()
42
+ ? '<br /><strong>' . __( 'This feature is not available when taxes are enabled.', 'easy-digital-downloads' ) . '</strong>'
43
+ : ''
44
+ ) . (
45
+ edd_is_test_mode()
46
+ ? '<br /><strong>' . __( 'Apple Pay is not available in Test Mode.', 'easy-digital-downloads' ) . '</strong> ' . sprintf(
47
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Opening anchor tag, do not translate. */
48
+ __( 'See our %1$sdocumentation%2$s for more information.', 'easy-digital-downloads' ),
49
+ '<a href="' . esc_url( edds_documentation_route( 'stripe-express-checkout' ) ) . '" target="_blank" rel="noopener noreferrer">',
50
+ '</a>'
51
+ )
52
+ : ''
53
+ )
54
+ ),
55
+ array(
56
+ 'br' => true,
57
+ 'strong' => true,
58
+ 'a' => array(
59
+ 'href' => true,
60
+ 'target' => true,
61
+ 'rel' => true,
62
+ ),
63
+ )
64
+ ),
65
+ 'type' => 'multicheck',
66
+ 'options' => array(
67
+ /** translators: %s Download noun */
68
+ 'single' => sprintf(
69
+ __( 'Single %s', 'easy-digital-downloads' ),
70
+ edd_get_label_singular()
71
+ ),
72
+ /** translators: %s Download noun */
73
+ 'archive' => sprintf(
74
+ __( '%s Archive (includes <code>[downloads]</code> shortcode)', 'easy-digital-downloads' ),
75
+ edd_get_label_singular()
76
+ ),
77
+ 'checkout' => __( 'Checkout', 'easy-digital-downloads' ),
78
+ ),
79
+ )
80
+ );
81
+
82
+ $position = array_search(
83
+ 'stripe_statement_descriptor',
84
+ array_values( wp_list_pluck( $settings['edd-stripe'], 'id' ) ),
85
+ true
86
+ );
87
+
88
+ $settings['edd-stripe'] = array_merge(
89
+ array_slice( $settings['edd-stripe'], 0, $position + 1 ),
90
+ $prb_settings,
91
+ array_slice( $settings['edd-stripe'], $position + 1 )
92
+ );
93
+
94
+ return $settings;
95
+ }
96
+ add_filter( 'edd_settings_gateways', 'edds_prb_add_settings', 20 );
97
+
98
+ /**
99
+ * Force "Payment Request Buttons" to be disabled if taxes are enabled.
100
+ *
101
+ * @since 2.8.0
102
+ *
103
+ * @param mixed $value Setting value.
104
+ * @param string $key Setting key.
105
+ * @return string Setting value.
106
+ */
107
+ function edds_prb_sanitize_setting( $value, $key ) {
108
+ if ( 'stripe_prb' === $key && edd_use_taxes() ) {
109
+ $value = array();
110
+ }
111
+
112
+ return $value;
113
+ }
114
+ add_filter( 'edd_settings_sanitize_multicheck', 'edds_prb_sanitize_setting', 10, 2 );
includes/gateways/stripe/includes/payment-methods/payment-request/ajax.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button: AJAX
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Starts the Checkout process for a Payment Request.
11
+ *
12
+ * This needs to be used instead of `_edds_process_purchase_form()` so
13
+ * Checkout form data can be shimmed or faked to prevent getting hung
14
+ * up on things like privacy policy, terms of service, etc.
15
+ *
16
+ * @since 2.8.0
17
+ */
18
+ function edds_prb_ajax_process_checkout() {
19
+ // Clear any errors that might be used as a reason to attempt a redirect in the following action.
20
+ edd_clear_errors();
21
+
22
+ $download_id = isset( $_POST['downloadId'] )
23
+ ? intval( $_POST['downloadId'] )
24
+ : 0;
25
+
26
+ $email = isset( $_POST['email'] )
27
+ ? sanitize_text_field( $_POST['email'] )
28
+ : '';
29
+
30
+ $name = isset( $_POST['name'] )
31
+ ? sanitize_text_field( $_POST['name'] )
32
+ : '';
33
+
34
+ $payment_method = isset( $_POST['paymentMethod'] )
35
+ ? $_POST['paymentMethod']
36
+ : '';
37
+
38
+ $context = isset( $_POST['context'] )
39
+ ? $_POST['context']
40
+ : 'checkout';
41
+
42
+ // Add a Download to the cart if we are not processing the full cart.
43
+ if ( 'download' === $context ) {
44
+ $price_id = isset( $_POST['priceId'] )
45
+ ? intval( $_POST['priceId'] )
46
+ : false;
47
+
48
+ $quantity = isset( $_POST['quantity'] )
49
+ ? intval( $_POST['quantity'] )
50
+ : 1;
51
+
52
+ // Empty cart.
53
+ edd_empty_cart();
54
+
55
+ // Add individual item.
56
+ edd_add_to_cart( $download_id, array(
57
+ 'quantity' => $quantity,
58
+ 'price_id' => $price_id,
59
+ ) );
60
+
61
+ // Refilter guest checkout when the item is added to the cart dynamically.
62
+ // This is a duplicate of EDD_Recurring_Gateway::require_login().
63
+ if ( defined( 'EDD_RECURRING_VERSION' ) ) {
64
+ $cart_items = edd_get_cart_contents();
65
+ $has_recurring = false;
66
+ $auto_register = class_exists( 'EDD_Auto_Register' );
67
+
68
+ if ( ! empty( $cart_items ) ) {
69
+ foreach ( $cart_items as $item ) {
70
+ if ( ! isset( $item['options']['recurring'] ) ) {
71
+ continue;
72
+ }
73
+
74
+ $has_recurring = true;
75
+ }
76
+
77
+ if ( $has_recurring && ! $auto_register ) {
78
+ add_filter( 'edd_no_guest_checkout', '__return_true' );
79
+ add_filter( 'edd_logged_in_only', '__return_true' );
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ try {
86
+ $data = array(
87
+ // Mark "sub-gateway" for Stripe. This represents the Payment Method
88
+ // currently being used. e.g `ideal`, `wepay`, `payment-request`, etc.
89
+ //
90
+ // This is used to filter field requirements via `edd_pre_process_purchase` hook.
91
+ 'edds-gateway' => 'payment-request',
92
+ 'edds-prb-context' => $context,
93
+ );
94
+
95
+ // Checkout-specific data.
96
+ if ( 'checkout' === $context ) {
97
+ $form_data = isset( $_POST['form_data'] )
98
+ ? $_POST['form_data']
99
+ : array();
100
+
101
+ // Use the Payment Method's billing details.
102
+ $card_name = (
103
+ ! empty( $payment_method['billing_details'] ) &&
104
+ ! empty( $payment_method['billing_details']['name'] )
105
+ )
106
+ ? $payment_method['billing_details']['name']
107
+ : $name;
108
+
109
+ $billing_details = ! empty( $payment_method['billing_details'] )
110
+ ? array(
111
+ 'card_name' => $card_name,
112
+ 'card_address' => $payment_method['billing_details']['address']['line1'],
113
+ 'card_address_2' => $payment_method['billing_details']['address']['line2'],
114
+ 'card_city' => $payment_method['billing_details']['address']['city'],
115
+ 'card_zip' => $payment_method['billing_details']['address']['postal_code'],
116
+ 'billing_country' => $payment_method['billing_details']['address']['country'],
117
+ 'card_state' => $payment_method['billing_details']['address']['state'],
118
+ )
119
+ : array(
120
+ 'card_name' => $card_name,
121
+ 'card_address' => '',
122
+ 'card_address_2' => '',
123
+ 'card_city' => '',
124
+ 'card_zip' => '',
125
+ 'billing_country' => '',
126
+ 'card_state' => '',
127
+ );
128
+
129
+ // Add the Payment Request's name as the card name.
130
+ $_POST['form_data'] = add_query_arg(
131
+ $billing_details,
132
+ $form_data
133
+ );
134
+
135
+ // Single-download data.
136
+ } else {
137
+ // Fake checkout form data.
138
+ $_POST['form_data'] = http_build_query(
139
+ array_merge(
140
+ $data,
141
+ array(
142
+ // Use Email from Payment Request.
143
+ 'edd_email' => $email,
144
+
145
+ 'edd-user-id' => get_current_user_id(),
146
+ 'edd_action' => 'purchase',
147
+ 'edd-gateway' => 'stripe',
148
+ 'edd_agree_to_terms' => '1',
149
+ 'edd_agree_to_privacy_policy' => '1',
150
+ 'edd-process-checkout-nonce' => wp_create_nonce( 'edd-process-checkout' ),
151
+ )
152
+ )
153
+ );
154
+ }
155
+
156
+ $_POST['payment_method_id'] = isset( $payment_method['id'] )
157
+ ? sanitize_text_field( $payment_method['id'] )
158
+ : '';
159
+
160
+ $_POST['payment_method_exists'] = false;
161
+
162
+ // Adjust PaymentIntent creation for PRB flow.
163
+ add_filter( 'edds_create_payment_intent_args', 'edds_prb_create_payment_intent_args', 20 );
164
+ add_filter( 'edds_create_setup_intent_args', 'edds_prb_create_setup_intent_args', 20 );
165
+
166
+ // This will send a JSON response.
167
+ _edds_process_purchase_form();
168
+ } catch ( \Exception $e ) {
169
+ wp_send_json_error( array(
170
+ 'message' => esc_html( $e->getMessage() ),
171
+ ) );
172
+ }
173
+ }
174
+ add_action( 'wp_ajax_edds_prb_ajax_process_checkout', 'edds_prb_ajax_process_checkout' );
175
+ add_action( 'wp_ajax_nopriv_edds_prb_ajax_process_checkout', 'edds_prb_ajax_process_checkout' );
176
+
177
+ /**
178
+ * Filters the arguments used when creating a PaymentIntent while
179
+ * using a Payment Request Button.
180
+ *
181
+ * @since 2.8.0
182
+ *
183
+ * @param array $args {
184
+ * PaymentIntent arguments.
185
+ *
186
+ * @link https://stripe.com/docs/api/payment_intents/create
187
+ * }
188
+ * @return array
189
+ */
190
+ function edds_prb_create_payment_intent_args( $args ) {
191
+ $args['confirmation_method'] = 'automatic';
192
+ $args['confirm'] = false;
193
+ $args['capture_method'] = 'automatic';
194
+ $args['metadata']['edds_prb'] = '1';
195
+
196
+ return $args;
197
+ }
198
+
199
+ /**
200
+ * Filters the arguments used when creating a SetupIntent while
201
+ * using a Payment Request Button.
202
+ *
203
+ * @since 2.8.0
204
+ *
205
+ * @param array $args {
206
+ * SetupIntent arguments.
207
+ *
208
+ * @link https://stripe.com/docs/api/setup_intents/create
209
+ * }
210
+ * @return array
211
+ */
212
+ function edds_prb_create_setup_intent_args( $args ) {
213
+ $args['confirm'] = false;
214
+ $args['metadata']['edds_prb'] = '1';
215
+
216
+ return $args;
217
+ }
218
+
219
+ /**
220
+ * Gathers Payment Request options based on the current context.
221
+ *
222
+ * @since 2.8.0
223
+ */
224
+ function edds_prb_ajax_get_options() {
225
+ $download_id = isset( $_POST['downloadId'] )
226
+ ? intval( $_POST['downloadId'] )
227
+ : 0;
228
+
229
+ // Single Download.
230
+ if ( ! empty( $download_id ) ) {
231
+ $price_id = isset( $_POST['priceId'] ) && 'false' !== $_POST['priceId']
232
+ ? intval( $_POST['priceId'] )
233
+ : false;
234
+
235
+ $quantity = isset( $_POST['quantity'] )
236
+ ? intval( $_POST['quantity'] )
237
+ : 1;
238
+
239
+ $data = edds_prb_get_download_data( $download_id, $price_id, $quantity );
240
+
241
+ // Handle cart eventually?
242
+ } else {
243
+ $data = edds_prb_get_cart_data();
244
+ }
245
+
246
+ // Country is not valid at this point.
247
+ // https://stripe.com/docs/js/payment_request/update
248
+ unset( $data['country'] );
249
+
250
+ wp_send_json_success( $data );
251
+ }
252
+ add_action( 'wp_ajax_edds_prb_ajax_get_options', 'edds_prb_ajax_get_options' );
253
+ add_action( 'wp_ajax_nopriv_edds_prb_ajax_get_options', 'edds_prb_ajax_get_options' );
includes/gateways/stripe/includes/payment-methods/payment-request/apple-pay.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request: Apple Pay
4
+ *
5
+ * @link https://stripe.com/docs/stripe-js/elements/payment-request-button#verifying-your-domain-with-apple-pay
6
+ *
7
+ * @package EDD_Stripe
8
+ * @since 2.8.0
9
+ */
10
+
11
+ /**
12
+ * Registers admin notices.
13
+ *
14
+ * @since 2.8.0
15
+ *
16
+ * @return true|WP_Error True if all notices are registered, otherwise WP_Error.
17
+ */
18
+ function edds_prb_apple_pay_admin_notices_register() {
19
+ $registry = edds_get_registry( 'admin-notices' );
20
+
21
+ if ( ! $registry ) {
22
+ return new WP_Error( 'edds-invalid-registry', esc_html__( 'Unable to locate registry', 'easy-digital-downloads' ) );
23
+ }
24
+
25
+ try {
26
+ // General error message.
27
+ $message = (
28
+ '<strong>' . esc_html__( 'Apple Pay domain verification error.', 'easy-digital-downloads' ) . '</strong><br />' .
29
+ edd_get_option( 'stripe_prb_apple_pay_domain_error', '' )
30
+ );
31
+
32
+ $registry->add(
33
+ 'apple-pay-' . $_SERVER['HTTP_HOST'],
34
+ array(
35
+ 'message' => wp_kses(
36
+ wpautop( $message ),
37
+ array(
38
+ 'code' => true,
39
+ 'br' => true,
40
+ 'strong' => true,
41
+ 'p' => true,
42
+ 'a' => array(
43
+ 'href' => true,
44
+ 'rel' => true,
45
+ 'target' => true,
46
+ ),
47
+ )
48
+ ),
49
+ 'type' => 'error',
50
+ 'dismissible' => true,
51
+ )
52
+ );
53
+ } catch( Exception $e ) {
54
+ return new WP_Error( 'edds-invalid-notices-registration', esc_html( $e->getMessage() ) );
55
+ };
56
+
57
+ return true;
58
+ }
59
+ add_action( 'admin_init', 'edds_prb_apple_pay_admin_notices_register', 30 );
60
+
61
+ /**
62
+ * Conditionally prints registered notices.
63
+ *
64
+ * @since 2.8.0
65
+ */
66
+ function edds_prb_apple_pay_admin_notices_print() {
67
+ // Current user needs capability to dismiss notices.
68
+ if ( ! current_user_can( 'manage_options' ) ) {
69
+ return;
70
+ }
71
+
72
+ $registry = edds_get_registry( 'admin-notices' );
73
+
74
+ if ( ! $registry ) {
75
+ return;
76
+ }
77
+
78
+ $notices = new EDD_Stripe_Admin_Notices( $registry );
79
+
80
+ wp_enqueue_script( 'edds-admin-notices' );
81
+
82
+ try {
83
+ $error = edd_get_option( 'stripe_prb_apple_pay_domain_error', '' );
84
+ $test_mode = edd_is_test_mode();
85
+
86
+ if ( ! empty( $error ) && false === $test_mode ) {
87
+ $notices->output( 'apple-pay-' . $_SERVER['HTTP_HOST'] );
88
+ }
89
+ } catch( Exception $e ) {}
90
+ }
91
+ add_action( 'admin_notices', 'edds_prb_apple_pay_admin_notices_print' );
92
+
93
+ /**
94
+ * Returns information associated with the name/location of the domain verification file.
95
+ *
96
+ * @since 2.8.0
97
+ *
98
+ * @return array Domain verification file information.
99
+ */
100
+ function edds_prb_apple_pay_get_fileinfo() {
101
+ $path = untrailingslashit( $_SERVER['DOCUMENT_ROOT'] );
102
+ $dir = '.well-known';
103
+ $file = 'apple-developer-merchantid-domain-association';
104
+
105
+ return array(
106
+ 'path' => $path,
107
+ 'dir' => $dir,
108
+ 'file' => $file,
109
+ 'fullpath' => $path . '/' . $dir . '/' . $file,
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Determines if the current website is setup to use Apple Pay.
115
+ *
116
+ * @since 2.8.0
117
+ *
118
+ * @return bool True if the domain has been verified and the association file exists.
119
+ */
120
+ function edds_prb_apple_pay_is_valid() {
121
+ return (
122
+ edds_prb_apple_pay_has_domain_verification_file() &&
123
+ edds_prb_apple_pay_has_domain_verification()
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Determines if the domain verification file already exists.
129
+ *
130
+ * @since 2.8.0
131
+ *
132
+ * @return bool True if the domain verification file exists.
133
+ */
134
+ function edds_prb_apple_pay_has_domain_verification_file() {
135
+ $fileinfo = edds_prb_apple_pay_get_fileinfo();
136
+
137
+ if ( ! @file_exists( $fileinfo['fullpath'] ) ) {
138
+ return false;
139
+ }
140
+
141
+ return true;
142
+ }
143
+
144
+ /**
145
+ * Determines if the currently verified domain matches the current site.
146
+ *
147
+ * @since 2.8.0
148
+ *
149
+ * @return bool True if the saved verified domain matches the current site.
150
+ */
151
+ function edds_prb_apple_pay_has_domain_verification() {
152
+ return edd_get_option( 'stripe_prb_apple_pay_domain' ) === $_SERVER['HTTP_HOST'];
153
+ }
154
+
155
+ /**
156
+ * Attempts to create a directory in the server root and copy the domain verification file.
157
+ *
158
+ * @since 2.8.0
159
+ *
160
+ * @throws \Exception If the directory or file cannot be created.
161
+ */
162
+ function edds_prb_apple_pay_create_directory_and_move_file() {
163
+ $file = edds_prb_apple_pay_has_domain_verification_file();
164
+
165
+ if ( true === $file ) {
166
+ return;
167
+ }
168
+
169
+ $fileinfo = edds_prb_apple_pay_get_fileinfo();
170
+
171
+ // Create directory if it does not exist.
172
+ if ( ! file_exists( trailingslashit( $fileinfo['path'] ) . $fileinfo['dir'] ) ) {
173
+ if ( ! @mkdir( trailingslashit( $fileinfo['path'] ) . $fileinfo['dir'], 0755 ) ) { // @codingStandardsIgnoreLine
174
+ throw new \Exception( __( 'Unable to create domain association folder in domain root.', 'easy-digital-downloads' ) );
175
+ }
176
+ }
177
+
178
+ // Move file if needed.
179
+ if ( ! edds_prb_apple_pay_has_domain_verification_file() ) {
180
+ if ( ! @copy( trailingslashit( EDDS_PLUGIN_DIR ) . $fileinfo['file'], $fileinfo['fullpath'] ) ) { // @codingStandardsIgnoreLine
181
+ throw new \Exception( __( 'Unable to copy domain association file to domain .well-known directory.', 'easy-digital-downloads' ) );
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Checks Apple Pay domain verification if there is an existing error.
188
+ * If the domain was added to the Stripe Dashboard clear the error.
189
+ *
190
+ * @since 2.8.0
191
+ */
192
+ function edds_prb_apple_pay_check_domain() {
193
+ $error = edd_get_option( 'stripe_prb_apple_pay_domain_error', '' );
194
+
195
+ if ( empty( $error ) ) {
196
+ return;
197
+ }
198
+
199
+ try {
200
+ $domains = edds_api_request( 'ApplePayDomain', 'all' );
201
+
202
+ foreach ( $domains->autoPagingIterator() as $domain ) {
203
+ if ( $domain->domain_name === $_SERVER['HTTP_HOST'] ) {
204
+ edd_delete_option( 'stripe_prb_apple_pay_domain_error' );
205
+ edd_update_option( 'stripe_prb_apple_pay_domain', $_SERVER['HTTP_HOST'] );
206
+ break;
207
+ }
208
+ }
209
+ } catch ( \Exception $e ) {}
210
+ }
211
+ add_action( 'admin_init', 'edds_prb_apple_pay_check_domain', 10 );
212
+
213
+ /**
214
+ * Verifies the current domain.
215
+ *
216
+ * @since 2.8.0
217
+ */
218
+ function edds_prb_apple_pay_verify_domain() {
219
+ // Payment Request Button is not enabled, do nothing.
220
+ if ( false === edds_prb_is_enabled() ) {
221
+ return;
222
+ }
223
+
224
+ // Avoid getting caught in AJAX requests.
225
+ if ( defined( 'DOING_AJAX' ) && true === DOING_AJAX ) {
226
+ return;
227
+ }
228
+
229
+ // Must be verified in Live Mode.
230
+ if ( true === edd_is_test_mode() ) {
231
+ return;
232
+ }
233
+
234
+ // Current site is a development environment, Apple Pay won't be able to be used, do nothing.
235
+ if ( false !== edd_is_dev_environment() ) {
236
+ return;
237
+ }
238
+
239
+ // Current domain matches and the file exists, do nothing.
240
+ if ( true === edds_prb_apple_pay_is_valid() ) {
241
+ return;
242
+ }
243
+
244
+ try {
245
+ // Create directory and move file if needed.
246
+ edds_prb_apple_pay_create_directory_and_move_file();
247
+
248
+ $stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id', '' );
249
+
250
+ // Automatically verify when using "real" API keys.
251
+ if ( empty( $stripe_connect_account_id ) ) {
252
+ $verification = edds_api_request(
253
+ 'ApplePayDomain',
254
+ 'create',
255
+ array(
256
+ 'domain_name' => $_SERVER['HTTP_HOST'],
257
+ )
258
+ );
259
+
260
+ edd_update_option( 'stripe_prb_apple_pay_domain', $_SERVER['HTTP_HOST'] );
261
+
262
+ // Set an error that the domain needs to be manually added.
263
+ // Using Stripe Connect API keys does not allow this to be done automatically.
264
+ } else {
265
+ throw new \Exception(
266
+ sprintf(
267
+ /* translators: %1$s Opening anchor tag, do not translate. %2$s Closing anchor tag, do not translate. */
268
+ ( __( 'Please %1$smanually add your domain%2$s %3$s to use Apple Pay.', 'easy-digital-downloads' ) . '<br />' ),
269
+ '<a href="https://dashboard.stripe.com/settings/payments/apple_pay" target="_blank" rel="noopener noreferrer">',
270
+ '</a>',
271
+ '<code>' . $_SERVER['HTTP_HOST'] . '</code>'
272
+ )
273
+ );
274
+ }
275
+ } catch ( \Exception $e ) {
276
+ // Set error if something went wrong.
277
+ edd_update_option( 'stripe_prb_apple_pay_domain_error', $e->getMessage() );
278
+ }
279
+ }
280
+ add_action( 'admin_init', 'edds_prb_apple_pay_verify_domain', 20 );
includes/gateways/stripe/includes/payment-methods/payment-request/checkout.php ADDED
@@ -0,0 +1,372 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button: Checkout
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Registers "Express" (via Apple Pay/Google Pay) gateway.
11
+ *
12
+ * @since 2.8.0
13
+ *
14
+ * @param array $gateways Registered payment gateways.
15
+ * @return array
16
+ */
17
+ function edds_prb_shim_gateways( $gateways ) {
18
+ // Do nothing in admin.
19
+ if ( is_admin() ) {
20
+ return $gateways;
21
+ }
22
+
23
+ // Avoid endless loops when checking if the Stripe gateway is active.
24
+ remove_filter( 'edd_payment_gateways', 'edds_prb_shim_gateways' );
25
+ remove_filter( 'edd_enabled_payment_gateways', 'edds_prb_shim_gateways' );
26
+
27
+ $enabled = true;
28
+
29
+ // Do nothing if Payment Requests are not enabled.
30
+ if ( false === edds_prb_is_enabled( 'checkout' ) ) {
31
+ $enabled = false;
32
+ }
33
+
34
+ // Track default gateway so we can resort the list.
35
+ $default_gateway_id = edd_get_default_gateway();
36
+
37
+ if ( 'stripe-prb' === $default_gateway_id ) {
38
+ $default_gateway_id = 'stripe';
39
+ }
40
+
41
+ // Avoid endless loops when checking if the Stripe gateway is active.
42
+ add_filter( 'edd_payment_gateways', 'edds_prb_shim_gateways' );
43
+ add_filter( 'edd_enabled_payment_gateways', 'edds_prb_shim_gateways' );
44
+
45
+ if ( false === $enabled ) {
46
+ return $gateways;
47
+ }
48
+
49
+ // Ensure default gateway is considered registered at this point.
50
+ if ( isset( $gateways[ $default_gateway_id ] ) ) {
51
+ $default_gateway = array(
52
+ $default_gateway_id => $gateways[ $default_gateway_id ],
53
+ );
54
+
55
+ // Fall back to first gateway in the list.
56
+ } else {
57
+ $first_gateway_id = array_key_first( $gateways );
58
+ $default_gateway = array(
59
+ $first_gateway_id => $gateways[ $first_gateway_id ],
60
+ );
61
+ }
62
+
63
+ unset( $gateways[ $default_gateway_id ] );
64
+
65
+ return array_merge(
66
+ array(
67
+ 'stripe-prb' => array(
68
+ 'admin_label' => __( 'Express Checkout (Apple Pay/Google Pay)', 'easy-digital-downloads' ),
69
+ 'checkout_label' => __( 'Express Checkout', 'easy-digital-downloads' ),
70
+ 'supports' => array(),
71
+ ),
72
+ ),
73
+ $default_gateway,
74
+ $gateways
75
+ );
76
+ }
77
+ add_filter( 'edd_payment_gateways', 'edds_prb_shim_gateways' );
78
+ add_filter( 'edd_enabled_payment_gateways', 'edds_prb_shim_gateways' );
79
+
80
+ /**
81
+ * Enables the shimmed `stripe-prb` gateway.
82
+ *
83
+ * @since 2.8.0
84
+ *
85
+ * @param array $gateways Enabled payment gateways.
86
+ * @return array
87
+ */
88
+ function edds_prb_enable_shim_gateway( $gateways ) {
89
+ // Do nothing in admin.
90
+ if ( is_admin() ) {
91
+ return $gateways;
92
+ }
93
+
94
+ // Avoid endless loops when checking if the Stripe gateway is active.
95
+ remove_filter( 'edd_get_option_gateways', 'edds_prb_enable_shim_gateway' );
96
+
97
+ $enabled = true;
98
+
99
+ // Do nothing if Payment Requests are not enabled.
100
+ if ( false === edds_prb_is_enabled( 'checkout' ) ) {
101
+ $enabled = false;
102
+ }
103
+
104
+ // Avoid endless loops when checking if the Stripe gateway is active.
105
+ add_filter( 'edd_get_option_gateways', 'edds_prb_enable_shim_gateway' );
106
+
107
+ if ( false === $enabled ) {
108
+ return $gateways;
109
+ }
110
+
111
+ $gateways['stripe-prb'] = 1;
112
+
113
+ return $gateways;
114
+ }
115
+ add_filter( 'edd_get_option_gateways', 'edds_prb_enable_shim_gateway' );
116
+
117
+ /**
118
+ * Ensures the base `stripe` gateway is used as an ID _only_ when generating
119
+ * the hidden `input[name="edd-gateway"]` field.
120
+ *
121
+ * @since 2.8.0
122
+ */
123
+ function edds_prb_shim_active_gateways() {
124
+ add_filter( 'edd_chosen_gateway', 'edds_prb_set_base_gateway' );
125
+ add_filter( 'edd_is_gateway_active', 'edds_prb_is_gateway_active', 10, 2 );
126
+ }
127
+ add_action( 'edd_purchase_form_before_submit', 'edds_prb_shim_active_gateways' );
128
+
129
+ /**
130
+ * Removes conversion of `stripe-prb` to `stripe` after the `input[name="edd-gateway"]`
131
+ * hidden input is generated.
132
+ *
133
+ * @since 2.8.0
134
+ */
135
+ function edds_prb_unshim_active_gateways() {
136
+ remove_filter( 'edd_chosen_gateway', 'edds_prb_set_base_gateway' );
137
+ remove_filter( 'edd_is_gateway_active', 'edds_prb_is_gateway_active', 10, 2 );
138
+ }
139
+ add_action( 'edd_purchase_form_after_submit', 'edds_prb_unshim_active_gateways' );
140
+
141
+ /**
142
+ * Ensures the "Express Checkout" gateway is considered active if the setting
143
+ * is enabled.
144
+ *
145
+ * @since 2.8.0
146
+ *
147
+ * @param bool $active Determines if the gateway is considered active.
148
+ * @param string $gateway The gateway ID to check.
149
+ * @return bool
150
+ */
151
+ function edds_prb_is_gateway_active( $active, $gateway ) {
152
+ remove_filter( 'edd_is_gateway_active', 'edds_prb_is_gateway_active', 10, 2 );
153
+
154
+ if (
155
+ 'stripe-prb' === $gateway &&
156
+ true === edds_prb_is_enabled( 'checkout' )
157
+ ) {
158
+ $active = true;
159
+ }
160
+
161
+ add_filter( 'edd_is_gateway_active', 'edds_prb_is_gateway_active', 10, 2 );
162
+
163
+ return $active;
164
+ }
165
+
166
+ /**
167
+ * Transforms the found active `stripe-prb` Express Checkout gateway back
168
+ * to the base `stripe` gateway ID.
169
+ *
170
+ * @param string $gateway Chosen payment gateway.
171
+ * @return string
172
+ */
173
+ function edds_prb_set_base_gateway( $gateway ) {
174
+ if ( 'stripe-prb' === $gateway ) {
175
+ $gateway = 'stripe';
176
+ }
177
+
178
+ return $gateway;
179
+ }
180
+
181
+ /**
182
+ * Filters the default gateway.
183
+ *
184
+ * Sets the Payment Request Button (Express Checkout) as default
185
+ * when enabled for the context.
186
+ *
187
+ * @since 2.8.0
188
+ *
189
+ * @param string $default Default gateway.
190
+ * @return string
191
+ */
192
+ function edds_prb_default_gateway( $default ) {
193
+ // Do nothing in admin.
194
+ if ( is_admin() ) {
195
+ return $default;
196
+ }
197
+
198
+ // Avoid endless loops when checking if the Stripe gateway is active.
199
+ remove_filter( 'edd_default_gateway', 'edds_prb_default_gateway' );
200
+
201
+ $enabled = true;
202
+
203
+ // Do nothing if Payment Requests are not enabled.
204
+ if ( false === edds_prb_is_enabled( 'checkout' ) ) {
205
+ $enabled = false;
206
+ }
207
+
208
+ // Avoid endless loops when checking if the Stripe gateway is active.
209
+ add_filter( 'edd_default_gateway', 'edds_prb_default_gateway' );
210
+
211
+ if ( false === $enabled ) {
212
+ return $default;
213
+ }
214
+
215
+ return 'stripe' === $default
216
+ ? 'stripe-prb'
217
+ : $default;
218
+ }
219
+ add_filter( 'edd_default_gateway', 'edds_prb_default_gateway' );
220
+
221
+ /**
222
+ * Adds Payment Request-specific overrides when processing a single Download.
223
+ *
224
+ * Disables all required fields.
225
+ *
226
+ * @since 2.8.0
227
+ */
228
+ function edds_prb_process_overrides() {
229
+ if ( ! isset( $_POST ) ) {
230
+ return;
231
+ }
232
+
233
+ if ( ! isset( $_POST['edds-gateway'] ) ) {
234
+ return;
235
+ }
236
+
237
+ if ( 'payment-request' !== $_POST['edds-gateway'] ) {
238
+ return;
239
+ }
240
+
241
+ if ( 'download' !== $_POST['edds-prb-context'] ) {
242
+ return;
243
+ }
244
+
245
+ // Ensure Billing Address and Name Fields are not required.
246
+ add_filter( 'edd_require_billing_address', '__return_false' );
247
+
248
+ // Require email address.
249
+ add_filter( 'edd_purchase_form_required_fields', 'edds_prb_purchase_form_required_fields', 9999 );
250
+
251
+ // Remove 3rd party validations.
252
+ remove_all_actions( 'edd_checkout_error_checks' );
253
+ remove_all_actions( 'edd_checkout_user_error_checks' );
254
+ }
255
+ add_action( 'edd_pre_process_purchase', 'edds_prb_process_overrides' );
256
+
257
+ /**
258
+ * Filters the purchase form's required field to only
259
+ * require an email address.
260
+ *
261
+ * @since 2.8.0
262
+ *
263
+ * @return array
264
+ */
265
+ function edds_prb_purchase_form_required_fields() {
266
+ return array(
267
+ 'edd_email' => array(
268
+ 'error_id' => 'invalid_email',
269
+ 'error_message' => __( 'Please enter a valid email address', 'easy-digital-downloads' )
270
+ ),
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Adds a note and metadata to Payments made with a Payment Request Button.
276
+ *
277
+ * @since 2.8.0
278
+ *
279
+ * @param \EDD_Payment $payment EDD Payment.
280
+ * @param \Stripe\PaymentIntent|\Stripe\SetupIntent $intent Created Stripe Intent.
281
+ */
282
+ function edds_prb_payment_created( $payment, $intent ) {
283
+ if ( false === isset( $intent['metadata']['edds_prb'] ) ) {
284
+ return;
285
+ }
286
+
287
+ $payment->update_meta( '_edds_stripe_prb', 1 );
288
+ $payment->add_note( 'Purchase completed with Express Checkout (Apple Pay/Google Pay)' );
289
+ }
290
+ add_action( 'edds_payment_created', 'edds_prb_payment_created', 10, 2 );
291
+
292
+ /**
293
+ * Creates an empty Credit Card form to ensure core actions are still called.
294
+ *
295
+ * @since 2.8.0
296
+ */
297
+ function edds_prb_cc_form() {
298
+ /* This action is documented in easy-digital-downloads/includes/checkout/template.php */
299
+ do_action( 'edd_before_cc_fields' );
300
+
301
+ /* This action is documented in easy-digital-downloads/includes/checkout/template.php */
302
+ do_action( 'edd_after_cc_fields' );
303
+ }
304
+
305
+ /**
306
+ * Loads the Payment Request gateway.
307
+ *
308
+ * This fires before core's callbacks to avoid firing additional
309
+ * actions (and therefore creating extra output) when using the Payment Request.
310
+ *
311
+ * @since 2.8.0
312
+ */
313
+ function edds_prb_load_gateway() {
314
+ if ( ! isset( $_POST['nonce'] ) ) {
315
+ edd_debug_log(
316
+ __( 'Missing nonce when loading the gateway fields. Please read the following for more information: https://easydigitaldownloads.com/development/2018/07/05/important-update-to-ajax-requests-in-easy-digital-downloads-2-9-4', 'easy-digital-downloads' ),
317
+ true
318
+ );
319
+ }
320
+
321
+ if ( isset( $_POST['edd_payment_mode'] ) && isset( $_POST['nonce'] ) ) {
322
+ $payment_mode = sanitize_text_field( $_POST['edd_payment_mode'] );
323
+ $nonce = sanitize_text_field( $_POST['nonce'] );
324
+
325
+ $nonce_verified = wp_verify_nonce( $nonce, 'edd-gateway-selected-' . $payment_mode );
326
+
327
+ if ( false !== $nonce_verified ) {
328
+ // Load the "Express" gateway.
329
+ if ( 'stripe-prb' === $payment_mode ) {
330
+ // Remove credit card fields.
331
+ remove_action( 'edd_stripe_cc_form', 'edds_credit_card_form' );
332
+ remove_action( 'edd_cc_form', 'edd_get_cc_form' );
333
+
334
+ // Hide "Billing Details" which are populated by the Payment Method.
335
+ add_filter( 'edd_require_billing_address', '__return_true' );
336
+ remove_filter( 'edd_purchase_form_required_fields', 'edd_stripe_require_zip_and_country' );
337
+
338
+ remove_action( 'edd_after_cc_fields', 'edd_stripe_zip_and_country', 9 );
339
+ remove_action( 'edd_after_cc_fields', 'edd_default_cc_address_fields', 10 );
340
+
341
+ // Remove "Update billing address" checkbox. All Payment Requests create
342
+ // a new source.
343
+ remove_action( 'edd_cc_billing_top', 'edd_stripe_update_billing_address_field', 10 );
344
+
345
+ // Output a Payment Request-specific credit card form (empty).
346
+ add_action( 'edd_stripe_cc_form', 'edds_prb_cc_form' );
347
+
348
+ // Swap purchase button with Payment Request button.
349
+ add_filter( 'edd_checkout_button_purchase', 'edds_prb_checkout_button_purchase', 10000 );
350
+
351
+ /**
352
+ * Allows further adjustments to made before the "Express Checkout"
353
+ * gateway is loaded.
354
+ *
355
+ * @since 2.8.0
356
+ */
357
+ do_action( 'edds_prb_before_purchase_form' );
358
+ }
359
+
360
+ /* This action is documented in easy-digital-downloads/includes/checkout/template.php */
361
+ do_action( 'edd_purchase_form' );
362
+
363
+ // Ensure core callbacks are fired.
364
+ add_action( 'wp_ajax_edd_load_gateway', 'edd_load_ajax_gateway' );
365
+ add_action( 'wp_ajax_nopriv_edd_load_gateway', 'edd_load_ajax_gateway' );
366
+ }
367
+
368
+ exit();
369
+ }
370
+ }
371
+ add_action( 'wp_ajax_edd_load_gateway', 'edds_prb_load_gateway', 5 );
372
+ add_action( 'wp_ajax_nopriv_edd_load_gateway', 'edds_prb_load_gateway', 5 );
includes/gateways/stripe/includes/payment-methods/payment-request/functions.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request: Functions
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Determines if Payment Requests are enabled.
11
+ *
12
+ * @since 2.8.0
13
+ *
14
+ * @param array|string $context Context the Payment Request Button is being output in.
15
+ * Default empty, checks if any are enabled.
16
+ * @return bool
17
+ */
18
+ function edds_prb_is_enabled( $context = array() ) {
19
+ // Stripe gateway is not active. Disabled.
20
+ if ( false === edd_is_gateway_active( 'stripe' ) ) {
21
+ return false;
22
+ }
23
+
24
+ // Gather allowed and enabled contexts.
25
+ $allowed_contexts = array( 'single', 'archive', 'checkout' );
26
+ $enabled_contexts = array_keys(
27
+ (array) edd_get_option( 'stripe_prb', array() )
28
+ );
29
+
30
+ if ( ! is_array( $context ) ) {
31
+ $context = array( $context );
32
+ }
33
+
34
+ // Nothing particular is being checked for; check if any values are checked.
35
+ if ( empty( $context ) ) {
36
+ return count( $enabled_contexts ) > 0;
37
+ }
38
+
39
+ // Passed context is not allowed. Disabled.
40
+ if ( 0 === count( array_intersect( $context, $allowed_contexts ) ) ) {
41
+ return false;
42
+ }
43
+
44
+ // Passed context is not enabled in setting. Disabled.
45
+ if ( 0 === count( array_intersect( $context, $enabled_contexts ) ) ) {
46
+ return false;
47
+ }
48
+
49
+ // Taxes are enabled. Disabled.
50
+ $taxes = edd_use_taxes();
51
+
52
+ if ( true === $taxes ) {
53
+ return false;
54
+ }
55
+
56
+ // Recurring is enabled and a trial is in the cart. Disabled.
57
+ //
58
+ // Disabling for cart context here to avoid further adjusting the already
59
+ // complex filtering of active gateways in checkout.php
60
+ if (
61
+ function_exists( 'edd_recurring' ) &&
62
+ edd_recurring()->cart_has_free_trial()
63
+ ) {
64
+ return false;
65
+ }
66
+
67
+ return true;
68
+ }
69
+
70
+ /**
71
+ * Retrieves data for a Payment Request Button for a single Download.
72
+ *
73
+ * @since 2.8.0
74
+ *
75
+ * @param int $download_id Download ID.
76
+ * @param false|int $price_id Price ID. Default will be used if not set. Default false.
77
+ * @param int $quantity Quantity. Default 1.
78
+ * @return array Payment Request Button data.
79
+ */
80
+ function edds_prb_get_download_data( $download_id, $price_id = false, $quantity = 1 ) {
81
+ $data = array(
82
+ 'currency' => strtolower( edd_get_currency() ),
83
+ 'country' => strtoupper( edd_get_shop_country() ),
84
+ 'total' => array(),
85
+ 'display-items' => array(),
86
+ );
87
+
88
+ $download = edd_get_download( $download_id );
89
+
90
+ // Return early if no Download can be found.
91
+ if ( ! $download ) {
92
+ return array();
93
+ }
94
+
95
+ // Hacky way to ensure we don't display quantity for Recurring
96
+ // downloads. The quantity field is output incorrectly.
97
+ //
98
+ // https://github.com/easydigitaldownloads/edd-recurring/issues/880
99
+ if ( defined( 'EDD_RECURRING_VERSION' ) ) {
100
+ $recurring = false;
101
+
102
+ if ( false !== $price_id ) {
103
+ $recurring = edd_recurring()->is_price_recurring( $download_id, $price_id );
104
+ } else {
105
+ $recurring = edd_recurring()->is_recurring( $download_id );
106
+ }
107
+
108
+ if ( true === $recurring ) {
109
+ $quantity = 1;
110
+ }
111
+ }
112
+
113
+ // Find price.
114
+ $variable_pricing = $download->has_variable_prices();
115
+ $price = 0;
116
+
117
+ if ( $variable_pricing ) {
118
+ if ( false === $price_id ) {
119
+ $price_id = edd_get_default_variable_price( $download_id );
120
+ }
121
+
122
+ $prices = $download->prices;
123
+
124
+ $price = isset( $prices[ $price_id ] )
125
+ ? $prices[ $price_id ]['amount']
126
+ : false;
127
+
128
+ $name = sprintf(
129
+ '%1$s - %2$s',
130
+ $download->get_name(),
131
+ edd_get_price_option_name( $download->ID, $price_id )
132
+ );
133
+ } else {
134
+ $price = $download->price;
135
+ $name = $download->get_name();
136
+ }
137
+
138
+ if ( false === edds_is_zero_decimal_currency() ) {
139
+ $price = round( $price * 100 );
140
+ }
141
+
142
+ $price = ( $price * $quantity );
143
+
144
+ // Add total.
145
+ $data['total'] = array(
146
+ 'label' => __( 'Total', 'easy-digital-downloads' ),
147
+ 'amount' => $price,
148
+ );
149
+
150
+ // Add Display items.
151
+ $has_quantity = edd_item_quantities_enabled() && ! edd_download_quantities_disabled( $download_id );
152
+
153
+ $quantity = true === $has_quantity
154
+ ? $quantity
155
+ : 1;
156
+
157
+ $data['display-items'][] = array(
158
+ 'label' => sprintf(
159
+ '%s%s',
160
+ strip_tags( $name ),
161
+ ( $quantity > 1 ? sprintf( __( ' × %d', 'easy-digital-downloads' ), $quantity ) : '' )
162
+ ),
163
+ 'amount' => $price,
164
+ );
165
+
166
+ return $data;
167
+ }
168
+
169
+ /**
170
+ * Retrieves data for a Payment Request Button for the cart.
171
+ *
172
+ * @since 2.8.0
173
+ *
174
+ * @return array Payment Request Button data.
175
+ */
176
+ function edds_prb_get_cart_data() {
177
+ $data = array(
178
+ 'currency' => strtolower( edd_get_currency() ),
179
+ 'country' => strtoupper( edd_get_shop_country() ),
180
+ 'total' => array(),
181
+ 'display-items' => array(),
182
+ );
183
+
184
+ $total = edd_get_cart_total();
185
+
186
+ if ( false === edds_is_zero_decimal_currency() ) {
187
+ $total = round( $total * 100 );
188
+ }
189
+
190
+ // Add total.
191
+ $data['total'] = array(
192
+ 'label' => __( 'Total', 'easy-digital-downloads' ),
193
+ 'amount' => $total,
194
+ );
195
+
196
+ // Add Display items.
197
+ $cart_items = edd_get_cart_contents();
198
+
199
+ foreach ( $cart_items as $key => $item ) {
200
+ $has_quantity = edd_item_quantities_enabled() && ! edd_download_quantities_disabled( $item['id'] );
201
+
202
+ $quantity = true === $has_quantity
203
+ ? edd_get_cart_item_quantity( $item['id'], $item['options'] )
204
+ : 1;
205
+
206
+ $price = edd_get_cart_item_price( $item['id'], $item['options'] );
207
+
208
+ if ( false === edds_is_zero_decimal_currency() ) {
209
+ $price = round( $price * 100 );
210
+ }
211
+
212
+ $price = ( $price * $quantity );
213
+
214
+ $data['display-items'][] = array(
215
+ 'label' => sprintf(
216
+ '%s%s',
217
+ strip_tags( edd_get_cart_item_name( $item ) ),
218
+ ( $quantity > 1 ? sprintf( __( ' × %d', 'easy-digital-downloads' ), $quantity ) : '' )
219
+ ),
220
+ 'amount' => $price,
221
+ );
222
+ }
223
+
224
+ return $data;
225
+ }
includes/gateways/stripe/includes/payment-methods/payment-request/index.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/ajax.php';
10
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/checkout.php';
11
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/functions.php';
12
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/template.php';
13
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/shortcode.php';
14
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/apple-pay.php';
15
+
16
+ if ( is_admin() ) {
17
+ require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/payment-request/admin/settings.php';
18
+ }
includes/gateways/stripe/includes/payment-methods/payment-request/shortcode.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button: Shortcode
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Allows `payment-request` to be passed to [purchase-link]
11
+ * to disable the Payment Request button.
12
+ *
13
+ * @since 2.8.0
14
+ *
15
+ * @param array $out Sanitized shortcode attributes.
16
+ * @param array $pairs Entire list of supported attributes and their defaults.
17
+ * @param array $atts User defined attributes in shortcode tag.
18
+ * @return array Combined and filtered attribute list.
19
+ */
20
+ function edds_prb_shortcode_atts( $out, $pairs, $atts ) {
21
+ if ( false === edd_is_gateway_active( 'stripe' ) ) {
22
+ return $out;
23
+ }
24
+
25
+ if ( isset( $atts['payment-request'] ) ) {
26
+ $out['payment-request'] = $atts['payment-request'];
27
+ }
28
+
29
+ return $out;
30
+ }
31
+ add_filter( 'shortcode_atts_purchase_link', 'edds_prb_shortcode_atts', 10, 3 );
includes/gateways/stripe/includes/payment-methods/payment-request/template.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment Request Button: Template
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.8.0
7
+ */
8
+
9
+ /**
10
+ * Outputs a Payment Request Button via `edd_get_purchase_link()`
11
+ * (which is implemented via [purchase_link])
12
+ *
13
+ * @since 2.8.0
14
+ *
15
+ * @param int $download_id Current Download ID.
16
+ * @param array $args Arguments for displaying the purchase link.
17
+ */
18
+ function edds_prb_purchase_link( $download_id, $args ) {
19
+ // Don't output if context is not enabled.
20
+ $context = is_singular() && 0 === did_action( 'edd_downloads_list_before' )
21
+ ? 'single'
22
+ : 'archive';
23
+
24
+ if ( false === edds_prb_is_enabled( $context ) ) {
25
+ return;
26
+ }
27
+
28
+ // Don't output if the item is free. Stripe won't process < $0.50
29
+ if ( true === edd_is_free_download( $download_id ) ) {
30
+ return;
31
+ }
32
+
33
+ // Don't output if the item is already in the cart.
34
+ if ( true === edd_item_in_cart( $download_id ) ) {
35
+ return;
36
+ }
37
+
38
+ // Don't output if `edd_get_purchase_link` is filtered to disable.
39
+ if (
40
+ isset( $args['payment-request'] ) &&
41
+ true !== edds_truthy_to_bool( $args['payment-request'] )
42
+ ) {
43
+ return;
44
+ }
45
+
46
+ // Don't output if Recurring is enabled, and a free trial is present.
47
+ // @link https://github.com/easydigitaldownloads/edd-stripe/issues/594
48
+ if ( function_exists( 'edd_recurring' ) ) {
49
+ // Don't output if non-variable price has a free trial.
50
+ if ( edd_recurring()->has_free_trial( $download_id ) ) {
51
+ return;
52
+ }
53
+
54
+ // ...or if a variable price options has a free trial.
55
+ $prices = edd_get_variable_prices( $download_id );
56
+
57
+ if ( ! empty( $prices ) ) {
58
+ foreach ( $prices as $price ) {
59
+ if ( edd_recurring()->has_free_trial( $download_id, $price['index'] ) ) {
60
+ return;
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ // Don't output if it has been filtered off for any reason.
67
+ $enabled = true;
68
+
69
+ /**
70
+ * Filters the output of Payment Request Button in purchase links.
71
+ *
72
+ * @since 2.8.0
73
+ *
74
+ * @param bool $enabled If the Payment Request Button is enabled.
75
+ * @param int $download_id Current Download ID.
76
+ * @param array $args Purchase link arguments.
77
+ */
78
+ $enabled = apply_filters( 'edds_prb_purchase_link_enabled', $enabled, $download_id, $args );
79
+
80
+ if ( true !== $enabled ) {
81
+ return;
82
+ }
83
+
84
+ static $instance_id = 0;
85
+
86
+ echo edds_get_prb_markup(
87
+ edds_prb_get_download_data( $download_id ),
88
+ array(
89
+ 'id' => sprintf(
90
+ 'edds-prb-download-%d-%d',
91
+ $download_id,
92
+ $instance_id
93
+ ),
94
+ 'classes' => array(
95
+ 'edds-prb--download',
96
+ ),
97
+ )
98
+ ); // WPCS: XSS okay.
99
+
100
+ // Shim the Checkout processing nonce.
101
+ wp_nonce_field( 'edd-process-checkout', 'edd-process-checkout-nonce', false );
102
+
103
+ $instance_id++;
104
+ }
105
+ add_action( 'edd_purchase_link_top', 'edds_prb_purchase_link', 20, 2 );
106
+
107
+ /**
108
+ * Outputs a Payment Request Button on the Checkout.
109
+ *
110
+ * @since 2.8.0
111
+ */
112
+ function edds_prb_checkout_button_purchase( $button ) {
113
+ // Do nothing if Payment Requests are not enabled.
114
+ if ( false === edds_prb_is_enabled( 'checkout' ) ) {
115
+ return $button;
116
+ }
117
+
118
+ $errors = '<div id="edds-prb-error-wrap"></div>';
119
+
120
+ $button = edds_get_prb_markup(
121
+ edds_prb_get_cart_data(),
122
+ array(
123
+ 'id' => 'edds-prb-checkout',
124
+ 'classes' => array(
125
+ 'edds-prb--checkout',
126
+ ),
127
+ )
128
+ );
129
+
130
+ return $errors . $button;
131
+ }
132
+
133
+ /**
134
+ * Retrieves HTML used to mount a Payment Request Button.
135
+ *
136
+ * @since 2.8.0
137
+ * @see edds_prb_get_download_data()
138
+ * @link https://stripe.com/docs/js/appendix/payment_item_object
139
+ *
140
+ * @param PaymentItem[] $data {
141
+ * PaymentItems.
142
+ *
143
+ * @type int $amount The amount in the currency's subunit.
144
+ * @type string $label A name the browser shows the customer in the payment interface.
145
+ * }
146
+ * @param array $args {
147
+ * Mount arguments.
148
+ *
149
+ * @type string $id HTML ID attribute.
150
+ * @type array $classes HTML classes.
151
+ * }
152
+ * @return string
153
+ */
154
+ function edds_get_prb_markup( $data, $args = array() ) {
155
+ $defaults = array(
156
+ 'id' => '',
157
+ 'classes' => array(),
158
+ );
159
+
160
+ $args = wp_parse_args( $args, $defaults );
161
+
162
+ // ID/Class
163
+ $id = $args['id'];
164
+ $class = implode(
165
+ ' ',
166
+ array_merge(
167
+ $args['classes'],
168
+ array(
169
+ 'edds-prb',
170
+ )
171
+ )
172
+ );
173
+
174
+ // Data
175
+ $_data = array();
176
+
177
+ foreach ( $data as $key => $value ) {
178
+ $_data[] = sprintf(
179
+ 'data-%s="%s"',
180
+ esc_attr( $key ),
181
+ esc_attr( is_array( $value ) ? wp_json_encode( $value ) : $value )
182
+ );
183
+ }
184
+
185
+ $_data = implode( ' ', $_data );
186
+
187
+ edd_stripe_js( true );
188
+ edd_stripe_css( true );
189
+
190
+ return sprintf(
191
+ '<div id="%1$s" class="%2$s" %3$s>
192
+ <div class="edds-prb__button"></div>
193
+ <div class="edds-prb__or">%4$s</div>
194
+ </div>',
195
+ esc_attr( $id ),
196
+ esc_attr( $class ),
197
+ $_data,
198
+ esc_html_x( 'or', 'payment request button divider', 'easy-digital-downloads' )
199
+ );
200
+ }
includes/gateways/stripe/includes/payment-receipt.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Payment receipt.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Output a Payment authorization form in the Payment Receipt.
11
+ *
12
+ * @param WP_Post $payment Payment.
13
+ */
14
+ function edds_payment_receipt_authorize_payment_form( $payment ) {
15
+ // EDD 3.0 compat.
16
+ if ( is_a( $payment, 'WP_Post' ) ) {
17
+ $payment = edd_get_payment( $payment->ID );
18
+ }
19
+
20
+ $customer_id = $payment->get_meta( '_edds_stripe_customer_id' );
21
+ $payment_intent_id = $payment->get_meta( '_edds_stripe_payment_intent_id' );
22
+
23
+ if ( empty( $customer_id ) || empty( $payment_intent_id ) ) {
24
+ return false;
25
+ }
26
+
27
+ if ( 'preapproval_pending' !== $payment->status ) {
28
+ return false;
29
+ }
30
+
31
+ $payment_intent = edds_api_request( 'PaymentIntent', 'retrieve', $payment_intent_id );
32
+
33
+ // Enqueue core scripts.
34
+ add_filter( 'edd_is_checkout', '__return_true' );
35
+
36
+ edd_load_scripts();
37
+
38
+ remove_filter( 'edd_is_checkout', '__return_true' );
39
+
40
+ edd_stripe_js( true );
41
+ edd_stripe_css( true );
42
+ ?>
43
+
44
+ <form
45
+ id="edds-update-payment-method"
46
+ data-payment-intent="<?php echo esc_attr( $payment_intent->id ); ?>"
47
+ <?php if ( isset( $payment_intent->last_payment_error ) && isset( $payment_intent->last_payment_error->payment_method ) ) : ?>
48
+ data-payment-method="<?php echo esc_attr( $payment_intent->last_payment_error->payment_method->id ); ?>"
49
+ <?php endif; ?>
50
+ >
51
+ <h3>Authorize Payment</h3>
52
+ <p><?php esc_html_e( 'To finalize your preapproved purchase, please confirm your payment method.', 'easy-digital-downloads' ); ?></p>
53
+
54
+ <div id="edd_checkout_form_wrap">
55
+ <?php
56
+ /** This filter is documented in easydigitaldownloads/includes/checkout/template.php */
57
+ do_action( 'edd_stripe_cc_form' );
58
+ ?>
59
+
60
+ <p>
61
+ <input
62
+ id="edds-update-payment-method-submit"
63
+ type="submit"
64
+ data-loading="<?php echo esc_attr( 'Please Wait…', 'edds' ); ?>"
65
+ data-submit="<?php echo esc_attr( 'Authorize Payment', 'edds' ); ?>"
66
+ value="<?php echo esc_attr( 'Authorize Payment', 'edds' ); ?>"
67
+ class="button edd-button"
68
+ />
69
+ </p>
70
+
71
+ <div id="edds-update-payment-method-errors"></div>
72
+
73
+ <?php
74
+ wp_nonce_field(
75
+ 'edds-complete-payment-authorization',
76
+ 'edds-complete-payment-authorization'
77
+ );
78
+ ?>
79
+
80
+ </div>
81
+ </form>
82
+
83
+ <?php
84
+ }
85
+ add_action( 'edd_payment_receipt_after_table', 'edds_payment_receipt_authorize_payment_form' );
includes/gateways/stripe/includes/scripts.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Load our javascript
5
+ *
6
+ * The Stripe JS is by default, loaded on every page as suggested by Stripe. This can be overridden by using the Restrict Stripe Assets
7
+ * setting within the admin, and the Stripe Javascript resources will only be loaded when necessary.
8
+ * @link https://stripe.com/docs/web/setup
9
+ *
10
+ * The custom Javascript for EDD is loaded if the page is checkout. If checkout, the function is called directly with
11
+ * `true` set for the `$force_load_scripts` argument.
12
+ *
13
+ * @access public
14
+ * @since 1.0
15
+ *
16
+ * @param bool $force_load_scripts Allows registering our Javascript files on pages other than is_checkout().
17
+ * This argument allows the `edd_stripe_js` function to be called directly, outside of
18
+ * the context of checkout, such as the card management or update subscription payment method
19
+ * UIs. Sending in 'true' will ensure that the Javascript resources are enqueued when you need them.
20
+ *
21
+ *
22
+ * @return void
23
+ */
24
+ function edd_stripe_js( $force_load_scripts = false ) {
25
+ if ( false === edds_is_gateway_active() ) {
26
+ return;
27
+ }
28
+
29
+ if ( function_exists( 'edd_is_checkout' ) ) {
30
+
31
+ $publishable_key = NULL;
32
+
33
+ if ( edd_is_test_mode() ) {
34
+ $publishable_key = edd_get_option( 'test_publishable_key', '' );
35
+ } else {
36
+ $publishable_key = edd_get_option( 'live_publishable_key', '' );
37
+ }
38
+
39
+ wp_register_script(
40
+ 'sandhills-stripe-js-v3',
41
+ 'https://js.stripe.com/v3/',
42
+ array(),
43
+ 'v3'
44
+ );
45
+
46
+ wp_register_script(
47
+ 'edd-stripe-js',
48
+ EDDSTRIPE_PLUGIN_URL . 'assets/js/build/app.min.js',
49
+ array(
50
+ 'sandhills-stripe-js-v3',
51
+ 'jquery',
52
+ 'edd-ajax'
53
+ ),
54
+ EDD_STRIPE_VERSION,
55
+ true
56
+ );
57
+
58
+ $is_checkout = edd_is_checkout();
59
+ $restrict_assets = edd_get_option( 'stripe_restrict_assets', false );
60
+
61
+ if ( $is_checkout || $force_load_scripts || false === $restrict_assets ) {
62
+ wp_enqueue_script( 'sandhills-stripe-js-v3' );
63
+ }
64
+
65
+ if ( $is_checkout || $force_load_scripts ) {
66
+ wp_enqueue_script( 'edd-stripe-js' );
67
+ wp_enqueue_script( 'jQuery.payment' );
68
+
69
+ $stripe_vars = apply_filters( 'edd_stripe_js_vars', array(
70
+ 'publishable_key' => trim( $publishable_key ),
71
+ 'is_ajaxed' => edd_is_ajax_enabled() ? 'true' : 'false',
72
+ 'currency' => edd_get_currency(),
73
+ 'locale' => edds_get_stripe_checkout_locale(),
74
+ 'is_zero_decimal' => edds_is_zero_decimal_currency() ? 'true' : 'false',
75
+ 'checkout' => edd_get_option( 'stripe_checkout' ) ? 'true' : 'false',
76
+ 'store_name' => get_bloginfo( 'name' ),
77
+ 'alipay' => edd_get_option( 'stripe_alipay' ) ? 'true' : 'false',
78
+ 'submit_text' => edd_get_option( 'stripe_checkout_button_text', __( 'Next', 'easy-digital-downloads' ) ),
79
+ 'image' => edd_get_option( 'stripe_checkout_image' ),
80
+ 'zipcode' => edd_get_option( 'stripe_checkout_zip_code', false ) ? 'true' : 'false',
81
+ 'billing_address' => edd_get_option( 'stripe_checkout_billing', false ) ? 'true' : 'false',
82
+ 'remember_me' => edd_get_option( 'stripe_checkout_remember', false ) ? 'true' : 'false',
83
+ 'no_key_error' => __( 'Stripe publishable key missing. Please enter your publishable key in Settings.', 'easy-digital-downloads' ),
84
+ 'checkout_required_fields_error' => __( 'Please fill out all required fields to continue your purchase.', 'easy-digital-downloads' ),
85
+ 'checkout_agree_to_terms' => __( 'Please agree to the terms to complete your purchase.', 'easy-digital-downloads' ),
86
+ 'checkout_agree_to_privacy' => __( 'Please agree to the privacy policy to complete your purchase.', 'easy-digital-downloads' ),
87
+ 'generic_error' => __( 'Unable to complete your request. Please try again.', 'easy-digital-downloads' ),
88
+ 'successPageUri' => edd_get_success_page_uri(),
89
+ 'failurePageUri' => edd_get_failed_transaction_uri(),
90
+ 'elementsOptions' => edds_get_stripe_elements_options(),
91
+ 'elementsSplitFields' => '1' === edd_get_option( 'stripe_split_payment_fields', false ) ? 'true' : 'false',
92
+ 'isTestMode' => edd_is_test_mode() ? 'true' : 'false',
93
+ ) );
94
+
95
+ wp_localize_script( 'edd-stripe-js', 'edd_stripe_vars', $stripe_vars );
96
+
97
+ }
98
+ }
99
+ }
100
+ add_action( 'wp_enqueue_scripts', 'edd_stripe_js', 100 );
101
+
102
+ function edd_stripe_css( $force_load_scripts = false ) {
103
+ if ( false === edds_is_gateway_active() ) {
104
+ return;
105
+ }
106
+
107
+ if ( edd_is_checkout() || $force_load_scripts ) {
108
+ $deps = array( 'edd-styles' );
109
+
110
+ if ( ! wp_script_is( 'edd-styles', 'enqueued' ) ) {
111
+ $deps = array();
112
+ }
113
+
114
+ wp_register_style( 'edd-stripe', EDDSTRIPE_PLUGIN_URL . 'assets/css/build/app.min.css', $deps, EDD_STRIPE_VERSION );
115
+ wp_enqueue_style( 'edd-stripe' );
116
+ }
117
+ }
118
+ add_action( 'wp_enqueue_scripts', 'edd_stripe_css', 100 );
119
+
120
+ /**
121
+ * Load our admin javascript
122
+ *
123
+ * @access public
124
+ * @since 1.8
125
+ * @return void
126
+ */
127
+ function edd_stripe_admin_js( $payment_id = 0 ) {
128
+
129
+ if( 'stripe' !== edd_get_payment_gateway( $payment_id ) ) {
130
+ return;
131
+ }
132
+ ?>
133
+ <script type="text/javascript">
134
+ jQuery(document).ready(function($) {
135
+ $('select[name=edd-payment-status]').change(function() {
136
+
137
+ if( 'refunded' == $(this).val() ) {
138
+
139
+ // Localize refund label
140
+ var edd_stripe_refund_charge_label = "<?php echo esc_js( __( 'Refund Charge in Stripe', 'easy-digital-downloads' ) ); ?>";
141
+
142
+ $(this).parent().parent().append( '<input type="checkbox" id="edd_refund_in_stripe" name="edd_refund_in_stripe" value="1" style="margin-top: 0;" />' );
143
+ $(this).parent().parent().append( '<label for="edd_refund_in_stripe">' + edd_stripe_refund_charge_label + '</label>' );
144
+
145
+ } else {
146
+
147
+ $('#edd_refund_in_stripe').remove();
148
+ $('label[for="edd_refund_in_stripe"]').remove();
149
+
150
+ }
151
+
152
+ });
153
+ });
154
+ </script>
155
+ <?php
156
+
157
+ }
158
+ add_action( 'edd_view_order_details_before', 'edd_stripe_admin_js', 100 );
159
+
160
+ /**
161
+ * Loads the javascript for the Stripe Connect functionality in the settings page.
162
+ *
163
+ * @param string $hook The current admin page.
164
+ */
165
+ function edd_stripe_connect_admin_script( $hook ) {
166
+
167
+ if( 'download_page_edd-settings' !== $hook ) {
168
+ return;
169
+ }
170
+
171
+ wp_enqueue_style( 'edd-stripe-admin-styles', EDDSTRIPE_PLUGIN_URL . 'assets/css/build/admin.min.css', array(), EDD_STRIPE_VERSION );
172
+
173
+ wp_enqueue_script( 'edd-stripe-admin-scripts', EDDSTRIPE_PLUGIN_URL . 'assets/js/build/admin.min.js', array( 'jquery' ), EDD_STRIPE_VERSION );
174
+
175
+ $test_key = edd_get_option( 'test_publishable_key' );
176
+ $live_key = edd_get_option( 'live_publishable_key' );
177
+
178
+ wp_localize_script(
179
+ 'edd-stripe-admin-scripts',
180
+ 'edd_stripe_admin',
181
+ array(
182
+ 'stripe_enabled' => array_key_exists( 'stripe', edd_get_enabled_payment_gateways() ),
183
+ 'test_mode' => (int) edd_is_test_mode(),
184
+ 'test_key_exists' => ! empty( $test_key ) ? 'true' : 'false',
185
+ 'live_key_exists' => ! empty( $live_key ) ? 'true' : 'false',
186
+ 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
187
+ )
188
+ );
189
+ }
190
+ add_action( 'admin_enqueue_scripts', 'edd_stripe_connect_admin_script' );
includes/gateways/stripe/includes/template-functions.php ADDED
@@ -0,0 +1,855 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add an errors div
4
+ *
5
+ * @since 1.0
6
+ * @return void
7
+ */
8
+ function edds_add_stripe_errors() {
9
+ echo '<div id="edd-stripe-payment-errors"></div>';
10
+ }
11
+ add_action( 'edd_after_cc_fields', 'edds_add_stripe_errors', 999 );
12
+
13
+ /**
14
+ * Stripe uses it's own credit card form because the card details are tokenized.
15
+ *
16
+ * We don't want the name attributes to be present on the fields in order to prevent them from getting posted to the server
17
+ *
18
+ * @since 1.7.5
19
+ * @return void
20
+ */
21
+ function edds_credit_card_form( $echo = true ) {
22
+
23
+ global $edd_options;
24
+
25
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
26
+ edd_set_error( 'edd_stripe_error_limit', __( 'We are unable to process your payment at this time, please try again later or contact support.', 'easy-digital-downloads' ) );
27
+ return;
28
+ }
29
+
30
+ ob_start(); ?>
31
+
32
+ <?php if ( ! wp_script_is ( 'edd-stripe-js' ) ) : ?>
33
+ <?php edd_stripe_js( true ); ?>
34
+ <?php endif; ?>
35
+
36
+ <?php do_action( 'edd_before_cc_fields' ); ?>
37
+
38
+ <fieldset id="edd_cc_fields" class="edd-do-validate">
39
+ <legend><?php _e( 'Credit Card Info', 'easy-digital-downloads' ); ?></legend>
40
+ <?php if( is_ssl() ) : ?>
41
+ <div id="edd_secure_site_wrapper">
42
+ <span class="padlock">
43
+ <?php
44
+ if ( function_exists( 'edd_get_payment_icon' ) ) {
45
+ echo edd_get_payment_icon(
46
+ array(
47
+ 'icon' => 'lock',
48
+ 'width' => 18,
49
+ 'height' => 28,
50
+ 'classes' => array(
51
+ 'edd-icon',
52
+ 'edd-icon-lock',
53
+ ),
54
+ )
55
+ );
56
+ } else {
57
+ ?>
58
+ <svg class="edd-icon edd-icon-lock" xmlns="http://www.w3.org/2000/svg" width="18" height="28" viewBox="0 0 18 28" aria-hidden="true">
59
+ <path d="M5 12h8V9c0-2.203-1.797-4-4-4S5 6.797 5 9v3zm13 1.5v9c0 .828-.672 1.5-1.5 1.5h-15C.672 24 0 23.328 0 22.5v-9c0-.828.672-1.5 1.5-1.5H2V9c0-3.844 3.156-7 7-7s7 3.156 7 7v3h.5c.828 0 1.5.672 1.5 1.5z"/>
60
+ </svg>
61
+ <?php
62
+ }
63
+ ?>
64
+ </span>
65
+ <span><?php _e( 'This is a secure SSL encrypted payment.', 'easy-digital-downloads' ); ?></span>
66
+ </div>
67
+ <?php endif; ?>
68
+
69
+ <?php
70
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
71
+ ?>
72
+ <?php if ( ! empty( $existing_cards ) ) { edd_stripe_existing_card_field_radio( get_current_user_id() ); } ?>
73
+
74
+ <div class="edd-stripe-new-card" <?php if ( ! empty( $existing_cards ) ) { echo 'style="display: none;"'; } ?>>
75
+ <?php do_action( 'edd_stripe_new_card_form' ); ?>
76
+ <?php do_action( 'edd_after_cc_expiration' ); ?>
77
+ </div>
78
+
79
+ </fieldset>
80
+ <?php
81
+
82
+ do_action( 'edd_after_cc_fields' );
83
+
84
+ $form = ob_get_clean();
85
+
86
+ if ( false !== $echo ) {
87
+ echo $form;
88
+ }
89
+
90
+ return $form;
91
+ }
92
+ add_action( 'edd_stripe_cc_form', 'edds_credit_card_form' );
93
+
94
+ /**
95
+ * Display the markup for the Stripe new card form
96
+ *
97
+ * @since 2.6
98
+ * @return void
99
+ */
100
+ function edd_stripe_new_card_form() {
101
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
102
+ edd_set_error( 'edd_stripe_error_limit', __( 'Adding new payment methods is currently unavailable.', 'easy-digital-downloads' ) );
103
+ edd_print_errors();
104
+ return;
105
+ }
106
+
107
+ $split = edd_get_option( 'stripe_split_payment_fields', false );
108
+ ?>
109
+
110
+ <p id="edd-card-name-wrap">
111
+ <label for="card_name" class="edd-label">
112
+ <?php esc_html_e( 'Name on the Card', 'easy-digital-downloads' ); ?>
113
+ <span class="edd-required-indicator">*</span>
114
+ </label>
115
+ <span class="edd-description"><?php esc_html_e( 'The name printed on the front of your credit card.', 'easy-digital-downloads' ); ?></span>
116
+ <input type="text" name="card_name" id="card_name" class="card-name edd-input required" placeholder="<?php esc_attr_e( 'Card name', 'easy-digital-downloads' ); ?>" autocomplete="cc-name" />
117
+ </p>
118
+
119
+ <div id="edd-card-wrap">
120
+ <label for="edd-card-element" class="edd-label">
121
+ <?php
122
+ if ( '1' === $split ) :
123
+ esc_html_e( 'Credit Card Number', 'easy-digital-downloads' );
124
+ else :
125
+ esc_html_e( 'Credit Card', 'easy-digital-downloads' );
126
+ endif;
127
+ ?>
128
+ <span class="edd-required-indicator">*</span>
129
+ </label>
130
+
131
+ <div id="edd-stripe-card-element-wrapper">
132
+ <?php if ( '1' === $split ) : ?>
133
+ <span class="card-type"></span>
134
+ <?php endif; ?>
135
+
136
+ <div id="edd-stripe-card-element" class="edd-stripe-card-element"></div>
137
+ </div>
138
+
139
+ <p class="edds-field-spacer-shim"></p><!-- Extra spacing -->
140
+ </div>
141
+
142
+ <?php if ( '1' === $split ) : ?>
143
+
144
+ <div id="edd-card-details-wrap">
145
+ <p class="edds-field-spacer-shim"></p><!-- Extra spacing -->
146
+
147
+ <div id="edd-card-exp-wrap">
148
+ <label for="edd-card-exp-element" class="edd-label">
149
+ <?php esc_html_e( 'Expiration', 'easy-digital-downloads' ); ?>
150
+ <span class="edd-required-indicator">*</span>
151
+ </label>
152
+
153
+ <div id="edd-stripe-card-exp-element" class="edd-stripe-card-exp-element"></div>
154
+ </div>
155
+
156
+ <div id="edd-card-cvv-wrap">
157
+ <label for="edd-card-exp-element" class="edd-label">
158
+ <?php esc_html_e( 'CVC', 'easy-digital-downloads' ); ?>
159
+ <span class="edd-required-indicator">*</span>
160
+ </label>
161
+
162
+ <div id="edd-stripe-card-cvc-element" class="edd-stripe-card-cvc-element"></div>
163
+ </div>
164
+ </div>
165
+
166
+ <?php endif; ?>
167
+
168
+ <div id="edd-stripe-card-errors" role="alert"></div>
169
+
170
+ <?php
171
+ /**
172
+ * Allow output of extra content before the credit card expiration field.
173
+ *
174
+ * This content no longer appears before the credit card expiration field
175
+ * with the introduction of Stripe Elements.
176
+ *
177
+ * @deprecated 2.7
178
+ * @since unknown
179
+ */
180
+ do_action( 'edd_before_cc_expiration' );
181
+ }
182
+ add_action( 'edd_stripe_new_card_form', 'edd_stripe_new_card_form' );
183
+
184
+ /**
185
+ * Show the checkbox for updating the billing information on an existing Stripe card
186
+ *
187
+ * @since 2.6
188
+ * @return void
189
+ */
190
+ function edd_stripe_update_billing_address_field() {
191
+ $payment_mode = strtolower( edd_get_chosen_gateway() );
192
+ if ( edd_is_checkout() && 'stripe' !== $payment_mode ) {
193
+ return;
194
+ }
195
+
196
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
197
+ if ( empty( $existing_cards ) ) {
198
+ return;
199
+ }
200
+
201
+ if ( ! did_action( 'edd_stripe_cc_form' ) ) {
202
+ return;
203
+ }
204
+
205
+ $default_card = false;
206
+
207
+ foreach ( $existing_cards as $existing_card ) {
208
+ if ( $existing_card['default'] ) {
209
+ $default_card = $existing_card['source'];
210
+ break;
211
+ }
212
+ }
213
+ ?>
214
+ <p class="edd-stripe-update-billing-address-current">
215
+ <?php
216
+ if ( $default_card ) :
217
+ $address_fields = array(
218
+ 'line1' => isset( $default_card->address_line1 ) ? $default_card->address_line1 : null,
219
+ 'line2' => isset( $default_card->address_line2 ) ? $default_card->address_line2 : null,
220
+ 'city' => isset( $default_card->address_city ) ? $default_card->address_city : null,
221
+ 'state' => isset( $default_card->address_state ) ? $default_card->address_state : null,
222
+ 'zip' => isset( $default_card->address_zip ) ? $default_card->address_zip : null,
223
+ 'country' => isset( $default_card->address_country ) ? $default_card->address_country : null,
224
+ );
225
+
226
+ $address_fields = array_filter( $address_fields );
227
+
228
+ echo esc_html( implode( ', ', $address_fields ) );
229
+ endif;
230
+ ?>
231
+ </p>
232
+
233
+ <p class="edd-stripe-update-billing-address-wrapper">
234
+ <input type="checkbox" name="edd_stripe_update_billing_address" id="edd-stripe-update-billing-address" value="1" />
235
+ <label for="edd-stripe-update-billing-address">
236
+ <?php
237
+ echo wp_kses(
238
+ sprintf(
239
+ /* translators: %1$s Card type. %2$s Card last 4. */
240
+ __( 'Update card billing address for %1$s •••• %2$s', 'easy-digital-downloads' ),
241
+ '<span class="edd-stripe-update-billing-address-brand">' . ( $default_card ? $default_card->brand : '' ) . '</span>',
242
+ '<span class="edd-stripe-update-billing-address-last4">' . ( $default_card ? $default_card->last4 : '' ) . '</span>'
243
+ ),
244
+ array(
245
+ 'strong' => true,
246
+ 'span' => array(
247
+ 'class' => true,
248
+ ),
249
+ )
250
+ );
251
+ ?>
252
+ </label>
253
+ </p>
254
+ <?php
255
+ }
256
+ add_action( 'edd_cc_billing_top', 'edd_stripe_update_billing_address_field', 10 );
257
+
258
+ /**
259
+ * Display a radio list of existing cards on file for a user ID
260
+ *
261
+ * @since 2.6
262
+ * @param int $user_id
263
+ *
264
+ * @return void
265
+ */
266
+ function edd_stripe_existing_card_field_radio( $user_id = 0 ) {
267
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
268
+ edd_set_error( 'edd_stripe_error_limit', __( 'We are unable to process your payment at this time, please try again later or contacts support.', 'easy-digital-downloads' ) );
269
+ return;
270
+ }
271
+
272
+ // Can't use just edd_is_checkout() because this could happen in an AJAX request.
273
+ $is_checkout = edd_is_checkout() || ( isset( $_REQUEST['action'] ) && 'edd_load_gateway' === $_REQUEST['action'] );
274
+
275
+ edd_stripe_css( true );
276
+ $existing_cards = edd_stripe_get_existing_cards( $user_id );
277
+ if ( ! empty( $existing_cards ) ) : ?>
278
+ <div class="edd-stripe-card-selector edd-card-selector-radio">
279
+ <?php foreach ( $existing_cards as $card ) : ?>
280
+ <?php $source = $card['source']; ?>
281
+ <div class="edd-stripe-card-radio-item existing-card-wrapper <?php if ( $card['default'] ) { echo ' selected'; } ?>">
282
+ <input type="hidden" id="<?php echo $source->id; ?>-billing-details"
283
+ data-address_city="<?php echo $source->address_city; ?>"
284
+ data-address_country="<?php echo $source->address_country; ?>"
285
+ data-address_line1="<?php echo $source->address_line1; ?>"
286
+ data-address_line2="<?php echo $source->address_line2; ?>"
287
+ data-address_state="<?php echo $source->address_state; ?>"
288
+ data-address_zip="<?php echo $source->address_zip; ?>"
289
+ data-brand="<?php echo $source->brand; ?>"
290
+ data-last4="<?php echo $source->last4; ?>"
291
+ />
292
+ <label for="<?php echo $source->id; ?>">
293
+ <input <?php checked( true, $card['default'], true ); ?> type="radio" id="<?php echo $source->id; ?>" name="edd_stripe_existing_card" value="<?php echo $source->id; ?>" class="edd-stripe-existing-card">
294
+ <span class="card-label">
295
+ <span class="card-data">
296
+ <span class="card-name-number">
297
+ <?php
298
+ echo wp_kses(
299
+ sprintf(
300
+ /* translators: %1$s Card type. %2$s Card last 4. */
301
+ __( '%1$s •••• %2$s', 'easy-digital-downloads' ),
302
+ '<span class="card-brand">' . $source->brand . '</span>',
303
+ '<span class="card-last-4">' . $source->last4 . '</span>'
304
+ ),
305
+ array(
306
+ 'span' => array(
307
+ 'class' => true,
308
+ ),
309
+ )
310
+ );
311
+ ?>
312
+ </span>
313
+ <small class="card-expires-on">
314
+ <span class="default-card-sep"><?php echo '&nbsp;&nbsp;&nbsp;'; ?></span>
315
+ <span class="card-expiration">
316
+ <?php echo $source->exp_month . '/' . $source->exp_year; ?>
317
+ </span>
318
+ </small>
319
+ </span>
320
+ <?php
321
+ $current = strtotime( date( 'm/Y' ) );
322
+ $exp_date = strtotime( $source->exp_month . '/' . $source->exp_year );
323
+ if ( $exp_date < $current ) :
324
+ ?>
325
+ <span class="card-expired">
326
+ <?php _e( 'Expired', 'easy-digital-downloads' ); ?>
327
+ </span>
328
+ <?php
329
+ endif;
330
+ ?>
331
+ </span>
332
+ </label>
333
+ </div>
334
+ <?php endforeach; ?>
335
+ <div class="edd-stripe-card-radio-item new-card-wrapper">
336
+ <label for="edd-stripe-add-new">
337
+ <input type="radio" id="edd-stripe-add-new" class="edd-stripe-existing-card" name="edd_stripe_existing_card" value="new" />
338
+ <span class="add-new-card"><?php _e( 'Add New Card', 'easy-digital-downloads' ); ?></span>
339
+ </label>
340
+ </div>
341
+ </div>
342
+ <?php endif;
343
+ }
344
+
345
+ /**
346
+ * Output the management interface for a user's Stripe card
347
+ *
348
+ * @since 2.6
349
+ * @return void
350
+ */
351
+ function edd_stripe_manage_cards() {
352
+ if ( false === edds_is_gateway_active() ) {
353
+ return;
354
+ }
355
+
356
+ $enabled = edd_stripe_existing_cards_enabled();
357
+ if ( ! $enabled ) {
358
+ return;
359
+ }
360
+
361
+ $stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
362
+ if ( empty( $stripe_customer_id ) ) {
363
+ return;
364
+ }
365
+
366
+ if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
367
+ edd_set_error( 'edd_stripe_error_limit', __( 'Payment method management is currently unavailable.', 'easy-digital-downloads' ) );
368
+ edd_print_errors();
369
+ return;
370
+ }
371
+
372
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
373
+
374
+ edd_stripe_css( true );
375
+ edd_stripe_js( true );
376
+ $display = edd_get_option( 'stripe_billing_fields', 'full' );
377
+ ?>
378
+ <div id="edd-stripe-manage-cards">
379
+ <fieldset>
380
+ <legend><?php _e( 'Manage Payment Methods', 'easy-digital-downloads' ); ?></legend>
381
+ <input type="hidden" id="stripe-update-card-user_id" name="stripe-update-user-id" value="<?php echo get_current_user_id(); ?>" />
382
+ <?php if ( ! empty( $existing_cards ) ) : ?>
383
+ <?php foreach( $existing_cards as $card ) : ?>
384
+ <?php $source = $card['source']; ?>
385
+ <div id="<?php echo esc_attr( $source->id ); ?>_card_item" class="edd-stripe-card-item">
386
+ <span class="card-details">
387
+ <?php
388
+ echo wp_kses(
389
+ sprintf(
390
+ __( '%1$s •••• %2$s', 'easy-digital-downloads' ),
391
+ '<span class="card-brand">' . $source->brand . '</span>',
392
+ '<span class="card-last-4">' . $source->last4 . '</span>'
393
+ ),
394
+ array(
395
+ 'span' => array(
396
+ 'class' => true,
397
+ ),
398
+ )
399
+ );
400
+ ?>
401
+
402
+ <?php if ( $card['default'] ) { ?>
403
+ <span class="default-card-sep"><?php echo '&mdash; '; ?></span>
404
+ <span class="card-is-default"><?php _e( 'Default', 'easy-digital-downloads'); ?></span>
405
+ <?php } ?>
406
+ </span>
407
+
408
+ <span class="card-meta">
409
+ <span class="card-expiration"><span class="card-expiration-label"><?php _e( 'Expires', 'easy-digital-downloads' ); ?>: </span><span class="card-expiration-date"><?php echo $source->exp_month; ?>/<?php echo $source->exp_year; ?></span></span>
410
+ <span class="card-address">
411
+ <?php
412
+ $address_fields = array(
413
+ 'line1' => isset( $source->address_line1 ) ? $source->address_line1 : '',
414
+ 'zip' => isset( $source->address_zip ) ? $source->address_zip : '',
415
+ 'country' => isset( $source->address_country ) ? $source->address_country : '',
416
+ );
417
+
418
+ echo esc_html( implode( ' ', $address_fields ) );
419
+ ?>
420
+ </span>
421
+ </span>
422
+
423
+ <span id="<?php echo esc_attr( $source->id ); ?>-card-actions" class="card-actions">
424
+ <span class="card-update">
425
+ <a href="#" class="edd-stripe-update-card" data-source="<?php echo esc_attr( $source->id ); ?>"><?php _e( 'Update', 'easy-digital-downloads' ); ?></a>
426
+ </span>
427
+
428
+ <?php if ( ! $card['default'] ) : ?>
429
+ |
430
+ <span class="card-set-as-default">
431
+ <a href="#" class="edd-stripe-default-card" data-source="<?php echo esc_attr( $source->id ); ?>"><?php _e( 'Set as Default', 'easy-digital-downloads' ); ?></a>
432
+ </span>
433
+ <?php
434
+ endif;
435
+
436
+ $can_delete = apply_filters( 'edd_stripe_can_delete_card', true, $card, $existing_cards );
437
+ if ( $can_delete ) :
438
+ ?>
439
+ |
440
+ <span class="card-delete">
441
+ <a href="#" class="edd-stripe-delete-card delete" data-source="<?php echo esc_attr( $source->id ); ?>"><?php _e( 'Delete', 'easy-digital-downloads' ); ?></a>
442
+ </span>
443
+ <?php endif; ?>
444
+
445
+ <span style="display: none;" class="edd-loading-ajax edd-loading"></span>
446
+ </span>
447
+
448
+ <form id="<?php echo esc_attr( $source->id ); ?>-update-form" class="card-update-form" data-source="<?php echo esc_attr( $source->id ); ?>">
449
+ <label><?php _e( 'Billing Details', 'easy-digital-downloads' ); ?></label>
450
+
451
+ <div class="card-address-fields">
452
+ <p class="edds-card-address-field edds-card-address-field--address1">
453
+ <?php
454
+ echo EDD()->html->text( array(
455
+ 'id' => sprintf( 'edds_address_line1_%1$s', $source->id ),
456
+ 'value' => sanitize_text_field( isset( $source->address_line1 ) ? $source->address_line1 : '' ),
457
+ 'label' => esc_html__( 'Address Line 1', 'easy-digital-downloads' ),
458
+ 'name' => 'address_line1',
459
+ 'class' => 'card-update-field address_line1 text edd-input',
460
+ 'data' => array(
461
+ 'key' => 'address_line1',
462
+ )
463
+ ) );
464
+ ?>
465
+ </p>
466
+ <p class="edds-card-address-field edds-card-address-field--address2">
467
+ <?php
468
+ echo EDD()->html->text( array(
469
+ 'id' => sprintf( 'edds_address_line2_%1$s', $source->id ),
470
+ 'value' => sanitize_text_field( isset( $source->address_line2 ) ? $source->address_line2 : '' ),
471
+ 'label' => esc_html__( 'Address Line 2', 'easy-digital-downloads' ),
472
+ 'name' => 'address_line2',
473
+ 'class' => 'card-update-field address_line2 text edd-input',
474
+ 'data' => array(
475
+ 'key' => 'address_line2',
476
+ )
477
+ ) );
478
+ ?>
479
+ </p>
480
+ <p class="edds-card-address-field edds-card-address-field--city">
481
+ <?php
482
+ echo EDD()->html->text( array(
483
+ 'id' => sprintf( 'edds_address_city_%1$s', $source->id ),
484
+ 'value' => sanitize_text_field( isset( $source->address_city ) ? $source->address_city : '' ),
485
+ 'label' => esc_html__( 'City', 'easy-digital-downloads' ),
486
+ 'name' => 'address_city',
487
+ 'class' => 'card-update-field address_city text edd-input',
488
+ 'data' => array(
489
+ 'key' => 'address_city',
490
+ )
491
+ ) );
492
+ ?>
493
+ </p>
494
+ <p class="edds-card-address-field edds-card-address-field--zip">
495
+ <?php
496
+ echo EDD()->html->text( array(
497
+ 'id' => sprintf( 'edds_address_zip_%1$s', $source->id ),
498
+ 'value' => sanitize_text_field( isset( $source->address_zip ) ? $source->address_zip : '' ),
499
+ 'label' => esc_html__( 'ZIP Code', 'easy-digital-downloads' ),
500
+ 'name' => 'address_zip',
501
+ 'class' => 'card-update-field address_zip text edd-input',
502
+ 'data' => array(
503
+ 'key' => 'address_zip',
504
+ )
505
+ ) );
506
+ ?>
507
+ </p>
508
+ <p class="edds-card-address-field edds-card-address-field--country">
509
+ <label for="<?php echo esc_attr( sprintf( 'edds_address_country_%1$s', $source->id ) ); ?>">
510
+ <?php esc_html_e( 'Country', 'easy-digital-downloads' ); ?>
511
+ </label>
512
+
513
+ <?php
514
+ $countries = array_filter( edd_get_country_list() );
515
+ $country = isset( $source->address_country ) ? $source->address_country : edd_get_shop_country();
516
+ echo EDD()->html->select( array(
517
+ 'id' => sprintf( 'edds_address_country_%1$s', $source->id ),
518
+ 'name' => 'address_country',
519
+ 'label' => esc_html__( 'Country', 'easy-digital-downloads' ),
520
+ 'options' => $countries,
521
+ 'selected' => $country,
522
+ 'class' => 'card-update-field address_country',
523
+ 'data' => array( 'key' => 'address_country' ),
524
+ 'show_option_all' => false,
525
+ 'show_option_none' => false,
526
+ ) );
527
+ ?>
528
+ </p>
529
+
530
+ <p class="edds-card-address-field edds-card-address-field--state">
531
+ <label for="<?php echo esc_attr( sprintf( 'edds_address_state_%1$s', $source->id ) ); ?>">
532
+ <?php esc_html_e( 'State', 'easy-digital-downloads' ); ?>
533
+ </label>
534
+
535
+ <?php
536
+ $selected_state = isset( $source->address_state ) ? $source->address_state : edd_get_shop_state();
537
+ $states = edd_get_shop_states( $country );
538
+ echo EDD()->html->select( array(
539
+ 'id' => sprintf( 'edds_address_state_%1$s', $source->id ),
540
+ 'name' => 'address_state',
541
+ 'options' => $states,
542
+ 'selected' => $selected_state,
543
+ 'class' => 'card-update-field address_state card_state',
544
+ 'data' => array( 'key' => 'address_state' ),
545
+ 'show_option_all' => false,
546
+ 'show_option_none' => false,
547
+ ) );
548
+ ?>
549
+ </p>
550
+ </div>
551
+
552
+ <p class="card-expiration-fields">
553
+ <label for="<?php echo esc_attr( sprintf( 'edds_card_exp_month_%1$s', $source->id ) ); ?>" class="edd-label">
554
+ <?php _e( 'Expiration (MM/YY)', 'easy-digital-downloads' ); ?>
555
+ </label>
556
+
557
+ <?php
558
+ $months = array_combine( $r = range( 1, 12 ), $r );
559
+ echo EDD()->html->select( array(
560
+ 'id' => sprintf( 'edds_card_exp_month_%1$s', $source->id ),
561
+ 'name' => 'exp_month',
562
+ 'options' => $months,
563
+ 'selected' => $source->exp_month,
564
+ 'class' => 'card-expiry-month edd-select edd-select-small card-update-field exp_month',
565
+ 'data' => array( 'key' => 'exp_month' ),
566
+ 'show_option_all' => false,
567
+ 'show_option_none' => false,
568
+ ) );
569
+ ?>
570
+
571
+ <span class="exp-divider"> / </span>
572
+
573
+ <?php
574
+ $years = array_combine( $r = range( date( 'Y' ), date( 'Y' ) + 30 ), $r );
575
+ echo EDD()->html->select( array(
576
+ 'id' => sprintf( 'edds_card_exp_year_%1$s', $source->id ),
577
+ 'name' => 'exp_year',
578
+ 'options' => $years,
579
+ 'selected' => $source->exp_year,
580
+ 'class' => 'card-expiry-year edd-select edd-select-small card-update-field exp_year',
581
+ 'data' => array( 'key' => 'exp_year' ),
582
+ 'show_option_all' => false,
583
+ 'show_option_none' => false,
584
+ ) );
585
+ ?>
586
+ </p>
587
+
588
+ <p>
589
+ <input
590
+ type="submit"
591
+ class="edd-stripe-submit-update"
592
+ data-loading="<?php echo esc_attr__( 'Please Wait…', 'easy-digital-downloads' ); ?>"
593
+ data-submit="<?php echo esc_attr__( 'Update Card', 'easy-digital-downloads' ); ?>"
594
+ value="<?php echo esc_attr__( 'Update Card', 'easy-digital-downloads' ); ?>"
595
+ />
596
+
597
+ <a href="#" class="edd-stripe-cancel-update" data-source="<?php echo esc_attr( $source->id ); ?>"><?php _e( 'Cancel', 'easy-digital-downloads' ); ?></a>
598
+
599
+ <input type="hidden" name="card_id" data-key="id" value="<?php echo $source->id; ?>" />
600
+ <?php wp_nonce_field( $source->id . '_update', 'card_update_nonce_' . $source->id, true ); ?>
601
+ </p>
602
+ </form>
603
+ </div>
604
+ <?php endforeach; ?>
605
+ <?php endif; ?>
606
+ <form id="edd-stripe-add-new-card">
607
+ <div class="edd-stripe-add-new-card edd-stripe-new-card" style="display: none;">
608
+ <label><?php _e( 'Add New Card', 'easy-digital-downloads' ); ?></label>
609
+ <fieldset id="edd_cc_card_info" class="cc-card-info">
610
+ <legend><?php _e( 'Credit Card Details', 'easy-digital-downloads' ); ?></legend>
611
+ <?php do_action( 'edd_stripe_new_card_form' ); ?>
612
+ </fieldset>
613
+ <?php
614
+ switch( $display ) {
615
+ case 'full' :
616
+ edd_default_cc_address_fields();
617
+ break;
618
+
619
+ case 'zip_country' :
620
+ edd_stripe_zip_and_country();
621
+ add_filter( 'edd_purchase_form_required_fields', 'edd_stripe_require_zip_and_country' );
622
+
623
+ break;
624
+ }
625
+ ?>
626
+ </div>
627
+ <div class="edd-stripe-add-card-errors"></div>
628
+ <div class="edd-stripe-add-card-actions">
629
+
630
+ <input
631
+ type="submit"
632
+ class="edd-button edd-stripe-add-new"
633
+ data-loading="<?php echo esc_attr__( 'Please Wait…', 'easy-digital-downloads' ); ?>"
634
+ data-submit="<?php echo esc_attr__( 'Add new card', 'easy-digital-downloads' ); ?>"
635
+ value="<?php echo esc_attr__( 'Add new card', 'easy-digital-downloads' ); ?>"
636
+ />
637
+ <a href="#" id="edd-stripe-add-new-cancel" style="display: none;"><?php _e( 'Cancel', 'easy-digital-downloads' ); ?></a>
638
+ <?php wp_nonce_field( 'edd-stripe-add-card', 'edd-stripe-add-card-nonce', false, true ); ?>
639
+ </div>
640
+ </form>
641
+ </fieldset>
642
+ </div>
643
+ <?php
644
+ }
645
+ add_action( 'edd_profile_editor_after', 'edd_stripe_manage_cards' );
646
+
647
+ /**
648
+ * Determines if the default Profile Editor's "Billing Address"
649
+ * fields should be hidden.
650
+ *
651
+ * If using Stripe + Saved Cards (and Stripe is the only active gateway)
652
+ * the information set in "Billing Address" is never utilized:
653
+ *
654
+ * - When using an existing Card that Card's billing address is used.
655
+ * - When adding a new Card the address form is blanked.
656
+ *
657
+ * @since 2.8.0
658
+ */
659
+ function edd_stripe_maybe_hide_profile_editor_billing_address() {
660
+ if ( false === edds_is_gateway_active() ) {
661
+ return;
662
+ }
663
+
664
+ // Only hide if Stripe is the only active gateway.
665
+ $active_gateways = edd_get_enabled_payment_gateways();
666
+
667
+ if ( ! ( 1 === count( $active_gateways ) && isset( $active_gateways['stripe'] ) ) ) {
668
+ return;
669
+ }
670
+
671
+ // Only hide if using Saved Cards.
672
+ $use_saved_cards = edd_stripe_existing_cards_enabled();
673
+
674
+ if ( false === $use_saved_cards ) {
675
+ return;
676
+ }
677
+
678
+ // Allow a default addres to be entered for the first Card
679
+ // if the Profile Editor is found before Checkout.
680
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
681
+
682
+ if ( empty( $existing_cards ) ) {
683
+ return;
684
+ }
685
+
686
+ echo '<style>#edd_profile_address_fieldset { display: none; }</style>';
687
+ }
688
+ add_action( 'edd_profile_editor_after', 'edd_stripe_maybe_hide_profile_editor_billing_address' );
689
+
690
+ /**
691
+ * Zip / Postal Code field for when full billing address is disabled
692
+ *
693
+ * @since 2.5
694
+ * @return void
695
+ */
696
+ function edd_stripe_zip_and_country() {
697
+
698
+ $logged_in = is_user_logged_in();
699
+ $customer = EDD()->session->get( 'customer' );
700
+ $customer = wp_parse_args( $customer, array( 'address' => array(
701
+ 'line1' => '',
702
+ 'line2' => '',
703
+ 'city' => '',
704
+ 'zip' => '',
705
+ 'state' => '',
706
+ 'country' => ''
707
+ ) ) );
708
+
709
+ $customer['address'] = array_map( 'sanitize_text_field', $customer['address'] );
710
+
711
+ if( $logged_in ) {
712
+ $existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
713
+ if ( empty( $existing_cards ) ) {
714
+
715
+ $user_address = edd_get_customer_address( get_current_user() );
716
+
717
+ foreach( $customer['address'] as $key => $field ) {
718
+
719
+ if ( empty( $field ) && ! empty( $user_address[ $key ] ) ) {
720
+ $customer['address'][ $key ] = $user_address[ $key ];
721
+ } else {
722
+ $customer['address'][ $key ] = '';
723
+ }
724
+
725
+ }
726
+ } else {
727
+ foreach ( $existing_cards as $card ) {
728
+ if ( false === $card['default'] ) {
729
+ continue;
730
+ }
731
+
732
+ $source = $card['source'];
733
+ $customer['address'] = array(
734
+ 'line1' => $source->address_line1,
735
+ 'line2' => $source->address_line2,
736
+ 'city' => $source->address_city,
737
+ 'zip' => $source->address_zip,
738
+ 'state' => $source->address_state,
739
+ 'country' => $source->address_country,
740
+ );
741
+ }
742
+ }
743
+
744
+ }
745
+ ?>
746
+ <fieldset id="edd_cc_address" class="cc-address">
747
+ <legend><?php _e( 'Billing Details', 'easy-digital-downloads' ); ?></legend>
748
+ <p id="edd-card-country-wrap">
749
+ <label for="billing_country" class="edd-label">
750
+ <?php _e( 'Billing Country', 'easy-digital-downloads' ); ?>
751
+ <?php if( edd_field_is_required( 'billing_country' ) ) { ?>
752
+ <span class="edd-required-indicator">*</span>
753
+ <?php } ?>
754
+ </label>
755
+ <span class="edd-description"><?php _e( 'The country for your billing address.', 'easy-digital-downloads' ); ?></span>
756
+ <select name="billing_country" id="billing_country" class="billing_country edd-select<?php if( edd_field_is_required( 'billing_country' ) ) { echo ' required'; } ?>"<?php if( edd_field_is_required( 'billing_country' ) ) { echo ' required '; } ?> autocomplete="billing country">
757
+ <?php
758
+
759
+ $selected_country = edd_get_shop_country();
760
+
761
+ if( ! empty( $customer['address']['country'] ) && '*' !== $customer['address']['country'] ) {
762
+ $selected_country = $customer['address']['country'];
763
+ }
764
+
765
+ $countries = edd_get_country_list();
766
+ foreach( $countries as $country_code => $country ) {
767
+ echo '<option value="' . esc_attr( $country_code ) . '"' . selected( $country_code, $selected_country, false ) . '>' . $country . '</option>';
768
+ }
769
+ ?>
770
+ </select>
771
+ </p>
772
+ <p id="edd-card-zip-wrap">
773
+ <label for="card_zip" class="edd-label">
774
+ <?php _e( 'Billing Zip / Postal Code', 'easy-digital-downloads' ); ?>
775
+ <?php if( edd_field_is_required( 'card_zip' ) ) { ?>
776
+ <span class="edd-required-indicator">*</span>
777
+ <?php } ?>
778
+ </label>
779
+ <span class="edd-description"><?php _e( 'The zip or postal code for your billing address.', 'easy-digital-downloads' ); ?></span>
780
+ <input type="text" size="4" name="card_zip" id="card_zip" class="card-zip edd-input<?php if( edd_field_is_required( 'card_zip' ) ) { echo ' required'; } ?>" placeholder="<?php _e( 'Zip / Postal Code', 'easy-digital-downloads' ); ?>" value="<?php echo $customer['address']['zip']; ?>"<?php if( edd_field_is_required( 'card_zip' ) ) { echo ' required '; } ?> autocomplete="billing postal-code" />
781
+ </p>
782
+ </fieldset>
783
+ <?php
784
+ }
785
+
786
+ /**
787
+ * Determine how the billing address fields should be displayed
788
+ *
789
+ * @access public
790
+ * @since 2.5
791
+ * @return void
792
+ */
793
+ function edd_stripe_setup_billing_address_fields() {
794
+
795
+ if( ! function_exists( 'edd_use_taxes' ) ) {
796
+ return;
797
+ }
798
+
799
+ if( edd_use_taxes() || 'stripe' !== edd_get_chosen_gateway() || ! edd_get_cart_total() > 0 ) {
800
+ return;
801
+ }
802
+
803
+ $display = edd_get_option( 'stripe_billing_fields', 'full' );
804
+
805
+ switch( $display ) {
806
+
807
+ case 'full' :
808
+
809
+ // Make address fields required
810
+ add_filter( 'edd_require_billing_address', '__return_true' );
811
+
812
+ break;
813
+
814
+ case 'zip_country' :
815
+
816
+ remove_action( 'edd_after_cc_fields', 'edd_default_cc_address_fields', 10 );
817
+ add_action( 'edd_after_cc_fields', 'edd_stripe_zip_and_country', 9 );
818
+
819
+ // Make Zip required
820
+ add_filter( 'edd_purchase_form_required_fields', 'edd_stripe_require_zip_and_country' );
821
+
822
+ break;
823
+
824
+ case 'none' :
825
+
826
+ remove_action( 'edd_after_cc_fields', 'edd_default_cc_address_fields', 10 );
827
+
828
+ break;
829
+
830
+ }
831
+
832
+ }
833
+ add_action( 'init', 'edd_stripe_setup_billing_address_fields', 9 );
834
+
835
+ /**
836
+ * Force zip code and country to be required when billing address display is zip only
837
+ *
838
+ * @access public
839
+ * @since 2.5
840
+ * @return array $fields The required fields
841
+ */
842
+ function edd_stripe_require_zip_and_country( $fields ) {
843
+
844
+ $fields['card_zip'] = array(
845
+ 'error_id' => 'invalid_zip_code',
846
+ 'error_message' => __( 'Please enter your zip / postal code', 'easy-digital-downloads' )
847
+ );
848
+
849
+ $fields['billing_country'] = array(
850
+ 'error_id' => 'invalid_country',
851
+ 'error_message' => __( 'Please select your billing country', 'easy-digital-downloads' )
852
+ );
853
+
854
+ return $fields;
855
+ }
includes/gateways/stripe/includes/utils/class-registry.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic registry functionality.
4
+ *
5
+ * @todo Replace with EDD\Utils\Registry when EDD 3.x is required.
6
+ *
7
+ * @package EDD_Stripe
8
+ * @since 2.6.19
9
+ */
10
+
11
+ /**
12
+ * Defines the construct for building an item registry.
13
+ *
14
+ * @since 2.6.19
15
+ * @abstract
16
+ */
17
+ abstract class EDD_Stripe_Utils_Registry extends ArrayObject {
18
+
19
+ /**
20
+ * Item error label.
21
+ *
22
+ * Used for customizing exception messages to the current registry instance. Default 'item'.
23
+ *
24
+ * @since 2.6.19
25
+ * @var string
26
+ */
27
+ public static $item_error_label = 'item';
28
+
29
+ /**
30
+ * Adds an item to the registry.
31
+ *
32
+ * @since 2.6.19
33
+ *
34
+ * @throws Exception If the `$attributes` array is empty.
35
+ *
36
+ * @param string $item_id Item ID.
37
+ * @param array $attributes Array of item attributes. Each extending registry will
38
+ * handle item ID and attribute building in different ways.
39
+ * @return bool True if `$attributes` is not empty, otherwise false.
40
+ */
41
+ public function add_item( $item_id, $attributes ) {
42
+ $result = false;
43
+
44
+ if ( ! empty( $attributes ) ) {
45
+ $this->offsetSet( $item_id, $attributes );
46
+
47
+ $result = true;
48
+ } else {
49
+ $message = sprintf(
50
+ 'The attributes were missing when attempting to add the \'%1$s\' %2$s.',
51
+ $item_id,
52
+ static::$item_error_label
53
+ );
54
+
55
+ throw new Exception( $message );
56
+ }
57
+
58
+ return $result;
59
+ }
60
+
61
+ /**
62
+ * Removes an item from the registry by ID.
63
+ *
64
+ * @since 2.6.19
65
+ *
66
+ * @param string $item_id Item ID.
67
+ */
68
+ public function remove_item( $item_id ) {
69
+ if ( $this->offsetExists( $item_id ) ) {
70
+ $this->offsetUnset( $item_id );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Retrieves an item and its associated attributes.
76
+ *
77
+ * @since 2.6.19
78
+ *
79
+ * @throws Exception if the item does not exist.
80
+ *
81
+ * @param string $item_id Item ID.
82
+ * @return array Array of attributes for the item if the item is set,
83
+ * otherwise an empty array.
84
+ */
85
+ public function get_item( $item_id ) {
86
+ $item = array();
87
+
88
+ if ( $this->offsetExists( $item_id ) ) {
89
+ $item = $this->offsetGet( $item_id );
90
+ } else {
91
+ $message = sprintf(
92
+ 'The \'%1$s\' %2$s does not exist.',
93
+ $item_id,
94
+ static::$item_error_label
95
+ );
96
+
97
+ throw new Exception( $message );
98
+ }
99
+
100
+ return $item;
101
+ }
102
+
103
+ /**
104
+ * Retrieves registered items.
105
+ *
106
+ * @since 2.6.19
107
+ *
108
+ * @return array The list of registered items.
109
+ */
110
+ public function get_items() {
111
+ return $this->getArrayCopy();
112
+ }
113
+
114
+ /**
115
+ * Retrieves the value of a given attribute for a given item.
116
+ *
117
+ * @since 2.6.19
118
+ *
119
+ * @throws Exception if the item does not exist.
120
+ * @throws EDD_Stripe_Exceptions_Attribute_Not_Found if the attribute and/or item does not exist.
121
+ *
122
+ * @param string $key Key of the attribute to retrieve.
123
+ * @param string $item_id Collection to retrieve the attribute from.
124
+ * @return mixed|null The attribute value if set, otherwise null.
125
+ */
126
+ public function get_attribute( $key, $item_id ) {
127
+ $attribute = null;
128
+ $item = $this->get_item( $item_id );
129
+
130
+ if ( ! empty( $item[ $key ] ) ) {
131
+ $attribute = $item[ $key ];
132
+ } else {
133
+ throw EDD_Stripe_Utils_Exceptions_Attribute_Not_Found::from_attr( $key, $item_id );
134
+ }
135
+
136
+ return $attribute;
137
+ }
138
+
139
+ }
includes/gateways/stripe/includes/utils/exceptions/class-attribute-not-found.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EDD_Stripe_Utils_Exceptions_Attribute_Not_Found exception class
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Implements an EDD_Stripe_Utils_Exceptions_Attribute_Not_Found exception thrown when a given
11
+ * attribute is not found.
12
+ *
13
+ * @since 2.6.19
14
+ *
15
+ * @see OutOfBoundsException
16
+ */
17
+ class EDD_Stripe_Utils_Exceptions_Attribute_Not_Found extends OutOfBoundsException {
18
+
19
+ /**
20
+ * Retrieves an informed Attribute_Not_Found instance via late-static binding.
21
+ *
22
+ * @since 2.6.19
23
+ *
24
+ * @param string $attribute_name Attribute resulting in the exception.
25
+ * @param string $collection Collection the attribute belongs to.
26
+ * @param int $code Optional. Exception code. Default null.
27
+ * @param Exception $previous Optional. Previous exception (used for chaining).
28
+ * Default null.
29
+ * @return EDD_Stripe_Exceptions_Attribute_Not_Found Exception instance.
30
+ */
31
+ public static function from_attr( $attribute_name, $collection, $code = null, $previous = null ) {
32
+ $message = sprintf( 'The \'%1$s\' attribute does not exist for \'%2$s\'.',
33
+ $attribute_name,
34
+ $collection
35
+ );
36
+
37
+ return new static( $message, $code, $previous);
38
+ }
39
+
40
+ }
includes/gateways/stripe/includes/utils/exceptions/class-gateway-exception.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Exception: Gateway
4
+ *
5
+ * @package EDD_Stripe
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * EDD_Stripe_Gateway_Exception class.
18
+ */
19
+ class EDD_Stripe_Gateway_Exception extends \Exception {
20
+
21
+ /**
22
+ * Log message, not displayed to the user.
23
+ *
24
+ * @since 2.8.1
25
+ * @var string
26
+ */
27
+ public $log_message;
28
+
29
+ /**
30
+ * Constructs the exception.
31
+ *
32
+ * @since 2.8.1
33
+ *
34
+ * @param string $display_message User-facing exception message.
35
+ * @param string $log_message Optional. Admin-facing exception message.
36
+ * @param int $http_status_code Optional. HTTP status code to respond with, e.g. 400.
37
+ */
38
+ public function __construct(
39
+ $display_message,
40
+ $log_message = '',
41
+ $http_status_code = 400
42
+ ) {
43
+ parent::__construct( $display_message, $http_status_code );
44
+
45
+ if ( ! empty( $log_message ) ) {
46
+ $this->log_message = $log_message;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Determines if an admin-facing message is set.
52
+ *
53
+ * @since 2.8.1
54
+ *
55
+ * @return bool
56
+ */
57
+ public function hasLogMessage() {
58
+ return ! empty( $this->log_message );
59
+ }
60
+
61
+ /**
62
+ * Returns the admin-facing log message.
63
+ *
64
+ * @since 2.8.1
65
+ *
66
+ * @return string
67
+ */
68
+ public function getLogMessage() {
69
+ if ( false === $this->hasLogMessage() ) {
70
+ return '';
71
+ }
72
+
73
+ return $this->log_message;
74
+ }
75
+
76
+ }
includes/gateways/stripe/includes/utils/exceptions/class-stripe-api-unmet-requirements.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EDD_Stripe_Utils_Exceptions_Stripe_API_Unmet_Requirements exception class
4
+ *
5
+ * @package EDD_Stripe\Utils\Exceptions
6
+ * @copyright Copyright (c) 2021, Sandhills Development, LLC
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 2.8.1
9
+ */
10
+
11
+ /**
12
+ * EDD_Stripe_Utils_Exceptions_Stripe_API_Unmet_Requirements
13
+ *
14
+ * @since 2.8.1
15
+ */
16
+ class EDD_Stripe_Utils_Exceptions_Stripe_API_Unmet_Requirements extends \Exception {
17
+
18
+ }
includes/gateways/stripe/includes/utils/exceptions/class-stripe-object-not-found.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found exception class
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Implements an EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found exception.
11
+ *
12
+ * @since 2.7.0
13
+ */
14
+ class EDD_Stripe_Utils_Exceptions_Stripe_Object_Not_Found extends BadMethodCallException {
15
+
16
+ }
includes/gateways/stripe/includes/utils/interface-static-registry.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EDD_Stripe_Utils_Static_Registry interface.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.6.19
7
+ */
8
+
9
+ /**
10
+ * Defines the contract for a static (singleton) registry object.
11
+ *
12
+ * @since 2.6.19
13
+ */
14
+ interface EDD_Stripe_Utils_Static_Registry {
15
+
16
+ /**
17
+ * Retrieves the one true registry instance.
18
+ *
19
+ * @since 2.6.19
20
+ *
21
+ * @return EDD_Stripe_Utils_Static_Registry Registry instance.
22
+ */
23
+ public static function instance();
24
+
25
+ }
includes/gateways/stripe/includes/utils/modal.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Utils: Modal
4
+ *
5
+ * Generic "Modal" helper for generating markup.
6
+ *
7
+ * @package EDD_Stripe
8
+ * @since 2.8.0
9
+ */
10
+
11
+ /**
12
+ * Generates HTML for a Modal.
13
+ *
14
+ * @since 2.8.0
15
+ *
16
+ * @param int $download_id
17
+ * @param array $args
18
+ */
19
+ function edds_modal( $args = array() ) {
20
+ $defaults = array(
21
+ 'id' => '',
22
+ 'class' => array(),
23
+ 'title' => '',
24
+ 'content' => ''
25
+ );
26
+
27
+ $args = wp_parse_args( $args, $defaults );
28
+
29
+ // ID is required for any Javascript interaction
30
+ // and accessibility.
31
+ if ( empty( $args['id'] ) ) {
32
+ return;
33
+ }
34
+
35
+ $classnames = implode( ' ', array_map( 'trim', (array) $args['class'] ) );
36
+
37
+ ob_start();
38
+ ?>
39
+
40
+ <div
41
+ id="<?php echo esc_attr( $args['id'] ); ?>"
42
+ class="edds-modal has-slide"
43
+ aria-hidden="true"
44
+ >
45
+ <div
46
+ class="edds-modal__overlay"
47
+ tabindex="-1"
48
+ data-micromodal-close
49
+ >
50
+ <div
51
+ class="edds-modal__container <?php echo esc_attr( $classnames ); ?>"
52
+ role="dialog"
53
+ aria-modal="true"
54
+ aria-labelledby="<?php echo esc_attr( $args['id'] ); ?>-modal-title"
55
+ >
56
+ <header class="edds-modal__header">
57
+ <?php if ( ! empty( $args['title'] ) ) : ?>
58
+ <h2
59
+ id="<?php echo esc_attr( $args['id'] ); ?>-modal-title"
60
+ class="edds-modal__title"
61
+ >
62
+ <?php echo esc_html( $args['title'] ); ?>
63
+ </h2>
64
+ <?php endif; ?>
65
+
66
+ <button
67
+ type="button"
68
+ class="edds-modal__close"
69
+ aria-label="<?php echo esc_attr_e( 'Close', 'easy-digital-downloads' ); ?>"
70
+ data-micromodal-close
71
+ >
72
+ </button>
73
+ </header>
74
+
75
+ <div
76
+ id="<?php echo esc_attr( $args['id'] ); ?>-modal-content"
77
+ class="edds-modal__content"
78
+ >
79
+ <?php echo $args['content']; // WPCS: XSS okay. ?>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ <?php
85
+
86
+ return ob_get_clean();
87
+ }
includes/gateways/stripe/includes/webhooks.php ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webhooks.
4
+ *
5
+ * @package EDD_Stripe
6
+ * @since 2.7.0
7
+ */
8
+
9
+ /**
10
+ * Listen for Stripe Webhooks.
11
+ *
12
+ * @since 1.5
13
+ */
14
+ function edds_stripe_event_listener() {
15
+ if ( ! isset( $_GET['edd-listener'] ) || 'stripe' !== $_GET['edd-listener'] ) {
16
+ return;
17
+ }
18
+
19
+ try {
20
+ // Retrieve the request's body and parse it as JSON.
21
+ $body = @file_get_contents( 'php://input' );
22
+ $event = json_decode( $body );
23
+
24
+ if ( isset( $event->id ) ) {
25
+ $event = edds_api_request( 'Event', 'retrieve', $event->id );
26
+ } else {
27
+ throw new \Exception( esc_html__( 'Unable to find Event', 'easy-digital-downloads' ) );
28
+ }
29
+
30
+ // Handle events.
31
+ //
32
+ switch ( $event->type ) {
33
+
34
+ // Charge succeeded. Update EDD Payment address.
35
+ case 'charge.succeeded' :
36
+ $charge = $event->data->object;
37
+ $payment_id = edd_get_purchase_id_by_transaction_id( $charge->id );
38
+ $payment = new EDD_Payment( $payment_id );
39
+
40
+ if ( $payment && $payment->ID > 0 ) {
41
+ $payment->address = array(
42
+ 'line1' => $charge->billing_details->address->line1,
43
+ 'line2' => $charge->billing_details->address->line2,
44
+ 'state' => $charge->billing_details->address->state,
45
+ 'city' => $charge->billing_details->address->city,
46
+ 'zip' => $charge->billing_details->address->postal_code,
47
+ 'country' => $charge->billing_details->address->country,
48
+ );
49
+
50
+ $payment->save();
51
+ }
52
+
53
+ break;
54
+
55
+ // Charge refunded. Ensure EDD Payment status is correct.
56
+ case 'charge.refunded':
57
+ $charge = $event->data->object;
58
+ $payment_id = edd_get_purchase_id_by_transaction_id( $charge->id );
59
+ $payment = new EDD_Payment( $payment_id );
60
+
61
+ // This is an uncaptured PaymentIntent, not a true refund.
62
+ if ( ! $charge->captured ) {
63
+ return;
64
+ }
65
+
66
+ if ( $payment && $payment->ID > 0 ) {
67
+
68
+ // If this was completely refunded, set the status to refunded.
69
+ if ( $charge->refunded ) {
70
+ $payment->status = 'refunded';
71
+ $payment->save();
72
+ // Translators: The charge ID from Stripe that is being refunded.
73
+ $payment->add_note( sprintf( __( 'Charge %s has been fully refunded in Stripe.', 'easy-digital-downloads' ), $charge->id ) );
74
+
75
+ // If this was partially refunded, don't change the status.
76
+ } else {
77
+ // Translators: The charge ID from Stripe that is being partially refunded.
78
+ $payment->add_note( sprintf( __( 'Charge %s partially refunded in Stripe.', 'easy-digital-downloads' ), $charge->id ) );
79
+ }
80
+ }
81
+
82
+ break;
83
+
84
+ // Review started.
85
+ case 'review.opened' :
86
+ $is_live = ! edd_is_test_mode();
87
+ $review = $event->data->object;
88
+
89
+ // Make sure the modes match.
90
+ if ( $is_live !== $review->livemode ) {
91
+ return;
92
+ }
93
+
94
+ $charge = $review->charge;
95
+
96
+ // Get the charge from the PaymentIntent.
97
+ if ( ! $charge ) {
98
+ $payment_intent = $review->payment_intent;
99
+
100
+ if ( ! $payment_intent ) {
101
+ return;
102
+ }
103
+
104
+ $payment_intent = edds_api_request( 'PaymentIntent', 'retrieve', $payment_intent );
105
+ $charge = $payment_intent->charges->data[0]->id;
106
+ }
107
+
108
+ $payment_id = edd_get_purchase_id_by_transaction_id( $charge );
109
+ $payment = new EDD_Payment( $payment_id );
110
+
111
+ if ( $payment && $payment->ID > 0 ) {
112
+ $payment->add_note(
113
+ sprintf(
114
+ /* translators: %s Stripe Radar review opening reason. */
115
+ __( 'Stripe Radar review opened with a reason of %s.', 'easy-digital-downloads' ),
116
+ $review->reason
117
+ )
118
+ );
119
+ $payment->save();
120
+
121
+ do_action( 'edd_stripe_review_opened', $review, $payment_id );
122
+ }
123
+
124
+ break;
125
+
126
+ // Review closed.
127
+ case 'review.closed' :
128
+ $is_live = ! edd_is_test_mode();
129
+ $review = $event->data->object;
130
+
131
+ // Make sure the modes match
132
+ if ( $is_live !== $review->livemode ) {
133
+ return;
134
+ }
135
+
136
+ $charge = $review->charge;
137
+
138
+ // Get the charge from the PaymentIntent.
139
+ if ( ! $charge ) {
140
+ $payment_intent = $review->payment_intent;
141
+
142
+ if ( ! $payment_intent ) {
143
+ return;
144
+ }
145
+
146
+ $payment_intent = edds_api_request( 'PaymentIntent', 'retrieve', $payment_intent );
147
+ $charge = $payment_intent->charges->data[0]->id;
148
+ }
149
+
150
+ $payment_id = edd_get_purchase_id_by_transaction_id( $charge );
151
+ $payment = new EDD_Payment( $payment_id );
152
+
153
+ if ( $payment && $payment->ID > 0 ) {
154
+ $payment->add_note(
155
+ sprintf(
156
+ /* translators: %s Stripe Radar review closing reason. */
157
+ __( 'Stripe Radar review closed with a reason of %s.', 'easy-digital-downloads' ),
158
+ $review->reason
159
+ )
160
+ );
161
+ $payment->save();
162
+
163
+ do_action( 'edd_stripe_review_closed', $review, $payment_id );
164
+ }
165
+
166
+ break;
167
+ }
168
+
169
+ do_action( 'edds_stripe_event_' . $event->type, $event );
170
+
171
+ // Nothing failed, mark complete.
172
+ status_header( 200 );
173
+ die( esc_html( 'EDD Stripe: ' . $event->type ) );
174
+
175
+ // Fail, allow a retry.
176
+ } catch ( \Exception $e ) {
177
+ status_header( 500 );
178
+ die( '-2' );
179
+ }
180
+ }
181
+ add_action( 'init', 'edds_stripe_event_listener' );
includes/gateways/stripe/vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInitdfbee5702addcbc9a3b31d6d120a387d::getLoader();
includes/gateways/stripe/vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+ private $classMapAuthoritative = false;
57
+ private $missingClasses = array();
58
+ private $apcuPrefix;
59
+
60
+ public function getPrefixes()
61
+ {
62
+ if (!empty($this->prefixesPsr0)) {
63
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
64
+ }
65
+
66
+ return array();
67
+ }
68
+
69
+ public function getPrefixesPsr4()
70
+ {
71
+ return $this->prefixDirsPsr4;
72
+ }
73
+
74
+ public function getFallbackDirs()
75
+ {
76
+ return $this->fallbackDirsPsr0;
77
+ }
78
+
79
+ public function getFallbackDirsPsr4()
80
+ {
81
+ return $this->fallbackDirsPsr4;
82
+ }
83
+
84
+ public function getClassMap()
85
+ {
86
+ return $this->classMap;
87
+ }
88
+
89
+ /**
90
+ * @param array $classMap Class to filename map
91
+ */
92
+ public function addClassMap(array $classMap)
93
+ {
94
+ if ($this->classMap) {
95
+ $this->classMap = array_merge($this->classMap, $classMap);
96
+ } else {
97
+ $this->classMap = $classMap;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Registers a set of PSR-0 directories for a given prefix, either
103
+ * appending or prepending to the ones previously set for this prefix.
104
+ *
105
+ * @param string $prefix The prefix
106
+ * @param array|string $paths The PSR-0 root directories
107
+ * @param bool $prepend Whether to prepend the directories
108
+ */
109
+ public function add($prefix, $paths, $prepend = false)
110
+ {
111
+ if (!$prefix) {
112
+ if ($prepend) {
113
+ $this->fallbackDirsPsr0 = array_merge(
114
+ (array) $paths,
115
+ $this->fallbackDirsPsr0
116
+ );
117
+ } else {
118
+ $this->fallbackDirsPsr0 = array_merge(
119
+ $this->fallbackDirsPsr0,
120
+ (array) $paths
121
+ );
122
+ }
123
+
124
+ return;
125
+ }
126
+
127
+ $first = $prefix[0];
128
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
129
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
130
+
131
+ return;
132
+ }
133
+ if ($prepend) {
134
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
135
+ (array) $paths,
136
+ $this->prefixesPsr0[$first][$prefix]
137
+ );
138
+ } else {
139
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
140
+ $this->prefixesPsr0[$first][$prefix],
141
+ (array) $paths
142
+ );
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Registers a set of PSR-4 directories for a given namespace, either
148
+ * appending or prepending to the ones previously set for this namespace.
149
+ *
150
+ * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
+ * @param bool $prepend Whether to prepend the directories
153
+ *
154
+ * @throws \InvalidArgumentException
155
+ */
156
+ public function addPsr4($prefix, $paths, $prepend = false)
157
+ {
158
+ if (!$prefix) {
159
+ // Register directories for the root namespace.
160
+ if ($prepend) {
161
+ $this->fallbackDirsPsr4 = array_merge(
162
+ (array) $paths,
163
+ $this->fallbackDirsPsr4
164
+ );
165
+ } else {
166
+ $this->fallbackDirsPsr4 = array_merge(
167
+ $this->fallbackDirsPsr4,
168
+ (array) $paths
169
+ );
170
+ }
171
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
172
+ // Register directories for a new namespace.
173
+ $length = strlen($prefix);
174
+ if ('\\' !== $prefix[$length - 1]) {
175
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
176
+ }
177
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
178
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
179
+ } elseif ($prepend) {
180
+ // Prepend directories for an already registered namespace.
181
+ $this->prefixDirsPsr4[$prefix] = array_merge(
182
+ (array) $paths,
183
+ $this->prefixDirsPsr4[$prefix]
184
+ );
185
+ } else {
186
+ // Append directories for an already registered namespace.
187
+ $this->prefixDirsPsr4[$prefix] = array_merge(
188
+ $this->prefixDirsPsr4[$prefix],
189
+ (array) $paths
190
+ );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Registers a set of PSR-0 directories for a given prefix,
196
+ * replacing any others previously set for this prefix.
197
+ *
198
+ * @param string $prefix The prefix
199
+ * @param array|string $paths The PSR-0 base directories
200
+ */
201
+ public function set($prefix, $paths)
202
+ {
203
+ if (!$prefix) {
204
+ $this->fallbackDirsPsr0 = (array) $paths;
205
+ } else {
206
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Registers a set of PSR-4 directories for a given namespace,
212
+ * replacing any others previously set for this namespace.
213
+ *
214
+ * @param string $prefix The prefix/namespace, with trailing '\\'
215
+ * @param array|string $paths The PSR-4 base directories
216
+ *
217
+ * @throws \InvalidArgumentException
218
+ */
219
+ public function setPsr4($prefix, $paths)
220
+ {
221
+ if (!$prefix) {
222
+ $this->fallbackDirsPsr4 = (array) $paths;
223
+ } else {
224
+ $length = strlen($prefix);
225
+ if ('\\' !== $prefix[$length - 1]) {
226
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
227
+ }
228
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
229
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Turns on searching the include path for class files.
235
+ *
236
+ * @param bool $useIncludePath
237
+ */
238
+ public function setUseIncludePath($useIncludePath)
239
+ {
240
+ $this->useIncludePath = $useIncludePath;
241
+ }
242
+
243
+ /**
244
+ * Can be used to check if the autoloader uses the include path to check
245
+ * for classes.
246
+ *
247
+ * @return bool
248
+ */
249
+ public function getUseIncludePath()
250
+ {
251
+ return $this->useIncludePath;
252
+ }
253
+
254
+ /**
255
+ * Turns off searching the prefix and fallback directories for classes
256
+ * that have not been registered with the class map.
257
+ *
258
+ * @param bool $classMapAuthoritative
259
+ */
260
+ public function setClassMapAuthoritative($classMapAuthoritative)
261
+ {
262
+ $this->classMapAuthoritative = $classMapAuthoritative;
263
+ }
264
+
265
+ /**
266
+ * Should class lookup fail if not found in the current class map?
267
+ *
268
+ * @return bool
269
+ */
270
+ public function isClassMapAuthoritative()
271
+ {
272
+ return $this->classMapAuthoritative;
273
+ }
274
+
275
+ /**
276
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
+ *
278
+ * @param string|null $apcuPrefix
279
+ */
280
+ public function setApcuPrefix($apcuPrefix)
281
+ {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
+ }
284
+
285
+ /**
286
+ * The APCu prefix in use, or null if APCu caching is not enabled.
287
+ *
288
+ * @return string|null
289
+ */
290
+ public function getApcuPrefix()
291
+ {
292
+ return $this->apcuPrefix;
293
+ }
294
+
295
+ /**
296
+ * Registers this instance as an autoloader.
297
+ *
298
+ * @param bool $prepend Whether to prepend the autoloader or not
299
+ */
300
+ public function register($prepend = false)
301
+ {
302
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
303
+ }
304
+
305
+ /**
306
+ * Unregisters this instance as an autoloader.
307
+ */
308
+ public function unregister()
309
+ {
310
+ spl_autoload_unregister(array($this, 'loadClass'));
311
+ }
312
+
313
+ /**
314
+ * Loads the given class or interface.
315
+ *
316
+ * @param string $class The name of the class
317
+ * @return bool|null True if loaded, null otherwise
318
+ */
319
+ public function loadClass($class)
320
+ {
321
+ if ($file = $this->findFile($class)) {
322
+ includeFile($file);
323
+
324
+ return true;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Finds the path to the file where the class is defined.
330
+ *
331
+ * @param string $class The name of the class
332
+ *
333
+ * @return string|false The path if found, false otherwise
334
+ */
335
+ public function findFile($class)
336
+ {
337
+ // class map lookup
338
+ if (isset($this->classMap[$class])) {
339
+ return $this->classMap[$class];
340
+ }
341
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
+ return false;
343
+ }
344
+ if (null !== $this->apcuPrefix) {
345
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
+ if ($hit) {
347
+ return $file;
348
+ }
349
+ }
350
+
351
+ $file = $this->findFileWithExtension($class, '.php');
352
+
353
+ // Search for Hack files if we are running on HHVM
354
+ if (false === $file && defined('HHVM_VERSION')) {
355
+ $file = $this->findFileWithExtension($class, '.hh');
356
+ }
357
+
358
+ if (null !== $this->apcuPrefix) {
359
+ apcu_add($this->apcuPrefix.$class, $file);
360
+ }
361
+
362
+ if (false === $file) {
363
+ // Remember that this class does not exist.
364
+ $this->missingClasses[$class] = true;
365
+ }
366
+
367
+ return $file;
368
+ }
369
+
370
+ private function findFileWithExtension($class, $ext)
371
+ {
372
+ // PSR-4 lookup
373
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
374
+
375
+ $first = $class[0];
376
+ if (isset($this->prefixLengthsPsr4[$first])) {
377
+ $subPath = $class;
378
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
379
+ $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
+ if (isset($this->prefixDirsPsr4[$search])) {
382
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
384
+ if (file_exists($file = $dir . $pathEnd)) {
385
+ return $file;
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+
392
+ // PSR-4 fallback dirs
393
+ foreach ($this->fallbackDirsPsr4 as $dir) {
394
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395
+ return $file;
396
+ }
397
+ }
398
+
399
+ // PSR-0 lookup
400
+ if (false !== $pos = strrpos($class, '\\')) {
401
+ // namespaced class name
402
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
403
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
404
+ } else {
405
+ // PEAR-like class name
406
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
407
+ }
408
+
409
+ if (isset($this->prefixesPsr0[$first])) {
410
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411
+ if (0 === strpos($class, $prefix)) {
412
+ foreach ($dirs as $dir) {
413
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414
+ return $file;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ // PSR-0 fallback dirs
422
+ foreach ($this->fallbackDirsPsr0 as $dir) {
423
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424
+ return $file;
425
+ }
426
+ }
427
+
428
+ // PSR-0 include paths.
429
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430
+ return $file;
431
+ }
432
+
433
+ return false;
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Scope isolated include.
439
+ *
440
+ * Prevents access to $this/self from included files.
441
+ */
442
+ function includeFile($file)
443
+ {
444
+ include $file;
445
+ }
includes/gateways/stripe/vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
includes/gateways/stripe/vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
includes/gateways/stripe/vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
includes/gateways/stripe/vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Stripe\\' => array($vendorDir . '/stripe/stripe-php/lib'),
10
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
11
+ );
includes/gateways/stripe/vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInitdfbee5702addcbc9a3b31d6d120a387d
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInitdfbee5702addcbc9a3b31d6d120a387d', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitdfbee5702addcbc9a3b31d6d120a387d', 'loadClassLoader'));
25
+
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
+ if ($useStaticLoader) {
28
+ require_once __DIR__ . '/autoload_static.php';
29
+
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitdfbee5702addcbc9a3b31d6d120a387d::getInitializer($loader));
31
+ } else {
32
+ $map = require __DIR__ . '/autoload_namespaces.php';
33
+ foreach ($map as $namespace => $path) {
34
+ $loader->set($namespace, $path);
35
+ }
36
+
37
+ $map = require __DIR__ . '/autoload_psr4.php';
38
+ foreach ($map as $namespace => $path) {
39
+ $loader->setPsr4($namespace, $path);
40
+ }
41
+
42
+ $classMap = require __DIR__ . '/autoload_classmap.php';
43
+ if ($classMap) {
44
+ $loader->addClassMap($classMap);
45
+ }
46
+ }
47
+
48
+ $loader->register(true);
49
+
50
+ return $loader;
51
+ }
52
+ }
includes/gateways/stripe/vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInitdfbee5702addcbc9a3b31d6d120a387d
8
+ {
9
+ public static $prefixLengthsPsr4 = array (
10
+ 'S' =>
11
+ array (
12
+ 'Stripe\\' => 7,
13
+ ),
14
+ 'C' =>
15
+ array (
16
+ 'Composer\\Installers\\' => 20,
17
+ ),
18
+ );
19
+
20
+ public static $prefixDirsPsr4 = array (
21
+ 'Stripe\\' =>
22
+ array (
23
+ 0 => __DIR__ . '/..' . '/stripe/stripe-php/lib',
24
+ ),
25
+ 'Composer\\Installers\\' =>
26
+ array (
27
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
28
+ ),
29
+ );
30
+
31
+ public static function getInitializer(ClassLoader $loader)
32
+ {
33
+ return \Closure::bind(function () use ($loader) {
34
+ $loader->prefixLengthsPsr4 = ComposerStaticInitdfbee5702addcbc9a3b31d6d120a387d::$prefixLengthsPsr4;
35
+ $loader->prefixDirsPsr4 = ComposerStaticInitdfbee5702addcbc9a3b31d6d120a387d::$prefixDirsPsr4;
36
+
37
+ }, null, ClassLoader::class);
38
+ }
39
+ }
includes/gateways/stripe/vendor/composer/installed.json ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "composer/installers",
4
+ "version": "v1.0.25",
5
+ "version_normalized": "1.0.25.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/composer/installers.git",
9
+ "reference": "36e5b5843203d7f1cf6ffb0305a97e014387bd8e"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/36e5b5843203d7f1cf6ffb0305a97e014387bd8e",
14
+ "reference": "36e5b5843203d7f1cf6ffb0305a97e014387bd8e",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "composer-plugin-api": "^1.0"
19
+ },
20
+ "replace": {
21
+ "roundcube/plugin-installer": "*",
22
+ "shama/baton": "*"
23
+ },
24
+ "require-dev": {
25
+ "composer/composer": "1.0.*@dev",
26
+ "phpunit/phpunit": "4.1.*"
27
+ },
28
+ "time": "2016-04-13T19:46:30+00:00",
29
+ "type": "composer-plugin",
30
+ "extra": {
31
+ "class": "Composer\\Installers\\Plugin",
32
+ "branch-alias": {
33
+ "dev-master": "1.0-dev"
34
+ }
35
+ },
36
+ "installation-source": "dist",
37
+ "autoload": {
38
+ "psr-4": {
39
+ "Composer\\Installers\\": "src/Composer/Installers"
40
+ }
41
+ },
42
+ "notification-url": "https://packagist.org/downloads/",
43
+ "license": [
44
+ "MIT"
45
+ ],
46
+ "authors": [
47
+ {
48
+ "name": "Kyle Robinson Young",
49
+ "email": "kyle@dontkry.com",
50
+ "homepage": "https://github.com/shama"
51
+ }
52
+ ],
53
+ "description": "A multi-framework Composer library installer",
54
+ "homepage": "https://composer.github.io/installers/",
55
+ "keywords": [
56
+ "Craft",
57
+ "Dolibarr",
58
+ "Hurad",
59
+ "ImageCMS",
60
+ "MODX Evo",
61
+ "Mautic",
62
+ "OXID",
63
+ "SMF",
64
+ "Thelia",
65
+ "WolfCMS",
66
+ "agl",
67
+ "aimeos",
68
+ "annotatecms",
69
+ "bitrix",
70
+ "cakephp",
71
+ "chef",
72
+ "codeigniter",
73
+ "concrete5",
74
+ "croogo",
75
+ "dokuwiki",
76
+ "drupal",
77
+ "elgg",
78
+ "fuelphp",
79
+ "grav",
80
+ "installer",
81
+ "joomla",
82
+ "kohana",
83
+ "laravel",
84
+ "lithium",
85
+ "magento",
86
+ "mako",
87
+ "mediawiki",
88
+ "modulework",
89
+ "moodle",
90
+ "phpbb",
91
+ "piwik",
92
+ "ppi",
93
+ "puppet",
94
+ "roundcube",
95
+ "shopware",
96
+ "silverstripe",
97
+ "symfony",
98
+ "typo3",
99
+ "wordpress",
100
+ "zend",
101
+ "zikula"
102
+ ]
103
+ },
104
+ {
105
+ "name": "stripe/stripe-php",
106
+ "version": "v7.47.0",
107
+ "version_normalized": "7.47.0.0",
108
+ "source": {
109
+ "type": "git",
110
+ "url": "https://github.com/stripe/stripe-php.git",
111
+ "reference": "b51656cb398d081fcee53a76f6edb8fd5c1a5306"
112
+ },
113
+ "dist": {
114
+ "type": "zip",
115
+ "url": "https://api.github.com/repos/stripe/stripe-php/zipball/b51656cb398d081fcee53a76f6edb8fd5c1a5306",
116
+ "reference": "b51656cb398d081fcee53a76f6edb8fd5c1a5306",
117
+ "shasum": ""
118
+ },
119
+ "require": {
120
+ "ext-curl": "*",
121
+ "ext-json": "*",
122
+ "ext-mbstring": "*",
123
+ "php": ">=5.6.0"
124
+ },
125
+ "require-dev": {
126
+ "friendsofphp/php-cs-fixer": "2.16.1",
127
+ "php-coveralls/php-coveralls": "^2.1",
128
+ "phpunit/phpunit": "^5.7",
129
+ "squizlabs/php_codesniffer": "^3.3",
130
+ "symfony/process": "~3.4"
131
+ },
132
+ "time": "2020-08-13T22:35:56+00:00",
133
+ "type": "library",
134
+ "extra": {
135
+ "branch-alias": {
136
+ "dev-master": "2.0-dev"
137
+ }
138
+ },
139
+ "installation-source": "dist",
140
+ "autoload": {
141
+ "psr-4": {
142
+ "Stripe\\": "lib/"
143
+ }
144
+ },
145
+ "notification-url": "https://packagist.org/downloads/",
146
+ "license": [
147
+ "MIT"
148
+ ],
149
+ "authors": [
150
+ {
151
+ "name": "Stripe and contributors",
152
+ "homepage": "https://github.com/stripe/stripe-php/contributors"
153
+ }
154
+ ],
155
+ "description": "Stripe PHP Library",
156
+ "homepage": "https://stripe.com/",
157
+ "keywords": [
158
+ "api",
159
+ "payment processing",
160
+ "stripe"
161
+ ]
162
+ }
163
+ ]
includes/gateways/stripe/vendor/composer/installers/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2012 Kyle Robinson Young
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
includes/gateways/stripe/vendor/composer/installers/README.md ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # A Multi-Framework [Composer](http://getcomposer.org) Library Installer
2
+
3
+ [![Build Status](http://img.shields.io/travis/composer/installers.svg)](http://travis-ci.org/composer/installers)
4
+
5
+ This is for PHP package authors to require in their `composer.json`. It will
6
+ install their package to the correct location based on the specified package
7
+ type.
8
+
9
+ The goal of `installers` is to be a simple package type to install path map.
10
+ Users can also customize the install path per package and package authors can
11
+ modify the package name upon installing.
12
+
13
+ `installers` isn't intended on replacing all custom installers. If your
14
+ package requires special installation handling then by all means, create a
15
+ custom installer to handle it.
16
+
17
+ **Natively Supported Frameworks**:
18
+
19
+ The following frameworks natively work with Composer and will be
20
+ installed to the default `vendor` directory. `composer/installers`
21
+ is not needed to install packages with these frameworks:
22
+
23
+ * Aura
24
+ * Symfony2
25
+ * Yii
26
+ * Yii2
27
+
28
+ **Current Supported Package Types**:
29
+
30
+ > Stable types are marked as **bold**, this means that installation paths
31
+ > for those type will not be changed. Any adjustment for those types would
32
+ > require creation of brand new type that will cover required changes.
33
+
34
+ | Framework | Types
35
+ | --------- | -----
36
+ | Aimeos | `aimeos-extension`
37
+ | Asgard | `asgard-module`<br>`asgard-theme`
38
+ | AGL | `agl-module`
39
+ | Bonefish | `bonefish-package`
40
+ | AnnotateCms | `annotatecms-module`<br>`annotatecms-component`<br>`annotatecms-service`
41
+ | Bitrix | `bitrix-module`<br>`bitrix-component`<br>`bitrix-theme`
42
+ | CakePHP 2+ | **`cakephp-plugin`**
43
+ | Chef | `chef-cookbook`<br>`chef-role`
44
+ | CCFramework | `ccframework-ship`<br>`ccframework-theme`
45
+ | CodeIgniter | `codeigniter-library`<br>`codeigniter-third-party`<br>`codeigniter-module`
46
+ | concrete5 | `concrete5-block`<br>`concrete5-package`<br>`concrete5-theme`<br>`concrete5-update`
47
+ | Craft | `craft-plugin`
48
+ | Croogo | `croogo-plugin`<br>`croogo-theme`
49
+ | DokuWiki | `dokuwiki-plugin`<br>`dokuwiki-template`
50
+ | Dolibarr | `dolibarr-module`
51
+ | Drupal | <b>`drupal-core`<br>`drupal-module`<br>`drupal-theme`</b><br>`drupal-library`<br>`drupal-profile`<br>`drupal-drush`
52
+ | Elgg | `elgg-plugin`
53
+ | FuelPHP v1.x | `fuel-module`<br>`fuel-package`<br/>`fuel-theme`
54
+ | FuelPHP v2.x | `fuelphp-component`
55
+ | Grav | `grav-plugin`<br>`grav-theme`
56
+ | Hurad | `hurad-plugin`<br>`hurad-theme`
57
+ | ImageCMS | `imagecms-template`<br>`imagecms-module`<br>`imagecms-library`
58
+ | Joomla | `joomla-component`<br>`joomla-module`<br>`joomla-template`<br>`joomla-plugin`<br>`joomla-library`
59
+ | Kirby | **`kirby-plugin`**<br>`kirby-field`<br>`kirby-tag`
60
+ | KodiCMS | `kodicms-plugin`<br>`kodicms-media`
61
+ | Kohana | **`kohana-module`**
62
+ | Laravel | `laravel-library`
63
+ | Lithium | **`lithium-library`<br>`lithium-source`**
64
+ | Magento | `magento-library`<br>`magento-skin`<br>`magento-theme`
65
+ | Mako | `mako-package`
66
+ | Mautic | `mautic-plugin`<br>`mautic-theme`
67
+ | MODX Evo | `modxevo-snippet`<br>`modxevo-plugin`<br>`modxevo-module`<br>`modxevo-template`<br>`modxevo-lib`
68
+ | MediaWiki | `mediawiki-extension`
69
+ | October | **`october-module`<br>`october-plugin`<br>`october-theme`**
70
+ | OXID | `oxid-module`<br>`oxid-theme`<br>`oxid-out`
71
+ | MODULEWork | `modulework-module`
72
+ | Moodle | `moodle-*` (Please [check source](https://raw.githubusercontent.com/composer/installers/master/src/Composer/Installers/MoodleInstaller.php) for all supported types)
73
+ | Piwik | `piwik-plugin`
74
+ | phpBB | `phpbb-extension`<br>`phpbb-style`<br>`phpbb-language`
75
+ | Pimcore | `pimcore-plugin`
76
+ | PPI | **`ppi-module`**
77
+ | Puppet | `puppet-module`
78
+ | REDAXO | `redaxo-addon`
79
+ | Roundcube | `roundcube-plugin`
80
+ | shopware | `shopware-backend-plugin`<br/>`shopware-core-plugin`<br/>`shopware-frontend-plugin`<br/>`shopware-theme`
81
+ | SilverStripe | `silverstripe-module`<br>`silverstripe-theme`
82
+ | SMF | `smf-module`<br>`smf-theme`
83
+ | symfony1 | **`symfony1-plugin`**
84
+ | Tusk | `tusk-task`<br>`tusk-command`<br>`tusk-asset`
85
+ | TYPO3 Flow | `typo3-flow-package`<br>`typo3-flow-framework`<br>`typo3-flow-plugin`<br>`typo3-flow-site`<br>`typo3-flow-boilerplate`<br>`typo3-flow-build`
86
+ | TYPO3 CMS | `typo3-cms-extension` (Deprecated in this package, use the [TYPO3 CMS Installers](https://packagist.org/packages/typo3/cms-composer-installers) instead)
87
+ | Wolf CMS | `wolfcms-plugin`
88
+ | WordPress | <b>`wordpress-plugin`<br>`wordpress-theme`</b><br>`wordpress-muplugin`
89
+ | Zend | `zend-library`<br>`zend-extra`<br>`zend-module`
90
+ | Zikula | `zikula-module`<br>`zikula-theme`
91
+ | Prestashop | `prestashop-module`<br>`prestashop-theme`
92
+
93
+ ## Example `composer.json` File
94
+
95
+ This is an example for a CakePHP plugin. The only important parts to set in your
96
+ composer.json file are `"type": "cakephp-plugin"` which describes what your
97
+ package is and `"require": { "composer/installers": "~1.0" }` which tells composer
98
+ to load the custom installers.
99
+
100
+ ```json
101
+ {
102
+ "name": "you/ftp",
103
+ "type": "cakephp-plugin",
104
+ "require": {
105
+ "composer/installers": "~1.0"
106
+ }
107
+ }
108
+ ```
109
+
110
+ This would install your package to the `Plugin/Ftp/` folder of a CakePHP app
111
+ when a user runs `php composer.phar install`.
112
+
113
+ So submit your packages to [packagist.org](http://packagist.org)!
114
+
115
+ ## Custom Install Paths
116
+
117
+ If you are consuming a package that uses the `composer/installers` you can
118
+ override the install path with the following extra in your `composer.json`:
119
+
120
+ ```json
121
+ {
122
+ "extra": {
123
+ "installer-paths": {
124
+ "your/custom/path/{$name}/": ["shama/ftp", "vendor/package"]
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ A package type can have a custom installation path with a `type:` prefix.
131
+
132
+ ``` json
133
+ {
134
+ "extra": {
135
+ "installer-paths": {
136
+ "your/custom/path/{$name}/": ["type:wordpress-plugin"]
137
+ }
138
+ }
139
+ }
140
+ ```
141
+
142
+ You can also have the same vendor packages with a custom installation path by
143
+ using the `vendor:` prefix.
144
+
145
+ ``` json
146
+ {
147
+ "extra": {
148
+ "installer-paths": {
149
+ "your/custom/path/{$name}/": ["vendor:my_organization"]
150
+ }
151
+ }
152
+ }
153
+ ```
154
+
155
+ These would use your custom path for each of the listed packages. The available
156
+ variables to use in your paths are: `{$name}`, `{$vendor}`, `{$type}`.
157
+
158
+ ## Custom Install Names
159
+
160
+ If you're a package author and need your package to be named differently when
161
+ installed consider using the `installer-name` extra.
162
+
163
+ For example you have a package named `shama/cakephp-ftp` with the type
164
+ `cakephp-plugin`. Installing with `composer/installers` would install to the
165
+ path `Plugin/CakephpFtp`. Due to the strict naming conventions, you as a
166
+ package author actually need the package to be named and installed to
167
+ `Plugin/Ftp`. Using the following config within your **package** `composer.json`
168
+ will allow this:
169
+
170
+ ```json
171
+ {
172
+ "name": "shama/cakephp-ftp",
173
+ "type": "cakephp-plugin",
174
+ "extra": {
175
+ "installer-name": "Ftp"
176
+ }
177
+ }
178
+ ```
179
+
180
+ Please note the name entered into `installer-name` will be the final and will
181
+ not be inflected.
182
+
183
+ ## Contribute!
184
+
185
+ * [Fork and clone](https://help.github.com/articles/fork-a-repo).
186
+ * Run the command `php composer.phar install` to install the dependencies.
187
+ This will also install the dev dependencies. See [Composer](https://getcomposer.org/doc/03-cli.md#install).
188
+ * Use the command `phpunit` to run the tests. See [PHPUnit](http://phpunit.de).
189
+ * Create a branch, commit, push and send us a
190
+ [pull request](https://help.github.com/articles/using-pull-requests).
191
+
192
+ To ensure a consistent code base, you should make sure the code follows the
193
+ [Coding Standards](http://symfony.com/doc/2.0/contributing/code/standards.html)
194
+ which we borrowed from Symfony.
195
+
196
+ If you would like to help, please take a look at the list of
197
+ [issues](https://github.com/composer/installers/issues).
198
+
199
+ ### Should we allow dynamic package types or paths? No.
200
+ What are they? The ability for a package author to determine where a package
201
+ will be installed either through setting the path directly in their
202
+ `composer.json` or through a dynamic package type: `"type":
203
+ "framework-install-here"`.
204
+
205
+ It has been proposed many times. Even implemented once early on and then
206
+ removed. `installers` won't do this because it would allow a single package
207
+ author to wipe out entire folders without the user's consent. That user would
208
+ then come here to yell at us.
209
+
210
+ Anyone still wanting this capability should consider requiring https://github.com/oomphinc/composer-installers-extender.
includes/gateways/stripe/vendor/composer/installers/composer.json ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "composer/installers",
3
+ "type": "composer-plugin",
4
+ "license": "MIT",
5
+ "description": "A multi-framework Composer library installer",
6
+ "keywords": [
7
+ "installer",
8
+ "Aimeos",
9
+ "AGL",
10
+ "AnnotateCms",
11
+ "Bitrix",
12
+ "CakePHP",
13
+ "Chef",
14
+ "CodeIgniter",
15
+ "concrete5",
16
+ "Craft",
17
+ "Croogo",
18
+ "DokuWiki",
19
+ "Dolibarr",
20
+ "Drupal",
21
+ "Elgg",
22
+ "FuelPHP",
23
+ "Grav",
24
+ "Hurad",
25
+ "ImageCMS",
26
+ "Joomla",
27
+ "Kohana",
28
+ "Laravel",
29
+ "Lithium",
30
+ "Magento",
31
+ "Mako",
32
+ "Mautic",
33
+ "MODX Evo",
34
+ "MediaWiki",
35
+ "OXID",
36
+ "MODULEWork",
37
+ "Moodle",
38
+ "Piwik",
39
+ "phpBB",
40
+ "PPI",
41
+ "Puppet",
42
+ "Roundcube",
43
+ "shopware",
44
+ "SilverStripe",
45
+ "SMF",
46
+ "symfony",
47
+ "Thelia",
48
+ "TYPO3",
49
+ "WolfCMS",
50
+ "WordPress",
51
+ "Zend",
52
+ "Zikula"
53
+ ],
54
+ "homepage": "https://composer.github.io/installers/",
55
+ "authors": [
56
+ {
57
+ "name": "Kyle Robinson Young",
58
+ "email": "kyle@dontkry.com",
59
+ "homepage": "https://github.com/shama"
60
+ }
61
+ ],
62
+ "autoload": {
63
+ "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
64
+ },
65
+ "extra": {
66
+ "class": "Composer\\Installers\\Plugin",
67
+ "branch-alias": {
68
+ "dev-master": "1.0-dev"
69
+ }
70
+ },
71
+ "replace": {
72
+ "shama/baton": "*",
73
+ "roundcube/plugin-installer": "*"
74
+ },
75
+ "require": {
76
+ "composer-plugin-api": "^1.0"
77
+ },
78
+ "require-dev": {
79
+ "composer/composer": "1.0.*@dev",
80
+ "phpunit/phpunit": "4.1.*"
81
+ },
82
+ "scripts": {
83
+ "test": "phpunit"
84
+ }
85
+ }
includes/gateways/stripe/vendor/composer/installers/phpunit.xml.dist ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit backupGlobals="false"
4
+ backupStaticAttributes="false"
5
+ colors="true"
6
+ convertErrorsToExceptions="true"
7
+ convertNoticesToExceptions="true"
8
+ convertWarningsToExceptions="true"
9
+ processIsolation="false"
10
+ stopOnFailure="false"
11
+ syntaxCheck="false"
12
+ bootstrap="tests/bootstrap.php"
13
+ >
14
+ <testsuites>
15
+ <testsuite name="Installers Test Suite">
16
+ <directory>tests/Composer/Installers</directory>
17
+ </testsuite>
18
+ </testsuites>
19
+
20
+ <filter>
21
+ <whitelist>
22
+ <directory>src/Composer/Installers</directory>
23
+ </whitelist>
24
+ </filter>
25
+ </phpunit>
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AglInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AglInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'More/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name to CamelCase
12
+ */
13
+ public function inflectPackageVars($vars)
14
+ {
15
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
16
+ return strtoupper($matches[1]);
17
+ }, $vars['name']);
18
+
19
+ return $vars;
20
+ }
21
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AimeosInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'ext/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AnnotateCmsInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'addons/modules/{$name}/',
8
+ 'component' => 'addons/components/{$name}/',
9
+ 'service' => 'addons/services/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AsgardInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'Modules/{$name}/',
8
+ 'theme' => 'Themes/{$name}/'
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type asgard-module, cut off a trailing '-plugin' if present.
15
+ *
16
+ * For package type asgard-theme, cut off a trailing '-theme' if present.
17
+ *
18
+ */
19
+ public function inflectPackageVars($vars)
20
+ {
21
+ if ($vars['type'] === 'asgard-module') {
22
+ return $this->inflectPluginVars($vars);
23
+ }
24
+
25
+ if ($vars['type'] === 'asgard-theme') {
26
+ return $this->inflectThemeVars($vars);
27
+ }
28
+
29
+ return $vars;
30
+ }
31
+
32
+ protected function inflectPluginVars($vars)
33
+ {
34
+ $vars['name'] = ucfirst(preg_replace('/-module/', '', $vars['name']));
35
+
36
+ return $vars;
37
+ }
38
+
39
+ protected function inflectThemeVars($vars)
40
+ {
41
+ $vars['name'] = ucfirst(preg_replace('/-theme$/', '', $vars['name']));
42
+
43
+ return $vars;
44
+ }
45
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\IO\IOInterface;
5
+ use Composer\Composer;
6
+ use Composer\Package\PackageInterface;
7
+
8
+ abstract class BaseInstaller
9
+ {
10
+ protected $locations = array();
11
+ protected $composer;
12
+ protected $package;
13
+ protected $io;
14
+
15
+ /**
16
+ * Initializes base installer.
17
+ *
18
+ * @param PackageInterface $package
19
+ * @param Composer $composer
20
+ * @param IOInterface $io
21
+ */
22
+ public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
23
+ {
24
+ $this->composer = $composer;
25
+ $this->package = $package;
26
+ $this->io = $io;
27
+ }
28
+
29
+ /**
30
+ * Return the install path based on package type.
31
+ *
32
+ * @param PackageInterface $package
33
+ * @param string $frameworkType
34
+ * @return string
35
+ */
36
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
37
+ {
38
+ $type = $this->package->getType();
39
+
40
+ $prettyName = $this->package->getPrettyName();
41
+ if (strpos($prettyName, '/') !== false) {
42
+ list($vendor, $name) = explode('/', $prettyName);
43
+ } else {
44
+ $vendor = '';
45
+ $name = $prettyName;
46
+ }
47
+
48
+ $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
49
+
50
+ $extra = $package->getExtra();
51
+ if (!empty($extra['installer-name'])) {
52
+ $availableVars['name'] = $extra['installer-name'];
53
+ }
54
+
55
+ if ($this->composer->getPackage()) {
56
+ $extra = $this->composer->getPackage()->getExtra();
57
+ if (!empty($extra['installer-paths'])) {
58
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
59
+ if ($customPath !== false) {
60
+ return $this->templatePath($customPath, $availableVars);
61
+ }
62
+ }
63
+ }
64
+
65
+ $packageType = substr($type, strlen($frameworkType) + 1);
66
+ $locations = $this->getLocations();
67
+ if (!isset($locations[$packageType])) {
68
+ throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
69
+ }
70
+
71
+ return $this->templatePath($locations[$packageType], $availableVars);
72
+ }
73
+
74
+ /**
75
+ * For an installer to override to modify the vars per installer.
76
+ *
77
+ * @param array $vars
78
+ * @return array
79
+ */
80
+ public function inflectPackageVars($vars)
81
+ {
82
+ return $vars;
83
+ }
84
+
85
+ /**
86
+ * Gets the installer's locations
87
+ *
88
+ * @return array
89
+ */
90
+ public function getLocations()
91
+ {
92
+ return $this->locations;
93
+ }
94
+
95
+ /**
96
+ * Replace vars in a path
97
+ *
98
+ * @param string $path
99
+ * @param array $vars
100
+ * @return string
101
+ */
102
+ protected function templatePath($path, array $vars = array())
103
+ {
104
+ if (strpos($path, '{') !== false) {
105
+ extract($vars);
106
+ preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
107
+ if (!empty($matches[1])) {
108
+ foreach ($matches[1] as $var) {
109
+ $path = str_replace('{$' . $var . '}', $$var, $path);
110
+ }
111
+ }
112
+ }
113
+
114
+ return $path;
115
+ }
116
+
117
+ /**
118
+ * Search through a passed paths array for a custom install path.
119
+ *
120
+ * @param array $paths
121
+ * @param string $name
122
+ * @param string $type
123
+ * @param string $vendor = NULL
124
+ * @return string
125
+ */
126
+ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
127
+ {
128
+ foreach ($paths as $path => $names) {
129
+ if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
130
+ return $path;
131
+ }
132
+ }
133
+
134
+ return false;
135
+ }
136
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ use Composer\Util\Filesystem;
6
+
7
+ /**
8
+ * Installer for Bitrix Framework. Supported types of extensions:
9
+ * - `bitrix-module` — copy the module to directory `bitrix/modules/` directory.
10
+ * - `bitrix-component` — copy the component to directory `bitrix/components/`.
11
+ * - `bitrix-template` — copy the template to directory `bitrix/templates/`.
12
+ *
13
+ * You can set custom path to directory with Bitrix kernel in `composer.json`:
14
+ *
15
+ * ```json
16
+ * {
17
+ * "extra": {
18
+ * "bitrix-dir": "s1/bitrix"
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * @author Nik Samokhvalov <nik@samokhvalov.info>
24
+ * @author Denis Kulichkin <onexhovia@gmail.com>
25
+ */
26
+ class BitrixInstaller extends BaseInstaller
27
+ {
28
+ protected $locations = array(
29
+ 'module' => '{$bitrix_dir}/modules/{$name}/',
30
+ 'component' => '{$bitrix_dir}/components/{$name}/',
31
+ 'theme' => '{$bitrix_dir}/templates/{$name}/',
32
+ );
33
+
34
+ /**
35
+ * @var array Storage for informations about duplicates at all the time of installation packages.
36
+ */
37
+ private static $checkedDuplicates = array();
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ */
42
+ public function inflectPackageVars($vars)
43
+ {
44
+ if ($this->composer->getPackage()) {
45
+ $extra = $this->composer->getPackage()->getExtra();
46
+
47
+ if (isset($extra['bitrix-dir'])) {
48
+ $vars['bitrix_dir'] = $extra['bitrix-dir'];
49
+ }
50
+ }
51
+
52
+ if (!isset($vars['bitrix_dir'])) {
53
+ $vars['bitrix_dir'] = 'bitrix';
54
+ }
55
+
56
+ return parent::inflectPackageVars($vars);
57
+ }
58
+
59
+ /**
60
+ * {@inheritdoc}
61
+ */
62
+ protected function templatePath($path, array $vars = array())
63
+ {
64
+ $templatePath = parent::templatePath($path, $vars);
65
+ $this->checkDuplicates($templatePath, $vars);
66
+
67
+ return $templatePath;
68
+ }
69
+
70
+ /**
71
+ * Duplicates search packages.
72
+ *
73
+ * @param string $path
74
+ * @param array $vars
75
+ */
76
+ protected function checkDuplicates($path, array $vars = array())
77
+ {
78
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
79
+ $localDir = explode('/', $vars['bitrix_dir']);
80
+ array_pop($localDir);
81
+ $localDir[] = 'local';
82
+ $localDir = implode('/', $localDir);
83
+
84
+ $oldPath = str_replace(
85
+ array('{$bitrix_dir}', '{$name}'),
86
+ array($localDir, $vars['name']),
87
+ $this->locations[$packageType]
88
+ );
89
+
90
+ if (in_array($oldPath, static::$checkedDuplicates)) {
91
+ return;
92
+ }
93
+
94
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
95
+
96
+ $this->io->writeError(' <error>Duplication of packages:</error>');
97
+ $this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
98
+
99
+ while (true) {
100
+ switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
101
+ case 'y':
102
+ $fs = new Filesystem();
103
+ $fs->removeDirectory($oldPath);
104
+ break 2;
105
+
106
+ case 'n':
107
+ break 2;
108
+
109
+ case '?':
110
+ default:
111
+ $this->io->writeError(array(
112
+ ' y - delete package ' . $oldPath . ' and to continue with the installation',
113
+ ' n - don\'t delete and to continue with the installation',
114
+ ));
115
+ $this->io->writeError(' ? - print help');
116
+ break;
117
+ }
118
+ }
119
+ }
120
+
121
+ static::$checkedDuplicates[] = $oldPath;
122
+ }
123
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class BonefishInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'Packages/{$vendor}/{$name}/'
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\DependencyResolver\Pool;
5
+ use Composer\Package\PackageInterface;
6
+
7
+ class CakePHPInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'plugin' => 'Plugin/{$name}/',
11
+ );
12
+
13
+ /**
14
+ * Format package name to CamelCase
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
19
+ return $vars;
20
+ }
21
+
22
+ $nameParts = explode('/', $vars['name']);
23
+ foreach ($nameParts as &$value) {
24
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
25
+ $value = str_replace(array('-', '_'), ' ', $value);
26
+ $value = str_replace(' ', '', ucwords($value));
27
+ }
28
+ $vars['name'] = implode('/', $nameParts);
29
+
30
+ return $vars;
31
+ }
32
+
33
+ /**
34
+ * Change the default plugin location when cakephp >= 3.0
35
+ */
36
+ public function getLocations()
37
+ {
38
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
39
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
40
+ }
41
+ return $this->locations;
42
+ }
43
+
44
+ /**
45
+ * Check if CakePHP version matches against a version
46
+ *
47
+ * @param string $matcher
48
+ * @param string $version
49
+ * @return bool
50
+ */
51
+ protected function matchesCakeVersion($matcher, $version)
52
+ {
53
+ if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
54
+ $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
55
+ $constraintClass = 'Composer\Semver\Constraint\Constraint';
56
+ } else {
57
+ $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
58
+ $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
59
+ }
60
+
61
+ $repositoryManager = $this->composer->getRepositoryManager();
62
+ if ($repositoryManager) {
63
+ $repos = $repositoryManager->getLocalRepository();
64
+ if (!$repos) {
65
+ return false;
66
+ }
67
+ $cake3 = new $multiClass(array(
68
+ new $constraintClass($matcher, $version),
69
+ new $constraintClass('!=', '9999999-dev'),
70
+ ));
71
+ $pool = new Pool('dev');
72
+ $pool->addRepository($repos);
73
+ $packages = $pool->whatProvides('cakephp/cakephp');
74
+ foreach ($packages as $package) {
75
+ $installed = new $constraintClass('=', $package->getVersion());
76
+ if ($cake3->matches($installed)) {
77
+ return true;
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ChefInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'cookbook' => 'Chef/{$vendor}/{$name}/',
8
+ 'role' => 'Chef/roles/{$name}/',
9
+ );
10
+ }
11
+
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ClanCatsFrameworkInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'ship' => 'CCF/orbit/{$name}/',
8
+ 'theme' => 'CCF/app/themes/{$name}/',
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CodeIgniterInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'application/libraries/{$name}/',
8
+ 'third-party' => 'application/third_party/{$name}/',
9
+ 'module' => 'application/modules/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class Concrete5Installer extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'block' => 'blocks/{$name}/',
8
+ 'package' => 'packages/{$name}/',
9
+ 'theme' => 'themes/{$name}/',
10
+ 'update' => 'updates/{$name}/',
11
+ );
12
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Installer for Craft Plugins
6
+ */
7
+ class CraftInstaller extends BaseInstaller
8
+ {
9
+ const NAME_PREFIX = 'craft';
10
+ const NAME_SUFFIX = 'plugin';
11
+
12
+ protected $locations = array(
13
+ 'plugin' => 'craft/plugins/{$name}/',
14
+ );
15
+
16
+ /**
17
+ * Strip `craft-` prefix and/or `-plugin` suffix from package names
18
+ *
19
+ * @param array $vars
20
+ *
21
+ * @return array
22
+ */
23
+ final public function inflectPackageVars($vars)
24
+ {
25
+ return $this->inflectPluginVars($vars);
26
+ }
27
+
28
+ private function inflectPluginVars($vars)
29
+ {
30
+ $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
31
+ $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
32
+
33
+ return $vars;
34
+ }
35
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CroogoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'Plugin/{$name}/',
8
+ 'theme' => 'View/Themed/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name to CamelCase
13
+ */
14
+ public function inflectPackageVars($vars)
15
+ {
16
+ $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
17
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
+
19
+ return $vars;
20
+ }
21
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class DokuWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'lib/plugins/{$name}/',
8
+ 'template' => 'lib/tpl/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
15
+ * or leading dokuwiki_ if present.
16
+ *
17
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+
23
+ if ($vars['type'] === 'dokuwiki-plugin') {
24
+ return $this->inflectPluginVars($vars);
25
+ }
26
+
27
+ if ($vars['type'] === 'dokuwiki-template') {
28
+ return $this->inflectTemplateVars($vars);
29
+ }
30
+
31
+ return $vars;
32
+ }
33
+
34
+ protected function inflectPluginVars($vars)
35
+ {
36
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
37
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
38
+
39
+ return $vars;
40
+ }
41
+
42
+ protected function inflectTemplateVars($vars)
43
+ {
44
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
45
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
46
+
47
+ return $vars;
48
+ }
49
+
50
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Class DolibarrInstaller
6
+ *
7
+ * @package Composer\Installers
8
+ * @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9
+ */
10
+ class DolibarrInstaller extends BaseInstaller
11
+ {
12
+ //TODO: Add support for scripts and themes
13
+ protected $locations = array(
14
+ 'module' => 'htdocs/custom/{$name}/',
15
+ );
16
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class DrupalInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'core' => 'core/',
8
+ 'module' => 'modules/{$name}/',
9
+ 'theme' => 'themes/{$name}/',
10
+ 'library' => 'libraries/{$name}/',
11
+ 'profile' => 'profiles/{$name}/',
12
+ 'drush' => 'drush/{$name}/',
13
+ 'custom-theme' => 'themes/custom/{$name}/',
14
+ 'custom-module' => 'modules/custom/{$name}',
15
+ );
16
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ElggInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'mod/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class FuelInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'fuel/app/modules/{$name}/',
8
+ 'package' => 'fuel/packages/{$name}/',
9
+ 'theme' => 'fuel/app/themes/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class FuelphpInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'component' => 'components/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/GravInstaller.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class GravInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'user/plugins/{$name}/',
8
+ 'theme' => 'user/themes/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name
13
+ *
14
+ * @param array $vars
15
+ *
16
+ * @return array
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ $restrictedWords = implode('|', array_keys($this->locations));
21
+
22
+ $vars['name'] = strtolower($vars['name']);
23
+ $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
24
+ '$1',
25
+ $vars['name']
26
+ );
27
+
28
+ return $vars;
29
+ }
30
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class HuradInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ 'theme' => 'plugins/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name to CamelCase
13
+ */
14
+ public function inflectPackageVars($vars)
15
+ {
16
+ $nameParts = explode('/', $vars['name']);
17
+ foreach ($nameParts as &$value) {
18
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
19
+ $value = str_replace(array('-', '_'), ' ', $value);
20
+ $value = str_replace(' ', '', ucwords($value));
21
+ }
22
+ $vars['name'] = implode('/', $nameParts);
23
+ return $vars;
24
+ }
25
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ImageCMSInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'template' => 'templates/{$name}/',
8
+ 'module' => 'application/modules/{$name}/',
9
+ 'library' => 'application/libraries/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Installer.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\IO\IOInterface;
5
+ use Composer\Installer\LibraryInstaller;
6
+ use Composer\Package\PackageInterface;
7
+ use Composer\Repository\InstalledRepositoryInterface;
8
+
9
+ class Installer extends LibraryInstaller
10
+ {
11
+ /**
12
+ * Package types to installer class map
13
+ *
14
+ * @var array
15
+ */
16
+ private $supportedTypes = array(
17
+ 'aimeos' => 'AimeosInstaller',
18
+ 'asgard' => 'AsgardInstaller',
19
+ 'agl' => 'AglInstaller',
20
+ 'annotatecms' => 'AnnotateCmsInstaller',
21
+ 'bitrix' => 'BitrixInstaller',
22
+ 'bonefish' => 'BonefishInstaller',
23
+ 'cakephp' => 'CakePHPInstaller',
24
+ 'chef' => 'ChefInstaller',
25
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
26
+ 'codeigniter' => 'CodeIgniterInstaller',
27
+ 'concrete5' => 'Concrete5Installer',
28
+ 'craft' => 'CraftInstaller',
29
+ 'croogo' => 'CroogoInstaller',
30
+ 'dokuwiki' => 'DokuWikiInstaller',
31
+ 'dolibarr' => 'DolibarrInstaller',
32
+ 'drupal' => 'DrupalInstaller',
33
+ 'elgg' => 'ElggInstaller',
34
+ 'fuel' => 'FuelInstaller',
35
+ 'fuelphp' => 'FuelphpInstaller',
36
+ 'grav' => 'GravInstaller',
37
+ 'hurad' => 'HuradInstaller',
38
+ 'imagecms' => 'ImageCMSInstaller',
39
+ 'joomla' => 'JoomlaInstaller',
40
+ 'kirby' => 'KirbyInstaller',
41
+ 'kodicms' => 'KodiCMSInstaller',
42
+ 'kohana' => 'KohanaInstaller',
43
+ 'laravel' => 'LaravelInstaller',
44
+ 'lithium' => 'LithiumInstaller',
45
+ 'magento' => 'MagentoInstaller',
46
+ 'mako' => 'MakoInstaller',
47
+ 'mautic' => 'MauticInstaller',
48
+ 'mediawiki' => 'MediaWikiInstaller',
49
+ 'microweber' => 'MicroweberInstaller',
50
+ 'modulework' => 'MODULEWorkInstaller',
51
+ 'modxevo' => 'MODXEvoInstaller',
52
+ 'moodle' => 'MoodleInstaller',
53
+ 'october' => 'OctoberInstaller',
54
+ 'oxid' => 'OxidInstaller',
55
+ 'phpbb' => 'PhpBBInstaller',
56
+ 'pimcore' => 'PimcoreInstaller',
57
+ 'piwik' => 'PiwikInstaller',
58
+ 'ppi' => 'PPIInstaller',
59
+ 'puppet' => 'PuppetInstaller',
60
+ 'redaxo' => 'RedaxoInstaller',
61
+ 'roundcube' => 'RoundcubeInstaller',
62
+ 'shopware' => 'ShopwareInstaller',
63
+ 'silverstripe' => 'SilverStripeInstaller',
64
+ 'smf' => 'SMFInstaller',
65
+ 'symfony1' => 'Symfony1Installer',
66
+ 'thelia' => 'TheliaInstaller',
67
+ 'tusk' => 'TuskInstaller',
68
+ 'typo3-cms' => 'TYPO3CmsInstaller',
69
+ 'typo3-flow' => 'TYPO3FlowInstaller',
70
+ 'whmcs' => 'WHMCSInstaller',
71
+ 'wolfcms' => 'WolfCMSInstaller',
72
+ 'wordpress' => 'WordPressInstaller',
73
+ 'zend' => 'ZendInstaller',
74
+ 'zikula' => 'ZikulaInstaller',
75
+ 'prestashop' => 'PrestashopInstaller'
76
+ );
77
+
78
+ /**
79
+ * {@inheritDoc}
80
+ */
81
+ public function getInstallPath(PackageInterface $package)
82
+ {
83
+ $type = $package->getType();
84
+ $frameworkType = $this->findFrameworkType($type);
85
+
86
+ if ($frameworkType === false) {
87
+ throw new \InvalidArgumentException(
88
+ 'Sorry the package type of this package is not yet supported.'
89
+ );
90
+ }
91
+
92
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
93
+ $installer = new $class($package, $this->composer, $this->getIO());
94
+
95
+ return $installer->getInstallPath($package, $frameworkType);
96
+ }
97
+
98
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
99
+ {
100
+ if (!$repo->hasPackage($package)) {
101
+ throw new \InvalidArgumentException('Package is not installed: '.$package);
102
+ }
103
+
104
+ $repo->removePackage($package);
105
+
106
+ $installPath = $this->getInstallPath($package);
107
+ $this->io->write(sprintf('Deleting %s - %s', $installPath, $this->filesystem->removeDirectory($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
108
+ }
109
+
110
+ /**
111
+ * {@inheritDoc}
112
+ */
113
+ public function supports($packageType)
114
+ {
115
+ $frameworkType = $this->findFrameworkType($packageType);
116
+
117
+ if ($frameworkType === false) {
118
+ return false;
119
+ }
120
+
121
+ $locationPattern = $this->getLocationPattern($frameworkType);
122
+
123
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
124
+ }
125
+
126
+ /**
127
+ * Finds a supported framework type if it exists and returns it
128
+ *
129
+ * @param string $type
130
+ * @return string
131
+ */
132
+ protected function findFrameworkType($type)
133
+ {
134
+ $frameworkType = false;
135
+
136
+ krsort($this->supportedTypes);
137
+
138
+ foreach ($this->supportedTypes as $key => $val) {
139
+ if ($key === substr($type, 0, strlen($key))) {
140
+ $frameworkType = substr($type, 0, strlen($key));
141
+ break;
142
+ }
143
+ }
144
+
145
+ return $frameworkType;
146
+ }
147
+
148
+ /**
149
+ * Get the second part of the regular expression to check for support of a
150
+ * package type
151
+ *
152
+ * @param string $frameworkType
153
+ * @return string
154
+ */
155
+ protected function getLocationPattern($frameworkType)
156
+ {
157
+ $pattern = false;
158
+ if (!empty($this->supportedTypes[$frameworkType])) {
159
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
160
+ /** @var BaseInstaller $framework */
161
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
162
+ $locations = array_keys($framework->getLocations());
163
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
164
+ }
165
+
166
+ return $pattern ? : '(\w+)';
167
+ }
168
+
169
+ /**
170
+ * Get I/O object
171
+ *
172
+ * @return IOInterface
173
+ */
174
+ private function getIO()
175
+ {
176
+ return $this->io;
177
+ }
178
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class JoomlaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'component' => 'components/{$name}/',
8
+ 'module' => 'modules/{$name}/',
9
+ 'template' => 'templates/{$name}/',
10
+ 'plugin' => 'plugins/{$name}/',
11
+ 'library' => 'libraries/{$name}/',
12
+ );
13
+
14
+ // TODO: Add inflector for mod_ and com_ names
15
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KirbyInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'site/plugins/{$name}/',
8
+ 'field' => 'site/fields/{$name}/',
9
+ 'tag' => 'site/tags/{$name}/'
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KodiCMSInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'cms/plugins/{$name}/',
8
+ 'media' => 'cms/media/vendor/{$name}/'
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KohanaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LaravelInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'libraries/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LithiumInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'libraries/{$name}/',
8
+ 'source' => 'libraries/_source/{$name}/',
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MODULEWorkInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * An installer to handle MODX Evolution specifics when installing packages.
6
+ */
7
+ class MODXEvoInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'snippet' => 'assets/snippets/{$name}/',
11
+ 'plugin' => 'assets/plugins/{$name}/',
12
+ 'module' => 'assets/modules/{$name}/',
13
+ 'template' => 'assets/templates/{$name}/',
14
+ 'lib' => 'assets/lib/{$name}/'
15
+ );
16
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MagentoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'theme' => 'app/design/frontend/{$name}/',
8
+ 'skin' => 'skin/frontend/default/{$name}/',
9
+ 'library' => 'lib/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MakoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'app/packages/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MauticInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ 'theme' => 'themes/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name of mautic-plugins to CamelCase
13
+ */
14
+ public function inflectPackageVars($vars)
15
+ {
16
+ if ($vars['type'] == 'mautic-plugin') {
17
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
18
+ return strtoupper($matches[0][1]);
19
+ }, ucfirst($vars['name']));
20
+ }
21
+
22
+ return $vars;
23
+ }
24
+
25
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MediaWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'extensions/{$name}/',
8
+ 'skin' => 'skins/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
15
+ * to CamelCase keeping existing uppercase chars.
16
+ *
17
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+
23
+ if ($vars['type'] === 'mediawiki-extension') {
24
+ return $this->inflectExtensionVars($vars);
25
+ }
26
+
27
+ if ($vars['type'] === 'mediawiki-skin') {
28
+ return $this->inflectSkinVars($vars);
29
+ }
30
+
31
+ return $vars;
32
+ }
33
+
34
+ protected function inflectExtensionVars($vars)
35
+ {
36
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
37
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
38
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
39
+
40
+ return $vars;
41
+ }
42
+
43
+ protected function inflectSkinVars($vars)
44
+ {
45
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
46
+
47
+ return $vars;
48
+ }
49
+
50
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MicroweberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'userfiles/modules/{$name}/',
8
+ 'module-skin' => 'userfiles/modules/{$name}/templates/',
9
+ 'template' => 'userfiles/templates/{$name}/',
10
+ 'element' => 'userfiles/elements/{$name}/',
11
+ 'vendor' => 'vendor/{$name}/',
12
+ 'components' => 'components/{$name}/'
13
+ );
14
+
15
+ /**
16
+ * Format package name.
17
+ *
18
+ * For package type microweber-module, cut off a trailing '-module' if present
19
+ *
20
+ * For package type microweber-template, cut off a trailing '-template' if present.
21
+ *
22
+ */
23
+ public function inflectPackageVars($vars)
24
+ {
25
+ if ($vars['type'] === 'microweber-template') {
26
+ return $this->inflectTemplateVars($vars);
27
+ }
28
+ if ($vars['type'] === 'microweber-templates') {
29
+ return $this->inflectTemplatesVars($vars);
30
+ }
31
+ if ($vars['type'] === 'microweber-core') {
32
+ return $this->inflectCoreVars($vars);
33
+ }
34
+ if ($vars['type'] === 'microweber-adapter') {
35
+ return $this->inflectCoreVars($vars);
36
+ }
37
+ if ($vars['type'] === 'microweber-module') {
38
+ return $this->inflectModuleVars($vars);
39
+ }
40
+ if ($vars['type'] === 'microweber-modules') {
41
+ return $this->inflectModulesVars($vars);
42
+ }
43
+ if ($vars['type'] === 'microweber-skin') {
44
+ return $this->inflectSkinVars($vars);
45
+ }
46
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
47
+ return $this->inflectElementVars($vars);
48
+ }
49
+
50
+ return $vars;
51
+ }
52
+
53
+ protected function inflectTemplateVars($vars)
54
+ {
55
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
56
+ $vars['name'] = preg_replace('/template-$/', '', $vars['name']);
57
+
58
+ return $vars;
59
+ }
60
+
61
+ protected function inflectTemplatesVars($vars)
62
+ {
63
+ $vars['name'] = preg_replace('/-templates$/', '', $vars['name']);
64
+ $vars['name'] = preg_replace('/templates-$/', '', $vars['name']);
65
+
66
+ return $vars;
67
+ }
68
+
69
+ protected function inflectCoreVars($vars)
70
+ {
71
+ $vars['name'] = preg_replace('/-providers$/', '', $vars['name']);
72
+ $vars['name'] = preg_replace('/-provider$/', '', $vars['name']);
73
+ $vars['name'] = preg_replace('/-adapter$/', '', $vars['name']);
74
+
75
+ return $vars;
76
+ }
77
+
78
+ protected function inflectModuleVars($vars)
79
+ {
80
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
81
+ $vars['name'] = preg_replace('/module-$/', '', $vars['name']);
82
+
83
+ return $vars;
84
+ }
85
+
86
+ protected function inflectModulesVars($vars)
87
+ {
88
+ $vars['name'] = preg_replace('/-modules$/', '', $vars['name']);
89
+ $vars['name'] = preg_replace('/modules-$/', '', $vars['name']);
90
+
91
+ return $vars;
92
+ }
93
+
94
+ protected function inflectSkinVars($vars)
95
+ {
96
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
97
+ $vars['name'] = preg_replace('/skin-$/', '', $vars['name']);
98
+
99
+ return $vars;
100
+ }
101
+
102
+ protected function inflectElementVars($vars)
103
+ {
104
+ $vars['name'] = preg_replace('/-elements$/', '', $vars['name']);
105
+ $vars['name'] = preg_replace('/elements-$/', '', $vars['name']);
106
+ $vars['name'] = preg_replace('/-element$/', '', $vars['name']);
107
+ $vars['name'] = preg_replace('/element-$/', '', $vars['name']);
108
+
109
+ return $vars;
110
+ }
111
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MoodleInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'mod' => 'mod/{$name}/',
8
+ 'admin_report' => 'admin/report/{$name}/',
9
+ 'atto' => 'lib/editor/atto/plugins/{$name}/',
10
+ 'tool' => 'admin/tool/{$name}/',
11
+ 'assignment' => 'mod/assignment/type/{$name}/',
12
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
13
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
14
+ 'auth' => 'auth/{$name}/',
15
+ 'availability' => 'availability/condition/{$name}/',
16
+ 'block' => 'blocks/{$name}/',
17
+ 'booktool' => 'mod/book/tool/{$name}/',
18
+ 'cachestore' => 'cache/stores/{$name}/',
19
+ 'cachelock' => 'cache/locks/{$name}/',
20
+ 'calendartype' => 'calendar/type/{$name}/',
21
+ 'format' => 'course/format/{$name}/',
22
+ 'coursereport' => 'course/report/{$name}/',
23
+ 'datafield' => 'mod/data/field/{$name}/',
24
+ 'datapreset' => 'mod/data/preset/{$name}/',
25
+ 'editor' => 'lib/editor/{$name}/',
26
+ 'enrol' => 'enrol/{$name}/',
27
+ 'filter' => 'filter/{$name}/',
28
+ 'gradeexport' => 'grade/export/{$name}/',
29
+ 'gradeimport' => 'grade/import/{$name}/',
30
+ 'gradereport' => 'grade/report/{$name}/',
31
+ 'gradingform' => 'grade/grading/form/{$name}/',
32
+ 'local' => 'local/{$name}/',
33
+ 'logstore' => 'admin/tool/log/store/{$name}/',
34
+ 'ltisource' => 'mod/lti/source/{$name}/',
35
+ 'ltiservice' => 'mod/lti/service/{$name}/',
36
+ 'message' => 'message/output/{$name}/',
37
+ 'mnetservice' => 'mnet/service/{$name}/',
38
+ 'plagiarism' => 'plagiarism/{$name}/',
39
+ 'portfolio' => 'portfolio/{$name}/',
40
+ 'qbehaviour' => 'question/behaviour/{$name}/',
41
+ 'qformat' => 'question/format/{$name}/',
42
+ 'qtype' => 'question/type/{$name}/',
43
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
44
+ 'quiz' => 'mod/quiz/report/{$name}/',
45
+ 'report' => 'report/{$name}/',
46
+ 'repository' => 'repository/{$name}/',
47
+ 'scormreport' => 'mod/scorm/report/{$name}/',
48
+ 'theme' => 'theme/{$name}/',
49
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
50
+ 'profilefield' => 'user/profile/field/{$name}/',
51
+ 'webservice' => 'webservice/{$name}/',
52
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
53
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
54
+ 'workshopform' => 'mod/workshop/form/{$name}/'
55
+ );
56
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class OctoberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
9
+ 'theme' => 'themes/{$name}/'
10
+ );
11
+
12
+ /**
13
+ * Format package name.
14
+ *
15
+ * For package type october-plugin, cut off a trailing '-plugin' if present.
16
+ *
17
+ * For package type october-theme, cut off a trailing '-theme' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+ if ($vars['type'] === 'october-plugin') {
23
+ return $this->inflectPluginVars($vars);
24
+ }
25
+
26
+ if ($vars['type'] === 'october-theme') {
27
+ return $this->inflectThemeVars($vars);
28
+ }
29
+
30
+ return $vars;
31
+ }
32
+
33
+ protected function inflectPluginVars($vars)
34
+ {
35
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
36
+
37
+ return $vars;
38
+ }
39
+
40
+ protected function inflectThemeVars($vars)
41
+ {
42
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
43
+
44
+ return $vars;
45
+ }
46
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Package\PackageInterface;
5
+
6
+ class OxidInstaller extends BaseInstaller
7
+ {
8
+ const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
9
+
10
+ protected $locations = array(
11
+ 'module' => 'modules/{$name}/',
12
+ 'theme' => 'application/views/{$name}/',
13
+ 'out' => 'out/{$name}/',
14
+ );
15
+
16
+ /**
17
+ * getInstallPath
18
+ *
19
+ * @param PackageInterface $package
20
+ * @param string $frameworkType
21
+ * @return void
22
+ */
23
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
+ {
25
+ $installPath = parent::getInstallPath($package, $frameworkType);
26
+ $type = $this->package->getType();
27
+ if ($type === 'oxid-module') {
28
+ $this->prepareVendorDirectory($installPath);
29
+ }
30
+ return $installPath;
31
+ }
32
+
33
+ /**
34
+ * prepareVendorDirectory
35
+ *
36
+ * Makes sure there is a vendormetadata.php file inside
37
+ * the vendor folder if there is a vendor folder.
38
+ *
39
+ * @param string $installPath
40
+ * @return void
41
+ */
42
+ protected function prepareVendorDirectory($installPath)
43
+ {
44
+ $matches = '';
45
+ $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
46
+ if (!$hasVendorDirectory) {
47
+ return;
48
+ }
49
+
50
+ $vendorDirectory = $matches['vendor'];
51
+ $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
52
+ if (!file_exists($vendorPath)) {
53
+ mkdir($vendorPath, 0755, true);
54
+ }
55
+
56
+ $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
57
+ touch($vendorMetaDataPath);
58
+ }
59
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PPIInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PhpBBInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'ext/{$vendor}/{$name}/',
8
+ 'language' => 'language/{$name}/',
9
+ 'style' => 'styles/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PimcoreInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name to CamelCase
12
+ */
13
+ public function inflectPackageVars($vars)
14
+ {
15
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
16
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
17
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
+
19
+ return $vars;
20
+ }
21
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Class PiwikInstaller
6
+ *
7
+ * @package Composer\Installers
8
+ */
9
+ class PiwikInstaller extends BaseInstaller
10
+ {
11
+ /**
12
+ * @var array
13
+ */
14
+ protected $locations = array(
15
+ 'plugin' => 'plugins/{$name}/',
16
+ );
17
+
18
+ /**
19
+ * Format package name to CamelCase
20
+ * @param array $vars
21
+ *
22
+ * @return array
23
+ */
24
+ public function inflectPackageVars($vars)
25
+ {
26
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
27
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
28
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
29
+
30
+ return $vars;
31
+ }
32
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Plugin.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ use Composer\Composer;
6
+ use Composer\IO\IOInterface;
7
+ use Composer\Plugin\PluginInterface;
8
+
9
+ class Plugin implements PluginInterface
10
+ {
11
+
12
+ public function activate(Composer $composer, IOInterface $io)
13
+ {
14
+ $installer = new Installer($io, $composer);
15
+ $composer->getInstallationManager()->addInstaller($installer);
16
+ }
17
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PrestashopInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ 'theme' => 'themes/{$name}/',
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class PuppetInstaller extends BaseInstaller
6
+ {
7
+
8
+ protected $locations = array(
9
+ 'module' => 'modules/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class RedaxoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'addon' => 'redaxo/include/addons/{$name}/',
8
+ 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class RoundcubeInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Lowercase name and changes the name to a underscores
12
+ *
13
+ * @param array $vars
14
+ * @return array
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
19
+
20
+ return $vars;
21
+ }
22
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class SMFInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'Sources/{$name}/',
8
+ 'theme' => 'Themes/{$name}/',
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Plugin/theme installer for shopware
6
+ * @author Benjamin Boit
7
+ */
8
+ class ShopwareInstaller extends BaseInstaller
9
+ {
10
+ protected $locations = array(
11
+ 'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/',
12
+ 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
13
+ 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
14
+ 'theme' => 'templates/{$name}/'
15
+ );
16
+
17
+ /**
18
+ * Transforms the names
19
+ * @param array $vars
20
+ * @return array
21
+ */
22
+ public function inflectPackageVars($vars)
23
+ {
24
+ if ($vars['type'] === 'shopware-theme') {
25
+ return $this->correctThemeName($vars);
26
+ } else {
27
+ return $this->correctPluginName($vars);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Changes the name to a camelcased combination of vendor and name
33
+ * @param array $vars
34
+ * @return array
35
+ */
36
+ private function correctPluginName($vars)
37
+ {
38
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
39
+ return strtoupper($matches[0][1]);
40
+ }, $vars['name']);
41
+
42
+ $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
43
+
44
+ return $vars;
45
+ }
46
+
47
+ /**
48
+ * Changes the name to a underscore separated name
49
+ * @param array $vars
50
+ * @return array
51
+ */
52
+ private function correctThemeName($vars)
53
+ {
54
+ $vars['name'] = str_replace('-', '_', $vars['name']);
55
+
56
+ return $vars;
57
+ }
58
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Package\PackageInterface;
5
+
6
+ class SilverStripeInstaller extends BaseInstaller
7
+ {
8
+ protected $locations = array(
9
+ 'module' => '{$name}/',
10
+ 'theme' => 'themes/{$name}/',
11
+ );
12
+
13
+ /**
14
+ * Return the install path based on package type.
15
+ *
16
+ * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
17
+ * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
18
+ *
19
+ * @param PackageInterface $package
20
+ * @param string $frameworkType
21
+ * @return string
22
+ */
23
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
+ {
25
+ if (
26
+ $package->getName() == 'silverstripe/framework'
27
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
28
+ && version_compare($package->getVersion(), '2.999.999') < 0
29
+ ) {
30
+ return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
31
+ } else {
32
+ return parent::getInstallPath($package, $frameworkType);
33
+ }
34
+
35
+ }
36
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Plugin installer for symfony 1.x
6
+ *
7
+ * @author Jérôme Tamarelle <jerome@tamarelle.net>
8
+ */
9
+ class Symfony1Installer extends BaseInstaller
10
+ {
11
+ protected $locations = array(
12
+ 'plugin' => 'plugins/{$name}/',
13
+ );
14
+
15
+ /**
16
+ * Format package name to CamelCase
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
21
+ return strtoupper($matches[0][1]);
22
+ }, $vars['name']);
23
+
24
+ return $vars;
25
+ }
26
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Extension installer for TYPO3 CMS
6
+ *
7
+ * @deprecated since 1.0.25, use https://packagist.org/packages/typo3/cms-composer-installers instead
8
+ *
9
+ * @author Sascha Egerer <sascha.egerer@dkd.de>
10
+ */
11
+ class TYPO3CmsInstaller extends BaseInstaller
12
+ {
13
+ protected $locations = array(
14
+ 'extension' => 'typo3conf/ext/{$name}/',
15
+ );
16
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * An installer to handle TYPO3 Flow specifics when installing packages.
6
+ */
7
+ class TYPO3FlowInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'package' => 'Packages/Application/{$name}/',
11
+ 'framework' => 'Packages/Framework/{$name}/',
12
+ 'plugin' => 'Packages/Plugins/{$name}/',
13
+ 'site' => 'Packages/Sites/{$name}/',
14
+ 'boilerplate' => 'Packages/Boilerplates/{$name}/',
15
+ 'build' => 'Build/{$name}/',
16
+ );
17
+
18
+ /**
19
+ * Modify the package name to be a TYPO3 Flow style key.
20
+ *
21
+ * @param array $vars
22
+ * @return array
23
+ */
24
+ public function inflectPackageVars($vars)
25
+ {
26
+ $autoload = $this->package->getAutoload();
27
+ if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
28
+ $namespace = key($autoload['psr-0']);
29
+ $vars['name'] = str_replace('\\', '.', $namespace);
30
+ }
31
+ if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
32
+ $namespace = key($autoload['psr-4']);
33
+ $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
34
+ }
35
+
36
+ return $vars;
37
+ }
38
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class TheliaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'local/modules/{$name}/',
8
+ 'frontoffice-template' => 'templates/frontOffice/{$name}/',
9
+ 'backoffice-template' => 'templates/backOffice/{$name}/',
10
+ 'email-template' => 'templates/email/{$name}/',
11
+ );
12
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+ /**
4
+ * Composer installer for 3rd party Tusk utilities
5
+ * @author Drew Ewing <drew@phenocode.com>
6
+ */
7
+ class TuskInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'task' => '.tusk/tasks/{$name}/',
11
+ 'command' => '.tusk/commands/{$name}/',
12
+ 'asset' => 'assets/tusk/{$name}/',
13
+ );
14
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class WHMCSInstaller extends BaseInstaller
6
+ {
7
+ protected $locations = array(
8
+ 'gateway' => 'modules/gateways/{$name}/',
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class WolfCMSInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'wolf/plugins/{$name}/',
8
+ );
9
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class WordPressInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'wp-content/plugins/{$name}/',
8
+ 'theme' => 'wp-content/themes/{$name}/',
9
+ 'muplugin' => 'wp-content/mu-plugins/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ZendInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'library/{$name}/',
8
+ 'extra' => 'extras/library/{$name}/',
9
+ 'module' => 'module/{$name}/',
10
+ );
11
+ }
includes/gateways/stripe/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ZikulaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$vendor}-{$name}/',
8
+ 'theme' => 'themes/{$vendor}-{$name}/'
9
+ );
10
+ }
includes/gateways/stripe/vendor/composer/installers/src/bootstrap.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function includeIfExists($file)
3
+ {
4
+ if (file_exists($file)) {
5
+ return include $file;
6
+ }
7
+ }
8
+ if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))) {
9
+ die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
10
+ 'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
11
+ 'php composer.phar install'.PHP_EOL);
12
+ }
13
+ return $loader;
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\AsgardInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class AsgardInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var OctoberInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new AsgardInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)),
30
+ array('name' => $expected, 'type' => $type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'asgard-module',
39
+ 'asgard-module',
40
+ 'Asgard'
41
+ ),
42
+ array(
43
+ 'asgard-module',
44
+ 'blog',
45
+ 'Blog'
46
+ ),
47
+ // tests that exactly one '-theme' is cut off
48
+ array(
49
+ 'asgard-theme',
50
+ 'some-theme-theme',
51
+ 'Some-theme',
52
+ ),
53
+ // tests that names without '-theme' suffix stay valid
54
+ array(
55
+ 'asgard-theme',
56
+ 'someothertheme',
57
+ 'Someothertheme',
58
+ ),
59
+ );
60
+ }
61
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\CakePHPInstaller;
5
+ use Composer\Repository\RepositoryManager;
6
+ use Composer\Repository\InstalledArrayRepository;
7
+ use Composer\Package\Package;
8
+ use Composer\Package\RootPackage;
9
+ use Composer\Package\Link;
10
+ use Composer\Package\Version\VersionParser;
11
+ use Composer\Composer;
12
+ use Composer\Config;
13
+
14
+ class CakePHPInstallerTest extends TestCase
15
+ {
16
+ private $composer;
17
+ private $io;
18
+
19
+ /**
20
+ * setUp
21
+ *
22
+ * @return void
23
+ */
24
+ public function setUp()
25
+ {
26
+ $this->package = new Package('CamelCased', '1.0', '1.0');
27
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
28
+ $this->composer = new Composer();
29
+ $this->composer->setConfig(new Config(false));
30
+ }
31
+
32
+ /**
33
+ * testInflectPackageVars
34
+ *
35
+ * @return void
36
+ */
37
+ public function testInflectPackageVars()
38
+ {
39
+ $installer = new CakePHPInstaller($this->package, $this->composer);
40
+ $result = $installer->inflectPackageVars(array('name' => 'CamelCased'));
41
+ $this->assertEquals($result, array('name' => 'CamelCased'));
42
+
43
+ $installer = new CakePHPInstaller($this->package, $this->composer);
44
+ $result = $installer->inflectPackageVars(array('name' => 'with-dash'));
45
+ $this->assertEquals($result, array('name' => 'WithDash'));
46
+
47
+ $installer = new CakePHPInstaller($this->package, $this->composer);
48
+ $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
49
+ $this->assertEquals($result, array('name' => 'WithUnderscore'));
50
+
51
+ $installer = new CakePHPInstaller($this->package, $this->composer);
52
+ $result = $installer->inflectPackageVars(array('name' => 'cake/acl'));
53
+ $this->assertEquals($result, array('name' => 'Cake/Acl'));
54
+
55
+ $installer = new CakePHPInstaller($this->package, $this->composer);
56
+ $result = $installer->inflectPackageVars(array('name' => 'cake/debug-kit'));
57
+ $this->assertEquals($result, array('name' => 'Cake/DebugKit'));
58
+ }
59
+
60
+ /**
61
+ * Test getLocations returning appropriate values based on CakePHP version
62
+ *
63
+ */
64
+ public function testGetLocations() {
65
+ $package = new RootPackage('CamelCased', '1.0', '1.0');
66
+ $composer = $this->composer;
67
+ $rm = new RepositoryManager(
68
+ $this->getMock('Composer\IO\IOInterface'),
69
+ $this->getMock('Composer\Config')
70
+ );
71
+ $composer->setRepositoryManager($rm);
72
+ $installer = new CakePHPInstaller($package, $composer);
73
+
74
+ // 2.0 < cakephp < 3.0
75
+ $this->setCakephpVersion($rm, '2.0.0');
76
+ $result = $installer->getLocations();
77
+ $this->assertContains('Plugin/', $result['plugin']);
78
+
79
+ $this->setCakephpVersion($rm, '2.5.9');
80
+ $result = $installer->getLocations();
81
+ $this->assertContains('Plugin/', $result['plugin']);
82
+
83
+ $this->setCakephpVersion($rm, '~2.5');
84
+ $result = $installer->getLocations();
85
+ $this->assertContains('Plugin/', $result['plugin']);
86
+
87
+ // special handling for 2.x versions when 3.x is still in development
88
+ $this->setCakephpVersion($rm, 'dev-master');
89
+ $result = $installer->getLocations();
90
+ $this->assertContains('Plugin/', $result['plugin']);
91
+
92
+ $this->setCakephpVersion($rm, '>=2.5');
93
+ $result = $installer->getLocations();
94
+ $this->assertContains('Plugin/', $result['plugin']);
95
+
96
+ // cakephp >= 3.0
97
+ $this->setCakephpVersion($rm, '3.0.*-dev');
98
+ $result = $installer->getLocations();
99
+ $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']);
100
+
101
+ $this->setCakephpVersion($rm, '~8.8');
102
+ $result = $installer->getLocations();
103
+ $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']);
104
+ }
105
+
106
+ protected function setCakephpVersion($rm, $version) {
107
+ $parser = new VersionParser();
108
+ list(, $version) = explode(' ', $parser->parseConstraints($version));
109
+ $installed = new InstalledArrayRepository();
110
+ $package = new Package('cakephp/cakephp', $version, $version);
111
+ $installed->addPackage($package);
112
+ $rm->setLocalRepository($installed);
113
+ }
114
+
115
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers\Test;
4
+
5
+ use Composer\Installers\CraftInstaller;
6
+
7
+ /**
8
+ * Tests for the CraftInstaller Class
9
+ *
10
+ * @coversDefaultClass Composer\Installers\CraftInstaller
11
+ */
12
+ class CraftInstallerTest extends TestCase
13
+ {
14
+ /** @var CraftInstaller */
15
+ private $installer;
16
+
17
+ /**
18
+ * Sets up the fixture, for example, instantiate the class-under-test.
19
+ *
20
+ * This method is called before a test is executed.
21
+ */
22
+ final public function setup()
23
+ {
24
+ $this->installer = new CraftInstaller();
25
+ }
26
+
27
+ /**
28
+ * @param string $packageName
29
+ * @param string $expectedName
30
+ *
31
+ * @covers ::inflectPackageVars
32
+ *
33
+ * @dataProvider provideExpectedInflectionResults
34
+ */
35
+ final public function testInflectPackageVars($packageName, $expectedName)
36
+ {
37
+ $installer = $this->installer;
38
+
39
+ $vars = array('name' => $packageName);
40
+ $expected = array('name' => $expectedName);
41
+
42
+ $actual = $installer->inflectPackageVars($vars);
43
+
44
+ $this->assertEquals($actual, $expected);
45
+ }
46
+
47
+ /**
48
+ * Provides various names for packages and the expected result after inflection
49
+ *
50
+ * @return array
51
+ */
52
+ final public function provideExpectedInflectionResults()
53
+ {
54
+ return array(
55
+ // lowercase
56
+ array('foo', 'foo'),
57
+ array('craftfoo', 'craftfoo'),
58
+ array('fooplugin', 'fooplugin'),
59
+ array('craftfooplugin', 'craftfooplugin'),
60
+ // lowercase - dash
61
+ array('craft-foo', 'foo'),
62
+ array('foo-plugin', 'foo'),
63
+ array('craft-foo-plugin', 'foo'),
64
+ // lowercase - underscore
65
+ array('craft_foo', 'craft_foo'),
66
+ array('foo_plugin', 'foo_plugin'),
67
+ array('craft_foo_plugin', 'craft_foo_plugin'),
68
+ // CamelCase
69
+ array('Foo', 'Foo'),
70
+ array('CraftFoo', 'CraftFoo'),
71
+ array('FooPlugin', 'FooPlugin'),
72
+ array('CraftFooPlugin', 'CraftFooPlugin'),
73
+ // CamelCase - Dash
74
+ array('Craft-Foo', 'Foo'),
75
+ array('Foo-Plugin', 'Foo'),
76
+ array('Craft-Foo-Plugin', 'Foo'),
77
+ // CamelCase - underscore
78
+ array('Craft_Foo', 'Craft_Foo'),
79
+ array('Foo_Plugin', 'Foo_Plugin'),
80
+ array('Craft_Foo_Plugin', 'Craft_Foo_Plugin'),
81
+ );
82
+ }
83
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\DokuWikiInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class DokuWikiInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var DokuWikiInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new DokuWikiInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
30
+ array('name' => $expected, 'type'=>$type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'dokuwiki-plugin',
39
+ 'dokuwiki-test-plugin',
40
+ 'test',
41
+ ),
42
+ array(
43
+ 'dokuwiki-plugin',
44
+ 'test-plugin',
45
+ 'test',
46
+ ),
47
+ array(
48
+ 'dokuwiki-plugin',
49
+ 'dokuwiki_test',
50
+ 'test',
51
+ ),
52
+ array(
53
+ 'dokuwiki-plugin',
54
+ 'test',
55
+ 'test',
56
+ ),
57
+ array(
58
+ 'dokuwiki-plugin',
59
+ 'test-template',
60
+ 'test-template',
61
+ ),
62
+ array(
63
+ 'dokuwiki-template',
64
+ 'dokuwiki-test-template',
65
+ 'test',
66
+ ),
67
+ array(
68
+ 'dokuwiki-template',
69
+ 'test-template',
70
+ 'test',
71
+ ),
72
+ array(
73
+ 'dokuwiki-template',
74
+ 'dokuwiki_test',
75
+ 'test',
76
+ ),
77
+ array(
78
+ 'dokuwiki-template',
79
+ 'test',
80
+ 'test',
81
+ ),
82
+ array(
83
+ 'dokuwiki-template',
84
+ 'test-plugin',
85
+ 'test-plugin',
86
+ ),
87
+ );
88
+ }
89
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Composer;
5
+ use Composer\Installers\GravInstaller;
6
+
7
+ class GravInstallerTest extends TestCase
8
+ {
9
+ /* @var \Composer\Composer */
10
+ protected $composer;
11
+
12
+ public function setUp()
13
+ {
14
+ $this->composer = new Composer();
15
+ }
16
+
17
+ public function testInflectPackageVars()
18
+ {
19
+ $package = $this->getPackage('vendor/name', '0.0.0');
20
+ $installer = new GravInstaller($package, $this->composer);
21
+ $packageVars = $this->getPackageVars($package);
22
+
23
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => 'test')));
24
+ $this->assertEquals('test', $result['name']);
25
+
26
+ foreach ($installer->getLocations() as $name => $location) {
27
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test")));
28
+ $this->assertEquals('test', $result['name']);
29
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-$name")));
30
+ $this->assertEquals('test', $result['name']);
31
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test-test")));
32
+ $this->assertEquals('test-test', $result['name']);
33
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-test-$name")));
34
+ $this->assertEquals('test-test', $result['name']);
35
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test")));
36
+ $this->assertEquals('test', $result['name']);
37
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-$name")));
38
+ $this->assertEquals('test', $result['name']);
39
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test-test")));
40
+ $this->assertEquals('test-test', $result['name']);
41
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-test-$name")));
42
+ $this->assertEquals('test-test', $result['name']);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @param $package \Composer\Package\PackageInterface
48
+ */
49
+ public function getPackageVars($package)
50
+ {
51
+ $type = $package->getType();
52
+
53
+ $prettyName = $package->getPrettyName();
54
+ if (strpos($prettyName, '/') !== false) {
55
+ list($vendor, $name) = explode('/', $prettyName);
56
+ } else {
57
+ $vendor = '';
58
+ $name = $prettyName;
59
+ }
60
+
61
+ return compact('name', 'vendor', 'type');
62
+ }
63
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\Installer;
5
+ use Composer\Util\Filesystem;
6
+ use Composer\Package\Package;
7
+ use Composer\Package\RootPackage;
8
+ use Composer\Composer;
9
+ use Composer\Config;
10
+
11
+ class InstallerTest extends TestCase
12
+ {
13
+ private $composer;
14
+ private $config;
15
+ private $vendorDir;
16
+ private $binDir;
17
+ private $dm;
18
+ private $repository;
19
+ private $io;
20
+ private $fs;
21
+
22
+ /**
23
+ * setUp
24
+ *
25
+ * @return void
26
+ */
27
+ public function setUp()
28
+ {
29
+ $this->fs = new Filesystem;
30
+
31
+ $this->composer = new Composer();
32
+ $this->config = new Config();
33
+ $this->composer->setConfig($this->config);
34
+
35
+ $this->vendorDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-vendor';
36
+ $this->ensureDirectoryExistsAndClear($this->vendorDir);
37
+
38
+ $this->binDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-bin';
39
+ $this->ensureDirectoryExistsAndClear($this->binDir);
40
+
41
+ $this->config->merge(array(
42
+ 'config' => array(
43
+ 'vendor-dir' => $this->vendorDir,
44
+ 'bin-dir' => $this->binDir,
45
+ ),
46
+ ));
47
+
48
+ $this->dm = $this->getMockBuilder('Composer\Downloader\DownloadManager')
49
+ ->disableOriginalConstructor()
50
+ ->getMock();
51
+ $this->composer->setDownloadManager($this->dm);
52
+
53
+ $this->repository = $this->getMock('Composer\Repository\InstalledRepositoryInterface');
54
+ $this->io = $this->getMock('Composer\IO\IOInterface');
55
+ }
56
+
57
+ /**
58
+ * tearDown
59
+ *
60
+ * @return void
61
+ */
62
+ public function tearDown()
63
+ {
64
+ $this->fs->removeDirectory($this->vendorDir);
65
+ $this->fs->removeDirectory($this->binDir);
66
+ }
67
+
68
+ /**
69
+ * testSupports
70
+ *
71
+ * @return void
72
+ *
73
+ * @dataProvider dataForTestSupport
74
+ */
75
+ public function testSupports($type, $expected)
76
+ {
77
+ $installer = new Installer($this->io, $this->composer);
78
+ $this->assertSame($expected, $installer->supports($type), sprintf('Failed to show support for %s', $type));
79
+ }
80
+
81
+ /**
82
+ * dataForTestSupport
83
+ */
84
+ public function dataForTestSupport()
85
+ {
86
+ return array(
87
+ array('agl-module', true),
88
+ array('aimeos-extension', true),
89
+ array('annotatecms-module', true),
90
+ array('annotatecms-component', true),
91
+ array('annotatecms-service', true),
92
+ array('bitrix-module', true),
93
+ array('bitrix-component', true),
94
+ array('bitrix-theme', true),
95
+ array('bonefish-package', true),
96
+ array('cakephp', false),
97
+ array('cakephp-', false),
98
+ array('cakephp-app', false),
99
+ array('cakephp-plugin', true),
100
+ array('chef-cookbook', true),
101
+ array('chef-role', true),
102
+ array('codeigniter-app', false),
103
+ array('codeigniter-library', true),
104
+ array('codeigniter-third-party', true),
105
+ array('codeigniter-module', true),
106
+ array('concrete5-block', true),
107
+ array('concrete5-package', true),
108
+ array('concrete5-theme', true),
109
+ array('concrete5-update', true),
110
+ array('craft-plugin', true),
111
+ array('croogo-plugin', true),
112
+ array('croogo-theme', true),
113
+ array('dokuwiki-plugin', true),
114
+ array('dokuwiki-template', true),
115
+ array('drupal-module', true),
116
+ array('dolibarr-module', true),
117
+ array('elgg-plugin', true),
118
+ array('fuel-module', true),
119
+ array('fuel-package', true),
120
+ array('fuel-theme', true),
121
+ array('fuelphp-component', true),
122
+ array('hurad-plugin', true),
123
+ array('hurad-theme', true),
124
+ array('imagecms-template', true),
125
+ array('imagecms-module', true),
126
+ array('imagecms-library', true),
127
+ array('joomla-library', true),
128
+ array('kirby-plugin', true),
129
+ array('kohana-module', true),
130
+ array('laravel-library', true),
131
+ array('lithium-library', true),
132
+ array('magento-library', true),
133
+ array('mako-package', true),
134
+ array('modxevo-snippet', true),
135
+ array('modxevo-plugin', true),
136
+ array('modxevo-module', true),
137
+ array('modxevo-template', true),
138
+ array('modxevo-lib', true),
139
+ array('mediawiki-extension', true),
140
+ array('mediawiki-skin', true),
141
+ array('microweber-module', true),
142
+ array('modulework-module', true),
143
+ array('moodle-mod', true),
144
+ array('october-module', true),
145
+ array('october-plugin', true),
146
+ array('piwik-plugin', true),
147
+ array('phpbb-extension', true),
148
+ array('pimcore-plugin', true),
149
+ array('ppi-module', true),
150
+ array('prestashop-module', true),
151
+ array('prestashop-theme', true),
152
+ array('puppet-module', true),
153
+ array('redaxo-addon', true),
154
+ array('redaxo-bestyle-plugin', true),
155
+ array('roundcube-plugin', true),
156
+ array('shopware-backend-plugin', true),
157
+ array('shopware-core-plugin', true),
158
+ array('shopware-frontend-plugin', true),
159
+ array('shopware-theme', true),
160
+ array('silverstripe-module', true),
161
+ array('silverstripe-theme', true),
162
+ array('smf-module', true),
163
+ array('smf-theme', true),
164
+ array('symfony1-plugin', true),
165
+ array('thelia-module', true),
166
+ array('thelia-frontoffice-template', true),
167
+ array('thelia-backoffice-template', true),
168
+ array('thelia-email-template', true),
169
+ array('tusk-task', true),
170
+ array('tusk-asset', true),
171
+ array('typo3-flow-plugin', true),
172
+ array('typo3-cms-extension', true),
173
+ array('whmcs-gateway', true),
174
+ array('wolfcms-plugin', true),
175
+ array('wordpress-plugin', true),
176
+ array('wordpress-core', false),
177
+ array('zend-library', true),
178
+ array('zikula-module', true),
179
+ array('zikula-theme', true),
180
+ array('kodicms-plugin', true),
181
+ array('kodicms-media', true),
182
+ );
183
+ }
184
+
185
+ /**
186
+ * testInstallPath
187
+ *
188
+ * @dataProvider dataForTestInstallPath
189
+ */
190
+ public function testInstallPath($type, $path, $name, $version = '1.0.0')
191
+ {
192
+ $installer = new Installer($this->io, $this->composer);
193
+ $package = new Package($name, $version, $version);
194
+
195
+ $package->setType($type);
196
+ $result = $installer->getInstallPath($package);
197
+ $this->assertEquals($path, $result);
198
+ }
199
+
200
+ /**
201
+ * dataFormTestInstallPath
202
+ */
203
+ public function dataForTestInstallPath()
204
+ {
205
+ return array(
206
+ array('agl-module', 'More/MyTestPackage/', 'agl/my_test-package'),
207
+ array('aimeos-extension', 'ext/ai-test/', 'author/ai-test'),
208
+ array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'),
209
+ array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'),
210
+ array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'),
211
+ array('bitrix-module', 'bitrix/modules/my_module/', 'author/my_module'),
212
+ array('bitrix-component', 'bitrix/components/my_component/', 'author/my_component'),
213
+ array('bitrix-theme', 'bitrix/templates/my_theme/', 'author/my_theme'),
214
+ array('bonefish-package', 'Packages/bonefish/package/', 'bonefish/package'),
215
+ array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'),
216
+ array('chef-cookbook', 'Chef/mre/my_cookbook/', 'mre/my_cookbook'),
217
+ array('chef-role', 'Chef/roles/my_role/', 'mre/my_role'),
218
+ array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'),
219
+ array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'),
220
+ array('concrete5-block', 'blocks/concrete5_block/', 'remo/concrete5_block'),
221
+ array('concrete5-package', 'packages/concrete5_package/', 'remo/concrete5_package'),
222
+ array('concrete5-theme', 'themes/concrete5_theme/', 'remo/concrete5_theme'),
223
+ array('concrete5-update', 'updates/concrete5/', 'concrete5/concrete5'),
224
+ array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'),
225
+ array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'),
226
+ array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'),
227
+ array('dokuwiki-plugin', 'lib/plugins/someplugin/', 'author/someplugin'),
228
+ array('dokuwiki-template', 'lib/tpl/sometemplate/', 'author/sometemplate'),
229
+ array('dolibarr-module', 'htdocs/custom/my_module/', 'shama/my_module'),
230
+ array('drupal-module', 'modules/my_module/', 'shama/my_module'),
231
+ array('drupal-theme', 'themes/my_module/', 'shama/my_module'),
232
+ array('drupal-profile', 'profiles/my_module/', 'shama/my_module'),
233
+ array('drupal-drush', 'drush/my_module/', 'shama/my_module'),
234
+ array('elgg-plugin', 'mod/sample_plugin/', 'test/sample_plugin'),
235
+ array('fuel-module', 'fuel/app/modules/module/', 'fuel/module'),
236
+ array('fuel-package', 'fuel/packages/orm/', 'fuel/orm'),
237
+ array('fuel-theme', 'fuel/app/themes/theme/', 'fuel/theme'),
238
+ array('fuelphp-component', 'components/demo/', 'fuelphp/demo'),
239
+ array('hurad-plugin', 'plugins/Akismet/', 'atkrad/akismet'),
240
+ array('hurad-theme', 'plugins/Hurad2013/', 'atkrad/Hurad2013'),
241
+ array('imagecms-template', 'templates/my_template/', 'shama/my_template'),
242
+ array('imagecms-module', 'application/modules/my_module/', 'shama/my_module'),
243
+ array('imagecms-library', 'application/libraries/my_library/', 'shama/my_library'),
244
+ array('joomla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'),
245
+ array('kirby-plugin', 'site/plugins/my_plugin/', 'shama/my_plugin'),
246
+ array('kohana-module', 'modules/my_package/', 'shama/my_package'),
247
+ array('laravel-library', 'libraries/my_package/', 'shama/my_package'),
248
+ array('lithium-library', 'libraries/li3_test/', 'user/li3_test'),
249
+ array('magento-library', 'lib/foo/', 'test/foo'),
250
+ array('modxevo-snippet', 'assets/snippets/my_snippet/', 'shama/my_snippet'),
251
+ array('modxevo-plugin', 'assets/plugins/my_plugin/', 'shama/my_plugin'),
252
+ array('modxevo-module', 'assets/modules/my_module/', 'shama/my_module'),
253
+ array('modxevo-template', 'assets/templates/my_template/', 'shama/my_template'),
254
+ array('modxevo-lib', 'assets/lib/my_lib/', 'shama/my_lib'),
255
+ array('mako-package', 'app/packages/my_package/', 'shama/my_package'),
256
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC'),
257
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC-extension'),
258
+ array('mediawiki-extension', 'extensions/UploadWizard/', 'author/upload-wizard'),
259
+ array('mediawiki-extension', 'extensions/SyntaxHighlight_GeSHi/', 'author/syntax-highlight_GeSHi'),
260
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin-skin'),
261
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin'),
262
+ array('microweber-module', 'userfiles/modules/my-thing/', 'author/my-thing-module'),
263
+ array('modulework-module', 'modules/my_package/', 'shama/my_package'),
264
+ array('moodle-mod', 'mod/my_package/', 'shama/my_package'),
265
+ array('october-module', 'modules/my_plugin/', 'shama/my_plugin'),
266
+ array('october-plugin', 'plugins/shama/my_plugin/', 'shama/my_plugin'),
267
+ array('october-theme', 'themes/my_theme/', 'shama/my_theme'),
268
+ array('piwik-plugin', 'plugins/VisitSummary/', 'shama/visit-summary'),
269
+ array('prestashop-module', 'modules/a-module/', 'vendor/a-module'),
270
+ array('prestashop-theme', 'themes/a-theme/', 'vendor/a-theme'),
271
+ array('phpbb-extension', 'ext/test/foo/', 'test/foo'),
272
+ array('phpbb-style', 'styles/foo/', 'test/foo'),
273
+ array('phpbb-language', 'language/foo/', 'test/foo'),
274
+ array('pimcore-plugin', 'plugins/MyPlugin/', 'ubikz/my_plugin'),
275
+ array('ppi-module', 'modules/foo/', 'test/foo'),
276
+ array('puppet-module', 'modules/puppet-name/', 'puppet/puppet-name'),
277
+ array('redaxo-addon', 'redaxo/include/addons/my_plugin/', 'shama/my_plugin'),
278
+ array('redaxo-bestyle-plugin', 'redaxo/include/addons/be_style/plugins/my_plugin/', 'shama/my_plugin'),
279
+ array('roundcube-plugin', 'plugins/base/', 'test/base'),
280
+ array('roundcube-plugin', 'plugins/replace_dash/', 'test/replace-dash'),
281
+ array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'),
282
+ array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'),
283
+ array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'),
284
+ array('shopware-theme', 'templates/my_theme/', 'shama/my-theme'),
285
+ array('silverstripe-module', 'my_module/', 'shama/my_module'),
286
+ array('silverstripe-module', 'sapphire/', 'silverstripe/framework', '2.4.0'),
287
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0'),
288
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0-rc1'),
289
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', 'my/branch'),
290
+ array('silverstripe-theme', 'themes/my_theme/', 'shama/my_theme'),
291
+ array('smf-module', 'Sources/my_module/', 'shama/my_module'),
292
+ array('smf-theme', 'Themes/my_theme/', 'shama/my_theme'),
293
+ array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'),
294
+ array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'),
295
+ array('thelia-module', 'local/modules/my_module/', 'shama/my_module'),
296
+ array('thelia-frontoffice-template', 'templates/frontOffice/my_template_fo/', 'shama/my_template_fo'),
297
+ array('thelia-backoffice-template', 'templates/backOffice/my_template_bo/', 'shama/my_template_bo'),
298
+ array('thelia-email-template', 'templates/email/my_template_email/', 'shama/my_template_email'),
299
+ array('tusk-task', '.tusk/tasks/my_task/', 'shama/my_task'),
300
+ array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'),
301
+ array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'),
302
+ array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'),
303
+ array('whmcs-gateway', 'modules/gateways/gateway_name/', 'vendor/gateway_name'),
304
+ array('wolfcms-plugin', 'wolf/plugins/my_plugin/', 'shama/my_plugin'),
305
+ array('wordpress-plugin', 'wp-content/plugins/my_plugin/', 'shama/my_plugin'),
306
+ array('wordpress-muplugin', 'wp-content/mu-plugins/my_plugin/', 'shama/my_plugin'),
307
+ array('zend-extra', 'extras/library/zend_test/', 'shama/zend_test'),
308
+ array('zikula-module', 'modules/my-test_module/', 'my/test_module'),
309
+ array('zikula-theme', 'themes/my-test_theme/', 'my/test_theme'),
310
+ array('kodicms-media', 'cms/media/vendor/my_media/', 'shama/my_media'),
311
+ array('kodicms-plugin', 'cms/plugins/my_plugin/', 'shama/my_plugin'),
312
+ );
313
+ }
314
+
315
+ /**
316
+ * testGetCakePHPInstallPathException
317
+ *
318
+ * @return void
319
+ *
320
+ * @expectedException \InvalidArgumentException
321
+ */
322
+ public function testGetCakePHPInstallPathException()
323
+ {
324
+ $installer = new Installer($this->io, $this->composer);
325
+ $package = new Package('shama/ftp', '1.0.0', '1.0.0');
326
+
327
+ $package->setType('cakephp-whoops');
328
+ $result = $installer->getInstallPath($package);
329
+ }
330
+
331
+ /**
332
+ * testCustomInstallPath
333
+ */
334
+ public function testCustomInstallPath()
335
+ {
336
+ $installer = new Installer($this->io, $this->composer);
337
+ $package = new Package('shama/ftp', '1.0.0', '1.0.0');
338
+ $package->setType('cakephp-plugin');
339
+ $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0');
340
+ $this->composer->setPackage($consumerPackage);
341
+ $consumerPackage->setExtra(array(
342
+ 'installer-paths' => array(
343
+ 'my/custom/path/{$name}/' => array(
344
+ 'shama/ftp',
345
+ 'foo/bar',
346
+ ),
347
+ ),
348
+ ));
349
+ $result = $installer->getInstallPath($package);
350
+ $this->assertEquals('my/custom/path/Ftp/', $result);
351
+ }
352
+
353
+ /**
354
+ * testCustomInstallerName
355
+ */
356
+ public function testCustomInstallerName()
357
+ {
358
+ $installer = new Installer($this->io, $this->composer);
359
+ $package = new Package('shama/cakephp-ftp-plugin', '1.0.0', '1.0.0');
360
+ $package->setType('cakephp-plugin');
361
+ $package->setExtra(array(
362
+ 'installer-name' => 'FTP',
363
+ ));
364
+ $result = $installer->getInstallPath($package);
365
+ $this->assertEquals('Plugin/FTP/', $result);
366
+ }
367
+
368
+ /**
369
+ * testCustomTypePath
370
+ */
371
+ public function testCustomTypePath()
372
+ {
373
+ $installer = new Installer($this->io, $this->composer);
374
+ $package = new Package('slbmeh/my_plugin', '1.0.0', '1.0.0');
375
+ $package->setType('wordpress-plugin');
376
+ $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0');
377
+ $this->composer->setPackage($consumerPackage);
378
+ $consumerPackage->setExtra(array(
379
+ 'installer-paths' => array(
380
+ 'my/custom/path/{$name}/' => array(
381
+ 'type:wordpress-plugin'
382
+ ),
383
+ ),
384
+ ));
385
+ $result = $installer->getInstallPath($package);
386
+ $this->assertEquals('my/custom/path/my_plugin/', $result);
387
+ }
388
+
389
+ /**
390
+ * testVendorPath
391
+ */
392
+ public function testVendorPath()
393
+ {
394
+ $installer = new Installer($this->io, $this->composer);
395
+ $package = new Package('penyaskito/my_module', '1.0.0', '1.0.0');
396
+ $package->setType('drupal-module');
397
+ $consumerPackage = new RootPackage('drupal/drupal', '1.0.0', '1.0.0');
398
+ $this->composer->setPackage($consumerPackage);
399
+ $consumerPackage->setExtra(array(
400
+ 'installer-paths' => array(
401
+ 'modules/custom/{$name}/' => array(
402
+ 'vendor:penyaskito'
403
+ ),
404
+ ),
405
+ ));
406
+ $result = $installer->getInstallPath($package);
407
+ $this->assertEquals('modules/custom/my_module/', $result);
408
+ }
409
+
410
+ /**
411
+ * testNoVendorName
412
+ */
413
+ public function testNoVendorName()
414
+ {
415
+ $installer = new Installer($this->io, $this->composer);
416
+ $package = new Package('sfPhpunitPlugin', '1.0.0', '1.0.0');
417
+
418
+ $package->setType('symfony1-plugin');
419
+ $result = $installer->getInstallPath($package);
420
+ $this->assertEquals('plugins/sfPhpunitPlugin/', $result);
421
+ }
422
+
423
+ /**
424
+ * testTypo3Inflection
425
+ */
426
+ public function testTypo3Inflection()
427
+ {
428
+ $installer = new Installer($this->io, $this->composer);
429
+ $package = new Package('typo3/fluid', '1.0.0', '1.0.0');
430
+
431
+ $package->setAutoload(array(
432
+ 'psr-0' => array(
433
+ 'TYPO3\\Fluid' => 'Classes',
434
+ ),
435
+ ));
436
+
437
+ $package->setType('typo3-flow-package');
438
+ $result = $installer->getInstallPath($package);
439
+ $this->assertEquals('Packages/Application/TYPO3.Fluid/', $result);
440
+ }
441
+
442
+ public function testUninstallAndDeletePackageFromLocalRepo()
443
+ {
444
+ $package = new Package('foo', '1.0.0', '1.0.0');
445
+
446
+ $installer = $this->getMock('Composer\Installers\Installer', array('getInstallPath'), array($this->io, $this->composer));
447
+ $installer->expects($this->once())->method('getInstallPath')->with($package)->will($this->returnValue(sys_get_temp_dir().'/foo'));
448
+
449
+ $repo = $this->getMock('Composer\Repository\InstalledRepositoryInterface');
450
+ $repo->expects($this->once())->method('hasPackage')->with($package)->will($this->returnValue(true));
451
+ $repo->expects($this->once())->method('removePackage')->with($package);
452
+
453
+ $installer->uninstall($repo, $package);
454
+ }
455
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\MediaWikiInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class MediaWikiInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var MediaWikiInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new MediaWikiInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
30
+ array('name' => $expected, 'type'=>$type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'mediawiki-extension',
39
+ 'sub-page-list',
40
+ 'SubPageList',
41
+ ),
42
+ array(
43
+ 'mediawiki-extension',
44
+ 'sub-page-list-extension',
45
+ 'SubPageList',
46
+ ),
47
+ array(
48
+ 'mediawiki-extension',
49
+ 'semantic-mediawiki',
50
+ 'SemanticMediawiki',
51
+ ),
52
+ // tests that exactly one '-skin' is cut off, and that skins do not get ucwords treatment like extensions
53
+ array(
54
+ 'mediawiki-skin',
55
+ 'some-skin-skin',
56
+ 'some-skin',
57
+ ),
58
+ // tests that names without '-skin' suffix stay valid
59
+ array(
60
+ 'mediawiki-skin',
61
+ 'someotherskin',
62
+ 'someotherskin',
63
+ ),
64
+ );
65
+ }
66
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\OctoberInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class OctoberInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var OctoberInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new OctoberInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)),
30
+ array('name' => $expected, 'type' => $type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'october-plugin',
39
+ 'subpagelist',
40
+ 'subpagelist',
41
+ ),
42
+ array(
43
+ 'october-plugin',
44
+ 'subpagelist-plugin',
45
+ 'subpagelist',
46
+ ),
47
+ array(
48
+ 'october-plugin',
49
+ 'semanticoctober',
50
+ 'semanticoctober',
51
+ ),
52
+ // tests that exactly one '-theme' is cut off
53
+ array(
54
+ 'october-theme',
55
+ 'some-theme-theme',
56
+ 'some-theme',
57
+ ),
58
+ // tests that names without '-theme' suffix stay valid
59
+ array(
60
+ 'october-theme',
61
+ 'someothertheme',
62
+ 'someothertheme',
63
+ ),
64
+ );
65
+ }
66
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\PimcoreInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class PimcoreInstallerTest extends TestCase
9
+ {
10
+ private $composer;
11
+ private $io;
12
+
13
+ /**
14
+ * setUp
15
+ *
16
+ * @return void
17
+ */
18
+ public function setUp()
19
+ {
20
+ $this->package = new Package('CamelCased', '1.0', '1.0');
21
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
22
+ $this->composer = new Composer();
23
+ }
24
+
25
+ /**
26
+ * testInflectPackageVars
27
+ *
28
+ * @return void
29
+ */
30
+ public function testInflectPackageVars()
31
+ {
32
+ $installer = new PimcoreInstaller($this->package, $this->composer);
33
+ $result = $installer->inflectPackageVars(array('name' => 'CamelCased'));
34
+ $this->assertEquals($result, array('name' => 'CamelCased'));
35
+
36
+ $installer = new PimcoreInstaller($this->package, $this->composer);
37
+ $result = $installer->inflectPackageVars(array('name' => 'with-dash'));
38
+ $this->assertEquals($result, array('name' => 'WithDash'));
39
+
40
+ $installer = new PimcoreInstaller($this->package, $this->composer);
41
+ $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
42
+ $this->assertEquals($result, array('name' => 'WithUnderscore'));
43
+ }
44
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Composer;
5
+ use Composer\Installers\PiwikInstaller;
6
+ use Composer\Package\Package;
7
+ use Composer\Package\PackageInterface;
8
+
9
+ /**
10
+ * Class PiwikInstallerTest
11
+ *
12
+ * @package Composer\Installers\Test
13
+ */
14
+ class PiwikInstallerTest extends TestCase
15
+ {
16
+ /**
17
+ * @varComposer
18
+ */
19
+ private $composer;
20
+
21
+ /**
22
+ * @var PackageInterface
23
+ */
24
+ private $io;
25
+
26
+ /**
27
+ * @var Package
28
+ */
29
+ private $package;
30
+
31
+ /**
32
+ * setUp
33
+ *
34
+ * @return void
35
+ */
36
+ public function setUp()
37
+ {
38
+ $this->package = new Package('VisitSummary', '1.0', '1.0');
39
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
40
+ $this->composer = new Composer();
41
+ }
42
+
43
+ /**
44
+ * testInflectPackageVars
45
+ *
46
+ * @return void
47
+ */
48
+ public function testInflectPackageVars()
49
+ {
50
+ $installer = new PiwikInstaller($this->package, $this->composer);
51
+ $result = $installer->inflectPackageVars(array('name' => 'VisitSummary'));
52
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
53
+
54
+ $installer = new PiwikInstaller($this->package, $this->composer);
55
+ $result = $installer->inflectPackageVars(array('name' => 'visit-summary'));
56
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
57
+
58
+ $installer = new PiwikInstaller($this->package, $this->composer);
59
+ $result = $installer->inflectPackageVars(array('name' => 'visit_summary'));
60
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
61
+ }
62
+
63
+ }
includes/gateways/stripe/vendor/composer/installers/tests/Composer/Installers/Test/TestCase.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Installers\Test;
14
+
15
+ use Composer\Package\Version\VersionParser;
16
+ use Composer\Package\Package;
17
+ use Composer\Package\AliasPackage;
18
+ use Composer\Package\LinkConstraint\VersionConstraint;
19
+ use Composer\Util\Filesystem;
20
+
21
+ abstract class TestCase extends \PHPUnit_Framework_TestCase
22
+ {
23
+ private static $parser;
24
+
25
+ protected static function getVersionParser()
26
+ {
27
+ if (!self::$parser) {
28
+ self::$parser = new VersionParser();
29
+ }
30
+
31
+ return self::$parser;
32
+ }
33
+
34
+ protected function getVersionConstraint($operator, $version)
35
+ {
36
+ return new VersionConstraint(
37
+ $operator,
38
+ self::getVersionParser()->normalize($version)
39
+ );
40
+ }
41
+
42
+ protected function getPackage($name, $version)
43
+ {
44
+ $normVersion = self::getVersionParser()->normalize($version);
45
+
46
+ return new Package($name, $normVersion, $version);
47
+ }
48
+
49
+ protected function getAliasPackage($package, $version)
50
+ {
51
+ $normVersion = self::getVersionParser()->normalize($version);
52
+
53
+ return new AliasPackage($package, $normVersion, $version);
54
+ }
55
+
56
+ protected function ensureDirectoryExistsAndClear($directory)
57
+ {
58
+ $fs = new Filesystem();
59
+ if (is_dir($directory)) {
60
+ $fs->removeDirectory($directory);
61
+ }
62
+ mkdir($directory, 0777, true);
63
+ }
64
+ }
includes/gateways/stripe/vendor/composer/installers/tests/bootstrap.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+
3
+ $loader = require __DIR__ . '/../src/bootstrap.php';
4
+ $loader->add('Composer\Installers\Test', __DIR__);
includes/gateways/stripe/vendor/stripe/stripe-php/CHANGELOG.md ADDED
@@ -0,0 +1,1243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog
2
+
3
+ ## 7.47.0 - 2020-08-13
4
+ * [#994](https://github.com/stripe/stripe-php/pull/994) Nullable balance_transactions on issuing disputes
5
+ * [#991](https://github.com/stripe/stripe-php/pull/991) Fix invalid return types in OAuthService
6
+
7
+ ## 7.46.1 - 2020-08-07
8
+ * [#990](https://github.com/stripe/stripe-php/pull/990) PHPdoc changes
9
+
10
+ ## 7.46.0 - 2020-08-05
11
+ * [#989](https://github.com/stripe/stripe-php/pull/989) Add support for the `PromotionCode` resource and APIs
12
+
13
+ ## 7.45.0 - 2020-07-28
14
+ * [#981](https://github.com/stripe/stripe-php/pull/981) PHPdoc updates
15
+
16
+ ## 7.44.0 - 2020-07-20
17
+ * [#948](https://github.com/stripe/stripe-php/pull/948) Add `first()` and `last()` functions to `Collection`
18
+
19
+ ## 7.43.0 - 2020-07-17
20
+ * [#975](https://github.com/stripe/stripe-php/pull/975) Add support for `political_exposure` on `Person`
21
+
22
+ ## 7.42.0 - 2020-07-15
23
+ * [#974](https://github.com/stripe/stripe-php/pull/974) Add new constants for `purpose` on `File`
24
+
25
+ ## 7.41.1 - 2020-07-15
26
+ * [#973](https://github.com/stripe/stripe-php/pull/973) Multiple PHPDoc fixes
27
+
28
+ ## 7.41.0 - 2020-07-14
29
+ * [#971](https://github.com/stripe/stripe-php/pull/971) Adds enum values for `billing_address_collection` on Checkout `Session`
30
+
31
+ ## 7.40.0 - 2020-07-06
32
+ * [#964](https://github.com/stripe/stripe-php/pull/964) Add OAuthService
33
+
34
+ ## 7.39.0 - 2020-06-25
35
+ * [#960](https://github.com/stripe/stripe-php/pull/960) Add constants for `payment_behavior` on `Subscription`
36
+
37
+ ## 7.38.0 - 2020-06-24
38
+ * [#959](https://github.com/stripe/stripe-php/pull/959) Add multiple constants missing for `Event`
39
+
40
+ ## 7.37.2 - 2020-06-23
41
+ * [#957](https://github.com/stripe/stripe-php/pull/957) Updated PHPDocs
42
+
43
+ ## 7.37.1 - 2020-06-11
44
+ * [#952](https://github.com/stripe/stripe-php/pull/952) Improve PHPDoc
45
+
46
+ ## 7.37.0 - 2020-06-09
47
+ * [#950](https://github.com/stripe/stripe-php/pull/950) Add support for `id_npwp` and `my_frp` as `type` on `TaxId`
48
+
49
+ ## 7.36.2 - 2020-06-03
50
+ * [#946](https://github.com/stripe/stripe-php/pull/946) Update PHPDoc
51
+
52
+ ## 7.36.1 - 2020-05-28
53
+ * [#938](https://github.com/stripe/stripe-php/pull/938) Remove extra array_keys() call.
54
+ * [#942](https://github.com/stripe/stripe-php/pull/942) fix autopagination for service methods
55
+
56
+ ## 7.36.0 - 2020-05-21
57
+ * [#937](https://github.com/stripe/stripe-php/pull/937) Add support for `ae_trn`, `cl_tin` and `sa_vat` as `type` on `TaxId`
58
+
59
+ ## 7.35.0 - 2020-05-20
60
+ * [#936](https://github.com/stripe/stripe-php/pull/936) Add `anticipation_repayment` as a `type` on `BalanceTransaction`
61
+
62
+ ## 7.34.0 - 2020-05-18
63
+ * [#934](https://github.com/stripe/stripe-php/pull/934) Add support for `issuing_dispute` as a `type` on `BalanceTransaction`
64
+
65
+ ## 7.33.1 - 2020-05-15
66
+ * [#933](https://github.com/stripe/stripe-php/pull/933) Services bugfix: convert nested null params to empty strings
67
+
68
+ ## 7.33.0 - 2020-05-14
69
+ * [#771](https://github.com/stripe/stripe-php/pull/771) Introduce client/services API. The [migration guide](https://github.com/stripe/stripe-php/wiki/Migration-to-StripeClient-and-services-in-7.33.0) contains before & after examples of the backwards-compatible changes.
70
+
71
+ ## 7.32.1 - 2020-05-13
72
+ * [#932](https://github.com/stripe/stripe-php/pull/932) Fix multiple PHPDoc
73
+
74
+ ## 7.32.0 - 2020-05-11
75
+ * [#931](https://github.com/stripe/stripe-php/pull/931) Add support for the `LineItem` resource and APIs
76
+
77
+ ## 7.31.0 - 2020-05-01
78
+ * [#927](https://github.com/stripe/stripe-php/pull/927) Add support for new tax IDs
79
+
80
+ ## 7.30.0 - 2020-04-29
81
+ * [#924](https://github.com/stripe/stripe-php/pull/924) Add support for the `Price` resource and APIs
82
+
83
+ ## 7.29.0 - 2020-04-22
84
+ * [#920](https://github.com/stripe/stripe-php/pull/920) Add support for the `Session` resource and APIs on the `BillingPortal` namespace
85
+
86
+ ## 7.28.1 - 2020-04-10
87
+ * [#915](https://github.com/stripe/stripe-php/pull/915) Improve PHPdocs for many classes
88
+
89
+ ## 7.28.0 - 2020-04-03
90
+ * [#912](https://github.com/stripe/stripe-php/pull/912) Preserve backwards compatibility for typoed `TYPE_ADJUSTEMENT` enum.
91
+ * [#911](https://github.com/stripe/stripe-php/pull/911) Codegenerated PHPDoc for nested resources
92
+ * [#902](https://github.com/stripe/stripe-php/pull/902) Update docstrings for nested resources
93
+
94
+ ## 7.27.3 - 2020-03-18
95
+ * [#899](https://github.com/stripe/stripe-php/pull/899) Convert keys to strings in `StripeObject::toArray()`
96
+
97
+ ## 7.27.2 - 2020-03-13
98
+ * [#894](https://github.com/stripe/stripe-php/pull/894) Multiple PHPDocs changes
99
+
100
+ ## 7.27.1 - 2020-03-03
101
+ * [#890](https://github.com/stripe/stripe-php/pull/890) Update PHPdoc
102
+
103
+ ## 7.27.0 - 2020-02-28
104
+ * [#889](https://github.com/stripe/stripe-php/pull/889) Add new constants for `type` on `TaxId`
105
+
106
+ ## 7.26.0 - 2020-02-26
107
+ * [#886](https://github.com/stripe/stripe-php/pull/886) Add support for listing Checkout `Session`
108
+ * [#883](https://github.com/stripe/stripe-php/pull/883) Add PHPDoc class descriptions
109
+
110
+ ## 7.25.0 - 2020-02-14
111
+ * [#879](https://github.com/stripe/stripe-php/pull/879) Make `\Stripe\Collection` implement `\Countable`
112
+ * [#875](https://github.com/stripe/stripe-php/pull/875) Last set of PHP-CS-Fixer updates
113
+ * [#874](https://github.com/stripe/stripe-php/pull/874) Enable php_unit_internal_class rule
114
+ * [#873](https://github.com/stripe/stripe-php/pull/873) Add support for phpDocumentor in Makefile
115
+ * [#872](https://github.com/stripe/stripe-php/pull/872) Another batch of PHP-CS-Fixer rule updates
116
+ * [#871](https://github.com/stripe/stripe-php/pull/871) Fix a few PHPDoc comments
117
+ * [#870](https://github.com/stripe/stripe-php/pull/870) More PHP-CS-Fixer tweaks
118
+
119
+ ## 7.24.0 - 2020-02-10
120
+ * [#862](https://github.com/stripe/stripe-php/pull/862) Better PHPDoc
121
+ * [#865](https://github.com/stripe/stripe-php/pull/865) Get closer to `@PhpCsFixer` standard ruleset
122
+
123
+ ## 7.23.0 - 2020-02-05
124
+ * [#860](https://github.com/stripe/stripe-php/pull/860) Add PHPDoc types for expandable fields
125
+ * [#858](https://github.com/stripe/stripe-php/pull/858) Use `native_function_invocation` PHPStan rule
126
+ * [#857](https://github.com/stripe/stripe-php/pull/857) Update PHPDoc on nested resources
127
+ * [#855](https://github.com/stripe/stripe-php/pull/855) PHPDoc: `StripeObject` -> `ErrorObject` where appropriate
128
+ * [#837](https://github.com/stripe/stripe-php/pull/837) Autogen diff
129
+ * [#854](https://github.com/stripe/stripe-php/pull/854) Upgrade PHPStan and fix settings
130
+ * [#850](https://github.com/stripe/stripe-php/pull/850) Yet more PHPDoc updates
131
+
132
+ ## 7.22.0 - 2020-01-31
133
+ * [#849](https://github.com/stripe/stripe-php/pull/849) Add new constants for `type` on `TaxId`
134
+ * [#843](https://github.com/stripe/stripe-php/pull/843) Even more PHPDoc fixes
135
+ * [#841](https://github.com/stripe/stripe-php/pull/841) More PHPDoc fixes
136
+
137
+ ## 7.21.1 - 2020-01-29
138
+ * [#840](https://github.com/stripe/stripe-php/pull/840) Update phpdocs across multiple resources.
139
+
140
+ ## 7.21.0 - 2020-01-28
141
+ * [#839](https://github.com/stripe/stripe-php/pull/839) Add support for `TYPE_ES_CIF` on `TaxId`
142
+
143
+ ## 7.20.0 - 2020-01-23
144
+ * [#836](https://github.com/stripe/stripe-php/pull/836) Add new type values for `TaxId`
145
+
146
+ ## 7.19.1 - 2020-01-14
147
+ * [#831](https://github.com/stripe/stripe-php/pull/831) Fix incorrect `UnexpectedValueException` instantiation
148
+
149
+ ## 7.19.0 - 2020-01-14
150
+ * [#830](https://github.com/stripe/stripe-php/pull/830) Add support for `CreditNoteLineItem`
151
+
152
+ ## 7.18.0 - 2020-01-13
153
+ * [#829](https://github.com/stripe/stripe-php/pull/829) Don't call php_uname function if disabled by php.ini
154
+
155
+ ## 7.17.0 - 2020-01-08
156
+ * [#821](https://github.com/stripe/stripe-php/pull/821) Improve PHPDoc types for `ApiErrorException.get/setJsonBody()` methods
157
+
158
+ ## 7.16.0 - 2020-01-06
159
+ * [#826](https://github.com/stripe/stripe-php/pull/826) Rename remaining `$options` to `$opts`
160
+ * [#825](https://github.com/stripe/stripe-php/pull/825) Update PHPDoc
161
+
162
+ ## 7.15.0 - 2020-01-06
163
+ * [#824](https://github.com/stripe/stripe-php/pull/824) Add constant `TYPE_SG_UEN` to `TaxId`
164
+
165
+ ## 7.14.2 - 2019-12-04
166
+ * [#816](https://github.com/stripe/stripe-php/pull/816) Disable autoloader when checking for `Throwable`
167
+
168
+ ## 7.14.1 - 2019-11-26
169
+ * [#812](https://github.com/stripe/stripe-php/pull/812) Fix invalid PHPdoc on `Subscription`
170
+
171
+ ## 7.14.0 - 2019-11-26
172
+ * [#811](https://github.com/stripe/stripe-php/pull/811) Add support for `CreditNote` preview.
173
+
174
+ ## 7.13.0 - 2019-11-19
175
+ * [#808](https://github.com/stripe/stripe-php/pull/808) Add support for listing lines on an Invoice directly via `Invoice::allLines()`
176
+
177
+ ## 7.12.0 - 2019-11-08
178
+
179
+ - [#805](https://github.com/stripe/stripe-php/pull/805) Add Source::allSourceTransactions and SubscriptionItem::allUsageRecordSummaries
180
+ - [#798](https://github.com/stripe/stripe-php/pull/798) The argument of `array_key_exists` cannot be `null`
181
+ - [#803](https://github.com/stripe/stripe-php/pull/803) Removed unwanted got
182
+
183
+ ## 7.11.0 - 2019-11-06
184
+
185
+ - [#797](https://github.com/stripe/stripe-php/pull/797) Add support for reverse pagination
186
+
187
+ ## 7.10.0 - 2019-11-05
188
+
189
+ - [#795](https://github.com/stripe/stripe-php/pull/795) Add support for `Mandate`
190
+
191
+ ## 7.9.0 - 2019-11-05
192
+
193
+ - [#794](https://github.com/stripe/stripe-php/pull/794) Add PHPDoc to `ApiResponse`
194
+ - [#792](https://github.com/stripe/stripe-php/pull/792) Use single quotes for `OBJECT_NAME` constants
195
+
196
+ ## 7.8.0 - 2019-11-05
197
+
198
+ - [#790](https://github.com/stripe/stripe-php/pull/790) Mark nullable fields in PHPDoc
199
+ - [#788](https://github.com/stripe/stripe-php/pull/788) Early codegen fixes
200
+ - [#787](https://github.com/stripe/stripe-php/pull/787) Use PHPStan in Travis CI
201
+
202
+ ## 7.7.1 - 2019-10-25
203
+
204
+ - [#781](https://github.com/stripe/stripe-php/pull/781) Fix telemetry header
205
+ - [#780](https://github.com/stripe/stripe-php/pull/780) Contributor Convenant
206
+
207
+ ## 7.7.0 - 2019-10-23
208
+
209
+ - [#776](https://github.com/stripe/stripe-php/pull/776) Add `CAPABILITY_TRANSFERS` to `Account`
210
+ - [#778](https://github.com/stripe/stripe-php/pull/778) Add support for `TYPE_MX_RFC` type on `TaxId`
211
+
212
+ ## 7.6.0 - 2019-10-22
213
+
214
+ - [#770](https://github.com/stripe/stripe-php/pull/770) Add missing constants for Customer's `TaxId`
215
+
216
+ ## 7.5.0 - 2019-10-18
217
+
218
+ - [#768](https://github.com/stripe/stripe-php/pull/768) Redact API key in `RequestOptions` debug info
219
+
220
+ ## 7.4.0 - 2019-10-15
221
+
222
+ - [#764](https://github.com/stripe/stripe-php/pull/764) Add support for HTTP request monitoring callback
223
+
224
+ ## 7.3.1 - 2019-10-07
225
+
226
+ - [#755](https://github.com/stripe/stripe-php/pull/755) Respect Stripe-Should-Retry and Retry-After headers
227
+
228
+ ## 7.3.0 - 2019-10-02
229
+
230
+ - [#752](https://github.com/stripe/stripe-php/pull/752) Add `payment_intent.canceled` and `setup_intent.canceled` events
231
+ - [#749](https://github.com/stripe/stripe-php/pull/749) Call `toArray()` on objects only
232
+
233
+ ## 7.2.2 - 2019-09-24
234
+
235
+ - [#746](https://github.com/stripe/stripe-php/pull/746) Add missing decline codes
236
+
237
+ ## 7.2.1 - 2019-09-23
238
+
239
+ - [#744](https://github.com/stripe/stripe-php/pull/744) Added new PHPDoc
240
+
241
+ ## 7.2.0 - 2019-09-17
242
+
243
+ - [#738](https://github.com/stripe/stripe-php/pull/738) Added missing constants for `SetupIntent` events
244
+
245
+ ## 7.1.1 - 2019-09-16
246
+
247
+ - [#737](https://github.com/stripe/stripe-php/pull/737) Added new PHPDoc
248
+
249
+ ## 7.1.0 - 2019-09-13
250
+
251
+ - [#736](https://github.com/stripe/stripe-php/pull/736) Make `CaseInsensitiveArray` countable and traversable
252
+
253
+ ## 7.0.2 - 2019-09-06
254
+
255
+ - [#729](https://github.com/stripe/stripe-php/pull/729) Fix usage of `SignatureVerificationException` in PHPDoc blocks
256
+
257
+ ## 7.0.1 - 2019-09-05
258
+
259
+ - [#728](https://github.com/stripe/stripe-php/pull/728) Clean up Collection
260
+
261
+ ## 7.0.0 - 2019-09-03
262
+
263
+ Major version release. The [migration guide](https://github.com/stripe/stripe-php/wiki/Migration-guide-for-v7) contains a detailed list of backwards-incompatible changes with upgrade instructions.
264
+
265
+ Pull requests included in this release (cf. [#552](https://github.com/stripe/stripe-php/pull/552)) (⚠️ = breaking changes):
266
+
267
+ - ⚠️ Drop support for PHP 5.4 ([#551](https://github.com/stripe/stripe-php/pull/551))
268
+ - ⚠️ Drop support for PHP 5.5 ([#554](https://github.com/stripe/stripe-php/pull/554))
269
+ - Bump dependencies ([#553](https://github.com/stripe/stripe-php/pull/553))
270
+ - Remove `CURLFile` check ([#555](https://github.com/stripe/stripe-php/pull/555))
271
+ - Update constant definitions for PHP >= 5.6 ([#556](https://github.com/stripe/stripe-php/pull/556))
272
+ - ⚠️ Remove `FileUpload` alias ([#557](https://github.com/stripe/stripe-php/pull/557))
273
+ - Remove `curl_reset` check ([#570](https://github.com/stripe/stripe-php/pull/570))
274
+ - Use `\Stripe\<class>::class` constant instead of strings ([#643](https://github.com/stripe/stripe-php/pull/643))
275
+ - Use `array_column` to flatten params ([#686](https://github.com/stripe/stripe-php/pull/686))
276
+ - ⚠️ Remove deprecated methods ([#692](https://github.com/stripe/stripe-php/pull/692))
277
+ - ⚠️ Remove `IssuerFraudRecord` ([#696](https://github.com/stripe/stripe-php/pull/696))
278
+ - Update constructors of Stripe exception classes ([#559](https://github.com/stripe/stripe-php/pull/559))
279
+ - Fix remaining TODOs ([#700](https://github.com/stripe/stripe-php/pull/700))
280
+ - Use yield for autopagination ([#703](https://github.com/stripe/stripe-php/pull/703))
281
+ - ⚠️ Rename fake magic methods and rewrite array conversion ([#704](https://github.com/stripe/stripe-php/pull/704))
282
+ - Add `ErrorObject` to Stripe exceptions ([#705](https://github.com/stripe/stripe-php/pull/705))
283
+ - Start using PHP CS Fixer ([#706](https://github.com/stripe/stripe-php/pull/706))
284
+ - Update error messages for nested resource operations ([#708](https://github.com/stripe/stripe-php/pull/708))
285
+ - Upgrade retry logic ([#707](https://github.com/stripe/stripe-php/pull/707))
286
+ - ⚠️ `Collection` improvements / fixes ([#715](https://github.com/stripe/stripe-php/pull/715))
287
+ - ⚠️ Modernize exceptions ([#709](https://github.com/stripe/stripe-php/pull/709))
288
+ - Add constants for error codes ([#716](https://github.com/stripe/stripe-php/pull/716))
289
+ - Update certificate bundle ([#717](https://github.com/stripe/stripe-php/pull/717))
290
+ - Retry requests on a 429 that's a lock timeout ([#718](https://github.com/stripe/stripe-php/pull/718))
291
+ - Fix `toArray()` calls ([#719](https://github.com/stripe/stripe-php/pull/719))
292
+ - Couple of fixes for PHP 7.4 ([#725](https://github.com/stripe/stripe-php/pull/725))
293
+
294
+ ## 6.43.1 - 2019-08-29
295
+
296
+ - [#722](https://github.com/stripe/stripe-php/pull/722) Make `LoggerInterface::error` compatible with its PSR-3 counterpart
297
+ - [#714](https://github.com/stripe/stripe-php/pull/714) Add `pending_setup_intent` property in `Subscription`
298
+ - [#713](https://github.com/stripe/stripe-php/pull/713) Add typehint to `ApiResponse`
299
+ - [#712](https://github.com/stripe/stripe-php/pull/712) Fix comment
300
+ - [#701](https://github.com/stripe/stripe-php/pull/701) Start testing PHP 7.3
301
+
302
+ ## 6.43.0 - 2019-08-09
303
+
304
+ - [#694](https://github.com/stripe/stripe-php/pull/694) Add `SubscriptionItem::createUsageRecord` method
305
+
306
+ ## 6.42.0 - 2019-08-09
307
+
308
+ - [#688](https://github.com/stripe/stripe-php/pull/688) Remove `SubscriptionScheduleRevision`
309
+ - Note that this is technically a breaking change, however we've chosen to release it as a minor version in light of the fact that this resource and its API methods were virtually unused.
310
+
311
+ ## 6.41.0 - 2019-07-31
312
+
313
+ - [#683](https://github.com/stripe/stripe-php/pull/683) Move the List Balance History API to `/v1/balance_transactions`
314
+
315
+ ## 6.40.0 - 2019-06-27
316
+
317
+ - [#675](https://github.com/stripe/stripe-php/pull/675) Add support for `SetupIntent` resource and APIs
318
+
319
+ ## 6.39.2 - 2019-06-26
320
+
321
+ - [#676](https://github.com/stripe/stripe-php/pull/676) Fix exception message in `CustomerBalanceTransaction::update()`
322
+
323
+ ## 6.39.1 - 2019-06-25
324
+
325
+ - [#674](https://github.com/stripe/stripe-php/pull/674) Add new constants for `collection_method` on `Invoice`
326
+
327
+ ## 6.39.0 - 2019-06-24
328
+
329
+ - [#673](https://github.com/stripe/stripe-php/pull/673) Enable request latency telemetry by default
330
+
331
+ ## 6.38.0 - 2019-06-17
332
+
333
+ - [#649](https://github.com/stripe/stripe-php/pull/649) Add support for `CustomerBalanceTransaction` resource and APIs
334
+
335
+ ## 6.37.2 - 2019-06-17
336
+
337
+ - [#671](https://github.com/stripe/stripe-php/pull/671) Add new PHPDoc
338
+ - [#672](https://github.com/stripe/stripe-php/pull/672) Add constants for `submit_type` on Checkout `Session`
339
+
340
+ ## 6.37.1 - 2019-06-14
341
+
342
+ - [#670](https://github.com/stripe/stripe-php/pull/670) Add new PHPDoc
343
+
344
+ ## 6.37.0 - 2019-05-23
345
+
346
+ - [#663](https://github.com/stripe/stripe-php/pull/663) Add support for `radar.early_fraud_warning` resource
347
+
348
+ ## 6.36.0 - 2019-05-22
349
+
350
+ - [#661](https://github.com/stripe/stripe-php/pull/661) Add constants for new TaxId types
351
+ - [#662](https://github.com/stripe/stripe-php/pull/662) Add constants for BalanceTransaction types
352
+
353
+ ## 6.35.2 - 2019-05-20
354
+
355
+ - [#655](https://github.com/stripe/stripe-php/pull/655) Add constants for payment intent statuses
356
+ - [#659](https://github.com/stripe/stripe-php/pull/659) Fix PHPDoc for various nested Account actions
357
+ - [#660](https://github.com/stripe/stripe-php/pull/660) Fix various PHPDoc
358
+
359
+ ## 6.35.1 - 2019-05-20
360
+
361
+ - [#658](https://github.com/stripe/stripe-php/pull/658) Use absolute value when checking timestamp tolerance
362
+
363
+ ## 6.35.0 - 2019-05-14
364
+
365
+ - [#651](https://github.com/stripe/stripe-php/pull/651) Add support for the Capability resource and APIs
366
+
367
+ ## 6.34.6 - 2019-05-13
368
+
369
+ - [#654](https://github.com/stripe/stripe-php/pull/654) Fix typo in definition of `Event::PAYMENT_METHOD_ATTACHED` constant
370
+
371
+ ## 6.34.5 - 2019-05-06
372
+
373
+ - [#647](https://github.com/stripe/stripe-php/pull/647) Set the return type to static for more operations
374
+
375
+ ## 6.34.4 - 2019-05-06
376
+
377
+ - [#650](https://github.com/stripe/stripe-php/pull/650) Add missing constants for Event types
378
+
379
+ ## 6.34.3 - 2019-05-01
380
+
381
+ - [#644](https://github.com/stripe/stripe-php/pull/644) Update return type to `static` to improve static analysis
382
+ - [#645](https://github.com/stripe/stripe-php/pull/645) Fix constant for `payment_intent.payment_failed`
383
+
384
+ ## 6.34.2 - 2019-04-26
385
+
386
+ - [#642](https://github.com/stripe/stripe-php/pull/642) Fix an issue where existing idempotency keys would be overwritten when using automatic retries
387
+
388
+ ## 6.34.1 - 2019-04-25
389
+
390
+ - [#640](https://github.com/stripe/stripe-php/pull/640) Add missing phpdocs
391
+
392
+ ## 6.34.0 - 2019-04-24
393
+
394
+ - [#626](https://github.com/stripe/stripe-php/pull/626) Add support for the `TaxRate` resource and APIs
395
+ - [#639](https://github.com/stripe/stripe-php/pull/639) Fix multiple phpdoc issues
396
+
397
+ ## 6.33.0 - 2019-04-22
398
+
399
+ - [#630](https://github.com/stripe/stripe-php/pull/630) Add support for the `TaxId` resource and APIs
400
+
401
+ ## 6.32.1 - 2019-04-19
402
+
403
+ - [#636](https://github.com/stripe/stripe-php/pull/636) Correct type of `$personId` in PHPDoc
404
+
405
+ ## 6.32.0 - 2019-04-18
406
+
407
+ - [#621](https://github.com/stripe/stripe-php/pull/621) Add support for `CreditNote`
408
+
409
+ ## 6.31.5 - 2019-04-12
410
+
411
+ - [#628](https://github.com/stripe/stripe-php/pull/628) Add constants for `person.*` event types
412
+ - [#628](https://github.com/stripe/stripe-php/pull/628) Add missing constants for `Account` and `Person`
413
+
414
+ ## 6.31.4 - 2019-04-05
415
+
416
+ - [#624](https://github.com/stripe/stripe-php/pull/624) Fix encoding of nested parameters in multipart requests
417
+
418
+ ## 6.31.3 - 2019-04-02
419
+
420
+ - [#623](https://github.com/stripe/stripe-php/pull/623) Only use HTTP/2 with curl >= 7.60.0
421
+
422
+ ## 6.31.2 - 2019-03-25
423
+
424
+ - [#619](https://github.com/stripe/stripe-php/pull/619) Fix PHPDoc return types for list methods for nested resources
425
+
426
+ ## 6.31.1 - 2019-03-22
427
+
428
+ - [#612](https://github.com/stripe/stripe-php/pull/612) Add a lot of constants
429
+ - [#614](https://github.com/stripe/stripe-php/pull/614) Add missing subscription status constants
430
+
431
+ ## 6.31.0 - 2019-03-18
432
+
433
+ - [#600](https://github.com/stripe/stripe-php/pull/600) Add support for the `PaymentMethod` resource and APIs
434
+ - [#606](https://github.com/stripe/stripe-php/pull/606) Add support for retrieving a Checkout `Session`
435
+ - [#611](https://github.com/stripe/stripe-php/pull/611) Add support for deleting a Terminal `Location` and `Reader`
436
+
437
+ ## 6.30.5 - 2019-03-11
438
+
439
+ - [#607](https://github.com/stripe/stripe-php/pull/607) Correctly handle case where a metadata key is called `metadata`
440
+
441
+ ## 6.30.4 - 2019-02-27
442
+
443
+ - [#602](https://github.com/stripe/stripe-php/pull/602) Add `subscription_schedule` to `Subscription` for PHPDoc.
444
+
445
+ ## 6.30.3 - 2019-02-26
446
+
447
+ - [#603](https://github.com/stripe/stripe-php/pull/603) Improve PHPDoc on the `Source` object to cover all types of Sources currently supported.
448
+
449
+ ## 6.30.2 - 2019-02-25
450
+
451
+ - [#601](https://github.com/stripe/stripe-php/pull/601) Fix PHPDoc across multiple resources and add support for new events.
452
+
453
+ ## 6.30.1 - 2019-02-16
454
+
455
+ - [#599](https://github.com/stripe/stripe-php/pull/599) Fix PHPDoc for `SubscriptionSchedule` and `SubscriptionScheduleRevision`
456
+
457
+ ## 6.30.0 - 2019-02-12
458
+
459
+ - [#590](https://github.com/stripe/stripe-php/pull/590) Add support for `SubscriptionSchedule` and `SubscriptionScheduleRevision`
460
+
461
+ ## 6.29.3 - 2019-01-31
462
+
463
+ - [#592](https://github.com/stripe/stripe-php/pull/592) Some more PHPDoc fixes
464
+
465
+ ## 6.29.2 - 2019-01-31
466
+
467
+ - [#591](https://github.com/stripe/stripe-php/pull/591) Fix PHPDoc for nested resources
468
+
469
+ ## 6.29.1 - 2019-01-25
470
+
471
+ - [#566](https://github.com/stripe/stripe-php/pull/566) Fix dangling message contents
472
+ - [#586](https://github.com/stripe/stripe-php/pull/586) Don't overwrite `CURLOPT_HTTP_VERSION` option
473
+
474
+ ## 6.29.0 - 2019-01-23
475
+
476
+ - [#579](https://github.com/stripe/stripe-php/pull/579) Rename `CheckoutSession` to `Session` and move it under the `Checkout` namespace. This is a breaking change, but we've reached out to affected merchants and all new merchants would use the new approach.
477
+
478
+ ## 6.28.1 - 2019-01-21
479
+
480
+ - [#580](https://github.com/stripe/stripe-php/pull/580) Properly serialize `individual` on `Account` objects
481
+
482
+ ## 6.28.0 - 2019-01-03
483
+
484
+ - [#576](https://github.com/stripe/stripe-php/pull/576) Add support for iterating directly over `Collection` instances
485
+
486
+ ## 6.27.0 - 2018-12-21
487
+
488
+ - [#571](https://github.com/stripe/stripe-php/pull/571) Add support for the `CheckoutSession` resource
489
+
490
+ ## 6.26.0 - 2018-12-11
491
+
492
+ - [#568](https://github.com/stripe/stripe-php/pull/568) Enable persistent connections
493
+
494
+ ## 6.25.0 - 2018-12-10
495
+
496
+ - [#567](https://github.com/stripe/stripe-php/pull/567) Add support for account links
497
+
498
+ ## 6.24.0 - 2018-11-28
499
+
500
+ - [#562](https://github.com/stripe/stripe-php/pull/562) Add support for the Review resource
501
+ - [#564](https://github.com/stripe/stripe-php/pull/564) Add event name constants for subscription schedule aborted/expiring
502
+
503
+ ## 6.23.0 - 2018-11-27
504
+
505
+ - [#542](https://github.com/stripe/stripe-php/pull/542) Add support for `ValueList` and `ValueListItem` for Radar
506
+
507
+ ## 6.22.1 - 2018-11-20
508
+
509
+ - [#561](https://github.com/stripe/stripe-php/pull/561) Add cast and some docs to telemetry introduced in 6.22.0/549
510
+
511
+ ## 6.22.0 - 2018-11-15
512
+
513
+ - [#549](https://github.com/stripe/stripe-php/pull/549) Add support for client telemetry
514
+
515
+ ## 6.21.1 - 2018-11-12
516
+
517
+ - [#548](https://github.com/stripe/stripe-php/pull/548) Don't mutate `Exception` class properties from `OAuthBase` error
518
+
519
+ ## 6.21.0 - 2018-11-08
520
+
521
+ - [#537](https://github.com/stripe/stripe-php/pull/537) Add new API endpoints for the `Invoice` resource.
522
+
523
+ ## 6.20.1 - 2018-11-07
524
+
525
+ - [#546](https://github.com/stripe/stripe-php/pull/546) Drop files from the Composer package that aren't needed in the release
526
+
527
+ ## 6.20.0 - 2018-10-30
528
+
529
+ - [#536](https://github.com/stripe/stripe-php/pull/536) Add support for the `Person` resource
530
+ - [#541](https://github.com/stripe/stripe-php/pull/541) Add support for the `WebhookEndpoint` resource
531
+
532
+ ## 6.19.5 - 2018-10-17
533
+
534
+ - [#539](https://github.com/stripe/stripe-php/pull/539) Fix methods on `\Stripe\PaymentIntent` to properly pass arguments to the API.
535
+
536
+ ## 6.19.4 - 2018-10-11
537
+
538
+ - [#534](https://github.com/stripe/stripe-php/pull/534) Fix PSR-4 autoloading for `\Stripe\FileUpload` class alias
539
+
540
+ ## 6.19.3 - 2018-10-09
541
+
542
+ - [#530](https://github.com/stripe/stripe-php/pull/530) Add constants for `flow` (`FLOW_*`), `status` (`STATUS_*`) and `usage` (`USAGE_*`) on `\Stripe\Source`
543
+
544
+ ## 6.19.2 - 2018-10-08
545
+
546
+ - [#531](https://github.com/stripe/stripe-php/pull/531) Store HTTP response headers in case-insensitive array
547
+
548
+ ## 6.19.1 - 2018-09-25
549
+
550
+ - [#526](https://github.com/stripe/stripe-php/pull/526) Ignore null values in request parameters
551
+
552
+ ## 6.19.0 - 2018-09-24
553
+
554
+ - [#523](https://github.com/stripe/stripe-php/pull/523) Add support for Stripe Terminal
555
+
556
+ ## 6.18.0 - 2018-09-24
557
+
558
+ - [#520](https://github.com/stripe/stripe-php/pull/520) Rename `\Stripe\FileUpload` to `\Stripe\File`
559
+
560
+ ## 6.17.2 - 2018-09-18
561
+
562
+ - [#522](https://github.com/stripe/stripe-php/pull/522) Fix warning when adding a new additional owner to an existing array
563
+
564
+ ## 6.17.1 - 2018-09-14
565
+
566
+ - [#517](https://github.com/stripe/stripe-php/pull/517) Integer-index encode all sequential arrays
567
+
568
+ ## 6.17.0 - 2018-09-05
569
+
570
+ - [#514](https://github.com/stripe/stripe-php/pull/514) Add support for reporting resources
571
+
572
+ ## 6.16.0 - 2018-08-23
573
+
574
+ - [#509](https://github.com/stripe/stripe-php/pull/509) Add support for usage record summaries
575
+
576
+ ## 6.15.0 - 2018-08-03
577
+
578
+ - [#504](https://github.com/stripe/stripe-php/pull/504) Add cancel support for topups
579
+
580
+ ## 6.14.0 - 2018-08-02
581
+
582
+ - [#505](https://github.com/stripe/stripe-php/pull/505) Add support for file links
583
+
584
+ ## 6.13.0 - 2018-07-31
585
+
586
+ - [#502](https://github.com/stripe/stripe-php/pull/502) Add `isDeleted()` method to `\Stripe\StripeObject`
587
+
588
+ ## 6.12.0 - 2018-07-28
589
+
590
+ - [#501](https://github.com/stripe/stripe-php/pull/501) Add support for scheduled query runs (`\Stripe\Sigma\ScheduledQueryRun`) for Sigma
591
+
592
+ ## 6.11.0 - 2018-07-26
593
+
594
+ - [#500](https://github.com/stripe/stripe-php/pull/500) Add support for Stripe Issuing
595
+
596
+ ## 6.10.4 - 2018-07-19
597
+
598
+ - [#498](https://github.com/stripe/stripe-php/pull/498) Internal improvements to the `\Stripe\ApiResource.classUrl()` method
599
+
600
+ ## 6.10.3 - 2018-07-16
601
+
602
+ - [#497](https://github.com/stripe/stripe-php/pull/497) Use HTTP/2 only for HTTPS requests
603
+
604
+ ## 6.10.2 - 2018-07-11
605
+
606
+ - [#494](https://github.com/stripe/stripe-php/pull/494) Enable HTTP/2 support
607
+
608
+ ## 6.10.1 - 2018-07-10
609
+
610
+ - [#493](https://github.com/stripe/stripe-php/pull/493) Add PHPDoc for `auto_advance` on `\Stripe\Invoice`
611
+
612
+ ## 6.10.0 - 2018-06-28
613
+
614
+ - [#488](https://github.com/stripe/stripe-php/pull/488) Add support for `$appPartnerId` to `Stripe::setAppInfo()`
615
+
616
+ ## 6.9.0 - 2018-06-28
617
+
618
+ - [#487](https://github.com/stripe/stripe-php/pull/487) Add support for payment intents
619
+
620
+ ## 6.8.2 - 2018-06-24
621
+
622
+ - [#486](https://github.com/stripe/stripe-php/pull/486) Make `Account.deauthorize()` return the `StripeObject` from the API
623
+
624
+ ## 6.8.1 - 2018-06-13
625
+
626
+ - [#472](https://github.com/stripe/stripe-php/pull/472) Added phpDoc for `ApiRequestor` and others, especially regarding thrown errors
627
+
628
+ ## 6.8.0 - 2018-06-13
629
+
630
+ - [#481](https://github.com/stripe/stripe-php/pull/481) Add new `\Stripe\Discount` and `\Stripe\OrderItem` classes, add more PHPDoc describing object attributes
631
+
632
+ ## 6.7.4 - 2018-05-29
633
+
634
+ - [#480](https://github.com/stripe/stripe-php/pull/480) PHPDoc changes for API version 2018-05-21 and the addition of the new `CHARGE_EXPIRED` event type
635
+
636
+ ## 6.7.3 - 2018-05-28
637
+
638
+ - [#479](https://github.com/stripe/stripe-php/pull/479) Fix unnecessary traits on `\Stripe\InvoiceLineItem`
639
+
640
+ ## 6.7.2 - 2018-05-28
641
+
642
+ - [#471](https://github.com/stripe/stripe-php/pull/471) Add `OBJECT_NAME` constant to all API resource classes, add `\Stripe\InvoiceLineItem` class
643
+
644
+ ## 6.7.1 - 2018-05-13
645
+
646
+ - [#468](https://github.com/stripe/stripe-php/pull/468) Update fields in PHP docs for accuracy
647
+
648
+ ## 6.7.0 - 2018-05-09
649
+
650
+ - [#466](https://github.com/stripe/stripe-php/pull/466) Add support for issuer fraud records
651
+
652
+ ## 6.6.0 - 2018-04-11
653
+
654
+ - [#460](https://github.com/stripe/stripe-php/pull/460) Add support for flexible billing primitives
655
+
656
+ ## 6.5.0 - 2018-04-05
657
+
658
+ - [#461](https://github.com/stripe/stripe-php/pull/461) Don't zero keys on non-`metadata` subobjects
659
+
660
+ ## 6.4.2 - 2018-03-17
661
+
662
+ - [#458](https://github.com/stripe/stripe-php/pull/458) Add PHPDoc for `account` on `\Stripe\Event`
663
+
664
+ ## 6.4.1 - 2018-03-02
665
+
666
+ - [#455](https://github.com/stripe/stripe-php/pull/455) Fix namespaces in PHPDoc
667
+ - [#456](https://github.com/stripe/stripe-php/pull/456) Fix namespaces for some exceptions
668
+
669
+ ## 6.4.0 - 2018-02-28
670
+
671
+ - [#453](https://github.com/stripe/stripe-php/pull/453) Add constants for `reason` (`REASON_*`) and `status` (`STATUS_*`) on `\Stripe\Dispute`
672
+
673
+ ## 6.3.2 - 2018-02-27
674
+
675
+ - [#452](https://github.com/stripe/stripe-php/pull/452) Add PHPDoc for `amount_paid` and `amount_remaining` on `\Stripe\Invoice`
676
+
677
+ ## 6.3.1 - 2018-02-26
678
+
679
+ - [#443](https://github.com/stripe/stripe-php/pull/443) Add event types as constants to `\Stripe\Event` class
680
+
681
+ ## 6.3.0 - 2018-02-23
682
+
683
+ - [#450](https://github.com/stripe/stripe-php/pull/450) Add support for `code` attribute on all Stripe exceptions
684
+
685
+ ## 6.2.0 - 2018-02-21
686
+
687
+ - [#440](https://github.com/stripe/stripe-php/pull/440) Add support for topups
688
+ - [#442](https://github.com/stripe/stripe-php/pull/442) Fix PHPDoc for `\Stripe\Error\SignatureVerification`
689
+
690
+ ## 6.1.0 - 2018-02-12
691
+
692
+ - [#435](https://github.com/stripe/stripe-php/pull/435) Fix header persistence on `Collection` objects
693
+ - [#436](https://github.com/stripe/stripe-php/pull/436) Introduce new `Idempotency` error class
694
+
695
+ ## 6.0.0 - 2018-02-07
696
+
697
+ Major version release. List of backwards incompatible changes to watch out for:
698
+
699
+ - The minimum PHP version is now 5.4.0. If you're using PHP 5.3 or older, consider upgrading to a more recent version.
700
+
701
+ * `\Stripe\AttachedObject` no longer exists. Attributes that used to be instances of `\Stripe\AttachedObject` (such as `metadata`) are now instances of `\Stripe\StripeObject`.
702
+
703
+ - Attributes that used to be PHP arrays (such as `legal_entity->additional_owners` on `\Stripe\Account` instances) are now instances of `\Stripe\StripeObject`, except when they are empty. `\Stripe\StripeObject` has array semantics so this should not be an issue unless you are actively checking types.
704
+
705
+ * `\Stripe\Collection` now derives from `\Stripe\StripeObject` rather than from `\Stripe\ApiResource`.
706
+
707
+ Pull requests included in this release:
708
+
709
+ - [#410](https://github.com/stripe/stripe-php/pull/410) Drop support for PHP 5.3
710
+ - [#411](https://github.com/stripe/stripe-php/pull/411) Use traits for common API operations
711
+ - [#414](https://github.com/stripe/stripe-php/pull/414) Use short array syntax
712
+ - [#404](https://github.com/stripe/stripe-php/pull/404) Fix serialization logic
713
+ - [#417](https://github.com/stripe/stripe-php/pull/417) Remove `ExternalAccount` class
714
+ - [#418](https://github.com/stripe/stripe-php/pull/418) Increase test coverage
715
+ - [#421](https://github.com/stripe/stripe-php/pull/421) Update CA bundle and add script for future updates
716
+ - [#422](https://github.com/stripe/stripe-php/pull/422) Use vendored CA bundle for all requests
717
+ - [#428](https://github.com/stripe/stripe-php/pull/428) Support for automatic request retries
718
+
719
+ ## 5.9.2 - 2018-02-07
720
+
721
+ - [#431](https://github.com/stripe/stripe-php/pull/431) Update PHPDoc @property tags for latest API version
722
+
723
+ ## 5.9.1 - 2018-02-06
724
+
725
+ - [#427](https://github.com/stripe/stripe-php/pull/427) Add and update PHPDoc @property tags on all API resources
726
+
727
+ ## 5.9.0 - 2018-01-17
728
+
729
+ - [#421](https://github.com/stripe/stripe-php/pull/421) Updated bundled CA certificates
730
+ - [#423](https://github.com/stripe/stripe-php/pull/423) Escape unsanitized input in OAuth example
731
+
732
+ ## 5.8.0 - 2017-12-20
733
+
734
+ - [#403](https://github.com/stripe/stripe-php/pull/403) Add `__debugInfo()` magic method to `StripeObject`
735
+
736
+ ## 5.7.0 - 2017-11-28
737
+
738
+ - [#390](https://github.com/stripe/stripe-php/pull/390) Remove some unsupported API methods
739
+ - [#391](https://github.com/stripe/stripe-php/pull/391) Alphabetize the list of API resources in `Util::convertToStripeObject()` and add missing resources
740
+ - [#393](https://github.com/stripe/stripe-php/pull/393) Fix expiry date update for card sources
741
+
742
+ ## 5.6.0 - 2017-10-31
743
+
744
+ - [#386](https://github.com/stripe/stripe-php/pull/386) Support for exchange rates APIs
745
+
746
+ ## 5.5.1 - 2017-10-30
747
+
748
+ - [#387](https://github.com/stripe/stripe-php/pull/387) Allow `personal_address_kana` and `personal_address_kanji` to be updated on an account
749
+
750
+ ## 5.5.0 - 2017-10-27
751
+
752
+ - [#385](https://github.com/stripe/stripe-php/pull/385) Support for listing source transactions
753
+
754
+ ## 5.4.0 - 2017-10-24
755
+
756
+ - [#383](https://github.com/stripe/stripe-php/pull/383) Add static methods to manipulate resources from parent
757
+ - `Account` gains methods for external accounts and login links (e.g. `createExternalAccount`, `createLoginLink`)
758
+ - `ApplicationFee` gains methods for refunds
759
+ - `Customer` gains methods for sources
760
+ - `Transfer` gains methods for reversals
761
+
762
+ ## 5.3.0 - 2017-10-11
763
+
764
+ - [#378](https://github.com/stripe/stripe-php/pull/378) Rename source `delete` to `detach` (and deprecate the former)
765
+
766
+ ## 5.2.3 - 2017-09-27
767
+
768
+ - Add PHPDoc for `Card`
769
+
770
+ ## 5.2.2 - 2017-09-20
771
+
772
+ - Fix deserialization mapping of `FileUpload` objects
773
+
774
+ ## 5.2.1 - 2017-09-14
775
+
776
+ - Serialized `shipping` nested attribute
777
+
778
+ ## 5.2.0 - 2017-08-29
779
+
780
+ - Add support for `InvalidClient` OAuth error
781
+
782
+ ## 5.1.3 - 2017-08-14
783
+
784
+ - Allow `address_kana` and `address_kanji` to be updated for custom accounts
785
+
786
+ ## 5.1.2 - 2017-08-01
787
+
788
+ - Fix documented return type of `autoPagingIterator()` (was missing namespace)
789
+
790
+ ## 5.1.1 - 2017-07-03
791
+
792
+ - Fix order returns to use the right URL `/v1/order_returns`
793
+
794
+ ## 5.1.0 - 2017-06-30
795
+
796
+ - Add support for OAuth
797
+
798
+ ## 5.0.0 - 2017-06-27
799
+
800
+ - `pay` on invoice now takes params as well as opts
801
+
802
+ ## 4.13.0 - 2017-06-19
803
+
804
+ - Add support for ephemeral keys
805
+
806
+ ## 4.12.0 - 2017-06-05
807
+
808
+ - Clients can implement `getUserAgentInfo()` to add additional user agent information
809
+
810
+ ## 4.11.0 - 2017-06-05
811
+
812
+ - Implement `Countable` for `AttachedObject` (`metadata` and `additional_owners`)
813
+
814
+ ## 4.10.0 - 2017-05-25
815
+
816
+ - Add support for login links
817
+
818
+ ## 4.9.1 - 2017-05-10
819
+
820
+ - Fix docs to include arrays on `$id` parameter for retrieve methods
821
+
822
+ ## 4.9.0 - 2017-04-28
823
+
824
+ - Support for checking webhook signatures
825
+
826
+ ## 4.8.1 - 2017-04-24
827
+
828
+ - Allow nested field `payout_schedule` to be updated
829
+
830
+ ## 4.8.0 - 2017-04-20
831
+
832
+ - Add `\Stripe\Stripe::setLogger()` to support an external PSR-3 compatible logger
833
+
834
+ ## 4.7.0 - 2017-04-10
835
+
836
+ - Add support for payouts and recipient transfers
837
+
838
+ ## 4.6.0 - 2017-04-06
839
+
840
+ - Please see 4.7.0 instead (no-op release)
841
+
842
+ ## 4.5.1 - 2017-03-22
843
+
844
+ - Remove hard dependency on cURL
845
+
846
+ ## 4.5.0 - 2017-03-20
847
+
848
+ - Support for detaching sources from customers
849
+
850
+ ## 4.4.2 - 2017-02-27
851
+
852
+ - Correct handling of `owner` parameter when updating sources
853
+
854
+ ## 4.4.1 - 2017-02-24
855
+
856
+ - Correct the error check on a bad JSON decoding
857
+
858
+ ## 4.4.0 - 2017-01-18
859
+
860
+ - Add support for updating sources
861
+
862
+ ## 4.3.0 - 2016-11-30
863
+
864
+ - Add support for verifying sources
865
+
866
+ ## 4.2.0 - 2016-11-21
867
+
868
+ - Add retrieve method for 3-D Secure resources
869
+
870
+ ## 4.1.1 - 2016-10-21
871
+
872
+ - Add docblock with model properties for `Plan`
873
+
874
+ ## 4.1.0 - 2016-10-18
875
+
876
+ - Support for 403 status codes (permission denied)
877
+
878
+ ## 4.0.1 - 2016-10-17
879
+
880
+ - Fix transfer reversal materialization
881
+ - Fixes for some property definitions in docblocks
882
+
883
+ ## 4.0.0 - 2016-09-28
884
+
885
+ - Support for subscription items
886
+ - Drop attempt to force TLS 1.2: please note that this could be breaking if you're using old OS distributions or packages and upgraded recently (so please make sure to test your integration!)
887
+
888
+ ## 3.23.0 - 2016-09-15
889
+
890
+ - Add support for Apple Pay domains
891
+
892
+ ## 3.22.0 - 2016-09-13
893
+
894
+ - Add `Stripe::setAppInfo` to allow plugins to register user agent information
895
+
896
+ ## 3.21.0 - 2016-08-25
897
+
898
+ - Add `Source` model for generic payment sources
899
+
900
+ ## 3.20.0 - 2016-08-08
901
+
902
+ - Add `getDeclineCode` to card errors
903
+
904
+ ## 3.19.0 - 2016-07-29
905
+
906
+ - Opt requests directly into TLS 1.2 where OpenSSL >= 1.0.1 (see #277 for context)
907
+
908
+ ## 3.18.0 - 2016-07-28
909
+
910
+ - Add new `STATUS_` constants for subscriptions
911
+
912
+ ## 3.17.1 - 2016-07-28
913
+
914
+ - Fix auto-paging iterator so that it plays nicely with `iterator_to_array`
915
+
916
+ ## 3.17.0 - 2016-07-14
917
+
918
+ - Add field annotations to model classes for better editor hinting
919
+
920
+ ## 3.16.0 - 2016-07-12
921
+
922
+ - Add `ThreeDSecure` model for 3-D secure payments
923
+
924
+ ## 3.15.0 - 2016-06-29
925
+
926
+ - Add static `update` method to all resources that can be changed.
927
+
928
+ ## 3.14.3 - 2016-06-20
929
+
930
+ - Make sure that cURL never sends `Expects: 100-continue`, even on large request bodies
931
+
932
+ ## 3.14.2 - 2016-06-03
933
+
934
+ - Add `inventory` under `SKU` to list of keys that have nested data and can be updated
935
+
936
+ ## 3.14.1 - 2016-05-27
937
+
938
+ - Fix some inconsistencies in PHPDoc
939
+
940
+ ## 3.14.0 - 2016-05-25
941
+
942
+ - Add support for returning Relay orders
943
+
944
+ ## 3.13.0 - 2016-05-04
945
+
946
+ - Add `list`, `create`, `update`, `retrieve`, and `delete` methods to the Subscription class
947
+
948
+ ## 3.12.1 - 2016-04-07
949
+
950
+ - Additional check on value arrays for some extra safety
951
+
952
+ ## 3.12.0 - 2016-03-31
953
+
954
+ - Fix bug `refreshFrom` on `StripeObject` would not take an `$opts` array
955
+ - Fix bug where `$opts` not passed to parent `save` method in `Account`
956
+ - Fix bug where non-existent variable was referenced in `reverse` in `Transfer`
957
+ - Update CA cert bundle for compatibility with OpenSSL versions below 1.0.1
958
+
959
+ ## 3.11.0 - 2016-03-22
960
+
961
+ - Allow `CurlClient` to be initialized with default `CURLOPT_*` options
962
+
963
+ ## 3.10.1 - 2016-03-22
964
+
965
+ - Fix bug where request params and options were ignored in `ApplicationFee`'s `refund.`
966
+
967
+ ## 3.10.0 - 2016-03-15
968
+
969
+ - Add `reject` on `Account` to support the new API feature
970
+
971
+ ## 3.9.2 - 2016-03-04
972
+
973
+ - Fix error when an object's metadata is set more than once
974
+
975
+ ## 3.9.1 - 2016-02-24
976
+
977
+ - Fix encoding behavior of nested arrays for requests (see #227)
978
+
979
+ ## 3.9.0 - 2016-02-09
980
+
981
+ - Add automatic pagination mechanism with `autoPagingIterator()`
982
+ - Allow global account ID to be set with `Stripe::setAccountId()`
983
+
984
+ ## 3.8.0 - 2016-02-08
985
+
986
+ - Add `CountrySpec` model for looking up country payment information
987
+
988
+ ## 3.7.1 - 2016-02-01
989
+
990
+ - Update bundled CA certs
991
+
992
+ ## 3.7.0 - 2016-01-27
993
+
994
+ - Support deleting Relay products and SKUs
995
+
996
+ ## 3.6.0 - 2016-01-05
997
+
998
+ - Allow configuration of HTTP client timeouts
999
+
1000
+ ## 3.5.0 - 2015-12-01
1001
+
1002
+ - Add a verification routine for external accounts
1003
+
1004
+ ## 3.4.0 - 2015-09-14
1005
+
1006
+ - Products, SKUs, and Orders -- https://stripe.com/relay
1007
+
1008
+ ## 3.3.0 - 2015-09-11
1009
+
1010
+ - Add support for 429 Rate Limit response
1011
+
1012
+ ## 3.2.0 - 2015-08-17
1013
+
1014
+ - Add refund listing and retrieval without an associated charge
1015
+
1016
+ ## 3.1.0 - 2015-08-03
1017
+
1018
+ - Add dispute listing and retrieval
1019
+ - Add support for manage account deletion
1020
+
1021
+ ## 3.0.0 - 2015-07-28
1022
+
1023
+ - Rename `\Stripe\Object` to `\Stripe\StripeObject` (PHP 7 compatibility)
1024
+ - Rename `getCode` and `getParam` in exceptions to `getStripeCode` and `getStripeParam`
1025
+ - Add support for calling `json_encode` on Stripe objects in PHP 5.4+
1026
+ - Start supporting/testing PHP 7
1027
+
1028
+ ## 2.3.0 - 2015-07-06
1029
+
1030
+ - Add request ID to all Stripe exceptions
1031
+
1032
+ ## 2.2.0 - 2015-06-01
1033
+
1034
+ - Add support for Alipay accounts as sources
1035
+ - Add support for bank accounts as sources (private beta)
1036
+ - Add support for bank accounts and cards as external_accounts on Account objects
1037
+
1038
+ ## 2.1.4 - 2015-05-13
1039
+
1040
+ - Fix CA certificate file path (thanks @lphilps & @matthewarkin)
1041
+
1042
+ ## 2.1.3 - 2015-05-12
1043
+
1044
+ - Fix to account updating to permit `tos_acceptance` and `personal_address` to be set properly
1045
+ - Fix to Transfer reversal creation (thanks @neatness!)
1046
+ - Network requests are now done through a swappable class for easier mocking
1047
+
1048
+ ## 2.1.2 - 2015-04-10
1049
+
1050
+ - Remove SSL cert revokation checking (all pre-Heartbleed certs have expired)
1051
+ - Bug fixes to account updating
1052
+
1053
+ ## 2.1.1 - 2015-02-27
1054
+
1055
+ - Support transfer reversals
1056
+
1057
+ ## 2.1.0 - 2015-02-19
1058
+
1059
+ - Support new API version (2015-02-18)
1060
+ - Added Bitcoin Receiever update and delete actions
1061
+ - Edited tests to prefer "source" over "card" as per new API version
1062
+
1063
+ ## 2.0.1 - 2015-02-16
1064
+
1065
+ - Fix to fetching endpoints that use a non-default baseUrl (`FileUpload`)
1066
+
1067
+ ## 2.0.0 - 2015-02-14
1068
+
1069
+ - Bumped minimum version to 5.3.3
1070
+ - Switched to Stripe namespace instead of Stripe\_ class name prefiexes (thanks @chadicus!)
1071
+ - Switched tests to PHPUnit (thanks @chadicus!)
1072
+ - Switched style guide to PSR2 (thanks @chadicus!)
1073
+ - Added \$opts hash to the end of most methods: this permits passing 'idempotency_key', 'stripe_account', or 'stripe_version'. The last 2 will persist across multiple object loads.
1074
+ - Added support for retrieving Account by ID
1075
+
1076
+ ## 1.18.0 - 2015-01-21
1077
+
1078
+ - Support making bitcoin charges through BitcoinReceiver source object
1079
+
1080
+ ## 1.17.5 - 2014-12-23
1081
+
1082
+ - Adding support for creating file uploads.
1083
+
1084
+ ## 1.17.4 - 2014-12-15
1085
+
1086
+ - Saving objects fetched with a custom key now works (thanks @JustinHook & @jpasilan)
1087
+ - Added methods for reporting charges as safe or fraudulent and for specifying the reason for refunds
1088
+
1089
+ ## 1.17.3 - 2014-11-06
1090
+
1091
+ - Better handling of HHVM support for SSL certificate blacklist checking.
1092
+
1093
+ ## 1.17.2 - 2014-09-23
1094
+
1095
+ - Coupons now are backed by a `Stripe_Coupon` instead of `Stripe_Object`, and support updating metadata
1096
+ - Running operations (`create`, `retrieve`, `all`) on upcoming invoice items now works
1097
+
1098
+ ## 1.17.1 - 2014-07-31
1099
+
1100
+ - Requests now send Content-Type header
1101
+
1102
+ ## 1.17.0 - 2014-07-29
1103
+
1104
+ - Application Fee refunds now a list instead of array
1105
+ - HHVM now works
1106
+ - Small bug fixes (thanks @bencromwell & @fastest963)
1107
+ - `__toString` now returns the name of the object in addition to its JSON representation
1108
+
1109
+ ## 1.16.0 - 2014-06-17
1110
+
1111
+ - Add metadata for refunds and disputes
1112
+
1113
+ ## 1.15.0 - 2014-05-28
1114
+
1115
+ - Support canceling transfers
1116
+
1117
+ ## 1.14.1 - 2014-05-21
1118
+
1119
+ - Support cards for recipients.
1120
+
1121
+ ## 1.13.1 - 2014-05-15
1122
+
1123
+ - Fix bug in account resource where `id` wasn't in the result
1124
+
1125
+ ## 1.13.0 - 2014-04-10
1126
+
1127
+ - Add support for certificate blacklisting
1128
+ - Update ca bundle
1129
+ - Drop support for HHVM (Temporarily)
1130
+
1131
+ ## 1.12.0 - 2014-04-01
1132
+
1133
+ - Add Stripe_RateLimitError for catching rate limit errors.
1134
+ - Update to Zend coding style (thanks, @jpiasetz)
1135
+
1136
+ ## 1.11.0 - 2014-01-29
1137
+
1138
+ - Add support for multiple subscriptions per customer
1139
+
1140
+ ## 1.10.1 - 2013-12-02
1141
+
1142
+ - Add new ApplicationFee
1143
+
1144
+ ## 1.9.1 - 2013-11-08
1145
+
1146
+ - Fix a bug where a null nestable object causes warnings to fire.
1147
+
1148
+ ## 1.9.0 - 2013-10-16
1149
+
1150
+ - Add support for metadata API.
1151
+
1152
+ ## 1.8.4 - 2013-09-18
1153
+
1154
+ - Add support for closing disputes.
1155
+
1156
+ ## 1.8.3 - 2013-08-13
1157
+
1158
+ - Add new Balance and BalanceTransaction
1159
+
1160
+ ## 1.8.2 - 2013-08-12
1161
+
1162
+ - Add support for unsetting attributes by updating to NULL. Setting properties to a blank string is now an error.
1163
+
1164
+ ## 1.8.1 - 2013-07-12
1165
+
1166
+ - Add support for multiple cards API (Stripe API version 2013-07-12: https://stripe.com/docs/upgrades#2013-07-05)
1167
+
1168
+ ## 1.8.0 - 2013-04-11
1169
+
1170
+ - Allow Transfers to be creatable
1171
+ - Add new Recipient resource
1172
+
1173
+ ## 1.7.15 - 2013-02-21
1174
+
1175
+ - Add 'id' to the list of permanent object attributes
1176
+
1177
+ ## 1.7.14 - 2013-02-20
1178
+
1179
+ - Don't re-encode strings that are already encoded in UTF-8. If you were previously using plan or coupon objects with UTF-8 IDs, they may have been treated as ISO-8859-1 (Latin-1) and encoded to UTF-8 a 2nd time. You may now need to pass the IDs to utf8_encode before passing them to Stripe_Plan::retrieve or Stripe_Coupon::retrieve.
1180
+ - Ensure that all input is encoded in UTF-8 before submitting it to Stripe's servers. (github issue #27)
1181
+
1182
+ ## 1.7.13 - 2013-02-01
1183
+
1184
+ - Add support for passing options when retrieving Stripe objects e.g., Stripe_Charge::retrieve(array("id"=>"foo", "expand" => array("customer"))); Stripe_Charge::retrieve("foo") will continue to work
1185
+
1186
+ ## 1.7.12 - 2013-01-15
1187
+
1188
+ - Add support for setting a Stripe API version override
1189
+
1190
+ ## 1.7.11 - 2012-12-30
1191
+
1192
+ - Version bump to cleanup constants and such (fix issue #26)
1193
+
1194
+ ## 1.7.10 - 2012-11-08
1195
+
1196
+ - Add support for updating charge disputes.
1197
+ - Fix bug preventing retrieval of null attributes
1198
+
1199
+ ## 1.7.9 - 2012-11-08
1200
+
1201
+ - Fix usage under autoloaders such as the one generated by composer (fix issue #22)
1202
+
1203
+ ## 1.7.8 - 2012-10-30
1204
+
1205
+ - Add support for creating invoices.
1206
+ - Add support for new invoice lines return format
1207
+ - Add support for new list objects
1208
+
1209
+ ## 1.7.7 - 2012-09-14
1210
+
1211
+ - Get all of the various version numbers in the repo in sync (no other changes)
1212
+
1213
+ ## 1.7.6 - 2012-08-31
1214
+
1215
+ - Add update and pay methods to Invoice resource
1216
+
1217
+ ## 1.7.5 - 2012-08-23
1218
+
1219
+ - Change internal function names so that Stripe_SingletonApiRequest is E_STRICT-clean (github issue #16)
1220
+
1221
+ ## 1.7.4 - 2012-08-21
1222
+
1223
+ - Bugfix so that Stripe objects (e.g. Customer, Charge objects) used in API calls are transparently converted to their object IDs
1224
+
1225
+ ## 1.7.3 - 2012-08-15
1226
+
1227
+ - Add new Account resource
1228
+
1229
+ ## 1.7.2 - 2012-06-26
1230
+
1231
+ - Make clearer that you should be including lib/Stripe.php, not test/Stripe.php (github issue #14)
1232
+
1233
+ ## 1.7.1 - 2012-05-24
1234
+
1235
+ - Add missing argument to Stripe_InvalidRequestError constructor in Stripe_ApiResource::instanceUrl. Fixes a warning when Stripe_ApiResource::instanceUrl is called on a resource with no ID (fix issue #12)
1236
+
1237
+ ## 1.7.0 - 2012-05-17
1238
+
1239
+ - Support Composer and Packagist (github issue #9)
1240
+ - Add new deleteDiscount method to Stripe_Customer
1241
+ - Add new Transfer resource
1242
+ - Switch from using HTTP Basic auth to Bearer auth. (Note: Stripe will support Basic auth for the indefinite future, but recommends Bearer auth when possible going forward)
1243
+ - Numerous test suite improvements
includes/gateways/stripe/vendor/stripe/stripe-php/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to make participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies within all project spaces, and it also applies when
49
+ an individual is representing the project or its community in public spaces.
50
+ Examples of representing a project or community include using an official
51
+ project e-mail address, posting via an official social media account, or acting
52
+ as an appointed representative at an online or offline event. Representation of
53
+ a project may be further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at conduct@stripe.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
77
+
includes/gateways/stripe/vendor/stripe/stripe-php/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License
2
+
3
+ Copyright (c) 2010-2019 Stripe, Inc. (https://stripe.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
includes/gateways/stripe/vendor/stripe/stripe-php/Makefile ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export PHPDOCUMENTOR_VERSION := v3.0.0-rc
2
+ export PHPSTAN_VERSION := 0.12.18
3
+
4
+ vendor: composer.json
5
+ composer install
6
+
7
+ vendor/bin/phpstan: vendor
8
+ curl -sfL https://github.com/phpstan/phpstan/releases/download/$(PHPSTAN_VERSION)/phpstan.phar -o vendor/bin/phpstan
9
+ chmod +x vendor/bin/phpstan
10
+
11
+ vendor/bin/phpdoc: vendor
12
+ curl -sfL https://github.com/phpDocumentor/phpDocumentor/releases/download/$(PHPDOCUMENTOR_VERSION)/phpDocumentor.phar -o vendor/bin/phpdoc
13
+ chmod +x vendor/bin/phpdoc
14
+
15
+ test: vendor
16
+ vendor/bin/phpunit
17
+ .PHONY: test
18
+
19
+ fmt: vendor
20
+ vendor/bin/php-cs-fixer fix -v --using-cache=no .
21
+ .PHONY: fmt
22
+
23
+ fmtcheck: vendor
24
+ vendor/bin/php-cs-fixer fix -v --dry-run --using-cache=no .
25
+ .PHONY: fmtcheck
26
+
27
+ phpdoc: vendor/bin/phpdoc
28
+ vendor/bin/phpdoc
29
+
30
+ phpstan: vendor/bin/phpstan
31
+ php -d memory_limit=512M vendor/bin/phpstan analyse lib tests
32
+ .PHONY: phpstan
33
+
34
+ phpstan-baseline: vendor/bin/phpstan
35
+ php -d memory_limit=512M vendor/bin/phpstan analyse lib tests --generate-baseline
36
+ .PHONY: phpstan-baseline
includes/gateways/stripe/vendor/stripe/stripe-php/README.md ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stripe PHP bindings
2
+
3
+ [![Build Status](https://travis-ci.org/stripe/stripe-php.svg?branch=master)](https://travis-ci.org/stripe/stripe-php)
4
+ [![Latest Stable Version](https://poser.pugx.org/stripe/stripe-php/v/stable.svg)](https://packagist.org/packages/stripe/stripe-php)
5
+ [![Total Downloads](https://poser.pugx.org/stripe/stripe-php/downloads.svg)](https://packagist.org/packages/stripe/stripe-php)
6
+ [![License](https://poser.pugx.org/stripe/stripe-php/license.svg)](https://packagist.org/packages/stripe/stripe-php)
7
+ [![Code Coverage](https://coveralls.io/repos/stripe/stripe-php/badge.svg?branch=master)](https://coveralls.io/r/stripe/stripe-php?branch=master)
8
+
9
+ The Stripe PHP library provides convenient access to the Stripe API from
10
+ applications written in the PHP language. It includes a pre-defined set of
11
+ classes for API resources that initialize themselves dynamically from API
12
+ responses which makes it compatible with a wide range of versions of the Stripe
13
+ API.
14
+
15
+ ## Requirements
16
+
17
+ PHP 5.6.0 and later.
18
+
19
+ ## Composer
20
+
21
+ You can install the bindings via [Composer](http://getcomposer.org/). Run the following command:
22
+
23
+ ```bash
24
+ composer require stripe/stripe-php
25
+ ```
26
+
27
+ To use the bindings, use Composer's [autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading):
28
+
29
+ ```php
30
+ require_once('vendor/autoload.php');
31
+ ```
32
+
33
+ ## Manual Installation
34
+
35
+ If you do not wish to use Composer, you can download the [latest release](https://github.com/stripe/stripe-php/releases). Then, to use the bindings, include the `init.php` file.
36
+
37
+ ```php
38
+ require_once('/path/to/stripe-php/init.php');
39
+ ```
40
+
41
+ ## Dependencies
42
+
43
+ The bindings require the following extensions in order to work properly:
44
+
45
+ - [`curl`](https://secure.php.net/manual/en/book.curl.php), although you can use your own non-cURL client if you prefer
46
+ - [`json`](https://secure.php.net/manual/en/book.json.php)
47
+ - [`mbstring`](https://secure.php.net/manual/en/book.mbstring.php) (Multibyte String)
48
+
49
+ If you use Composer, these dependencies should be handled automatically. If you install manually, you'll want to make sure that these extensions are available.
50
+
51
+ ## Getting Started
52
+
53
+ Simple usage looks like:
54
+
55
+ ```php
56
+ $stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2');
57
+ $customer = $stripe->customers->create([
58
+ 'description' => 'example customer',
59
+ 'email' => 'email@example.com',
60
+ 'payment_method' => 'pm_card_visa',
61
+ ]);
62
+ echo $customer;
63
+ ```
64
+
65
+ ### Client/service patterns vs legacy patterns
66
+
67
+ You can continue to use the legacy integration patterns used prior to version [7.33.0](https://github.com/stripe/stripe-php/blob/master/CHANGELOG.md#7330---2020-05-14). Review the [migration guide](https://github.com/stripe/stripe-php/wiki/Migration-to-StripeClient-and-services-in-7.33.0) for the backwards-compatible client/services pattern changes.
68
+
69
+ ## Documentation
70
+
71
+ See the [PHP API docs](https://stripe.com/docs/api/php#intro).
72
+
73
+ ## Legacy Version Support
74
+
75
+ ### PHP 5.4 & 5.5
76
+
77
+ If you are using PHP 5.4 or 5.5, you can download v6.21.1 ([zip](https://github.com/stripe/stripe-php/archive/v6.21.1.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.9.2.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses.
78
+
79
+ ### PHP 5.3
80
+
81
+ If you are using PHP 5.3, you can download v5.9.2 ([zip](https://github.com/stripe/stripe-php/archive/v5.9.2.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.9.2.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses.
82
+
83
+ ## Custom Request Timeouts
84
+
85
+ _NOTE:_ We do not recommend decreasing the timeout for non-read-only calls (e.g. charge creation), since even if you locally timeout, the request on Stripe's side can still complete. If you are decreasing timeouts on these calls, make sure to use [idempotency tokens](https://stripe.com/docs/api/php#idempotent_requests) to avoid executing the same transaction twice as a result of timeout retry logic.
86
+
87
+ To modify request timeouts (connect or total, in seconds) you'll need to tell the API client to use a CurlClient other than its default. You'll set the timeouts in that CurlClient.
88
+
89
+ ```php
90
+ // set up your tweaked Curl client
91
+ $curl = new \Stripe\HttpClient\CurlClient();
92
+ $curl->setTimeout(10); // default is \Stripe\HttpClient\CurlClient::DEFAULT_TIMEOUT
93
+ $curl->setConnectTimeout(5); // default is \Stripe\HttpClient\CurlClient::DEFAULT_CONNECT_TIMEOUT
94
+
95
+ echo $curl->getTimeout(); // 10
96
+ echo $curl->getConnectTimeout(); // 5
97
+
98
+ // tell Stripe to use the tweaked client
99
+ \Stripe\ApiRequestor::setHttpClient($curl);
100
+
101
+ // use the Stripe API client as you normally would
102
+ ```
103
+
104
+ ## Custom cURL Options (e.g. proxies)
105
+
106
+ Need to set a proxy for your requests? Pass in the requisite `CURLOPT_*` array to the CurlClient constructor, using the same syntax as `curl_stopt_array()`. This will set the default cURL options for each HTTP request made by the SDK, though many more common options (e.g. timeouts; see above on how to set those) will be overridden by the client even if set here.
107
+
108
+ ```php
109
+ // set up your tweaked Curl client
110
+ $curl = new \Stripe\HttpClient\CurlClient([CURLOPT_PROXY => 'proxy.local:80']);
111
+ // tell Stripe to use the tweaked client
112
+ \Stripe\ApiRequestor::setHttpClient($curl);
113
+ ```
114
+
115
+ Alternately, a callable can be passed to the CurlClient constructor that returns the above array based on request inputs. See `testDefaultOptions()` in `tests/CurlClientTest.php` for an example of this behavior. Note that the callable is called at the beginning of every API request, before the request is sent.
116
+
117
+ ### Configuring a Logger
118
+
119
+ The library does minimal logging, but it can be configured
120
+ with a [`PSR-3` compatible logger][psr3] so that messages
121
+ end up there instead of `error_log`:
122
+
123
+ ```php
124
+ \Stripe\Stripe::setLogger($logger);
125
+ ```
126
+
127
+ ### Accessing response data
128
+
129
+ You can access the data from the last API response on any object via `getLastResponse()`.
130
+
131
+ ```php
132
+ $customer = $stripe->customers->create([
133
+ 'description' => 'example customer',
134
+ ]);
135
+ echo $customer->getLastResponse()->headers['Request-Id'];
136
+ ```
137
+
138
+ ### SSL / TLS compatibility issues
139
+
140
+ Stripe's API now requires that [all connections use TLS 1.2](https://stripe.com/blog/upgrading-tls). Some systems (most notably some older CentOS and RHEL versions) are capable of using TLS 1.2 but will use TLS 1.0 or 1.1 by default. In this case, you'd get an `invalid_request_error` with the following error message: "Stripe no longer supports API requests made with TLS 1.0. Please initiate HTTPS connections with TLS 1.2 or later. You can learn more about this at [https://stripe.com/blog/upgrading-tls](https://stripe.com/blog/upgrading-tls).".
141
+
142
+ The recommended course of action is to [upgrade your cURL and OpenSSL packages](https://support.stripe.com/questions/how-do-i-upgrade-my-stripe-integration-from-tls-1-0-to-tls-1-2#php) so that TLS 1.2 is used by default, but if that is not possible, you might be able to solve the issue by setting the `CURLOPT_SSLVERSION` option to either `CURL_SSLVERSION_TLSv1` or `CURL_SSLVERSION_TLSv1_2`:
143
+
144
+ ```php
145
+ $curl = new \Stripe\HttpClient\CurlClient([CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1]);
146
+ \Stripe\ApiRequestor::setHttpClient($curl);
147
+ ```
148
+
149
+ ### Per-request Configuration
150
+
151
+ For apps that need to use multiple keys during the lifetime of a process, like
152
+ one that uses [Stripe Connect][connect], it's also possible to set a
153
+ per-request key and/or account:
154
+
155
+ ```php
156
+ $customers = $stripe->customers->all([],[
157
+ 'api_key' => 'sk_test_...',
158
+ 'stripe_account' => 'acct_...'
159
+ ]);
160
+
161
+ $stripe->customers->retrieve('cus_123456789', [], [
162
+ 'api_key' => 'sk_test_...',
163
+ 'stripe_account' => 'acct_...'
164
+ ]);
165
+ ```
166
+
167
+ ### Configuring CA Bundles
168
+
169
+ By default, the library will use its own internal bundle of known CA
170
+ certificates, but it's possible to configure your own:
171
+
172
+ ```php
173
+ \Stripe\Stripe::setCABundlePath("path/to/ca/bundle");
174
+ ```
175
+
176
+ ### Configuring Automatic Retries
177
+
178
+ The library can be configured to automatically retry requests that fail due to
179
+ an intermittent network problem:
180
+
181
+ ```php
182
+ \Stripe\Stripe::setMaxNetworkRetries(2);
183
+ ```
184
+
185
+ [Idempotency keys][idempotency-keys] are added to requests to guarantee that
186
+ retries are safe.
187
+
188
+ ### Request latency telemetry
189
+
190
+ By default, the library sends request latency telemetry to Stripe. These
191
+ numbers help Stripe improve the overall latency of its API for all users.
192
+
193
+ You can disable this behavior if you prefer:
194
+
195
+ ```php
196
+ \Stripe\Stripe::setEnableTelemetry(false);
197
+ ```
198
+
199
+ ## Development
200
+
201
+ Get [Composer][composer]. For example, on Mac OS:
202
+
203
+ ```bash
204
+ brew install composer
205
+ ```
206
+
207
+ Install dependencies:
208
+
209
+ ```bash
210
+ composer install
211
+ ```
212
+
213
+ The test suite depends on [stripe-mock], so make sure to fetch and run it from a
214
+ background terminal ([stripe-mock's README][stripe-mock] also contains
215
+ instructions for installing via Homebrew and other methods):
216
+
217
+ ```bash
218
+ go get -u github.com/stripe/stripe-mock
219
+ stripe-mock
220
+ ```
221
+
222
+ Install dependencies as mentioned above (which will resolve [PHPUnit](http://packagist.org/packages/phpunit/phpunit)), then you can run the test suite:
223
+
224
+ ```bash
225
+ ./vendor/bin/phpunit
226
+ ```
227
+
228
+ Or to run an individual test file:
229
+
230
+ ```bash
231
+ ./vendor/bin/phpunit tests/UtilTest.php
232
+ ```
233
+
234
+ Update bundled CA certificates from the [Mozilla cURL release][curl]:
235
+
236
+ ```bash
237
+ ./update_certs.php
238
+ ```
239
+
240
+ The library uses [PHP CS Fixer][php-cs-fixer] for code formatting. Code must be formatted before PRs are submitted, otherwise CI will fail. Run the formatter with:
241
+
242
+ ```bash
243
+ ./vendor/bin/php-cs-fixer fix -v .
244
+ ```
245
+
246
+ ## Attention plugin developers
247
+
248
+ Are you writing a plugin that integrates Stripe and embeds our library? Then please use the `setAppInfo` function to identify your plugin. For example:
249
+
250
+ ```php
251
+ \Stripe\Stripe::setAppInfo("MyAwesomePlugin", "1.2.34", "https://myawesomeplugin.info");
252
+ ```
253
+
254
+ The method should be called once, before any request is sent to the API. The second and third parameters are optional.
255
+
256
+ ### SSL / TLS configuration option
257
+
258
+ See the "SSL / TLS compatibility issues" paragraph above for full context. If you want to ensure that your plugin can be used on all systems, you should add a configuration option to let your users choose between different values for `CURLOPT_SSLVERSION`: none (default), `CURL_SSLVERSION_TLSv1` and `CURL_SSLVERSION_TLSv1_2`.
259
+
260
+ [composer]: https://getcomposer.org/
261
+ [connect]: https://stripe.com/connect
262
+ [curl]: http://curl.haxx.se/docs/caextract.html
263
+ [idempotency-keys]: https://stripe.com/docs/api/php#idempotent_requests
264
+ [php-cs-fixer]: https://github.com/FriendsOfPHP/PHP-CS-Fixer
265
+ [psr3]: http://www.php-fig.org/psr/psr-3/
266
+ [stripe-mock]: https://github.com/stripe/stripe-mock
includes/gateways/stripe/vendor/stripe/stripe-php/VERSION ADDED
@@ -0,0 +1 @@
 
1
+ 7.47.0
includes/gateways/stripe/vendor/stripe/stripe-php/build.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env php
2
+ <?php
3
+ \chdir(__DIR__);
4
+
5
+ $autoload = (int) $argv[1];
6
+ $returnStatus = null;
7
+
8
+ if (!$autoload) {
9
+ // Modify composer to not autoload Stripe
10
+ $composer = \json_decode(\file_get_contents('composer.json'), true);
11
+ unset($composer['autoload'], $composer['autoload-dev']);
12
+
13
+ \file_put_contents('composer.json', \json_encode($composer, \JSON_PRETTY_PRINT));
14
+ }
15
+
16
+ \passthru('composer update', $returnStatus);
17
+ if (0 !== $returnStatus) {
18
+ exit(1);
19
+ }
20
+
21
+ $config = $autoload ? 'phpunit.xml' : 'phpunit.no_autoload.xml';
22
+ \passthru("./vendor/bin/phpunit -c {$config}", $returnStatus);
23
+ if (0 !== $returnStatus) {
24
+ exit(1);
25
+ }
includes/gateways/stripe/vendor/stripe/stripe-php/composer.json ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "stripe/stripe-php",
3
+ "description": "Stripe PHP Library",
4
+ "keywords": [
5
+ "stripe",
6
+ "payment processing",
7
+ "api"
8
+ ],
9
+ "homepage": "https://stripe.com/",
10
+ "license": "MIT",
11
+ "authors": [
12
+ {
13
+ "name": "Stripe and contributors",
14
+ "homepage": "https://github.com/stripe/stripe-php/contributors"
15
+ }
16
+ ],
17
+ "require": {
18
+ "php": ">=5.6.0",
19
+ "ext-curl": "*",
20
+ "ext-json": "*",
21
+ "ext-mbstring": "*"
22
+ },
23
+ "require-dev": {
24
+ "phpunit/phpunit": "^5.7",
25
+ "php-coveralls/php-coveralls": "^2.1",
26
+ "squizlabs/php_codesniffer": "^3.3",
27
+ "symfony/process": "~3.4",
28
+ "friendsofphp/php-cs-fixer": "2.16.1"
29
+ },
30
+ "autoload": {
31
+ "psr-4": {
32
+ "Stripe\\": "lib/"
33
+ }
34
+ },
35
+ "autoload-dev": {
36
+ "psr-4": {
37
+ "Stripe\\": [
38
+ "tests/",
39
+ "tests/Stripe/"
40
+ ]
41
+ }
42
+ },
43
+ "extra": {
44
+ "branch-alias": {
45
+ "dev-master": "2.0-dev"
46
+ }
47
+ }
48
+ }
includes/gateways/stripe/vendor/stripe/stripe-php/data/ca-certificates.crt ADDED
@@ -0,0 +1,3476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##
2
+ ## Bundle of CA Root Certificates
3
+ ##
4
+ ## Certificate data from Mozilla as of: Wed Aug 28 03:12:10 2019 GMT
5
+ ##
6
+ ## This is a bundle of X.509 certificates of public Certificate Authorities
7
+ ## (CA). These were automatically extracted from Mozilla's root certificates
8
+ ## file (certdata.txt). This file can be found in the mozilla source tree:
9
+ ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
10
+ ##
11
+ ## It contains the certificates in PEM format and therefore
12
+ ## can be directly used with curl / libcurl / php_curl, or with
13
+ ## an Apache+mod_ssl webserver for SSL client authentication.
14
+ ## Just configure this file as the SSLCACertificateFile.
15
+ ##
16
+ ## Conversion done with mk-ca-bundle.pl version 1.27.
17
+ ## SHA256: fffa309937c3be940649293f749b8207fabc6eb224e50e4bb3f2c5e44e0d6a6b
18
+ ##
19
+
20
+
21
+ GlobalSign Root CA
22
+ ==================
23
+ -----BEGIN CERTIFICATE-----
24
+ MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
25
+ GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
26
+ b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
27
+ BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
28
+ VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
29
+ DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
30
+ THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
31
+ Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
32
+ c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
33
+ gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
34
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
35
+ AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
36
+ Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
37
+ j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
38
+ hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
39
+ X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
40
+ -----END CERTIFICATE-----
41
+
42
+ GlobalSign Root CA - R2
43
+ =======================
44
+ -----BEGIN CERTIFICATE-----
45
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
46
+ YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
47
+ bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
48
+ aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
49
+ bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
50
+ ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
51
+ s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
52
+ S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
53
+ TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
54
+ ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
55
+ FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
56
+ YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
57
+ BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
58
+ 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
59
+ 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
60
+ 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
61
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
62
+ -----END CERTIFICATE-----
63
+
64
+ Verisign Class 3 Public Primary Certification Authority - G3
65
+ ============================================================
66
+ -----BEGIN CERTIFICATE-----
67
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
68
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
69
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
70
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
71
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
72
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
73
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
74
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
75
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
76
+ ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
77
+ EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
78
+ cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
79
+ EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
80
+ 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
81
+ ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
82
+ j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
83
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
84
+ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
85
+ t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
86
+ -----END CERTIFICATE-----
87
+
88
+ Entrust.net Premium 2048 Secure Server CA
89
+ =========================================
90
+ -----BEGIN CERTIFICATE-----
91
+ MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
92
+ ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
93
+ bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
94
+ BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
95
+ NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
96
+ d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
97
+ MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
98
+ ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
99
+ MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
100
+ Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
101
+ hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
102
+ nLLPKQP5L6RQstRIzgUyVY