WooCommerce PayPal Payments - Version 1.0.0

Version Description

Download this release

Release Info

Developer woothemes
Plugin Icon 128x128 WooCommerce PayPal Payments
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

Files changed (290) hide show
  1. LICENSE +235 -0
  2. changelog.txt +4 -0
  3. modules/ppcp-admin-notices/extensions.php +10 -0
  4. modules/ppcp-admin-notices/module.php +16 -0
  5. modules/ppcp-admin-notices/services.php +28 -0
  6. modules/ppcp-admin-notices/src/Entity/class-message.php +77 -0
  7. modules/ppcp-admin-notices/src/Renderer/class-renderer.php +53 -0
  8. modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php +23 -0
  9. modules/ppcp-admin-notices/src/Repository/class-repository.php +37 -0
  10. modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php +26 -0
  11. modules/ppcp-admin-notices/src/class-adminnotices.php +56 -0
  12. modules/ppcp-api-client/extensions.php +12 -0
  13. modules/ppcp-api-client/module.php +16 -0
  14. modules/ppcp-api-client/services.php +294 -0
  15. modules/ppcp-api-client/src/Authentication/class-bearer.php +25 -0
  16. modules/ppcp-api-client/src/Authentication/class-connectbearer.php +32 -0
  17. modules/ppcp-api-client/src/Authentication/class-paypalbearer.php +140 -0
  18. modules/ppcp-api-client/src/Endpoint/class-identitytoken.php +133 -0
  19. modules/ppcp-api-client/src/Endpoint/class-loginseller.php +196 -0
  20. modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php +538 -0
  21. modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php +146 -0
  22. modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php +149 -0
  23. modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php +251 -0
  24. modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php +203 -0
  25. modules/ppcp-api-client/src/Endpoint/class-requesttrait.php +39 -0
  26. modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php +305 -0
  27. modules/ppcp-api-client/src/Entity/class-address.php +155 -0
  28. modules/ppcp-api-client/src/Entity/class-amount.php +84 -0
  29. modules/ppcp-api-client/src/Entity/class-amountbreakdown.php +190 -0
  30. modules/ppcp-api-client/src/Entity/class-applicationcontext.php +249 -0
  31. modules/ppcp-api-client/src/Entity/class-authorization.php +75 -0
  32. modules/ppcp-api-client/src/Entity/class-authorizationstatus.php +94 -0
  33. modules/ppcp-api-client/src/Entity/class-capture.php +197 -0
  34. modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php +119 -0
  35. modules/ppcp-api-client/src/Entity/class-item.php +185 -0
  36. modules/ppcp-api-client/src/Entity/class-money.php +71 -0
  37. modules/ppcp-api-client/src/Entity/class-order.php +245 -0
  38. modules/ppcp-api-client/src/Entity/class-orderstatus.php +89 -0
  39. modules/ppcp-api-client/src/Entity/class-patch.php +100 -0
  40. modules/ppcp-api-client/src/Entity/class-patchcollection.php +55 -0
  41. modules/ppcp-api-client/src/Entity/class-payee.php +79 -0
  42. modules/ppcp-api-client/src/Entity/class-payer.php +186 -0
  43. modules/ppcp-api-client/src/Entity/class-payername.php +75 -0
  44. modules/ppcp-api-client/src/Entity/class-payertaxinfo.php +93 -0
  45. modules/ppcp-api-client/src/Entity/class-paymentmethod.php +81 -0
  46. modules/ppcp-api-client/src/Entity/class-payments.php +93 -0
  47. modules/ppcp-api-client/src/Entity/class-paymentsource.php +82 -0
  48. modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php +123 -0
  49. modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php +25 -0
  50. modules/ppcp-api-client/src/Entity/class-paymenttoken.php +85 -0
  51. modules/ppcp-api-client/src/Entity/class-phone.php +52 -0
  52. modules/ppcp-api-client/src/Entity/class-phonewithtype.php +79 -0
  53. modules/ppcp-api-client/src/Entity/class-purchaseunit.php +358 -0
  54. modules/ppcp-api-client/src/Entity/class-refund.php +118 -0
  55. modules/ppcp-api-client/src/Entity/class-sellerstatus.php +65 -0
  56. modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php +108 -0
  57. modules/ppcp-api-client/src/Entity/class-shipping.php +73 -0
  58. modules/ppcp-api-client/src/Entity/class-token.php +123 -0
  59. modules/ppcp-api-client/src/Entity/class-webhook.php +97 -0
  60. modules/ppcp-api-client/src/Exception/class-notfoundexception.php +21 -0
  61. modules/ppcp-api-client/src/Exception/class-paypalapiexception.php +109 -0
  62. modules/ppcp-api-client/src/Exception/class-runtimeexception.php +18 -0
  63. modules/ppcp-api-client/src/Factory/class-addressfactory.php +86 -0
  64. modules/ppcp-api-client/src/Factory/class-amountfactory.php +222 -0
  65. modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php +44 -0
  66. modules/ppcp-api-client/src/Factory/class-authorizationfactory.php +47 -0
  67. modules/ppcp-api-client/src/Factory/class-capturefactory.php +57 -0
  68. modules/ppcp-api-client/src/Factory/class-itemfactory.php +155 -0
  69. modules/ppcp-api-client/src/Factory/class-orderfactory.php +171 -0
  70. modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php +85 -0
  71. modules/ppcp-api-client/src/Factory/class-payeefactory.php +38 -0
  72. modules/ppcp-api-client/src/Factory/class-payerfactory.php +147 -0
  73. modules/ppcp-api-client/src/Factory/class-paymentsfactory.php +73 -0
  74. modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php +53 -0
  75. modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php +50 -0
  76. modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php +264 -0
  77. modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php +42 -0
  78. modules/ppcp-api-client/src/Factory/class-shippingfactory.php +99 -0
  79. modules/ppcp-api-client/src/Factory/class-webhookfactory.php +83 -0
  80. modules/ppcp-api-client/src/Helper/class-cache.php +76 -0
  81. modules/ppcp-api-client/src/Helper/class-dccapplies.php +239 -0
  82. modules/ppcp-api-client/src/Helper/class-errorresponse.php +121 -0
  83. modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php +62 -0
  84. modules/ppcp-api-client/src/Repository/class-cartrepository.php +46 -0
  85. modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php +117 -0
  86. modules/ppcp-api-client/src/Repository/class-payeerepository.php +55 -0
  87. modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php +90 -0
  88. modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php +26 -0
  89. modules/ppcp-api-client/src/class-apimodule.php +50 -0
  90. modules/ppcp-button/assets/css/hosted-fields.css +1 -0
  91. modules/ppcp-button/assets/js/button.js +2 -0
  92. modules/ppcp-button/assets/js/button.js.map +1 -0
  93. modules/ppcp-button/assets/js/hosted-fields.js +2 -0
  94. modules/ppcp-button/assets/js/hosted-fields.js.map +1 -0
  95. modules/ppcp-button/assets/js/hostedfields.js +2 -0
  96. modules/ppcp-button/assets/js/hostedfields.js.map +1 -0
  97. modules/ppcp-button/extensions.php +10 -0
  98. modules/ppcp-button/module.php +16 -0
  99. modules/ppcp-button/resources/css/hosted-fields.scss +5 -0
  100. modules/ppcp-button/resources/js/button.js +98 -0
  101. modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js +46 -0
  102. modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js +60 -0
  103. modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js +133 -0
  104. modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js +42 -0
  105. modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js +82 -0
  106. modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js +43 -0
  107. modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js +80 -0
  108. modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js +65 -0
  109. modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js +52 -0
  110. modules/ppcp-button/resources/js/modules/Entity/Product.js +18 -0
  111. modules/ppcp-button/resources/js/modules/ErrorHandler.js +46 -0
  112. modules/ppcp-button/resources/js/modules/Helper/ButtonsToggleListener.js +36 -0
  113. modules/ppcp-button/resources/js/modules/Helper/DccInputFactory.js +14 -0
  114. modules/ppcp-button/resources/js/modules/Helper/PayerData.js +34 -0
  115. modules/ppcp-button/resources/js/modules/Helper/Spinner.js +23 -0
  116. modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js +45 -0
  117. modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js +24 -0
  118. modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js +31 -0
  119. modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +150 -0
  120. modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js +49 -0
  121. modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +48 -0
  122. modules/ppcp-button/services.php +163 -0
  123. modules/ppcp-button/src/Assets/class-disabledsmartbutton.php +44 -0
  124. modules/ppcp-button/src/Assets/class-smartbutton.php +912 -0
  125. modules/ppcp-button/src/Assets/class-smartbuttoninterface.php +37 -0
  126. modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php +198 -0
  127. modules/ppcp-button/src/Endpoint/class-changecartendpoint.php +289 -0
  128. modules/ppcp-button/src/Endpoint/class-createorderendpoint.php +328 -0
  129. modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php +92 -0
  130. modules/ppcp-button/src/Endpoint/class-endpointinterface.php +30 -0
  131. modules/ppcp-button/src/Endpoint/class-requestdata.php +91 -0
  132. modules/ppcp-button/src/Exception/class-runtimeexception.php +18 -0
  133. modules/ppcp-button/src/Helper/class-earlyorderhandler.php +174 -0
  134. modules/ppcp-button/src/Helper/class-messagesapply.php +37 -0
  135. modules/ppcp-button/src/Helper/class-threedsecure.php +104 -0
  136. modules/ppcp-button/src/class-buttonmodule.php +162 -0
  137. modules/ppcp-onboarding/assets/css/onboarding.css +90 -0
  138. modules/ppcp-onboarding/assets/js/onboarding.js +212 -0
  139. modules/ppcp-onboarding/assets/js/settings.js +262 -0
  140. modules/ppcp-onboarding/extensions.php +12 -0
  141. modules/ppcp-onboarding/module.php +16 -0
  142. modules/ppcp-onboarding/services.php +210 -0
  143. modules/ppcp-onboarding/src/Assets/class-onboardingassets.php +130 -0
  144. modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php +149 -0
  145. modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php +112 -0
  146. modules/ppcp-onboarding/src/class-environment.php +60 -0
  147. modules/ppcp-onboarding/src/class-onboardingmodule.php +112 -0
  148. modules/ppcp-onboarding/src/class-state.php +145 -0
  149. modules/ppcp-session/extensions.php +12 -0
  150. modules/ppcp-session/module.php +16 -0
  151. modules/ppcp-session/services.php +39 -0
  152. modules/ppcp-session/src/Cancellation/class-cancelcontroller.php +74 -0
  153. modules/ppcp-session/src/Cancellation/class-cancelview.php +42 -0
  154. modules/ppcp-session/src/class-sessionhandler.php +126 -0
  155. modules/ppcp-session/src/class-sessionmodule.php +62 -0
  156. modules/ppcp-subscription/extensions.php +10 -0
  157. modules/ppcp-subscription/module.php +16 -0
  158. modules/ppcp-subscription/services.php +39 -0
  159. modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php +86 -0
  160. modules/ppcp-subscription/src/Repository/class-paymenttokenrepository.php +102 -0
  161. modules/ppcp-subscription/src/class-renewalhandler.php +222 -0
  162. modules/ppcp-subscription/src/class-subscriptionmodule.php +62 -0
  163. modules/ppcp-wc-gateway/assets/images/amex.svg +10 -0
  164. modules/ppcp-wc-gateway/assets/images/blik.svg +25 -0
  165. modules/ppcp-wc-gateway/assets/images/credit.svg +33 -0
  166. modules/ppcp-wc-gateway/assets/images/discover.svg +46 -0
  167. modules/ppcp-wc-gateway/assets/images/elo.svg +1 -0
  168. modules/ppcp-wc-gateway/assets/images/giropay.svg +15 -0
  169. modules/ppcp-wc-gateway/assets/images/hiper.svg +18 -0
  170. modules/ppcp-wc-gateway/assets/images/ideal.svg +21 -0
  171. modules/ppcp-wc-gateway/assets/images/jcb.svg +9 -0
  172. modules/ppcp-wc-gateway/assets/images/mastercard.svg +16 -0
  173. modules/ppcp-wc-gateway/assets/images/mybank.svg +19 -0
  174. modules/ppcp-wc-gateway/assets/images/przelewy.svg +33 -0
  175. modules/ppcp-wc-gateway/assets/images/sofort.svg +13 -0
  176. modules/ppcp-wc-gateway/assets/images/visa.svg +19 -0
  177. modules/ppcp-wc-gateway/extensions.php +100 -0
  178. modules/ppcp-wc-gateway/module.php +16 -0
  179. modules/ppcp-wc-gateway/services.php +1837 -0
  180. modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php +140 -0
  181. modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php +50 -0
  182. modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php +51 -0
  183. modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php +152 -0
  184. modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php +129 -0
  185. modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php +94 -0
  186. modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php +21 -0
  187. modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php +253 -0
  188. modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php +343 -0
  189. modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php +82 -0
  190. modules/ppcp-wc-gateway/src/Gateway/class-wcgatewayinterface.php +18 -0
  191. modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php +102 -0
  192. modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php +110 -0
  193. modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php +76 -0
  194. modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php +182 -0
  195. modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php +275 -0
  196. modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php +99 -0
  197. modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php +59 -0
  198. modules/ppcp-wc-gateway/src/Settings/class-settings.php +112 -0
  199. modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php +361 -0
  200. modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php +477 -0
  201. modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php +386 -0
  202. modules/ppcp-webhooks/extensions.php +12 -0
  203. modules/ppcp-webhooks/module.php +16 -0
  204. modules/ppcp-webhooks/services.php +58 -0
  205. modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php +226 -0
  206. modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php +166 -0
  207. modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php +141 -0
  208. modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php +156 -0
  209. modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php +144 -0
  210. modules/ppcp-webhooks/src/Handler/class-prefixtrait.php +37 -0
  211. modules/ppcp-webhooks/src/Handler/class-requesthandler.php +41 -0
  212. modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php +214 -0
  213. modules/ppcp-webhooks/src/class-webhookmodule.php +87 -0
  214. modules/ppcp-webhooks/src/class-webhookregistrar.php +116 -0
  215. modules/woocommerce-logging/extensions.php +13 -0
  216. modules/woocommerce-logging/module.php +16 -0
  217. modules/woocommerce-logging/services.php +33 -0
  218. modules/woocommerce-logging/src/Logger/class-nulllogger.php +33 -0
  219. modules/woocommerce-logging/src/Logger/class-woocommercelogger.php +64 -0
  220. modules/woocommerce-logging/src/class-woocommerceloggingmodule.php +50 -0
  221. readme.txt +62 -0
  222. src/README.md +3 -0
  223. src/class-pluginmodule.php +44 -0
  224. vendor/autoload.php +7 -0
  225. vendor/composer/ClassLoader.php +445 -0
  226. vendor/composer/LICENSE +21 -0
  227. vendor/composer/autoload_classmap.php +154 -0
  228. vendor/composer/autoload_namespaces.php +9 -0
  229. vendor/composer/autoload_psr4.php +21 -0
  230. vendor/composer/autoload_real.php +55 -0
  231. vendor/composer/autoload_static.php +247 -0
  232. vendor/composer/installed.json +781 -0
  233. vendor/composer/installers/LICENSE +19 -0
  234. vendor/composer/installers/composer.json +112 -0
  235. vendor/composer/installers/src/Composer/Installers/AglInstaller.php +21 -0
  236. vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +9 -0
  237. vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +11 -0
  238. vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +49 -0
  239. vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php +9 -0
  240. vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +137 -0
  241. vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +126 -0
  242. vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +9 -0
  243. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +72 -0
  244. vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +11 -0
  245. vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php +9 -0
  246. vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +10 -0
  247. vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php +34 -0
  248. vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +11 -0
  249. vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +13 -0
  250. vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +35 -0
  251. vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +21 -0
  252. vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php +10 -0
  253. vendor/composer/installers/src/Composer/Installers/DframeInstaller.php +10 -0
  254. vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +50 -0
  255. vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +16 -0
  256. vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +22 -0
  257. vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +9 -0
  258. vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php +12 -0
  259. vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php +29 -0
  260. vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php +10 -0
  261. vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +11 -0
  262. vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +9 -0
  263. vendor/composer/installers/src/Composer/Installers/GravInstaller.php +30 -0
  264. vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +25 -0
  265. vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php +11 -0
  266. vendor/composer/installers/src/Composer/Installers/Installer.php +280 -0
  267. vendor/composer/installers/src/Composer/Installers/ItopInstaller.php +9 -0
  268. vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +15 -0
  269. vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php +18 -0
  270. vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +11 -0
  271. vendor/composer/installers/src/Composer/Installers/KnownInstaller.php +11 -0
  272. vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +10 -0
  273. vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +9 -0
  274. vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php +27 -0
  275. vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +9 -0
  276. vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php +10 -0
  277. vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +10 -0
  278. vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +9 -0
  279. vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +16 -0
  280. vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +11 -0
  281. vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php +37 -0
  282. vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +9 -0
  283. vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php +23 -0
  284. vendor/composer/installers/src/Composer/Installers/MauticInstaller.php +25 -0
  285. vendor/composer/installers/src/Composer/Installers/MayaInstaller.php +33 -0
  286. vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +51 -0
  287. vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +119 -0
  288. vendor/composer/installers/src/Composer/Installers/ModxInstaller.php +12 -0
  289. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +58 -0
  290. vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +2 -0
LICENSE ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+
7
+ Everyone is permitted to copy and distribute verbatim copies
8
+ of this license document, but changing it is not allowed.
9
+
10
+ Preamble
11
+
12
+ The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General
13
+ Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free
14
+ for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other
15
+ program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library
16
+ General Public License instead.) You can apply it to your programs, too.
17
+
18
+ When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make
19
+ sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you
20
+ receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs;
21
+ and that you know you can do these things.
22
+
23
+ To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender
24
+ the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if
25
+ you modify it.
26
+
27
+ For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the
28
+ rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these
29
+ terms so they know their rights.
30
+
31
+ We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal
32
+ permission to copy, distribute and/or modify the software.
33
+
34
+ Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for
35
+ this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they
36
+ have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
37
+
38
+ Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a
39
+ free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have
40
+ made it clear that any patent must be licensed for everyone's free use or not licensed at all.
41
+
42
+ The precise terms and conditions for copying, distribution and modification follow.
43
+
44
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
45
+
46
+ 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be
47
+ distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a
48
+ "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work
49
+ containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language.
50
+ (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
51
+
52
+ Activities other than copying, distribution and modification are not covered by this License; they are outside its scope.
53
+ The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute
54
+ a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what
55
+ the Program does.
56
+
57
+ 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that
58
+ you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep
59
+ intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the
60
+ Program a copy of this License along with the Program.
61
+
62
+ You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in
63
+ exchange for a fee.
64
+
65
+ 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and
66
+ copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these
67
+ conditions:
68
+
69
+ a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any
70
+ change.
71
+
72
+ b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the
73
+ Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
74
+
75
+ c) If the modified program normally reads commands interactively when run, you must cause it, when started running for
76
+ such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright
77
+ notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may
78
+ redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if
79
+ the Program itself is interactive but does not normally print such an announcement, your work based on the Program is
80
+ not required to print an announcement.)
81
+
82
+ These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the
83
+ Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms,
84
+ do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as
85
+ part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License,
86
+ whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
87
+
88
+ Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather,
89
+ the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
90
+
91
+ In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the
92
+ Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
93
+
94
+ 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under
95
+ the terms of Sections 1 and 2 above provided that you also do one of the following:
96
+
97
+ a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms
98
+ of Sections 1 and 2 above on a medium customarily used for software interchange; or,
99
+
100
+ b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than
101
+ your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source
102
+ code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange;
103
+ or,
104
+
105
+ c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This
106
+ alternative is allowed only for noncommercial distribution and only if you received the program in object code or
107
+ executable form with such an offer, in accord with Subsection b above.)
108
+
109
+ The source code for a work means the preferred form of the work for making modifications to it. For an executable work,
110
+ complete source code means all the source code for all modules it contains, plus any associated interface definition files,
111
+ plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source
112
+ code distributed need not include anything that is normally distributed (in either source or binary form) with the major
113
+ components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself
114
+ accompanies the executable.
115
+
116
+ If distribution of executable or object code is made by offering access to copy from a designated place, then offering
117
+ equivalent access to copy the source code from the same place counts as distribution of the source code, even though third
118
+ parties are not compelled to copy the source along with the object code.
119
+
120
+ 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any
121
+ attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your
122
+ rights under this License. However, parties who have received copies, or rights, from you under this License will not have
123
+ their licenses terminated so long as such parties remain in full compliance.
124
+
125
+ 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to
126
+ modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this
127
+ License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance
128
+ of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based
129
+ on it.
130
+
131
+ 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license
132
+ from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not
133
+ impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for
134
+ enforcing compliance by third parties to this License.
135
+
136
+ 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to
137
+ patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions
138
+ of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy
139
+ simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not
140
+ distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program
141
+ by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this
142
+ License would be to refrain entirely from distribution of the Program.
143
+
144
+ If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the
145
+ section is intended to apply and the section as a whole is intended to apply in other circumstances.
146
+
147
+ It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest
148
+ validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution
149
+ system, which is implemented by public license practices. Many people have made generous contributions to the wide range of
150
+ software distributed through that system in reliance on consistent application of that system; it is up to the author/donor
151
+ to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
152
+
153
+ This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
154
+
155
+ 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted
156
+ interfaces, the original copyright holder who places the Program under this License may add an explicit geographical
157
+ distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus
158
+ excluded. In such case, this License incorporates the limitation as if written in the body of this License.
159
+
160
+ 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time.
161
+ Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or
162
+ concerns.
163
+
164
+ Each version is given a distinguishing version number. If the Program specifies a version number of this License which
165
+ applies to it and "any later version", you have the option of following the terms and conditions either of that version or
166
+ of any later version published by the Free Software Foundation. If the Program does not specify a version number of this
167
+ License, you may choose any version ever published by the Free Software Foundation.
168
+
169
+ 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different,
170
+ write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the
171
+ Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving
172
+ the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
173
+
174
+ NO WARRANTY
175
+
176
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
177
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS
178
+ IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
179
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
180
+ ITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
181
+
182
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
183
+ MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
184
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
185
+ LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO
186
+ OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
187
+
188
+ END OF TERMS AND CONDITIONS
189
+
190
+ How to Apply These Terms to Your New Programs
191
+
192
+ If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this
193
+ is to make it free software which everyone can redistribute and change under these terms.
194
+
195
+ To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most
196
+ effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where
197
+ the full notice is found.
198
+
199
+ One line to give the program's name and a brief idea of what it does.
200
+ Copyright (C) <year> <name of author>
201
+
202
+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
203
+ License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
204
+ version.
205
+
206
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
207
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
208
+
209
+ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
210
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
211
+
212
+ Also add information on how to contact you by electronic and paper mail.
213
+
214
+ If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
215
+
216
+ Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
217
+ type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for
218
+ details.
219
+
220
+ The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course,
221
+ the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu
222
+ tems--whatever suits your program.
223
+
224
+ You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for
225
+ the program, if necessary. Here is a sample; alter the names:
226
+
227
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers)
228
+ written by James Hacker.
229
+
230
+ signature of Ty Coon, 1 April 1989
231
+ Ty Coon, President of Vice
232
+
233
+ This General Public License does not permit incorporating your program into proprietary programs. If your program is a
234
+ subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is
235
+ what you want to do, use the GNU Library General Public License instead of this License.
changelog.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ *** Changelog ***
2
+
3
+ = 1.0.0 - 2020-10-15 =
4
+ * Initial release.
modules/ppcp-admin-notices/extensions.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The extensions of the admin notice module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ return array();
modules/ppcp-admin-notices/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin notice module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new AdminNotices();
16
+ };
modules/ppcp-admin-notices/services.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The services of the admin notice module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices;
11
+
12
+ use Dhii\Data\Container\ContainerInterface;
13
+ use WooCommerce\PayPalCommerce\AdminNotices\Renderer\Renderer;
14
+ use WooCommerce\PayPalCommerce\AdminNotices\Renderer\RendererInterface;
15
+ use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
16
+ use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
17
+
18
+ return array(
19
+ 'admin-notices.renderer' => static function ( $container ): RendererInterface {
20
+
21
+ $repository = $container->get( 'admin-notices.repository' );
22
+ return new Renderer( $repository );
23
+ },
24
+ 'admin-notices.repository' => static function ( $container ): RepositoryInterface {
25
+
26
+ return new Repository();
27
+ },
28
+ );
modules/ppcp-admin-notices/src/Entity/class-message.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The message entity.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\AdminNotices\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices\Entity;
11
+
12
+ /**
13
+ * Class Message
14
+ */
15
+ class Message {
16
+
17
+ /**
18
+ * The messagte text.
19
+ *
20
+ * @var string
21
+ */
22
+ private $message;
23
+
24
+ /**
25
+ * The message type.
26
+ *
27
+ * @var string
28
+ */
29
+ private $type;
30
+
31
+ /**
32
+ * Whether the message is dismissable.
33
+ *
34
+ * @var bool
35
+ */
36
+ private $dismissable;
37
+
38
+ /**
39
+ * Message constructor.
40
+ *
41
+ * @param string $message The message text.
42
+ * @param string $type The message type.
43
+ * @param bool $dismissable Whether the message is dismissable.
44
+ */
45
+ public function __construct( string $message, string $type, bool $dismissable = true ) {
46
+ $this->type = $type;
47
+ $this->message = $message;
48
+ $this->dismissable = $dismissable;
49
+ }
50
+
51
+ /**
52
+ * Returns the message text.
53
+ *
54
+ * @return string
55
+ */
56
+ public function message(): string {
57
+ return $this->message;
58
+ }
59
+
60
+ /**
61
+ * Returns the message type.
62
+ *
63
+ * @return string
64
+ */
65
+ public function type(): string {
66
+ return $this->type;
67
+ }
68
+
69
+ /**
70
+ * Returns whether the message is dismissable.
71
+ *
72
+ * @return bool
73
+ */
74
+ public function is_dismissable(): bool {
75
+ return $this->dismissable;
76
+ }
77
+ }
modules/ppcp-admin-notices/src/Renderer/class-renderer.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The renderer.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\AdminNotices\Renderer
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices\Renderer;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
13
+
14
+ /**
15
+ * Class Renderer
16
+ */
17
+ class Renderer implements RendererInterface {
18
+
19
+ /**
20
+ * The message repository.
21
+ *
22
+ * @var RepositoryInterface
23
+ */
24
+ private $repository;
25
+
26
+ /**
27
+ * Renderer constructor.
28
+ *
29
+ * @param RepositoryInterface $repository The message repository.
30
+ */
31
+ public function __construct( RepositoryInterface $repository ) {
32
+ $this->repository = $repository;
33
+ }
34
+
35
+ /**
36
+ * Renders the current messages.
37
+ *
38
+ * @return bool
39
+ */
40
+ public function render(): bool {
41
+ $messages = $this->repository->current_message();
42
+ foreach ( $messages as $message ) {
43
+ printf(
44
+ '<div class="notice notice-%s %s"><p>%s</p></div>',
45
+ $message->type(),
46
+ ( $message->is_dismissable() ) ? 'is-dismissible' : '',
47
+ wp_kses_post( $message->message() )
48
+ );
49
+ }
50
+
51
+ return (bool) count( $messages );
52
+ }
53
+ }
modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The renderer interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\AdminNotices\Renderer
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices\Renderer;
11
+
12
+ /**
13
+ * Interface RendererInterface
14
+ */
15
+ interface RendererInterface {
16
+
17
+ /**
18
+ * Renders the messages.
19
+ *
20
+ * @return bool
21
+ */
22
+ public function render(): bool;
23
+ }
modules/ppcp-admin-notices/src/Repository/class-repository.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The message repository.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\AdminNotices\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
+
14
+ /**
15
+ * Class Repository
16
+ */
17
+ class Repository implements RepositoryInterface {
18
+
19
+ const NOTICES_FILTER = 'ppcp.admin-notices.current-notices';
20
+
21
+ /**
22
+ * Returns the current messages.
23
+ *
24
+ * @return Message[]
25
+ */
26
+ public function current_message(): array {
27
+ return array_filter(
28
+ (array) apply_filters(
29
+ self::NOTICES_FILTER,
30
+ array()
31
+ ),
32
+ function( $element ) : bool {
33
+ return is_a( $element, Message::class );
34
+ }
35
+ );
36
+ }
37
+ }
modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The repository interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\AdminNotices\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
+
14
+ /**
15
+ * Interface RepositoryInterface
16
+ */
17
+ interface RepositoryInterface {
18
+
19
+
20
+ /**
21
+ * Returns the current messages.
22
+ *
23
+ * @return Message[]
24
+ */
25
+ public function current_message(): array;
26
+ }
modules/ppcp-admin-notices/src/class-adminnotices.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin notice module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\AdminNotices;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use Interop\Container\ServiceProviderInterface;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class AdminNotices
19
+ */
20
+ class AdminNotices implements ModuleInterface {
21
+
22
+ /**
23
+ * Sets up the module.
24
+ *
25
+ * @return ServiceProviderInterface
26
+ */
27
+ public function setup(): ServiceProviderInterface {
28
+ return new ServiceProvider(
29
+ require __DIR__ . '/../services.php',
30
+ require __DIR__ . '/../extensions.php'
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Runs the module.
36
+ *
37
+ * @param ContainerInterface $container The container.
38
+ */
39
+ public function run( ContainerInterface $container = null ) {
40
+ add_action(
41
+ 'admin_notices',
42
+ function() use ( $container ) {
43
+ $renderer = $container->get( 'admin-notices.renderer' );
44
+ $renderer->render();
45
+ }
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Returns the key for the module.
51
+ *
52
+ * @return string|void
53
+ */
54
+ public function getKey() {
55
+ }
56
+ }
modules/ppcp-api-client/extensions.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The extensions of the api client module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient;
11
+
12
+ return array();
modules/ppcp-api-client/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The api client module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return function (): ModuleInterface {
15
+ return new ApiModule();
16
+ };
modules/ppcp-api-client/services.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The services of the API client.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
19
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
20
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
21
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
22
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\AddressFactory;
23
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\AmountFactory;
24
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
25
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
26
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
27
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
28
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
29
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory;
30
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayeeFactory;
31
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
32
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentsFactory;
33
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentSourceFactory;
34
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
35
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
36
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerStatusFactory;
37
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingFactory;
38
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
39
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
40
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
41
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
42
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
43
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
44
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
45
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
46
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
47
+
48
+ return array(
49
+ 'api.host' => function( $container ) : string {
50
+ return PAYPAL_API_URL;
51
+ },
52
+ 'api.paypal-host' => function( $container ) : string {
53
+ return PAYPAL_API_URL;
54
+ },
55
+ 'api.partner_merchant_id' => static function () : string {
56
+ return '';
57
+ },
58
+ 'api.merchant_email' => function () : string {
59
+ return '';
60
+ },
61
+ 'api.merchant_id' => function () : string {
62
+ return '';
63
+ },
64
+ 'api.key' => static function (): string {
65
+ return '';
66
+ },
67
+ 'api.secret' => static function (): string {
68
+ return '';
69
+ },
70
+ 'api.prefix' => static function (): string {
71
+ return 'WC-';
72
+ },
73
+ 'api.bearer' => static function ( $container ): Bearer {
74
+
75
+ $cache = new Cache( 'ppcp-paypal-bearer' );
76
+ $key = $container->get( 'api.key' );
77
+ $secret = $container->get( 'api.secret' );
78
+
79
+ $host = $container->get( 'api.host' );
80
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
81
+ return new PayPalBearer(
82
+ $cache,
83
+ $host,
84
+ $key,
85
+ $secret,
86
+ $logger
87
+ );
88
+ },
89
+ 'api.endpoint.partners' => static function ( $container ) : PartnersEndpoint {
90
+ return new PartnersEndpoint(
91
+ $container->get( 'api.host' ),
92
+ $container->get( 'api.bearer' ),
93
+ $container->get( 'woocommerce.logger.woocommerce' ),
94
+ $container->get( 'api.factory.sellerstatus' ),
95
+ $container->get( 'api.partner_merchant_id' ),
96
+ $container->get( 'api.merchant_id' )
97
+ );
98
+ },
99
+ 'api.factory.sellerstatus' => static function ( $container ) : SellerStatusFactory {
100
+ return new SellerStatusFactory();
101
+ },
102
+ 'api.endpoint.payment-token' => static function ( $container ) : PaymentTokenEndpoint {
103
+ return new PaymentTokenEndpoint(
104
+ $container->get( 'api.host' ),
105
+ $container->get( 'api.bearer' ),
106
+ $container->get( 'api.factory.payment-token' ),
107
+ $container->get( 'woocommerce.logger.woocommerce' ),
108
+ $container->get( 'api.prefix' )
109
+ );
110
+ },
111
+ 'api.endpoint.webhook' => static function ( $container ) : WebhookEndpoint {
112
+
113
+ return new WebhookEndpoint(
114
+ $container->get( 'api.host' ),
115
+ $container->get( 'api.bearer' ),
116
+ $container->get( 'api.factory.webhook' ),
117
+ $container->get( 'woocommerce.logger.woocommerce' )
118
+ );
119
+ },
120
+ 'api.endpoint.partner-referrals' => static function ( $container ) : PartnerReferrals {
121
+
122
+ return new PartnerReferrals(
123
+ $container->get( 'api.host' ),
124
+ $container->get( 'api.bearer' ),
125
+ $container->get( 'api.repository.partner-referrals-data' ),
126
+ $container->get( 'woocommerce.logger.woocommerce' )
127
+ );
128
+ },
129
+ 'api.endpoint.identity-token' => static function ( $container ) : IdentityToken {
130
+
131
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
132
+ $prefix = $container->get( 'api.prefix' );
133
+ return new IdentityToken(
134
+ $container->get( 'api.host' ),
135
+ $container->get( 'api.bearer' ),
136
+ $logger,
137
+ $prefix
138
+ );
139
+ },
140
+ 'api.endpoint.payments' => static function ( $container ): PaymentsEndpoint {
141
+ $authorizations_factory = $container->get( 'api.factory.authorization' );
142
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
143
+
144
+ return new PaymentsEndpoint(
145
+ $container->get( 'api.host' ),
146
+ $container->get( 'api.bearer' ),
147
+ $authorizations_factory,
148
+ $logger
149
+ );
150
+ },
151
+ 'api.endpoint.login-seller' => static function ( $container ) : LoginSeller {
152
+
153
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
154
+ return new LoginSeller(
155
+ $container->get( 'api.paypal-host' ),
156
+ $container->get( 'api.partner_merchant_id' ),
157
+ $logger
158
+ );
159
+ },
160
+ 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
161
+ $order_factory = $container->get( 'api.factory.order' );
162
+ $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
163
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
164
+
165
+ /**
166
+ * The settings.
167
+ *
168
+ * @var Settings $settings
169
+ */
170
+ $settings = $container->get( 'wcgateway.settings' );
171
+ $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
172
+ $application_context_repository = $container->get( 'api.repository.application-context' );
173
+ $paypal_request_id = $container->get( 'api.repository.paypal-request-id' );
174
+ return new OrderEndpoint(
175
+ $container->get( 'api.host' ),
176
+ $container->get( 'api.bearer' ),
177
+ $order_factory,
178
+ $patch_collection_factory,
179
+ $intent,
180
+ $logger,
181
+ $application_context_repository,
182
+ $paypal_request_id
183
+ );
184
+ },
185
+ 'api.repository.paypal-request-id' => static function( $container ) : PayPalRequestIdRepository {
186
+ return new PayPalRequestIdRepository();
187
+ },
188
+ 'api.repository.application-context' => static function( $container ) : ApplicationContextRepository {
189
+
190
+ $settings = $container->get( 'wcgateway.settings' );
191
+ return new ApplicationContextRepository( $settings );
192
+ },
193
+ 'api.repository.partner-referrals-data' => static function ( $container ) : PartnerReferralsData {
194
+
195
+ $merchant_email = $container->get( 'api.merchant_email' );
196
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
197
+ return new PartnerReferralsData( $merchant_email, $dcc_applies );
198
+ },
199
+ 'api.repository.cart' => static function ( $container ): CartRepository {
200
+ $factory = $container->get( 'api.factory.purchase-unit' );
201
+ return new CartRepository( $factory );
202
+ },
203
+ 'api.repository.payee' => static function ( $container ): PayeeRepository {
204
+ $merchant_email = $container->get( 'api.merchant_email' );
205
+ $merchant_id = $container->get( 'api.merchant_id' );
206
+ return new PayeeRepository( $merchant_email, $merchant_id );
207
+ },
208
+ 'api.factory.application-context' => static function ( $container ) : ApplicationContextFactory {
209
+ return new ApplicationContextFactory();
210
+ },
211
+ 'api.factory.payment-token' => static function ( $container ) : PaymentTokenFactory {
212
+ return new PaymentTokenFactory();
213
+ },
214
+ 'api.factory.webhook' => static function ( $container ): WebhookFactory {
215
+ return new WebhookFactory();
216
+ },
217
+ 'api.factory.capture' => static function ( $container ): CaptureFactory {
218
+
219
+ $amount_factory = $container->get( 'api.factory.amount' );
220
+ return new CaptureFactory( $amount_factory );
221
+ },
222
+ 'api.factory.purchase-unit' => static function ( $container ): PurchaseUnitFactory {
223
+
224
+ $amount_factory = $container->get( 'api.factory.amount' );
225
+ $payee_repository = $container->get( 'api.repository.payee' );
226
+ $payee_factory = $container->get( 'api.factory.payee' );
227
+ $item_factory = $container->get( 'api.factory.item' );
228
+ $shipping_factory = $container->get( 'api.factory.shipping' );
229
+ $payments_factory = $container->get( 'api.factory.payments' );
230
+ $prefix = $container->get( 'api.prefix' );
231
+
232
+ return new PurchaseUnitFactory(
233
+ $amount_factory,
234
+ $payee_repository,
235
+ $payee_factory,
236
+ $item_factory,
237
+ $shipping_factory,
238
+ $payments_factory,
239
+ $prefix
240
+ );
241
+ },
242
+ 'api.factory.patch-collection-factory' => static function ( $container ): PatchCollectionFactory {
243
+ return new PatchCollectionFactory();
244
+ },
245
+ 'api.factory.payee' => static function ( $container ): PayeeFactory {
246
+ return new PayeeFactory();
247
+ },
248
+ 'api.factory.item' => static function ( $container ): ItemFactory {
249
+ return new ItemFactory();
250
+ },
251
+ 'api.factory.shipping' => static function ( $container ): ShippingFactory {
252
+ $address_factory = $container->get( 'api.factory.address' );
253
+ return new ShippingFactory( $address_factory );
254
+ },
255
+ 'api.factory.amount' => static function ( $container ): AmountFactory {
256
+ $item_factory = $container->get( 'api.factory.item' );
257
+ return new AmountFactory( $item_factory );
258
+ },
259
+ 'api.factory.payer' => static function ( $container ): PayerFactory {
260
+ $address_factory = $container->get( 'api.factory.address' );
261
+ return new PayerFactory( $address_factory );
262
+ },
263
+ 'api.factory.address' => static function ( $container ): AddressFactory {
264
+ return new AddressFactory();
265
+ },
266
+ 'api.factory.payment-source' => static function ( $container ): PaymentSourceFactory {
267
+ return new PaymentSourceFactory();
268
+ },
269
+ 'api.factory.order' => static function ( $container ): OrderFactory {
270
+ $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
271
+ $payer_factory = $container->get( 'api.factory.payer' );
272
+ $application_context_repository = $container->get( 'api.repository.application-context' );
273
+ $application_context_factory = $container->get( 'api.factory.application-context' );
274
+ $payment_source_factory = $container->get( 'api.factory.payment-source' );
275
+ return new OrderFactory(
276
+ $purchase_unit_factory,
277
+ $payer_factory,
278
+ $application_context_repository,
279
+ $application_context_factory,
280
+ $payment_source_factory
281
+ );
282
+ },
283
+ 'api.factory.payments' => static function ( $container ): PaymentsFactory {
284
+ $authorizations_factory = $container->get( 'api.factory.authorization' );
285
+ $capture_factory = $container->get( 'api.factory.capture' );
286
+ return new PaymentsFactory( $authorizations_factory, $capture_factory );
287
+ },
288
+ 'api.factory.authorization' => static function ( $container ): AuthorizationFactory {
289
+ return new AuthorizationFactory();
290
+ },
291
+ 'api.helpers.dccapplies' => static function ( $container ) : DccApplies {
292
+ return new DccApplies();
293
+ },
294
+ );
modules/ppcp-api-client/src/Authentication/class-bearer.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The bearer interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Authentication
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Authentication;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
13
+
14
+ /**
15
+ * Interface Bearer
16
+ */
17
+ interface Bearer {
18
+
19
+ /**
20
+ * Returns the bearer.
21
+ *
22
+ * @return Token
23
+ */
24
+ public function bearer(): Token;
25
+ }
modules/ppcp-api-client/src/Authentication/class-connectbearer.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The connect dummy bearer.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Authentication
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Authentication;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
13
+
14
+ /**
15
+ * Class ConnectBearer
16
+ */
17
+ class ConnectBearer implements Bearer {
18
+
19
+ /**
20
+ * Returns the bearer.
21
+ *
22
+ * @return Token
23
+ */
24
+ public function bearer(): Token {
25
+ $data = (object) array(
26
+ 'created' => time(),
27
+ 'expires_in' => 3600,
28
+ 'token' => 'token',
29
+ );
30
+ return new Token( $data );
31
+ }
32
+ }
modules/ppcp-api-client/src/Authentication/class-paypalbearer.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PayPal bearer.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Authentication
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Authentication;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
16
+ use Psr\Log\LoggerInterface;
17
+
18
+ /**
19
+ * Class PayPalBearer
20
+ */
21
+ class PayPalBearer implements Bearer {
22
+
23
+ use RequestTrait;
24
+
25
+ const CACHE_KEY = 'ppcp-bearer';
26
+
27
+ /**
28
+ * The cache.
29
+ *
30
+ * @var Cache
31
+ */
32
+ private $cache;
33
+
34
+ /**
35
+ * The host.
36
+ *
37
+ * @var string
38
+ */
39
+ private $host;
40
+
41
+ /**
42
+ * The client key.
43
+ *
44
+ * @var string
45
+ */
46
+ private $key;
47
+
48
+ /**
49
+ * The client secret.
50
+ *
51
+ * @var string
52
+ */
53
+ private $secret;
54
+
55
+ /**
56
+ * The logger.
57
+ *
58
+ * @var LoggerInterface
59
+ */
60
+ private $logger;
61
+
62
+ /**
63
+ * PayPalBearer constructor.
64
+ *
65
+ * @param Cache $cache The cache.
66
+ * @param string $host The host.
67
+ * @param string $key The key.
68
+ * @param string $secret The secret.
69
+ * @param LoggerInterface $logger The logger.
70
+ */
71
+ public function __construct(
72
+ Cache $cache,
73
+ string $host,
74
+ string $key,
75
+ string $secret,
76
+ LoggerInterface $logger
77
+ ) {
78
+
79
+ $this->cache = $cache;
80
+ $this->host = $host;
81
+ $this->key = $key;
82
+ $this->secret = $secret;
83
+ $this->logger = $logger;
84
+ }
85
+
86
+ /**
87
+ * Returns a bearer token.
88
+ *
89
+ * @return Token
90
+ * @throws RuntimeException When request fails.
91
+ */
92
+ public function bearer(): Token {
93
+ try {
94
+ $bearer = Token::from_json( (string) $this->cache->get( self::CACHE_KEY ) );
95
+ return ( $bearer->is_valid() ) ? $bearer : $this->newBearer();
96
+ } catch ( RuntimeException $error ) {
97
+ return $this->newBearer();
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Creates a new bearer token.
103
+ *
104
+ * @return Token
105
+ * @throws RuntimeException When request fails.
106
+ */
107
+ private function newBearer(): Token {
108
+ $url = trailingslashit( $this->host ) . 'v1/oauth2/token?grant_type=client_credentials';
109
+ $args = array(
110
+ 'method' => 'POST',
111
+ 'headers' => array(
112
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
113
+ 'Authorization' => 'Basic ' . base64_encode( $this->key . ':' . $this->secret ),
114
+ ),
115
+ );
116
+ $response = $this->request(
117
+ $url,
118
+ $args
119
+ );
120
+
121
+ if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
122
+ $error = new RuntimeException(
123
+ __( 'Could not create token.', 'woocommerce-paypal-payments' )
124
+ );
125
+ $this->logger->log(
126
+ 'warning',
127
+ $error->getMessage(),
128
+ array(
129
+ 'args' => $args,
130
+ 'response' => $response,
131
+ )
132
+ );
133
+ throw $error;
134
+ }
135
+
136
+ $token = Token::from_json( $response['body'] );
137
+ $this->cache->set( self::CACHE_KEY, $token->as_json() );
138
+ return $token;
139
+ }
140
+ }
modules/ppcp-api-client/src/Endpoint/class-identitytoken.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fetches identity tokens.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
+ use Psr\Log\LoggerInterface;
17
+
18
+ /**
19
+ * Class IdentityToken
20
+ */
21
+ class IdentityToken {
22
+
23
+ use RequestTrait;
24
+
25
+ /**
26
+ * The Bearer.
27
+ *
28
+ * @var Bearer
29
+ */
30
+ private $bearer;
31
+
32
+ /**
33
+ * The host.
34
+ *
35
+ * @var string
36
+ */
37
+ private $host;
38
+
39
+ /**
40
+ * The logger.
41
+ *
42
+ * @var LoggerInterface
43
+ */
44
+ private $logger;
45
+
46
+ /**
47
+ * The prefix.
48
+ *
49
+ * @var string
50
+ */
51
+ private $prefix;
52
+
53
+ /**
54
+ * IdentityToken constructor.
55
+ *
56
+ * @param string $host The host.
57
+ * @param Bearer $bearer The bearer.
58
+ * @param LoggerInterface $logger The logger.
59
+ * @param string $prefix The prefix.
60
+ */
61
+ public function __construct( string $host, Bearer $bearer, LoggerInterface $logger, string $prefix ) {
62
+ $this->host = $host;
63
+ $this->bearer = $bearer;
64
+ $this->logger = $logger;
65
+ $this->prefix = $prefix;
66
+ }
67
+
68
+ /**
69
+ * Generates a token for a specific customer.
70
+ *
71
+ * @param int $customer_id The id of the customer.
72
+ *
73
+ * @return Token
74
+ * @throws RuntimeException If the request fails.
75
+ */
76
+ public function generate_for_customer( int $customer_id ): Token {
77
+
78
+ $bearer = $this->bearer->bearer();
79
+ $url = trailingslashit( $this->host ) . 'v1/identity/generate-token';
80
+ $args = array(
81
+ 'method' => 'POST',
82
+ 'headers' => array(
83
+ 'Authorization' => 'Bearer ' . $bearer->token(),
84
+ 'Content-Type' => 'application/json',
85
+ ),
86
+ );
87
+ if ( $customer_id && defined( 'PPCP_FLAG_SUBSCRIPTION' ) && PPCP_FLAG_SUBSCRIPTION ) {
88
+ $args['body'] = wp_json_encode( array( 'customer_id' => $this->prefix . $customer_id ) );
89
+ }
90
+
91
+ $response = $this->request( $url, $args );
92
+
93
+ if ( is_wp_error( $response ) ) {
94
+ $error = new RuntimeException(
95
+ __(
96
+ 'Could not create identity token.',
97
+ 'woocommerce-paypal-payments'
98
+ )
99
+ );
100
+
101
+ $this->logger->log(
102
+ 'warning',
103
+ $error->getMessage(),
104
+ array(
105
+ 'args' => $args,
106
+ 'response' => $response,
107
+ )
108
+ );
109
+ throw $error;
110
+ }
111
+
112
+ $json = json_decode( $response['body'] );
113
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
114
+ if ( 200 !== $status_code ) {
115
+ $error = new PayPalApiException(
116
+ $json,
117
+ $status_code
118
+ );
119
+ $this->logger->log(
120
+ 'warning',
121
+ $error->getMessage(),
122
+ array(
123
+ 'args' => $args,
124
+ 'response' => $response,
125
+ )
126
+ );
127
+ throw $error;
128
+ }
129
+
130
+ $token = Token::from_json( $response['body'] );
131
+ return $token;
132
+ }
133
+ }
modules/ppcp-api-client/src/Endpoint/class-loginseller.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fetches credentials for an instance.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+ use Psr\Log\LoggerInterface;
15
+
16
+ /**
17
+ * Class LoginSeller
18
+ */
19
+ class LoginSeller {
20
+
21
+ use RequestTrait;
22
+
23
+ /**
24
+ * The host.
25
+ *
26
+ * @var string
27
+ */
28
+ private $host;
29
+
30
+ /**
31
+ * The partner merchant id.
32
+ *
33
+ * @var string
34
+ */
35
+ private $partner_merchant_id;
36
+
37
+ /**
38
+ * The logger.
39
+ *
40
+ * @var LoggerInterface
41
+ */
42
+ private $logger;
43
+
44
+ /**
45
+ * LoginSeller constructor.
46
+ *
47
+ * @param string $host The host.
48
+ * @param string $partner_marchant_id The partner merchant id.
49
+ * @param LoggerInterface $logger The logger.
50
+ */
51
+ public function __construct(
52
+ string $host,
53
+ string $partner_marchant_id,
54
+ LoggerInterface $logger
55
+ ) {
56
+
57
+ $this->host = $host;
58
+ $this->partner_merchant_id = $partner_marchant_id;
59
+ $this->logger = $logger;
60
+ }
61
+
62
+ /**
63
+ * Fetches credentials for a shared id, auth code and seller nonce.
64
+ *
65
+ * @param string $shared_id The shared id.
66
+ * @param string $auth_code The auth code.
67
+ * @param string $seller_nonce The seller nonce.
68
+ *
69
+ * @return \stdClass
70
+ * @throws RuntimeException If the request fails.
71
+ */
72
+ public function credentials_for(
73
+ string $shared_id,
74
+ string $auth_code,
75
+ string $seller_nonce
76
+ ): \stdClass {
77
+
78
+ $token = $this->generate_token_for( $shared_id, $auth_code, $seller_nonce );
79
+ $url = trailingslashit( $this->host ) .
80
+ 'v1/customer/partners/' . $this->partner_merchant_id .
81
+ '/merchant-integrations/credentials/';
82
+ $args = array(
83
+ 'method' => 'GET',
84
+ 'headers' => array(
85
+ 'Authorization' => 'Bearer ' . $token,
86
+ 'Content-Type' => 'application/json',
87
+ ),
88
+ );
89
+ $response = $this->request( $url, $args );
90
+ if ( is_wp_error( $response ) ) {
91
+ $error = new RuntimeException(
92
+ __( 'Could not fetch credentials.', 'woocommerce-paypal-payments' )
93
+ );
94
+ $this->logger->log(
95
+ 'warning',
96
+ $error->getMessage(),
97
+ array(
98
+ 'args' => $args,
99
+ 'response' => $response,
100
+ )
101
+ );
102
+ throw $error;
103
+ }
104
+ $json = json_decode( $response['body'] );
105
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
106
+ if ( ! isset( $json->client_id ) || ! isset( $json->client_secret ) ) {
107
+ $error = isset( $json->details ) ?
108
+ new PayPalApiException(
109
+ $json,
110
+ $status_code
111
+ ) : new RuntimeException(
112
+ __( 'Credentials not found.', 'woocommerce-paypal-payments' )
113
+ );
114
+ $this->logger->log(
115
+ 'warning',
116
+ $error->getMessage(),
117
+ array(
118
+ 'args' => $args,
119
+ 'response' => $response,
120
+ )
121
+ );
122
+ throw $error;
123
+ }
124
+
125
+ return $json;
126
+ }
127
+
128
+ /**
129
+ * Generates a token for a shared id and auth token and seller nonce.
130
+ *
131
+ * @param string $shared_id The shared id.
132
+ * @param string $auth_code The auth code.
133
+ * @param string $seller_nonce The seller nonce.
134
+ *
135
+ * @return string
136
+ * @throws RuntimeException If the request fails.
137
+ */
138
+ private function generate_token_for(
139
+ string $shared_id,
140
+ string $auth_code,
141
+ string $seller_nonce
142
+ ): string {
143
+
144
+ $url = trailingslashit( $this->host ) . 'v1/oauth2/token/';
145
+ $args = array(
146
+ 'method' => 'POST',
147
+ 'headers' => array(
148
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
149
+ 'Authorization' => 'Basic ' . base64_encode( $shared_id . ':' ),
150
+ ),
151
+ 'body' => array(
152
+ 'grant_type' => 'authorization_code',
153
+ 'code' => $auth_code,
154
+ 'code_verifier' => $seller_nonce,
155
+ ),
156
+ );
157
+ $response = $this->request( $url, $args );
158
+
159
+ if ( is_wp_error( $response ) ) {
160
+ $error = new RuntimeException(
161
+ __( 'Could not create token.', 'woocommerce-paypal-payments' )
162
+ );
163
+ $this->logger->log(
164
+ 'warning',
165
+ $error->getMessage(),
166
+ array(
167
+ 'args' => $args,
168
+ 'response' => $response,
169
+ )
170
+ );
171
+ throw $error;
172
+ }
173
+
174
+ $json = json_decode( $response['body'] );
175
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
176
+ if ( ! isset( $json->access_token ) ) {
177
+ $error = isset( $json->details ) ?
178
+ new PayPalApiException(
179
+ $json,
180
+ $status_code
181
+ ) : new RuntimeException(
182
+ __( 'No token found.', 'woocommerce-paypal-payments' )
183
+ );
184
+ $this->logger->log(
185
+ 'warning',
186
+ $error->getMessage(),
187
+ array(
188
+ 'args' => $args,
189
+ 'response' => $response,
190
+ )
191
+ );
192
+ throw $error;
193
+ }
194
+ return (string) $json->access_token;
195
+ }
196
+ }
modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The order endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
19
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
20
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
21
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
22
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
23
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory;
24
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\ErrorResponse;
25
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
26
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
27
+ use Psr\Log\LoggerInterface;
28
+
29
+ /**
30
+ * Class OrderEndpoint
31
+ */
32
+ class OrderEndpoint {
33
+
34
+ use RequestTrait;
35
+
36
+ /**
37
+ * The host.
38
+ *
39
+ * @var string
40
+ */
41
+ private $host;
42
+
43
+ /**
44
+ * The bearer.
45
+ *
46
+ * @var Bearer
47
+ */
48
+ private $bearer;
49
+
50
+ /**
51
+ * The order factory.
52
+ *
53
+ * @var OrderFactory
54
+ */
55
+ private $order_factory;
56
+
57
+ /**
58
+ * The patch collection factory.
59
+ *
60
+ * @var PatchCollectionFactory
61
+ */
62
+ private $patch_collection_factory;
63
+
64
+ /**
65
+ * The intent.
66
+ *
67
+ * @var string
68
+ */
69
+ private $intent;
70
+
71
+ /**
72
+ * The logger.
73
+ *
74
+ * @var LoggerInterface
75
+ */
76
+ private $logger;
77
+
78
+ /**
79
+ * The application context repository.
80
+ *
81
+ * @var ApplicationContextRepository
82
+ */
83
+ private $application_context_repository;
84
+
85
+ /**
86
+ * The BN Code.
87
+ *
88
+ * @var string
89
+ */
90
+ private $bn_code;
91
+
92
+ /**
93
+ * The paypal request id repository.
94
+ *
95
+ * @var PayPalRequestIdRepository
96
+ */
97
+ private $paypal_request_id_repository;
98
+
99
+ /**
100
+ * OrderEndpoint constructor.
101
+ *
102
+ * @param string $host The host.
103
+ * @param Bearer $bearer The bearer.
104
+ * @param OrderFactory $order_factory The order factory.
105
+ * @param PatchCollectionFactory $patch_collection_factory The patch collection factory.
106
+ * @param string $intent The intent.
107
+ * @param LoggerInterface $logger The logger.
108
+ * @param ApplicationContextRepository $application_context_repository The application context repository.
109
+ * @param PayPalRequestIdRepository $paypal_request_id_repository The paypal request id repository.
110
+ * @param string $bn_code The BN Code.
111
+ */
112
+ public function __construct(
113
+ string $host,
114
+ Bearer $bearer,
115
+ OrderFactory $order_factory,
116
+ PatchCollectionFactory $patch_collection_factory,
117
+ string $intent,
118
+ LoggerInterface $logger,
119
+ ApplicationContextRepository $application_context_repository,
120
+ PayPalRequestIdRepository $paypal_request_id_repository,
121
+ string $bn_code = ''
122
+ ) {
123
+
124
+ $this->host = $host;
125
+ $this->bearer = $bearer;
126
+ $this->order_factory = $order_factory;
127
+ $this->patch_collection_factory = $patch_collection_factory;
128
+ $this->intent = $intent;
129
+ $this->logger = $logger;
130
+ $this->application_context_repository = $application_context_repository;
131
+ $this->bn_code = $bn_code;
132
+ $this->paypal_request_id_repository = $paypal_request_id_repository;
133
+ }
134
+
135
+ /**
136
+ * Changes the used BN Code.
137
+ *
138
+ * @param string $bn_code The new BN Code to use.
139
+ *
140
+ * @return OrderEndpoint
141
+ * @throws RuntimeException If the request fails.
142
+ */
143
+ public function with_bn_code( string $bn_code ): OrderEndpoint {
144
+
145
+ $this->bn_code = $bn_code;
146
+ return $this;
147
+ }
148
+
149
+ /**
150
+ * Creates an order.
151
+ *
152
+ * @param PurchaseUnit[] $items The purchase unit items for the order.
153
+ * @param Payer|null $payer The payer off the order.
154
+ * @param PaymentToken|null $payment_token The payment token.
155
+ * @param PaymentMethod|null $payment_method The payment method.
156
+ * @param string $paypal_request_id The paypal request id.
157
+ *
158
+ * @return Order
159
+ * @throws RuntimeException If the request fails.
160
+ */
161
+ public function create(
162
+ array $items,
163
+ Payer $payer = null,
164
+ PaymentToken $payment_token = null,
165
+ PaymentMethod $payment_method = null,
166
+ string $paypal_request_id = ''
167
+ ): Order {
168
+
169
+ $contains_physical_goods = false;
170
+ $items = array_filter(
171
+ $items,
172
+ static function ( $item ) use ( &$contains_physical_goods ): bool {
173
+ $is_purchase_unit = is_a( $item, PurchaseUnit::class );
174
+ /**
175
+ * A purchase unit.
176
+ *
177
+ * @var PurchaseUnit $item
178
+ */
179
+ if ( $is_purchase_unit && $item->contains_physical_goods() ) {
180
+ $contains_physical_goods = true;
181
+ }
182
+
183
+ return $is_purchase_unit;
184
+ }
185
+ );
186
+ $shipping_preferences = $contains_physical_goods
187
+ ? ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
188
+ : ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
189
+ $bearer = $this->bearer->bearer();
190
+ $data = array(
191
+ 'intent' => $this->intent,
192
+ 'purchase_units' => array_map(
193
+ static function ( PurchaseUnit $item ): array {
194
+ return $item->to_array();
195
+ },
196
+ $items
197
+ ),
198
+ 'application_context' => $this->application_context_repository
199
+ ->current_context( $shipping_preferences )->to_array(),
200
+ );
201
+ if ( $payer ) {
202
+ $data['payer'] = $payer->to_array();
203
+ }
204
+ if ( $payment_token ) {
205
+ $data['payment_source']['token'] = $payment_token->to_array();
206
+ }
207
+ if ( $payment_method ) {
208
+ $data['payment_method'] = $payment_method->to_array();
209
+ }
210
+ $url = trailingslashit( $this->host ) . 'v2/checkout/orders';
211
+ $args = array(
212
+ 'method' => 'POST',
213
+ 'headers' => array(
214
+ 'Authorization' => 'Bearer ' . $bearer->token(),
215
+ 'Content-Type' => 'application/json',
216
+ 'Prefer' => 'return=representation',
217
+ ),
218
+ 'body' => wp_json_encode( $data ),
219
+ );
220
+
221
+ $paypal_request_id = $paypal_request_id ? $paypal_request_id : uniqid( 'ppcp-', true );
222
+ $args['headers']['PayPal-Request-Id'] = $paypal_request_id;
223
+ if ( $this->bn_code ) {
224
+ $args['headers']['PayPal-Partner-Attribution-Id'] = $this->bn_code;
225
+ }
226
+ $response = $this->request( $url, $args );
227
+ if ( is_wp_error( $response ) ) {
228
+ $error = new RuntimeException(
229
+ __( 'Could not create order.', 'woocommerce-paypal-payments' )
230
+ );
231
+ $this->logger->log(
232
+ 'warning',
233
+ $error->getMessage(),
234
+ array(
235
+ 'args' => $args,
236
+ 'response' => $response,
237
+ )
238
+ );
239
+ throw $error;
240
+ }
241
+ $json = json_decode( $response['body'] );
242
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
243
+ if ( 201 !== $status_code ) {
244
+ $error = new PayPalApiException(
245
+ $json,
246
+ $status_code
247
+ );
248
+ $this->logger->log(
249
+ 'warning',
250
+ $error->getMessage(),
251
+ array(
252
+ 'args' => $args,
253
+ 'response' => $response,
254
+ )
255
+ );
256
+ throw $error;
257
+ }
258
+ $order = $this->order_factory->from_paypal_response( $json );
259
+ $this->paypal_request_id_repository->set_for_order( $order, $paypal_request_id );
260
+ return $order;
261
+ }
262
+
263
+ /**
264
+ * Captures an order.
265
+ *
266
+ * @param Order $order The order.
267
+ *
268
+ * @return Order
269
+ * @throws RuntimeException If the request fails.
270
+ */
271
+ public function capture( Order $order ): Order {
272
+ if ( $order->status()->is( OrderStatus::COMPLETED ) ) {
273
+ return $order;
274
+ }
275
+ $bearer = $this->bearer->bearer();
276
+ $url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $order->id() . '/capture';
277
+ $args = array(
278
+ 'method' => 'POST',
279
+ 'headers' => array(
280
+ 'Authorization' => 'Bearer ' . $bearer->token(),
281
+ 'Content-Type' => 'application/json',
282
+ 'Prefer' => 'return=representation',
283
+ 'PayPal-Request-Id' => $this->paypal_request_id_repository->get_for_order( $order ),
284
+ ),
285
+ );
286
+ if ( $this->bn_code ) {
287
+ $args['headers']['PayPal-Partner-Attribution-Id'] = $this->bn_code;
288
+ }
289
+ $response = $this->request( $url, $args );
290
+
291
+ if ( is_wp_error( $response ) ) {
292
+ $error = new RuntimeException(
293
+ __( 'Could not capture order.', 'woocommerce-paypal-payments' )
294
+ );
295
+ $this->logger->log(
296
+ 'warning',
297
+ $error->getMessage(),
298
+ array(
299
+ 'args' => $args,
300
+ 'response' => $response,
301
+ )
302
+ );
303
+ throw $error;
304
+ }
305
+
306
+ $json = json_decode( $response['body'] );
307
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
308
+ if ( 201 !== $status_code ) {
309
+ $error = new PayPalApiException(
310
+ $json,
311
+ $status_code
312
+ );
313
+ // If the order has already been captured, we return the updated order.
314
+ if ( strpos( $response['body'], ErrorResponse::ORDER_ALREADY_CAPTURED ) !== false ) {
315
+ return $this->order( $order->id() );
316
+ }
317
+ $this->logger->log(
318
+ 'warning',
319
+ $error->getMessage(),
320
+ array(
321
+ 'args' => $args,
322
+ 'response' => $response,
323
+ )
324
+ );
325
+ throw $error;
326
+ }
327
+ $order = $this->order_factory->from_paypal_response( $json );
328
+ return $order;
329
+ }
330
+
331
+ /**
332
+ * Authorize an order.
333
+ *
334
+ * @param Order $order The order.
335
+ *
336
+ * @return Order
337
+ * @throws RuntimeException If the request fails.
338
+ */
339
+ public function authorize( Order $order ): Order {
340
+ $bearer = $this->bearer->bearer();
341
+ $url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $order->id() . '/authorize';
342
+ $args = array(
343
+ 'method' => 'POST',
344
+ 'headers' => array(
345
+ 'Authorization' => 'Bearer ' . $bearer->token(),
346
+ 'Content-Type' => 'application/json',
347
+ 'Prefer' => 'return=representation',
348
+ 'PayPal-Request-Id' => $this->paypal_request_id_repository->get_for_order( $order ),
349
+ ),
350
+ );
351
+ if ( $this->bn_code ) {
352
+ $args['headers']['PayPal-Partner-Attribution-Id'] = $this->bn_code;
353
+ }
354
+ $response = $this->request( $url, $args );
355
+
356
+ if ( is_wp_error( $response ) ) {
357
+ $error = new RuntimeException(
358
+ __(
359
+ 'Could not authorize order.',
360
+ 'woocommerce-paypal-payments'
361
+ )
362
+ );
363
+ $this->logger->log(
364
+ 'warning',
365
+ $error->getMessage(),
366
+ array(
367
+ 'args' => $args,
368
+ 'response' => $response,
369
+ )
370
+ );
371
+ throw $error;
372
+ }
373
+ $json = json_decode( $response['body'] );
374
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
375
+ if ( 201 !== $status_code ) {
376
+ if ( false !== strpos( $response['body'], ErrorResponse::ORDER_ALREADY_AUTHORIZED ) ) {
377
+ return $this->order( $order->id() );
378
+ }
379
+ $error = new PayPalApiException(
380
+ $json,
381
+ $status_code
382
+ );
383
+ $this->logger->log(
384
+ 'warning',
385
+ $error->getMessage(),
386
+ array(
387
+ 'args' => $args,
388
+ 'response' => $response,
389
+ )
390
+ );
391
+ throw $error;
392
+ }
393
+ $order = $this->order_factory->from_paypal_response( $json );
394
+ return $order;
395
+ }
396
+
397
+ /**
398
+ * Fetches an order for a given ID.
399
+ *
400
+ * @param string $id The ID.
401
+ *
402
+ * @return Order
403
+ * @throws RuntimeException If the request fails.
404
+ */
405
+ public function order( string $id ): Order {
406
+ $bearer = $this->bearer->bearer();
407
+ $url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $id;
408
+ $args = array(
409
+ 'headers' => array(
410
+ 'Authorization' => 'Bearer ' . $bearer->token(),
411
+ 'Content-Type' => 'application/json',
412
+ 'PayPal-Request-Id' => $this->paypal_request_id_repository->get_for_order_id( $id ),
413
+ ),
414
+ );
415
+ if ( $this->bn_code ) {
416
+ $args['headers']['PayPal-Partner-Attribution-Id'] = $this->bn_code;
417
+ }
418
+ $response = $this->request( $url, $args );
419
+ if ( is_wp_error( $response ) ) {
420
+ $error = new RuntimeException(
421
+ __( 'Could not retrieve order.', 'woocommerce-paypal-payments' )
422
+ );
423
+ $this->logger->log(
424
+ 'warning',
425
+ $error->getMessage(),
426
+ array(
427
+ 'args' => $args,
428
+ 'response' => $response,
429
+ )
430
+ );
431
+ throw $error;
432
+ }
433
+ $json = json_decode( $response['body'] );
434
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
435
+ if ( 404 === $status_code || empty( $response['body'] ) ) {
436
+ $error = new RuntimeException(
437
+ __( 'Could not retrieve order.', 'woocommerce-paypal-payments' ),
438
+ 404
439
+ );
440
+ $this->logger->log(
441
+ 'warning',
442
+ $error->getMessage(),
443
+ array(
444
+ 'args' => $args,
445
+ 'response' => $response,
446
+ )
447
+ );
448
+ throw $error;
449
+ }
450
+ if ( 200 !== $status_code ) {
451
+ $error = new PayPalApiException(
452
+ $json,
453
+ $status_code
454
+ );
455
+ $this->logger->log(
456
+ 'warning',
457
+ $error->getMessage(),
458
+ array(
459
+ 'args' => $args,
460
+ 'response' => $response,
461
+ )
462
+ );
463
+ throw $error;
464
+ }
465
+ $order = $this->order_factory->from_paypal_response( $json );
466
+ return $order;
467
+ }
468
+
469
+ /**
470
+ * Patches an order.
471
+ *
472
+ * @param Order $order_to_update The order to patch.
473
+ * @param Order $order_to_compare The target order.
474
+ *
475
+ * @return Order
476
+ * @throws RuntimeException If the request fails.
477
+ */
478
+ public function patch_order_with( Order $order_to_update, Order $order_to_compare ): Order {
479
+ $patches = $this->patch_collection_factory->from_orders( $order_to_update, $order_to_compare );
480
+ if ( ! count( $patches->patches() ) ) {
481
+ return $order_to_update;
482
+ }
483
+
484
+ $bearer = $this->bearer->bearer();
485
+ $url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $order_to_update->id();
486
+ $args = array(
487
+ 'method' => 'PATCH',
488
+ 'headers' => array(
489
+ 'Authorization' => 'Bearer ' . $bearer->token(),
490
+ 'Content-Type' => 'application/json',
491
+ 'Prefer' => 'return=representation',
492
+ 'PayPal-Request-Id' => $this->paypal_request_id_repository->get_for_order(
493
+ $order_to_update
494
+ ),
495
+ ),
496
+ 'body' => wp_json_encode( $patches->to_array() ),
497
+ );
498
+ if ( $this->bn_code ) {
499
+ $args['headers']['PayPal-Partner-Attribution-Id'] = $this->bn_code;
500
+ }
501
+ $response = $this->request( $url, $args );
502
+
503
+ if ( is_wp_error( $response ) ) {
504
+ $error = new RuntimeException(
505
+ __( 'Could not retrieve order.', 'woocommerce-paypal-payments' )
506
+ );
507
+ $this->logger->log(
508
+ 'warning',
509
+ $error->getMessage(),
510
+ array(
511
+ 'args' => $args,
512
+ 'response' => $response,
513
+ )
514
+ );
515
+ throw $error;
516
+ }
517
+ $json = json_decode( $response['body'] );
518
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
519
+ if ( 204 !== $status_code ) {
520
+ $error = new PayPalApiException(
521
+ $json,
522
+ $status_code
523
+ );
524
+ $this->logger->log(
525
+ 'warning',
526
+ $error->getMessage(),
527
+ array(
528
+ 'args' => $args,
529
+ 'response' => $response,
530
+ )
531
+ );
532
+ throw $error;
533
+ }
534
+
535
+ $new_order = $this->order( $order_to_update->id() );
536
+ return $new_order;
537
+ }
538
+ }
modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The partner referrals endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
16
+ use Psr\Log\LoggerInterface;
17
+
18
+ /**
19
+ * Class PartnerReferrals
20
+ */
21
+ class PartnerReferrals {
22
+
23
+ use RequestTrait;
24
+
25
+ /**
26
+ * The host.
27
+ *
28
+ * @var string
29
+ */
30
+ private $host;
31
+
32
+ /**
33
+ * The bearer.
34
+ *
35
+ * @var Bearer
36
+ */
37
+ private $bearer;
38
+
39
+ /**
40
+ * The PartnerReferralsData.
41
+ *
42
+ * @var PartnerReferralsData
43
+ */
44
+ private $data;
45
+
46
+ /**
47
+ * The logger.
48
+ *
49
+ * @var LoggerInterface
50
+ */
51
+ private $logger;
52
+
53
+ /**
54
+ * PartnerReferrals constructor.
55
+ *
56
+ * @param string $host The host.
57
+ * @param Bearer $bearer The bearer.
58
+ * @param PartnerReferralsData $data The partner referrals data.
59
+ * @param LoggerInterface $logger The logger.
60
+ */
61
+ public function __construct(
62
+ string $host,
63
+ Bearer $bearer,
64
+ PartnerReferralsData $data,
65
+ LoggerInterface $logger
66
+ ) {
67
+
68
+ $this->host = $host;
69
+ $this->bearer = $bearer;
70
+ $this->data = $data;
71
+ $this->logger = $logger;
72
+ }
73
+
74
+ /**
75
+ * Fetch the signup link.
76
+ *
77
+ * @return string
78
+ * @throws RuntimeException If the request fails.
79
+ */
80
+ public function signup_link(): string {
81
+ $data = $this->data->data();
82
+ $bearer = $this->bearer->bearer();
83
+ $args = array(
84
+ 'method' => 'POST',
85
+ 'headers' => array(
86
+ 'Authorization' => 'Bearer ' . $bearer->token(),
87
+ 'Content-Type' => 'application/json',
88
+ 'Prefer' => 'return=representation',
89
+ ),
90
+ 'body' => wp_json_encode( $data ),
91
+ );
92
+ $url = trailingslashit( $this->host ) . 'v2/customer/partner-referrals';
93
+ $response = $this->request( $url, $args );
94
+
95
+ if ( is_wp_error( $response ) ) {
96
+ $error = new RuntimeException(
97
+ __( 'Could not create referral.', 'woocommerce-paypal-payments' )
98
+ );
99
+ $this->logger->log(
100
+ 'warning',
101
+ $error->getMessage(),
102
+ array(
103
+ 'args' => $args,
104
+ 'response' => $response,
105
+ )
106
+ );
107
+ throw $error;
108
+ }
109
+ $json = json_decode( $response['body'] );
110
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
111
+ if ( 201 !== $status_code ) {
112
+ $error = new PayPalApiException(
113
+ $json,
114
+ $status_code
115
+ );
116
+ $this->logger->log(
117
+ 'warning',
118
+ $error->getMessage(),
119
+ array(
120
+ 'args' => $args,
121
+ 'response' => $response,
122
+ )
123
+ );
124
+ throw $error;
125
+ }
126
+
127
+ foreach ( $json->links as $link ) {
128
+ if ( 'action_url' === $link->rel ) {
129
+ return (string) $link->href;
130
+ }
131
+ }
132
+
133
+ $error = new RuntimeException(
134
+ __( 'Action URL not found.', 'woocommerce-paypal-payments' )
135
+ );
136
+ $this->logger->log(
137
+ 'warning',
138
+ $error->getMessage(),
139
+ array(
140
+ 'args' => $args,
141
+ 'response' => $response,
142
+ )
143
+ );
144
+ throw $error;
145
+ }
146
+ }
modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Partners Endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use Psr\Log\LoggerInterface;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatus;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerStatusFactory;
18
+
19
+ /**
20
+ * Class PartnersEndpoint
21
+ */
22
+ class PartnersEndpoint {
23
+
24
+ use RequestTrait;
25
+
26
+ /**
27
+ * The Host URL.
28
+ *
29
+ * @var string
30
+ */
31
+ private $host;
32
+
33
+ /**
34
+ * The bearer.
35
+ *
36
+ * @var Bearer
37
+ */
38
+ private $bearer;
39
+
40
+ /**
41
+ * The logger.
42
+ *
43
+ * @var LoggerInterface
44
+ */
45
+ private $logger;
46
+
47
+ /**
48
+ * The seller status factory.
49
+ *
50
+ * @var SellerStatusFactory
51
+ */
52
+ private $seller_status_factory;
53
+
54
+ /**
55
+ * The partner ID.
56
+ *
57
+ * @var string
58
+ */
59
+ private $partner_id;
60
+
61
+ /**
62
+ * The merchant ID.
63
+ *
64
+ * @var string
65
+ */
66
+ private $merchant_id;
67
+
68
+ /**
69
+ * PartnersEndpoint constructor.
70
+ *
71
+ * @param string $host The host.
72
+ * @param Bearer $bearer The bearer.
73
+ * @param LoggerInterface $logger The logger.
74
+ * @param SellerStatusFactory $seller_status_factory The seller status factory.
75
+ * @param string $partner_id The partner ID.
76
+ * @param string $merchant_id The merchant ID.
77
+ */
78
+ public function __construct(
79
+ string $host,
80
+ Bearer $bearer,
81
+ LoggerInterface $logger,
82
+ SellerStatusFactory $seller_status_factory,
83
+ string $partner_id,
84
+ string $merchant_id
85
+ ) {
86
+ $this->host = $host;
87
+ $this->bearer = $bearer;
88
+ $this->logger = $logger;
89
+ $this->seller_status_factory = $seller_status_factory;
90
+ $this->partner_id = $partner_id;
91
+ $this->merchant_id = $merchant_id;
92
+ }
93
+
94
+ /**
95
+ * Returns the current seller status.
96
+ *
97
+ * @return SellerStatus
98
+ * @throws RuntimeException When request could not be fullfilled.
99
+ */
100
+ public function seller_status() : SellerStatus {
101
+ $url = trailingslashit( $this->host ) . 'v1/customer/partners/' . $this->partner_id . '/merchant-integrations/' . $this->merchant_id;
102
+ $bearer = $this->bearer->bearer();
103
+ $args = array(
104
+ 'method' => 'GET',
105
+ 'headers' => array(
106
+ 'Authorization' => 'Bearer ' . $bearer->token(),
107
+ 'Content-Type' => 'application/json',
108
+ ),
109
+ );
110
+ $response = $this->request( $url, $args );
111
+ if ( is_wp_error( $response ) ) {
112
+
113
+ $error = new RuntimeException(
114
+ __(
115
+ 'Could not fetch sellers status.',
116
+ 'woocommerce-paypal-payments'
117
+ )
118
+ );
119
+
120
+ $this->logger->log(
121
+ 'warning',
122
+ $error->getMessage(),
123
+ array(
124
+ 'args' => $args,
125
+ 'response' => $response,
126
+ )
127
+ );
128
+ throw $error;
129
+ }
130
+
131
+ $json = json_decode( wp_remote_retrieve_body( $response ) );
132
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
133
+ if ( 200 !== $status_code ) {
134
+ $error = new PayPalApiException( $json, $status_code );
135
+ $this->logger->log(
136
+ 'warning',
137
+ $error->getMessage(),
138
+ array(
139
+ 'args' => $args,
140
+ 'response' => $response,
141
+ )
142
+ );
143
+ throw $error;
144
+ }
145
+
146
+ $status = $this->seller_status_factory->from_paypal_reponse( $json );
147
+ return $status;
148
+ }
149
+ }
modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The payments endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
18
+ use Psr\Log\LoggerInterface;
19
+
20
+ /**
21
+ * Class PaymentsEndpoint
22
+ */
23
+ class PaymentsEndpoint {
24
+
25
+ use RequestTrait;
26
+
27
+ /**
28
+ * The host.
29
+ *
30
+ * @var string
31
+ */
32
+ private $host;
33
+
34
+ /**
35
+ * The bearer.
36
+ *
37
+ * @var Bearer
38
+ */
39
+ private $bearer;
40
+
41
+ /**
42
+ * The authorization factory.
43
+ *
44
+ * @var AuthorizationFactory
45
+ */
46
+ private $authorizations_factory;
47
+
48
+ /**
49
+ * The logger.
50
+ *
51
+ * @var LoggerInterface
52
+ */
53
+ private $logger;
54
+
55
+ /**
56
+ * PaymentsEndpoint constructor.
57
+ *
58
+ * @param string $host The host.
59
+ * @param Bearer $bearer The bearer.
60
+ * @param AuthorizationFactory $authorization_factory The authorization factory.
61
+ * @param LoggerInterface $logger The logger.
62
+ */
63
+ public function __construct(
64
+ string $host,
65
+ Bearer $bearer,
66
+ AuthorizationFactory $authorization_factory,
67
+ LoggerInterface $logger
68
+ ) {
69
+
70
+ $this->host = $host;
71
+ $this->bearer = $bearer;
72
+ $this->authorizations_factory = $authorization_factory;
73
+ $this->logger = $logger;
74
+ }
75
+
76
+ /**
77
+ * Fetch an authorization by a given id.
78
+ *
79
+ * @param string $authorization_id The id.
80
+ *
81
+ * @return Authorization
82
+ * @throws RuntimeException If the request fails.
83
+ */
84
+ public function authorization( string $authorization_id ): Authorization {
85
+ $bearer = $this->bearer->bearer();
86
+ $url = trailingslashit( $this->host ) . 'v2/payments/authorizations/' . $authorization_id;
87
+ $args = array(
88
+ 'headers' => array(
89
+ 'Authorization' => 'Bearer ' . $bearer->token(),
90
+ 'Content-Type' => 'application/json',
91
+ 'Prefer' => 'return=representation',
92
+ ),
93
+ );
94
+
95
+ $response = $this->request( $url, $args );
96
+ $json = json_decode( $response['body'] );
97
+
98
+ if ( is_wp_error( $response ) ) {
99
+ $error = new RuntimeException(
100
+ __( 'Could not get authorized payment info.', 'woocommerce-paypal-payments' )
101
+ );
102
+ $this->logger->log(
103
+ 'warning',
104
+ $error->getMessage(),
105
+ array(
106
+ 'args' => $args,
107
+ 'response' => $response,
108
+ )
109
+ );
110
+ throw $error;
111
+ }
112
+
113
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
114
+ if ( 200 !== $status_code ) {
115
+ $error = new PayPalApiException(
116
+ $json,
117
+ $status_code
118
+ );
119
+ $this->logger->log(
120
+ 'warning',
121
+ $error->getMessage(),
122
+ array(
123
+ 'args' => $args,
124
+ 'response' => $response,
125
+ )
126
+ );
127
+ throw $error;
128
+ }
129
+
130
+ $authorization = $this->authorizations_factory->from_paypal_response( $json );
131
+ return $authorization;
132
+ }
133
+
134
+ /**
135
+ * Capture an authorization by a given ID.
136
+ *
137
+ * @param string $authorization_id The id.
138
+ *
139
+ * @return Authorization
140
+ * @throws RuntimeException If the request fails.
141
+ */
142
+ public function capture( string $authorization_id ): Authorization {
143
+ $bearer = $this->bearer->bearer();
144
+ $url = trailingslashit( $this->host ) . 'v2/payments/authorizations/' . $authorization_id . '/capture';
145
+ $args = array(
146
+ 'method' => 'POST',
147
+ 'headers' => array(
148
+ 'Authorization' => 'Bearer ' . $bearer->token(),
149
+ 'Content-Type' => 'application/json',
150
+ 'Prefer' => 'return=representation',
151
+ ),
152
+ );
153
+
154
+ $response = $this->request( $url, $args );
155
+ $json = json_decode( $response['body'] );
156
+
157
+ if ( is_wp_error( $response ) ) {
158
+ $error = new RuntimeException(
159
+ __( 'Could not capture authorized payment.', 'woocommerce-paypal-payments' )
160
+ );
161
+ $this->logger->log(
162
+ 'warning',
163
+ $error->getMessage(),
164
+ array(
165
+ 'args' => $args,
166
+ 'response' => $response,
167
+ )
168
+ );
169
+ throw $error;
170
+ }
171
+
172
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
173
+ if ( 201 !== $status_code ) {
174
+ $error = new PayPalApiException(
175
+ $json,
176
+ $status_code
177
+ );
178
+ $this->logger->log(
179
+ 'warning',
180
+ $error->getMessage(),
181
+ array(
182
+ 'args' => $args,
183
+ 'response' => $response,
184
+ )
185
+ );
186
+ throw $error;
187
+ }
188
+
189
+ $authorization = $this->authorizations_factory->from_paypal_response( $json );
190
+ return $authorization;
191
+ }
192
+
193
+ /**
194
+ * Refunds a payment.
195
+ *
196
+ * @param Refund $refund The refund to be processed.
197
+ *
198
+ * @return bool
199
+ * @throws RuntimeException If the request fails.
200
+ */
201
+ public function refund( Refund $refund ) : bool {
202
+ $bearer = $this->bearer->bearer();
203
+ $url = trailingslashit( $this->host ) . 'v2/payments/captures/' . $refund->for_capture()->id() . '/refund';
204
+ $args = array(
205
+ 'method' => 'POST',
206
+ 'headers' => array(
207
+ 'Authorization' => 'Bearer ' . $bearer->token(),
208
+ 'Content-Type' => 'application/json',
209
+ 'Prefer' => 'return=representation',
210
+ ),
211
+ 'body' => wp_json_encode( $refund->to_array() ),
212
+ );
213
+
214
+ $response = $this->request( $url, $args );
215
+ $json = json_decode( $response['body'] );
216
+
217
+ if ( is_wp_error( $response ) ) {
218
+ $error = new RuntimeException(
219
+ __( 'Could not refund payment.', 'woocommerce-paypal-payments' )
220
+ );
221
+ $this->logger->log(
222
+ 'warning',
223
+ $error->getMessage(),
224
+ array(
225
+ 'args' => $args,
226
+ 'response' => $response,
227
+ )
228
+ );
229
+ throw $error;
230
+ }
231
+
232
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
233
+ if ( 201 !== $status_code ) {
234
+ $error = new PayPalApiException(
235
+ $json,
236
+ $status_code
237
+ );
238
+ $this->logger->log(
239
+ 'warning',
240
+ $error->getMessage(),
241
+ array(
242
+ 'args' => $args,
243
+ 'response' => $response,
244
+ )
245
+ );
246
+ throw $error;
247
+ }
248
+
249
+ return true;
250
+ }
251
+ }
modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The payment token endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
17
+ use Psr\Log\LoggerInterface;
18
+
19
+ /**
20
+ * Class PaymentTokenEndpoint
21
+ */
22
+ class PaymentTokenEndpoint {
23
+
24
+ use RequestTrait;
25
+
26
+ /**
27
+ * The bearer.
28
+ *
29
+ * @var Bearer
30
+ */
31
+ private $bearer;
32
+
33
+ /**
34
+ * The host.
35
+ *
36
+ * @var string
37
+ */
38
+ private $host;
39
+
40
+ /**
41
+ * The payment token factory.
42
+ *
43
+ * @var PaymentTokenFactory
44
+ */
45
+ private $factory;
46
+
47
+ /**
48
+ * The logger.
49
+ *
50
+ * @var LoggerInterface
51
+ */
52
+ private $logger;
53
+ /**
54
+ * The prefix.
55
+ *
56
+ * @var string
57
+ */
58
+ private $prefix;
59
+
60
+ /**
61
+ * PaymentTokenEndpoint constructor.
62
+ *
63
+ * @param string $host The host.
64
+ * @param Bearer $bearer The bearer.
65
+ * @param PaymentTokenFactory $factory The payment token factory.
66
+ * @param LoggerInterface $logger The logger.
67
+ * @param string $prefix The prefix.
68
+ */
69
+ public function __construct(
70
+ string $host,
71
+ Bearer $bearer,
72
+ PaymentTokenFactory $factory,
73
+ LoggerInterface $logger,
74
+ string $prefix
75
+ ) {
76
+
77
+ $this->host = $host;
78
+ $this->bearer = $bearer;
79
+ $this->factory = $factory;
80
+ $this->logger = $logger;
81
+ $this->prefix = $prefix;
82
+ }
83
+
84
+ /**
85
+ * Returns the payment tokens for a user.
86
+ *
87
+ * @param int $id The user id.
88
+ *
89
+ * @return PaymentToken[]
90
+ * @throws RuntimeException If the request fails.
91
+ */
92
+ public function for_user( int $id ): array {
93
+ $bearer = $this->bearer->bearer();
94
+
95
+ $customer_id = $this->prefix . $id;
96
+ $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $customer_id;
97
+ $args = array(
98
+ 'method' => 'GET',
99
+ 'headers' => array(
100
+ 'Authorization' => 'Bearer ' . $bearer->token(),
101
+ 'Content-Type' => 'application/json',
102
+ ),
103
+ );
104
+
105
+ $response = $this->request( $url, $args );
106
+ if ( is_wp_error( $response ) ) {
107
+ $error = new RuntimeException(
108
+ __( 'Could not fetch payment token.', 'woocommerce-paypal-payments' )
109
+ );
110
+ $this->logger->log(
111
+ 'warning',
112
+ $error->getMessage(),
113
+ array(
114
+ 'args' => $args,
115
+ 'response' => $response,
116
+ )
117
+ );
118
+ throw $error;
119
+ }
120
+ $json = json_decode( $response['body'] );
121
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
122
+ if ( 200 !== $status_code ) {
123
+ $error = new PayPalApiException(
124
+ $json,
125
+ $status_code
126
+ );
127
+ $this->logger->log(
128
+ 'warning',
129
+ $error->getMessage(),
130
+ array(
131
+ 'args' => $args,
132
+ 'response' => $response,
133
+ )
134
+ );
135
+ throw $error;
136
+ }
137
+
138
+ $tokens = array();
139
+ foreach ( $json->payment_tokens as $token_value ) {
140
+ $tokens[] = $this->factory->from_paypal_response( $token_value );
141
+ }
142
+ if ( empty( $tokens ) ) {
143
+ $error = new RuntimeException(
144
+ sprintf(
145
+ // translators: %d is the customer id.
146
+ __( 'No token stored for customer %d.', 'woocommerce-paypal-payments' ),
147
+ $id
148
+ )
149
+ );
150
+ $this->logger->log(
151
+ 'warning',
152
+ $error->getMessage(),
153
+ array(
154
+ 'args' => $args,
155
+ 'response' => $response,
156
+ )
157
+ );
158
+ throw $error;
159
+ }
160
+ return $tokens;
161
+ }
162
+
163
+ /**
164
+ * Deletes a payment token.
165
+ *
166
+ * @param PaymentToken $token The token to delete.
167
+ *
168
+ * @return bool
169
+ * @throws RuntimeException If the request fails.
170
+ */
171
+ public function delete_token( PaymentToken $token ): bool {
172
+
173
+ $bearer = $this->bearer->bearer();
174
+
175
+ $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/' . $token->id();
176
+ $args = array(
177
+ 'method' => 'DELETE',
178
+ 'headers' => array(
179
+ 'Authorization' => 'Bearer ' . $bearer->token(),
180
+ 'Content-Type' => 'application/json',
181
+ ),
182
+ );
183
+
184
+ $response = $this->request( $url, $args );
185
+
186
+ if ( is_wp_error( $response ) ) {
187
+ $error = new RuntimeException(
188
+ __( 'Could not delete payment token.', 'woocommerce-paypal-payments' )
189
+ );
190
+ $this->logger->log(
191
+ 'warning',
192
+ $error->getMessage(),
193
+ array(
194
+ 'args' => $args,
195
+ 'response' => $response,
196
+ )
197
+ );
198
+ throw $error;
199
+ }
200
+
201
+ return wp_remote_retrieve_response_code( $response ) === 204;
202
+ }
203
+ }
modules/ppcp-api-client/src/Endpoint/class-requesttrait.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The RequestTrait wraps the wp_remote_get functionality for the API client.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ /**
13
+ * Trait RequestTrait
14
+ */
15
+ trait RequestTrait {
16
+
17
+ /**
18
+ * Performs a request
19
+ *
20
+ * @param string $url The URL to request.
21
+ * @param array $args The arguments by which to request.
22
+ *
23
+ * @return array|\WP_Error
24
+ */
25
+ private function request( string $url, array $args ) {
26
+
27
+ /**
28
+ * This filter can be used to alter the request args.
29
+ * For example, during testing, the PayPal-Mock-Response header could be
30
+ * added here.
31
+ */
32
+ $args = apply_filters( 'ppcp_request_args', $args, $url );
33
+ if ( ! isset( $args['headers']['PayPal-Partner-Attribution-Id'] ) ) {
34
+ $args['headers']['PayPal-Partner-Attribution-Id'] = 'Woo_PPCP';
35
+ }
36
+
37
+ return wp_remote_get( $url, $args );
38
+ }
39
+ }
modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The webhook endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
17
+ use Psr\Log\LoggerInterface;
18
+
19
+ /**
20
+ * Class WebhookEndpoint
21
+ */
22
+ class WebhookEndpoint {
23
+
24
+ use RequestTrait;
25
+
26
+ /**
27
+ * The host.
28
+ *
29
+ * @var string
30
+ */
31
+ private $host;
32
+
33
+ /**
34
+ * The bearer.
35
+ *
36
+ * @var Bearer
37
+ */
38
+ private $bearer;
39
+
40
+ /**
41
+ * The webhook factory.
42
+ *
43
+ * @var WebhookFactory
44
+ */
45
+ private $webhook_factory;
46
+
47
+ /**
48
+ * The logger.
49
+ *
50
+ * @var LoggerInterface
51
+ */
52
+ private $logger;
53
+
54
+ /**
55
+ * WebhookEndpoint constructor.
56
+ *
57
+ * @param string $host The host.
58
+ * @param Bearer $bearer The bearer.
59
+ * @param WebhookFactory $webhook_factory The webhook factory.
60
+ * @param LoggerInterface $logger The logger.
61
+ */
62
+ public function __construct(
63
+ string $host,
64
+ Bearer $bearer,
65
+ WebhookFactory $webhook_factory,
66
+ LoggerInterface $logger
67
+ ) {
68
+
69
+ $this->host = $host;
70
+ $this->bearer = $bearer;
71
+ $this->webhook_factory = $webhook_factory;
72
+ $this->logger = $logger;
73
+ }
74
+
75
+ /**
76
+ * Creates a webhook with PayPal.
77
+ *
78
+ * @param Webhook $hook The webhook to create.
79
+ *
80
+ * @return Webhook
81
+ * @throws RuntimeException If the request fails.
82
+ */
83
+ public function create( Webhook $hook ): Webhook {
84
+ /**
85
+ * An hook, which has an ID has already been created.
86
+ */
87
+ if ( $hook->id() ) {
88
+ return $hook;
89
+ }
90
+ $bearer = $this->bearer->bearer();
91
+ $url = trailingslashit( $this->host ) . 'v1/notifications/webhooks';
92
+ $args = array(
93
+ 'method' => 'POST',
94
+ 'headers' => array(
95
+ 'Authorization' => 'Bearer ' . $bearer->token(),
96
+ 'Content-Type' => 'application/json',
97
+ ),
98
+ 'body' => wp_json_encode( $hook->to_array() ),
99
+ );
100
+ $response = $this->request( $url, $args );
101
+
102
+ if ( is_wp_error( $response ) ) {
103
+ $error = new RuntimeException(
104
+ __( 'Not able to create a webhook.', 'woocommerce-paypal-payments' )
105
+ );
106
+ $this->logger->log(
107
+ 'warning',
108
+ $error->getMessage(),
109
+ array(
110
+ 'args' => $args,
111
+ 'response' => $response,
112
+ )
113
+ );
114
+ throw $error;
115
+ }
116
+
117
+ $json = json_decode( $response['body'] );
118
+ $status_code = (int) wp_remote_retrieve_response_code( $response );
119
+ if ( 201 !== $status_code ) {
120
+ $error = new PayPalApiException(
121
+ $json,
122
+ $status_code
123
+ );
124
+ $this->logger->log(
125
+ 'warning',
126
+ $error->getMessage(),
127
+ array(
128
+ 'args' => $args,
129
+ 'response' => $response,
130
+ )
131
+ );
132
+ throw $error;
133
+ }
134
+
135
+ $hook = $this->webhook_factory->from_paypal_response( $json );
136
+ return $hook;
137
+ }
138
+
139
+ /**
140
+ * Deletes a webhook.
141
+ *
142
+ * @param Webhook $hook The webhook to delete.
143
+ *
144
+ * @return bool
145
+ * @throws RuntimeException If the request fails.
146
+ */
147
+ public function delete( Webhook $hook ): bool {
148
+ if ( ! $hook->id() ) {
149
+ return false;
150
+ }
151
+
152
+ $bearer = $this->bearer->bearer();
153
+ $url = trailingslashit( $this->host ) . 'v1/notifications/webhooks/' . $hook->id();
154
+ $args = array(
155
+ 'method' => 'DELETE',
156
+ 'headers' => array(
157
+ 'Authorization' => 'Bearer ' . $bearer->token(),
158
+ ),
159
+ );
160
+ $response = $this->request( $url, $args );
161
+
162
+ if ( is_wp_error( $response ) ) {
163
+ $error = new RuntimeException(
164
+ __( 'Not able to delete the webhook.', 'woocommerce-paypal-payments' )
165
+ );
166
+ $this->logger->log(
167
+ 'warning',
168
+ $error->getMessage(),
169
+ array(
170
+ 'args' => $args,
171
+ 'response' => $response,
172
+ )
173
+ );
174
+ throw $error;
175
+ }
176
+ return wp_remote_retrieve_response_code( $response ) === 204;
177
+ }
178
+
179
+ /**
180
+ * Verifies if a webhook event is legitimate.
181
+ *
182
+ * @param string $auth_algo The auth algo.
183
+ * @param string $cert_url The cert URL.
184
+ * @param string $transmission_id The transmission id.
185
+ * @param string $transmission_sig The transmission signature.
186
+ * @param string $transmission_time The transmission time.
187
+ * @param string $webhook_id The webhook id.
188
+ * @param \stdClass $webhook_event The webhook event.
189
+ *
190
+ * @return bool
191
+ * @throws RuntimeException If the request fails.
192
+ */
193
+ public function verify_event(
194
+ string $auth_algo,
195
+ string $cert_url,
196
+ string $transmission_id,
197
+ string $transmission_sig,
198
+ string $transmission_time,
199
+ string $webhook_id,
200
+ \stdClass $webhook_event
201
+ ): bool {
202
+
203
+ $bearer = $this->bearer->bearer();
204
+ $url = trailingslashit( $this->host ) . 'v1/notifications/verify-webhook-signature';
205
+ $args = array(
206
+ 'method' => 'POST',
207
+ 'headers' => array(
208
+ 'Authorization' => 'Bearer ' . $bearer->token(),
209
+ 'Content-Type' => 'application/json',
210
+ ),
211
+ 'body' => wp_json_encode(
212
+ array(
213
+ 'transmission_id' => $transmission_id,
214
+ 'transmission_time' => $transmission_time,
215
+ 'cert_url' => $cert_url,
216
+ 'auth_algo' => $auth_algo,
217
+ 'transmission_sig' => $transmission_sig,
218
+ 'webhook_id' => $webhook_id,
219
+ 'webhook_event' => $webhook_event,
220
+ )
221
+ ),
222
+ );
223
+ $response = $this->request( $url, $args );
224
+ if ( is_wp_error( $response ) ) {
225
+ $error = new RuntimeException(
226
+ __( 'Not able to verify webhook event.', 'woocommerce-paypal-payments' )
227
+ );
228
+ $this->logger->log(
229
+ 'warning',
230
+ $error->getMessage(),
231
+ array(
232
+ 'args' => $args,
233
+ 'response' => $response,
234
+ )
235
+ );
236
+ throw $error;
237
+ }
238
+ $json = json_decode( $response['body'] );
239
+ return isset( $json->verification_status ) && 'SUCCESS' === $json->verification_status;
240
+ }
241
+
242
+ /**
243
+ * Verifies if the current request is a legit webhook event.
244
+ *
245
+ * @param Webhook $webhook The webhook.
246
+ *
247
+ * @return bool
248
+ * @throws RuntimeException If the request fails.
249
+ */
250
+ public function verify_current_request_for_webhook( Webhook $webhook ): bool {
251
+
252
+ if ( ! $webhook->id() ) {
253
+ $error = new RuntimeException(
254
+ __( 'Not a valid webhook to verify.', 'woocommerce-paypal-payments' )
255
+ );
256
+ $this->logger->log( 'warning', $error->getMessage(), array( 'webhook' => $webhook ) );
257
+ throw $error;
258
+ }
259
+
260
+ $expected_headers = array(
261
+ 'PAYPAL-AUTH-ALGO' => '',
262
+ 'PAYPAL-CERT-URL' => '',
263
+ 'PAYPAL-TRANSMISSION-ID' => '',
264
+ 'PAYPAL-TRANSMISSION-SIG' => '',
265
+ 'PAYPAL-TRANSMISSION-TIME' => '',
266
+ );
267
+ $headers = getallheaders();
268
+ foreach ( $headers as $key => $header ) {
269
+ $key = strtoupper( $key );
270
+ if ( isset( $expected_headers[ $key ] ) ) {
271
+ $expected_headers[ $key ] = $header;
272
+ }
273
+ };
274
+
275
+ foreach ( $expected_headers as $key => $value ) {
276
+ if ( ! empty( $value ) ) {
277
+ continue;
278
+ }
279
+
280
+ $error = new RuntimeException(
281
+ sprintf(
282
+ // translators: %s is the headers key.
283
+ __(
284
+ 'Not a valid webhook event. Header %s is missing',
285
+ 'woocommerce-paypal-payments'
286
+ ),
287
+ $key
288
+ )
289
+ );
290
+ $this->logger->log( 'warning', $error->getMessage(), array( 'webhook' => $webhook ) );
291
+ throw $error;
292
+ }
293
+
294
+ $request_body = json_decode( file_get_contents( 'php://input' ) );
295
+ return $this->verify_event(
296
+ $expected_headers['PAYPAL-AUTH-ALGO'],
297
+ $expected_headers['PAYPAL-CERT-URL'],
298
+ $expected_headers['PAYPAL-TRANSMISSION-ID'],
299
+ $expected_headers['PAYPAL-TRANSMISSION-SIG'],
300
+ $expected_headers['PAYPAL-TRANSMISSION-TIME'],
301
+ $webhook->id(),
302
+ $request_body ? $request_body : new \stdClass()
303
+ );
304
+ }
305
+ }
modules/ppcp-api-client/src/Entity/class-address.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The address object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Address
14
+ */
15
+ class Address {
16
+
17
+ /**
18
+ * The country code.
19
+ *
20
+ * @var string
21
+ */
22
+ private $country_code;
23
+
24
+ /**
25
+ * The 1st address line.
26
+ *
27
+ * @var string
28
+ */
29
+ private $address_line_1;
30
+
31
+ /**
32
+ * The 2nd address line.
33
+ *
34
+ * @var string
35
+ */
36
+ private $address_line_2;
37
+
38
+ /**
39
+ * The admin area 1.
40
+ *
41
+ * @var string
42
+ */
43
+ private $admin_area_1;
44
+
45
+ /**
46
+ * The admin area 2.
47
+ *
48
+ * @var string
49
+ */
50
+ private $admin_area_2;
51
+
52
+ /**
53
+ * The postal code.
54
+ *
55
+ * @var string
56
+ */
57
+ private $postal_code;
58
+
59
+ /**
60
+ * Address constructor.
61
+ *
62
+ * @param string $country_code The country code.
63
+ * @param string $address_line_1 The 1st address line.
64
+ * @param string $address_line_2 The 2nd address line.
65
+ * @param string $admin_area_1 The admin area 1.
66
+ * @param string $admin_area_2 The admin area 2.
67
+ * @param string $postal_code The postal code.
68
+ */
69
+ public function __construct(
70
+ string $country_code,
71
+ string $address_line_1 = '',
72
+ string $address_line_2 = '',
73
+ string $admin_area_1 = '',
74
+ string $admin_area_2 = '',
75
+ string $postal_code = ''
76
+ ) {
77
+
78
+ $this->country_code = $country_code;
79
+ $this->address_line_1 = $address_line_1;
80
+ $this->address_line_2 = $address_line_2;
81
+ $this->admin_area_1 = $admin_area_1;
82
+ $this->admin_area_2 = $admin_area_2;
83
+ $this->postal_code = $postal_code;
84
+ }
85
+
86
+ /**
87
+ * Returns the country code.
88
+ *
89
+ * @return string
90
+ */
91
+ public function country_code(): string {
92
+ return $this->country_code;
93
+ }
94
+
95
+ /**
96
+ * Returns the 1st address line.
97
+ *
98
+ * @return string
99
+ */
100
+ public function address_line_1(): string {
101
+ return $this->address_line_1;
102
+ }
103
+
104
+ /**
105
+ * Returns the 2nd address line.
106
+ *
107
+ * @return string
108
+ */
109
+ public function address_line_2(): string {
110
+ return $this->address_line_2;
111
+ }
112
+
113
+ /**
114
+ * Returns the admin area 1.
115
+ *
116
+ * @return string
117
+ */
118
+ public function admin_area_1(): string {
119
+ return $this->admin_area_1;
120
+ }
121
+
122
+ /**
123
+ * Returns the admin area 2.
124
+ *
125
+ * @return string
126
+ */
127
+ public function admin_area_2(): string {
128
+ return $this->admin_area_2;
129
+ }
130
+
131
+ /**
132
+ * Returns the postal code.
133
+ *
134
+ * @return string
135
+ */
136
+ public function postal_code(): string {
137
+ return $this->postal_code;
138
+ }
139
+
140
+ /**
141
+ * Returns the object as array.
142
+ *
143
+ * @return array
144
+ */
145
+ public function to_array(): array {
146
+ return array(
147
+ 'country_code' => $this->country_code(),
148
+ 'address_line_1' => $this->address_line_1(),
149
+ 'address_line_2' => $this->address_line_2(),
150
+ 'admin_area_1' => $this->admin_area_1(),
151
+ 'admin_area_2' => $this->admin_area_2(),
152
+ 'postal_code' => $this->postal_code(),
153
+ );
154
+ }
155
+ }
modules/ppcp-api-client/src/Entity/class-amount.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The amount object
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Amount
14
+ */
15
+ class Amount {
16
+
17
+ /**
18
+ * The money.
19
+ *
20
+ * @var Money
21
+ */
22
+ private $money;
23
+
24
+ /**
25
+ * The breakdown.
26
+ *
27
+ * @var AmountBreakdown
28
+ */
29
+ private $breakdown;
30
+
31
+ /**
32
+ * Amount constructor.
33
+ *
34
+ * @param Money $money The money.
35
+ * @param AmountBreakdown|null $breakdown The breakdown.
36
+ */
37
+ public function __construct( Money $money, AmountBreakdown $breakdown = null ) {
38
+ $this->money = $money;
39
+ $this->breakdown = $breakdown;
40
+ }
41
+
42
+ /**
43
+ * Returns the currency code.
44
+ *
45
+ * @return string
46
+ */
47
+ public function currency_code(): string {
48
+ return $this->money->currency_code();
49
+ }
50
+
51
+ /**
52
+ * Returns the value.
53
+ *
54
+ * @return float
55
+ */
56
+ public function value(): float {
57
+ return $this->money->value();
58
+ }
59
+
60
+ /**
61
+ * Returns the breakdown.
62
+ *
63
+ * @return AmountBreakdown|null
64
+ */
65
+ public function breakdown() {
66
+ return $this->breakdown;
67
+ }
68
+
69
+ /**
70
+ * Returns the object as array.
71
+ *
72
+ * @return array
73
+ */
74
+ public function to_array(): array {
75
+ $amount = array(
76
+ 'currency_code' => $this->currency_code(),
77
+ 'value' => $this->value(),
78
+ );
79
+ if ( $this->breakdown() && count( $this->breakdown()->to_array() ) ) {
80
+ $amount['breakdown'] = $this->breakdown()->to_array();
81
+ }
82
+ return $amount;
83
+ }
84
+ }
modules/ppcp-api-client/src/Entity/class-amountbreakdown.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Amount Breakdown object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class AmountBreakdown
14
+ */
15
+ class AmountBreakdown {
16
+
17
+ /**
18
+ * The item total.
19
+ *
20
+ * @var Money
21
+ */
22
+ private $item_total;
23
+
24
+ /**
25
+ * The shipping.
26
+ *
27
+ * @var Money
28
+ */
29
+ private $shipping;
30
+
31
+ /**
32
+ * The tax total.
33
+ *
34
+ * @var Money
35
+ */
36
+ private $tax_total;
37
+
38
+ /**
39
+ * The handling.
40
+ *
41
+ * @var Money
42
+ */
43
+ private $handling;
44
+
45
+ /**
46
+ * The insurance.
47
+ *
48
+ * @var Money
49
+ */
50
+ private $insurance;
51
+
52
+ /**
53
+ * The shipping discount.
54
+ *
55
+ * @var Money
56
+ */
57
+ private $shipping_discount;
58
+
59
+ /**
60
+ * The discount.
61
+ *
62
+ * @var Money
63
+ */
64
+ private $discount;
65
+
66
+ /**
67
+ * AmountBreakdown constructor.
68
+ *
69
+ * @param Money|null $item_total The item total.
70
+ * @param Money|null $shipping The shipping.
71
+ * @param Money|null $tax_total The tax total.
72
+ * @param Money|null $handling The handling.
73
+ * @param Money|null $insurance The insurance.
74
+ * @param Money|null $shipping_discount The shipping discount.
75
+ * @param Money|null $discount The discount.
76
+ */
77
+ public function __construct(
78
+ Money $item_total = null,
79
+ Money $shipping = null,
80
+ Money $tax_total = null,
81
+ Money $handling = null,
82
+ Money $insurance = null,
83
+ Money $shipping_discount = null,
84
+ Money $discount = null
85
+ ) {
86
+
87
+ $this->item_total = $item_total;
88
+ $this->shipping = $shipping;
89
+ $this->tax_total = $tax_total;
90
+ $this->handling = $handling;
91
+ $this->insurance = $insurance;
92
+ $this->shipping_discount = $shipping_discount;
93
+ $this->discount = $discount;
94
+ }
95
+
96
+ /**
97
+ * Returns the item total.
98
+ *
99
+ * @return Money|null
100
+ */
101
+ public function item_total() {
102
+ return $this->item_total;
103
+ }
104
+
105
+ /**
106
+ * Returns the shipping.
107
+ *
108
+ * @return Money|null
109
+ */
110
+ public function shipping() {
111
+ return $this->shipping;
112
+ }
113
+
114
+ /**
115
+ * Returns the tax total.
116
+ *
117
+ * @return Money|null
118
+ */
119
+ public function tax_total() {
120
+ return $this->tax_total;
121
+ }
122
+
123
+ /**
124
+ * Returns the handling.
125
+ *
126
+ * @return Money|null
127
+ */
128
+ public function handling() {
129
+ return $this->handling;
130
+ }
131
+
132
+ /**
133
+ * Returns the insurance.
134
+ *
135
+ * @return Money|null
136
+ */
137
+ public function insurance() {
138
+ return $this->insurance;
139
+ }
140
+
141
+ /**
142
+ * Returns the shipping discount.
143
+ *
144
+ * @return Money|null
145
+ */
146
+ public function shipping_discount() {
147
+ return $this->shipping_discount;
148
+ }
149
+
150
+ /**
151
+ * Returns the discount.
152
+ *
153
+ * @return Money|null
154
+ */
155
+ public function discount() {
156
+ return $this->discount;
157
+ }
158
+
159
+ /**
160
+ * Returns the object as array.
161
+ *
162
+ * @return array
163
+ */
164
+ public function to_array() {
165
+ $breakdown = array();
166
+ if ( $this->item_total ) {
167
+ $breakdown['item_total'] = $this->item_total->to_array();
168
+ }
169
+ if ( $this->shipping ) {
170
+ $breakdown['shipping'] = $this->shipping->to_array();
171
+ }
172
+ if ( $this->tax_total ) {
173
+ $breakdown['tax_total'] = $this->tax_total->to_array();
174
+ }
175
+ if ( $this->handling ) {
176
+ $breakdown['handling'] = $this->handling->to_array();
177
+ }
178
+ if ( $this->insurance ) {
179
+ $breakdown['insurance'] = $this->insurance->to_array();
180
+ }
181
+ if ( $this->shipping_discount ) {
182
+ $breakdown['shipping_discount'] = $this->shipping_discount->to_array();
183
+ }
184
+ if ( $this->discount ) {
185
+ $breakdown['discount'] = $this->discount->to_array();
186
+ }
187
+
188
+ return $breakdown;
189
+ }
190
+ }
modules/ppcp-api-client/src/Entity/class-applicationcontext.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The application context object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class ApplicationContext
16
+ */
17
+ class ApplicationContext {
18
+
19
+ const LANDING_PAGE_LOGIN = 'LOGIN';
20
+ const LANDING_PAGE_BILLING = 'BILLING';
21
+ const LANDING_PAGE_NO_PREFERENCE = 'NO_PREFERENCE';
22
+ const VALID_LANDING_PAGE_VALUES = array(
23
+ self::LANDING_PAGE_LOGIN,
24
+ self::LANDING_PAGE_BILLING,
25
+ self::LANDING_PAGE_NO_PREFERENCE,
26
+ );
27
+
28
+ const SHIPPING_PREFERENCE_GET_FROM_FILE = 'GET_FROM_FILE';
29
+ const SHIPPING_PREFERENCE_NO_SHIPPING = 'NO_SHIPPING';
30
+ const SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS = 'SET_PROVIDED_ADDRESS';
31
+ const VALID_SHIPPING_PREFERENCE_VALUES = array(
32
+ self::SHIPPING_PREFERENCE_GET_FROM_FILE,
33
+ self::SHIPPING_PREFERENCE_NO_SHIPPING,
34
+ self::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS,
35
+ );
36
+
37
+ const USER_ACTION_CONTINUE = 'CONTINUE';
38
+ const USER_ACTION_PAY_NOW = 'PAY_NOW';
39
+ const VALID_USER_ACTION_VALUES = array(
40
+ self::USER_ACTION_CONTINUE,
41
+ self::USER_ACTION_PAY_NOW,
42
+ );
43
+
44
+ /**
45
+ * The brand name.
46
+ *
47
+ * @var string
48
+ */
49
+ private $brand_name;
50
+
51
+ /**
52
+ * The locale.
53
+ *
54
+ * @var string
55
+ */
56
+ private $locale;
57
+
58
+ /**
59
+ * The landing page.
60
+ *
61
+ * @var string
62
+ */
63
+ private $landing_page;
64
+
65
+ /**
66
+ * The shipping preference.
67
+ *
68
+ * @var string
69
+ */
70
+ private $shipping_preference;
71
+
72
+ /**
73
+ * The user action.
74
+ *
75
+ * @var string
76
+ */
77
+ private $user_action;
78
+
79
+ /**
80
+ * The return url.
81
+ *
82
+ * @var string
83
+ */
84
+ private $return_url;
85
+
86
+ /**
87
+ * The cancel url.
88
+ *
89
+ * @var string
90
+ */
91
+ private $cancel_url;
92
+
93
+ /**
94
+ * The payment method.
95
+ *
96
+ * @var null
97
+ */
98
+ private $payment_method;
99
+
100
+ /**
101
+ * ApplicationContext constructor.
102
+ *
103
+ * @param string $return_url The return URL.
104
+ * @param string $cancel_url The cancel URL.
105
+ * @param string $brand_name The brand name.
106
+ * @param string $locale The locale.
107
+ * @param string $landing_page The landing page.
108
+ * @param string $shipping_preference The shipping preference.
109
+ * @param string $user_action The user action.
110
+ *
111
+ * @throws RuntimeException When values are not valid.
112
+ */
113
+ public function __construct(
114
+ string $return_url = '',
115
+ string $cancel_url = '',
116
+ string $brand_name = '',
117
+ string $locale = '',
118
+ string $landing_page = self::LANDING_PAGE_NO_PREFERENCE,
119
+ string $shipping_preference = self::SHIPPING_PREFERENCE_NO_SHIPPING,
120
+ string $user_action = self::USER_ACTION_CONTINUE
121
+ ) {
122
+
123
+ if ( ! in_array( $landing_page, self::VALID_LANDING_PAGE_VALUES, true ) ) {
124
+ throw new RuntimeException( 'Landingpage not correct' );
125
+ }
126
+ if ( ! in_array( $shipping_preference, self::VALID_SHIPPING_PREFERENCE_VALUES, true ) ) {
127
+ throw new RuntimeException( 'Shipping preference not correct' );
128
+ }
129
+ if ( ! in_array( $user_action, self::VALID_USER_ACTION_VALUES, true ) ) {
130
+ throw new RuntimeException( 'User action preference not correct' );
131
+ }
132
+ $this->return_url = $return_url;
133
+ $this->cancel_url = $cancel_url;
134
+ $this->brand_name = $brand_name;
135
+ $this->locale = $locale;
136
+ $this->landing_page = $landing_page;
137
+ $this->shipping_preference = $shipping_preference;
138
+ $this->user_action = $user_action;
139
+
140
+ // Currently we have not implemented the payment method.
141
+ $this->payment_method = null;
142
+ }
143
+
144
+ /**
145
+ * Returns the brand name.
146
+ *
147
+ * @return string
148
+ */
149
+ public function brand_name(): string {
150
+ return $this->brand_name;
151
+ }
152
+
153
+ /**
154
+ * Returns the locale.
155
+ *
156
+ * @return string
157
+ */
158
+ public function locale(): string {
159
+ return $this->locale;
160
+ }
161
+
162
+ /**
163
+ * Returns the landing page.
164
+ *
165
+ * @return string
166
+ */
167
+ public function landing_page(): string {
168
+ return $this->landing_page;
169
+ }
170
+
171
+ /**
172
+ * Returns the shipping preference.
173
+ *
174
+ * @return string
175
+ */
176
+ public function shipping_preference(): string {
177
+ return $this->shipping_preference;
178
+ }
179
+
180
+ /**
181
+ * Returns the user action.
182
+ *
183
+ * @return string
184
+ */
185
+ public function user_action(): string {
186
+ return $this->user_action;
187
+ }
188
+
189
+ /**
190
+ * Returns the return URL.
191
+ *
192
+ * @return string
193
+ */
194
+ public function return_url(): string {
195
+ return $this->return_url;
196
+ }
197
+
198
+ /**
199
+ * Returns the cancel URL.
200
+ *
201
+ * @return string
202
+ */
203
+ public function cancel_url(): string {
204
+ return $this->cancel_url;
205
+ }
206
+
207
+ /**
208
+ * Returns the payment method.
209
+ *
210
+ * @return PaymentMethod|null
211
+ */
212
+ public function payment_method() {
213
+ return $this->payment_method;
214
+ }
215
+
216
+ /**
217
+ * Returns the object as array.
218
+ *
219
+ * @return array
220
+ */
221
+ public function to_array(): array {
222
+ $data = array();
223
+ if ( $this->user_action() ) {
224
+ $data['user_action'] = $this->user_action();
225
+ }
226
+ if ( $this->payment_method() ) {
227
+ $data['payment_method'] = $this->payment_method();
228
+ }
229
+ if ( $this->shipping_preference() ) {
230
+ $data['shipping_preference'] = $this->shipping_preference();
231
+ }
232
+ if ( $this->landing_page() ) {
233
+ $data['landing_page'] = $this->landing_page();
234
+ }
235
+ if ( $this->locale() ) {
236
+ $data['locale'] = $this->locale();
237
+ }
238
+ if ( $this->brand_name() ) {
239
+ $data['brand_name'] = $this->brand_name();
240
+ }
241
+ if ( $this->return_url() ) {
242
+ $data['return_url'] = $this->return_url();
243
+ }
244
+ if ( $this->cancel_url() ) {
245
+ $data['cancel_url'] = $this->cancel_url();
246
+ }
247
+ return $data;
248
+ }
249
+ }
modules/ppcp-api-client/src/Entity/class-authorization.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Authorization object
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Authorization
14
+ */
15
+ class Authorization {
16
+
17
+ /**
18
+ * The Id.
19
+ *
20
+ * @var string
21
+ */
22
+ private $id;
23
+
24
+ /**
25
+ * The status.
26
+ *
27
+ * @var AuthorizationStatus
28
+ */
29
+ private $authorization_status;
30
+
31
+ /**
32
+ * Authorization constructor.
33
+ *
34
+ * @param string $id The id.
35
+ * @param AuthorizationStatus $authorization_status The status.
36
+ */
37
+ public function __construct(
38
+ string $id,
39
+ AuthorizationStatus $authorization_status
40
+ ) {
41
+
42
+ $this->id = $id;
43
+ $this->authorization_status = $authorization_status;
44
+ }
45
+
46
+ /**
47
+ * Returns the Id.
48
+ *
49
+ * @return string
50
+ */
51
+ public function id(): string {
52
+ return $this->id;
53
+ }
54
+
55
+ /**
56
+ * Returns the status.
57
+ *
58
+ * @return AuthorizationStatus
59
+ */
60
+ public function status(): AuthorizationStatus {
61
+ return $this->authorization_status;
62
+ }
63
+
64
+ /**
65
+ * Returns the object as array.
66
+ *
67
+ * @return array
68
+ */
69
+ public function to_array(): array {
70
+ return array(
71
+ 'id' => $this->id,
72
+ 'status' => $this->authorization_status->name(),
73
+ );
74
+ }
75
+ }
modules/ppcp-api-client/src/Entity/class-authorizationstatus.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The AuthorizationStatus object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class AuthorizationStatus
16
+ */
17
+ class AuthorizationStatus {
18
+
19
+ const INTERNAL = 'INTERNAL';
20
+ const CREATED = 'CREATED';
21
+ const CAPTURED = 'CAPTURED';
22
+ const COMPLETED = 'COMPLETED';
23
+ const DENIED = 'DENIED';
24
+ const EXPIRED = 'EXPIRED';
25
+ const PARTIALLY_CAPTURED = 'PARTIALLY_CAPTURED';
26
+ const VOIDED = 'VOIDED';
27
+ const PENDING = 'PENDING';
28
+ const VALID_STATUS = array(
29
+ self::INTERNAL,
30
+ self::CREATED,
31
+ self::CAPTURED,
32
+ self::COMPLETED,
33
+ self::DENIED,
34
+ self::EXPIRED,
35
+ self::PARTIALLY_CAPTURED,
36
+ self::VOIDED,
37
+ self::PENDING,
38
+ );
39
+
40
+ /**
41
+ * The status.
42
+ *
43
+ * @var string
44
+ */
45
+ private $status;
46
+
47
+ /**
48
+ * AuthorizationStatus constructor.
49
+ *
50
+ * @param string $status The status.
51
+ * @throws RuntimeException When the status is not valid.
52
+ */
53
+ public function __construct( string $status ) {
54
+ if ( ! in_array( $status, self::VALID_STATUS, true ) ) {
55
+ throw new RuntimeException(
56
+ sprintf(
57
+ // translators: %s is the current status.
58
+ __( '%s is not a valid status', 'woocommerce-paypal-payments' ),
59
+ $status
60
+ )
61
+ );
62
+ }
63
+ $this->status = $status;
64
+ }
65
+
66
+ /**
67
+ * Returns an AuthorizationStatus as Internal.
68
+ *
69
+ * @return AuthorizationStatus
70
+ */
71
+ public static function as_internal(): AuthorizationStatus {
72
+ return new self( self::INTERNAL );
73
+ }
74
+
75
+ /**
76
+ * Compares the current status with a given one.
77
+ *
78
+ * @param string $status The status to compare with.
79
+ *
80
+ * @return bool
81
+ */
82
+ public function is( string $status ): bool {
83
+ return $this->status === $status;
84
+ }
85
+
86
+ /**
87
+ * Returns the status.
88
+ *
89
+ * @return string
90
+ */
91
+ public function name(): string {
92
+ return $this->status;
93
+ }
94
+ }
modules/ppcp-api-client/src/Entity/class-capture.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The capture entity.
4
+ *
5
+ * @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
6
+ *
7
+ * @package Woocommerce\PayPalCommerce\ApiClient\Entity
8
+ */
9
+
10
+ declare( strict_types=1 );
11
+
12
+ namespace Woocommerce\PayPalCommerce\ApiClient\Entity;
13
+
14
+ /**
15
+ * Class Capture
16
+ */
17
+ class Capture {
18
+
19
+ /**
20
+ * The ID.
21
+ *
22
+ * @var string
23
+ */
24
+ private $id;
25
+
26
+ /**
27
+ * The status.
28
+ *
29
+ * @var string
30
+ */
31
+ private $status;
32
+
33
+ /**
34
+ * The status details.
35
+ *
36
+ * @var string
37
+ */
38
+ private $status_details;
39
+
40
+ /**
41
+ * The amount.
42
+ *
43
+ * @var Amount
44
+ */
45
+ private $amount;
46
+
47
+ /**
48
+ * Whether this is the final capture or not.
49
+ *
50
+ * @var bool
51
+ */
52
+ private $final_capture;
53
+
54
+ /**
55
+ * The seller protection.
56
+ *
57
+ * @var string
58
+ */
59
+ private $seller_protection;
60
+
61
+ /**
62
+ * The invoice id.
63
+ *
64
+ * @var string
65
+ */
66
+ private $invoice_id;
67
+
68
+ /**
69
+ * The custom id.
70
+ *
71
+ * @var string
72
+ */
73
+ private $custom_id;
74
+
75
+ /**
76
+ * Capture constructor.
77
+ *
78
+ * @param string $id The ID.
79
+ * @param string $status The status.
80
+ * @param string $status_details The status details.
81
+ * @param Amount $amount The amount.
82
+ * @param bool $final_capture The final capture.
83
+ * @param string $seller_protection The seller protection.
84
+ * @param string $invoice_id The invoice id.
85
+ * @param string $custom_id The custom id.
86
+ */
87
+ public function __construct(
88
+ string $id,
89
+ string $status,
90
+ string $status_details,
91
+ Amount $amount,
92
+ bool $final_capture,
93
+ string $seller_protection,
94
+ string $invoice_id,
95
+ string $custom_id
96
+ ) {
97
+
98
+ $this->id = $id;
99
+ $this->status = $status;
100
+ $this->status_details = $status_details;
101
+ $this->amount = $amount;
102
+ $this->final_capture = $final_capture;
103
+ $this->seller_protection = $seller_protection;
104
+ $this->invoice_id = $invoice_id;
105
+ $this->custom_id = $custom_id;
106
+ }
107
+
108
+ /**
109
+ * Returns the ID.
110
+ *
111
+ * @return string
112
+ */
113
+ public function id() : string {
114
+ return $this->id;
115
+ }
116
+
117
+ /**
118
+ * Returns the status.
119
+ *
120
+ * @return string
121
+ */
122
+ public function status() : string {
123
+ return $this->status;
124
+ }
125
+
126
+ /**
127
+ * Returns the status details object.
128
+ *
129
+ * @return \stdClass
130
+ */
131
+ public function status_details() : \stdClass {
132
+ return (object) array( 'reason' => $this->status_details );
133
+ }
134
+
135
+ /**
136
+ * Returns the amount.
137
+ *
138
+ * @return Amount
139
+ */
140
+ public function amount() : Amount {
141
+ return $this->amount;
142
+ }
143
+
144
+ /**
145
+ * Returns whether this is the final capture or not.
146
+ *
147
+ * @return bool
148
+ */
149
+ public function final_capture() : bool {
150
+ return $this->final_capture;
151
+ }
152
+
153
+ /**
154
+ * Returns the seller protection object.
155
+ *
156
+ * @return \stdClass
157
+ */
158
+ public function seller_protection() : \stdClass {
159
+ return (object) array( 'status' => $this->seller_protection );
160
+ }
161
+
162
+ /**
163
+ * Returns the invoice id.
164
+ *
165
+ * @return string
166
+ */
167
+ public function invoice_id() : string {
168
+ return $this->invoice_id;
169
+ }
170
+
171
+ /**
172
+ * Returns the custom id.
173
+ *
174
+ * @return string
175
+ */
176
+ public function custom_id() : string {
177
+ return $this->custom_id;
178
+ }
179
+
180
+ /**
181
+ * Returns the entity as array.
182
+ *
183
+ * @return array
184
+ */
185
+ public function to_array() : array {
186
+ return array(
187
+ 'id' => $this->id(),
188
+ 'status' => $this->status(),
189
+ 'status_details' => (array) $this->status_details(),
190
+ 'amount' => $this->amount()->to_array(),
191
+ 'final_capture' => $this->final_capture(),
192
+ 'seller_protection' => (array) $this->seller_protection(),
193
+ 'invoice_id' => $this->invoice_id(),
194
+ 'custom_id' => $this->custom_id(),
195
+ );
196
+ }
197
+ }
modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The CardauthenticationResult object
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class CardAuthenticationResult
14
+ */
15
+ class CardAuthenticationResult {
16
+
17
+
18
+ const LIABILITY_SHIFT_POSSIBLE = 'POSSIBLE';
19
+ const LIABILITY_SHIFT_NO = 'NO';
20
+ const LIABILITY_SHIFT_UNKNOWN = 'UNKNOWN';
21
+
22
+ const ENROLLMENT_STATUS_YES = 'Y';
23
+ const ENROLLMENT_STATUS_NO = 'N';
24
+ const ENROLLMENT_STATUS_UNAVAILABLE = 'U';
25
+ const ENROLLMENT_STATUS_BYPASS = 'B';
26
+
27
+ const AUTHENTICATION_RESULT_YES = 'Y';
28
+ const AUTHENTICATION_RESULT_NO = 'N';
29
+ const AUTHENTICATION_RESULT_REJECTED = 'R';
30
+ const AUTHENTICATION_RESULT_ATTEMPTED = 'A';
31
+ const AUTHENTICATION_RESULT_UNABLE = 'U';
32
+ const AUTHENTICATION_RESULT_CHALLENGE_REQUIRED = 'C';
33
+ const AUTHENTICATION_RESULT_INFO = 'I';
34
+ const AUTHENTICATION_RESULT_DECOUPLED = 'D';
35
+
36
+ /**
37
+ * The liability shift.
38
+ *
39
+ * @var string
40
+ */
41
+ private $liability_shift;
42
+
43
+ /**
44
+ * The enrollment status.
45
+ *
46
+ * @var string
47
+ */
48
+ private $enrollment_status;
49
+
50
+ /**
51
+ * The authentication result.
52
+ *
53
+ * @var string
54
+ */
55
+ private $authentication_result;
56
+
57
+ /**
58
+ * CardAuthenticationResult constructor.
59
+ *
60
+ * @param string $liability_shift The liability shift.
61
+ * @param string $enrollment_status The enrollment status.
62
+ * @param string $authentication_result The authentication result.
63
+ */
64
+ public function __construct(
65
+ string $liability_shift,
66
+ string $enrollment_status,
67
+ string $authentication_result
68
+ ) {
69
+
70
+ $this->liability_shift = strtoupper( $liability_shift );
71
+ $this->enrollment_status = strtoupper( $enrollment_status );
72
+ $this->authentication_result = strtoupper( $authentication_result );
73
+ }
74
+
75
+ /**
76
+ * Returns the liability shift.
77
+ *
78
+ * @return string
79
+ */
80
+ public function liability_shift(): string {
81
+
82
+ return $this->liability_shift;
83
+ }
84
+
85
+ /**
86
+ * Returns the enrollment status.
87
+ *
88
+ * @return string
89
+ */
90
+ public function enrollment_status(): string {
91
+
92
+ return $this->enrollment_status;
93
+ }
94
+
95
+ /**
96
+ * Returns the authentication result.
97
+ *
98
+ * @return string
99
+ */
100
+ public function authentication_result(): string {
101
+
102
+ return $this->authentication_result;
103
+ }
104
+
105
+ /**
106
+ * Returns the object as array.
107
+ *
108
+ * @return array
109
+ */
110
+ public function to_array(): array {
111
+ $data = array();
112
+ $data['liability_shift'] = $this->liability_shift();
113
+ $data['three_d_secure'] = array(
114
+ 'enrollment_status' => $this->enrollment_status(),
115
+ 'authentication_result' => $this->authentication_result(),
116
+ );
117
+ return $data;
118
+ }
119
+ }
modules/ppcp-api-client/src/Entity/class-item.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The item object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Item
14
+ */
15
+ class Item {
16
+
17
+
18
+ const PHYSICAL_GOODS = 'PHYSICAL_GOODS';
19
+ const DIGITAL_GOODS = 'DIGITAL_GOODS';
20
+
21
+ /**
22
+ * The name.
23
+ *
24
+ * @var string
25
+ */
26
+ private $name;
27
+
28
+ /**
29
+ * The unit amount.
30
+ *
31
+ * @var Money
32
+ */
33
+ private $unit_amount;
34
+
35
+ /**
36
+ * The quantity.
37
+ *
38
+ * @var int
39
+ */
40
+ private $quantity;
41
+
42
+ /**
43
+ * The description.
44
+ *
45
+ * @var string
46
+ */
47
+ private $description;
48
+
49
+ /**
50
+ * The tax.
51
+ *
52
+ * @var Money|null
53
+ */
54
+ private $tax;
55
+
56
+ /**
57
+ * The SKU.
58
+ *
59
+ * @var string
60
+ */
61
+ private $sku;
62
+
63
+ /**
64
+ * The category.
65
+ *
66
+ * @var string
67
+ */
68
+ private $category;
69
+
70
+ /**
71
+ * Item constructor.
72
+ *
73
+ * @param string $name The name.
74
+ * @param Money $unit_amount The unit amount.
75
+ * @param int $quantity The quantity.
76
+ * @param string $description The description.
77
+ * @param Money|null $tax The tax.
78
+ * @param string $sku The SKU.
79
+ * @param string $category The category.
80
+ */
81
+ public function __construct(
82
+ string $name,
83
+ Money $unit_amount,
84
+ int $quantity,
85
+ string $description = '',
86
+ Money $tax = null,
87
+ string $sku = '',
88
+ string $category = 'PHYSICAL_GOODS'
89
+ ) {
90
+
91
+ $this->name = $name;
92
+ $this->unit_amount = $unit_amount;
93
+ $this->quantity = $quantity;
94
+ $this->description = $description;
95
+ $this->tax = $tax;
96
+ $this->sku = $sku;
97
+ $this->category = ( self::DIGITAL_GOODS === $category ) ?
98
+ self::DIGITAL_GOODS : self::PHYSICAL_GOODS;
99
+ }
100
+
101
+ /**
102
+ * Returns the name of the item.
103
+ *
104
+ * @return string
105
+ */
106
+ public function name(): string {
107
+ return $this->name;
108
+ }
109
+
110
+ /**
111
+ * Returns the unit amount.
112
+ *
113
+ * @return Money
114
+ */
115
+ public function unit_amount(): Money {
116
+ return $this->unit_amount;
117
+ }
118
+
119
+ /**
120
+ * Returns the quantity.
121
+ *
122
+ * @return int
123
+ */
124
+ public function quantity(): int {
125
+ return $this->quantity;
126
+ }
127
+
128
+ /**
129
+ * Returns the description.
130
+ *
131
+ * @return string
132
+ */
133
+ public function description(): string {
134
+ return $this->description;
135
+ }
136
+
137
+ /**
138
+ * Returns the tax.
139
+ *
140
+ * @return Money|null
141
+ */
142
+ public function tax() {
143
+ return $this->tax;
144
+ }
145
+
146
+ /**
147
+ * Returns the SKU.
148
+ *
149
+ * @return string
150
+ */
151
+ public function sku() {
152
+ return $this->sku;
153
+ }
154
+
155
+ /**
156
+ * Returns the category.
157
+ *
158
+ * @return string
159
+ */
160
+ public function category() {
161
+ return $this->category;
162
+ }
163
+
164
+ /**
165
+ * Returns the object as array.
166
+ *
167
+ * @return array
168
+ */
169
+ public function to_array() {
170
+ $item = array(
171
+ 'name' => $this->name(),
172
+ 'unit_amount' => $this->unit_amount()->to_array(),
173
+ 'quantity' => $this->quantity(),
174
+ 'description' => $this->description(),
175
+ 'sku' => $this->sku(),
176
+ 'category' => $this->category(),
177
+ );
178
+
179
+ if ( $this->tax() ) {
180
+ $item['tax'] = $this->tax()->to_array();
181
+ }
182
+
183
+ return $item;
184
+ }
185
+ }
modules/ppcp-api-client/src/Entity/class-money.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The money object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Money
14
+ */
15
+ class Money {
16
+
17
+ /**
18
+ * The currency code.
19
+ *
20
+ * @var string
21
+ */
22
+ private $currency_code;
23
+
24
+ /**
25
+ * The value.
26
+ *
27
+ * @var float
28
+ */
29
+ private $value;
30
+
31
+ /**
32
+ * Money constructor.
33
+ *
34
+ * @param float $value The value.
35
+ * @param string $currency_code The currency code.
36
+ */
37
+ public function __construct( float $value, string $currency_code ) {
38
+ $this->value = $value;
39
+ $this->currency_code = $currency_code;
40
+ }
41
+
42
+ /**
43
+ * The value.
44
+ *
45
+ * @return float
46
+ */
47
+ public function value(): float {
48
+ return $this->value;
49
+ }
50
+
51
+ /**
52
+ * The currency code.
53
+ *
54
+ * @return string
55
+ */
56
+ public function currency_code(): string {
57
+ return $this->currency_code;
58
+ }
59
+
60
+ /**
61
+ * Returns the object as array.
62
+ *
63
+ * @return array
64
+ */
65
+ public function to_array(): array {
66
+ return array(
67
+ 'currency_code' => $this->currency_code(),
68
+ 'value' => number_format( $this->value(), 2 ),
69
+ );
70
+ }
71
+ }
modules/ppcp-api-client/src/Entity/class-order.php ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The order object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Order
14
+ */
15
+ class Order {
16
+
17
+
18
+ /**
19
+ * The ID.
20
+ *
21
+ * @var string
22
+ */
23
+ private $id;
24
+
25
+ /**
26
+ * The create time.
27
+ *
28
+ * @var \DateTime|null
29
+ */
30
+ private $create_time;
31
+
32
+ /**
33
+ * The purchase units.
34
+ *
35
+ * @var PurchaseUnit[]
36
+ */
37
+ private $purchase_units;
38
+
39
+ /**
40
+ * The payer.
41
+ *
42
+ * @var Payer|null
43
+ */
44
+ private $payer;
45
+
46
+ /**
47
+ * The order status.
48
+ *
49
+ * @var OrderStatus
50
+ */
51
+ private $order_status;
52
+
53
+ /**
54
+ * The intent.
55
+ *
56
+ * @var string
57
+ */
58
+ private $intent;
59
+
60
+ /**
61
+ * The update time.
62
+ *
63
+ * @var \DateTime|null
64
+ */
65
+ private $update_time;
66
+
67
+ /**
68
+ * The application context.
69
+ *
70
+ * @var ApplicationContext|null
71
+ */
72
+ private $application_context;
73
+
74
+ /**
75
+ * The payment source.
76
+ *
77
+ * @var PaymentSource|null
78
+ */
79
+ private $payment_source;
80
+
81
+ /**
82
+ * Order constructor.
83
+ *
84
+ * @see https://developer.paypal.com/docs/api/orders/v2/#orders-create-response
85
+ *
86
+ * @param string $id The ID.
87
+ * @param PurchaseUnit[] $purchase_units The purchase units.
88
+ * @param OrderStatus $order_status The order status.
89
+ * @param ApplicationContext|null $application_context The application context.
90
+ * @param PaymentSource|null $payment_source The payment source.
91
+ * @param Payer|null $payer The payer.
92
+ * @param string $intent The intent.
93
+ * @param \DateTime|null $create_time The create time.
94
+ * @param \DateTime|null $update_time The update time.
95
+ */
96
+ public function __construct(
97
+ string $id,
98
+ array $purchase_units,
99
+ OrderStatus $order_status,
100
+ ApplicationContext $application_context = null,
101
+ PaymentSource $payment_source = null,
102
+ Payer $payer = null,
103
+ string $intent = 'CAPTURE',
104
+ \DateTime $create_time = null,
105
+ \DateTime $update_time = null
106
+ ) {
107
+
108
+ $this->id = $id;
109
+ $this->application_context = $application_context;
110
+ $this->purchase_units = array_values(
111
+ array_filter(
112
+ $purchase_units,
113
+ static function ( $unit ): bool {
114
+ return is_a( $unit, PurchaseUnit::class );
115
+ }
116
+ )
117
+ );
118
+ $this->payer = $payer;
119
+ $this->order_status = $order_status;
120
+ $this->intent = ( 'CAPTURE' === $intent ) ? 'CAPTURE' : 'AUTHORIZE';
121
+ $this->purchase_units = $purchase_units;
122
+ $this->create_time = $create_time;
123
+ $this->update_time = $update_time;
124
+ $this->payment_source = $payment_source;
125
+ }
126
+
127
+ /**
128
+ * Returns the ID.
129
+ *
130
+ * @return string
131
+ */
132
+ public function id(): string {
133
+ return $this->id;
134
+ }
135
+
136
+ /**
137
+ * Returns the create time.
138
+ *
139
+ * @return \DateTime|null
140
+ */
141
+ public function create_time() {
142
+ return $this->create_time;
143
+ }
144
+
145
+ /**
146
+ * Returns the update time.
147
+ *
148
+ * @return \DateTime|null
149
+ */
150
+ public function update_time() {
151
+ return $this->update_time;
152
+ }
153
+
154
+ /**
155
+ * Returns the intent.
156
+ *
157
+ * @return string
158
+ */
159
+ public function intent() {
160
+ return $this->intent;
161
+ }
162
+
163
+ /**
164
+ * Returns the payer.
165
+ *
166
+ * @return Payer|null
167
+ */
168
+ public function payer() {
169
+ return $this->payer;
170
+ }
171
+
172
+ /**
173
+ * Returns the purchase units.
174
+ *
175
+ * @return PurchaseUnit[]
176
+ */
177
+ public function purchase_units() {
178
+ return $this->purchase_units;
179
+ }
180
+
181
+ /**
182
+ * Returns the order status.
183
+ *
184
+ * @return OrderStatus
185
+ */
186
+ public function status() {
187
+ return $this->order_status;
188
+ }
189
+
190
+ /**
191
+ * Returns the application context.
192
+ *
193
+ * @return ApplicationContext|null
194
+ */
195
+ public function application_context() {
196
+
197
+ return $this->application_context;
198
+ }
199
+
200
+ /**
201
+ * Returns the payment source.
202
+ *
203
+ * @return PaymentSource|null
204
+ */
205
+ public function payment_source() {
206
+
207
+ return $this->payment_source;
208
+ }
209
+
210
+ /**
211
+ * Returns the object as array.
212
+ *
213
+ * @return array
214
+ */
215
+ public function to_array() {
216
+ $order = array(
217
+ 'id' => $this->id(),
218
+ 'intent' => $this->intent(),
219
+ 'status' => $this->status()->name(),
220
+ 'purchase_units' => array_map(
221
+ static function ( PurchaseUnit $unit ): array {
222
+ return $unit->to_array();
223
+ },
224
+ $this->purchase_units()
225
+ ),
226
+ );
227
+ if ( $this->create_time() ) {
228
+ $order['create_time'] = $this->create_time()->format( 'Y-m-d\TH:i:sO' );
229
+ }
230
+ if ( $this->payer() ) {
231
+ $order['payer'] = $this->payer()->to_array();
232
+ }
233
+ if ( $this->update_time() ) {
234
+ $order['update_time'] = $this->update_time()->format( 'Y-m-d\TH:i:sO' );
235
+ }
236
+ if ( $this->application_context() ) {
237
+ $order['application_context'] = $this->application_context()->to_array();
238
+ }
239
+ if ( $this->payment_source() ) {
240
+ $order['payment_source'] = $this->payment_source()->to_array();
241
+ }
242
+
243
+ return $order;
244
+ }
245
+ }
modules/ppcp-api-client/src/Entity/class-orderstatus.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The OrderStatus object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class OrderStatus
16
+ */
17
+ class OrderStatus {
18
+
19
+
20
+ const INTERNAL = 'INTERNAL';
21
+ const CREATED = 'CREATED';
22
+ const SAVED = 'SAVED';
23
+ const APPROVED = 'APPROVED';
24
+ const VOIDED = 'VOIDED';
25
+ const COMPLETED = 'COMPLETED';
26
+ const VALID_STATI = array(
27
+ self::INTERNAL,
28
+ self::CREATED,
29
+ self::SAVED,
30
+ self::APPROVED,
31
+ self::VOIDED,
32
+ self::COMPLETED,
33
+ );
34
+
35
+ /**
36
+ * The status.
37
+ *
38
+ * @var string
39
+ */
40
+ private $status;
41
+
42
+ /**
43
+ * OrderStatus constructor.
44
+ *
45
+ * @param string $status The status.
46
+ * @throws RuntimeException When the status is not valid.
47
+ */
48
+ public function __construct( string $status ) {
49
+ if ( ! in_array( $status, self::VALID_STATI, true ) ) {
50
+ throw new RuntimeException(
51
+ sprintf(
52
+ // translators: %s is the current status.
53
+ __( '%s is not a valid status', 'woocommerce-paypal-payments' ),
54
+ $status
55
+ )
56
+ );
57
+ }
58
+ $this->status = $status;
59
+ }
60
+
61
+ /**
62
+ * Creates an OrderStatus "Internal"
63
+ *
64
+ * @return OrderStatus
65
+ */
66
+ public static function as_internal(): OrderStatus {
67
+ return new self( self::INTERNAL );
68
+ }
69
+
70
+ /**
71
+ * Compares the current status with a given one.
72
+ *
73
+ * @param string $status The status to compare with.
74
+ *
75
+ * @return bool
76
+ */
77
+ public function is( string $status ): bool {
78
+ return $this->status === $status;
79
+ }
80
+
81
+ /**
82
+ * Returns the status.
83
+ *
84
+ * @return string
85
+ */
86
+ public function name(): string {
87
+ return $this->status;
88
+ }
89
+ }
modules/ppcp-api-client/src/Entity/class-patch.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Patch object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Patch
14
+ */
15
+ class Patch {
16
+
17
+ /**
18
+ * The operation.
19
+ *
20
+ * @var string
21
+ */
22
+ private $op;
23
+
24
+ /**
25
+ * The path to the change.
26
+ *
27
+ * @var string
28
+ */
29
+ private $path;
30
+
31
+ /**
32
+ * The new value.
33
+ *
34
+ * @var array
35
+ */
36
+ private $value;
37
+
38
+ /**
39
+ * Patch constructor.
40
+ *
41
+ * @param string $op The operation.
42
+ * @param string $path The path.
43
+ * @param array $value The new value.
44
+ */
45
+ public function __construct( string $op, string $path, array $value ) {
46
+ $this->op = $op;
47
+ $this->path = $path;
48
+ $this->value = $value;
49
+ }
50
+
51
+ /**
52
+ * Returns the operation.
53
+ *
54
+ * @return string
55
+ */
56
+ public function op(): string {
57
+ return $this->op;
58
+ }
59
+
60
+ /**
61
+ * Returns the path.
62
+ *
63
+ * @return string
64
+ */
65
+ public function path(): string {
66
+ return $this->path;
67
+ }
68
+
69
+ /**
70
+ * Returns the value.
71
+ *
72
+ * @return array
73
+ */
74
+ public function value() {
75
+ return $this->value;
76
+ }
77
+
78
+ /**
79
+ * Returns the object as array.
80
+ *
81
+ * @return array
82
+ */
83
+ public function to_array(): array {
84
+ return array(
85
+ 'op' => $this->op(),
86
+ 'value' => $this->value(),
87
+ 'path' => $this->path(),
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Needed for the move operation. We currently do not
93
+ * support the move operation.
94
+ *
95
+ * @return string
96
+ */
97
+ public function from(): string {
98
+ return '';
99
+ }
100
+ }
modules/ppcp-api-client/src/Entity/class-patchcollection.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Patch collection object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PatchCollection
14
+ */
15
+ class PatchCollection {
16
+
17
+ /**
18
+ * The patches.
19
+ *
20
+ * @var Patch[]
21
+ */
22
+ private $patches;
23
+
24
+ /**
25
+ * PatchCollection constructor.
26
+ *
27
+ * @param Patch ...$patches The patches.
28
+ */
29
+ public function __construct( Patch ...$patches ) {
30
+ $this->patches = $patches;
31
+ }
32
+
33
+ /**
34
+ * Returns the patches.
35
+ *
36
+ * @return Patch[]
37
+ */
38
+ public function patches(): array {
39
+ return $this->patches;
40
+ }
41
+
42
+ /**
43
+ * Returns the object as array.
44
+ *
45
+ * @return array
46
+ */
47
+ public function to_array(): array {
48
+ return array_map(
49
+ static function ( Patch $patch ): array {
50
+ return $patch->to_array();
51
+ },
52
+ $this->patches()
53
+ );
54
+ }
55
+ }
modules/ppcp-api-client/src/Entity/class-payee.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The payee object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Payee
14
+ * The entity, which receives the money.
15
+ */
16
+ class Payee {
17
+
18
+ /**
19
+ * The email address.
20
+ *
21
+ * @var string
22
+ */
23
+ private $email;
24
+
25
+ /**
26
+ * The merchant id.
27
+ *
28
+ * @var string
29
+ */
30
+ private $merchant_id;
31
+
32
+ /**
33
+ * Payee constructor.
34
+ *
35
+ * @param string $email The email.
36
+ * @param string $merchant_id The merchant id.
37
+ */
38
+ public function __construct(
39
+ string $email,
40
+ string $merchant_id
41
+ ) {
42
+
43
+ $this->email = $email;
44
+ $this->merchant_id = $merchant_id;
45
+ }
46
+
47
+ /**
48
+ * Returns the email.
49
+ *
50
+ * @return string
51
+ */
52
+ public function email(): string {
53
+ return $this->email;
54
+ }
55
+
56
+ /**
57
+ * Returns the merchant id.
58
+ *
59
+ * @return string
60
+ */
61
+ public function merchant_id(): string {
62
+ return $this->merchant_id;
63
+ }
64
+
65
+ /**
66
+ * Returns the object as array.
67
+ *
68
+ * @return array
69
+ */
70
+ public function to_array(): array {
71
+ $data = array(
72
+ 'email_address' => $this->email(),
73
+ );
74
+ if ( $this->merchant_id ) {
75
+ $data['merchant_id'] = $this->merchant_id();
76
+ }
77
+ return $data;
78
+ }
79
+ }
modules/ppcp-api-client/src/Entity/class-payer.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The payer object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Payer
14
+ * The customer who sends the money.
15
+ */
16
+ class Payer {
17
+
18
+ /**
19
+ * The name.
20
+ *
21
+ * @var PayerName
22
+ */
23
+ private $name;
24
+
25
+ /**
26
+ * The email address.
27
+ *
28
+ * @var string
29
+ */
30
+ private $email_address;
31
+
32
+ /**
33
+ * The payer id.
34
+ *
35
+ * @var string
36
+ */
37
+ private $payer_id;
38
+
39
+ /**
40
+ * The birth date.
41
+ *
42
+ * @var \DateTime|null
43
+ */
44
+ private $birthdate;
45
+
46
+ /**
47
+ * The address.
48
+ *
49
+ * @var Address
50
+ */
51
+ private $address;
52
+
53
+ /**
54
+ * The phone.
55
+ *
56
+ * @var PhoneWithType|null
57
+ */
58
+ private $phone;
59
+
60
+ /**
61
+ * The tax info.
62
+ *
63
+ * @var PayerTaxInfo|null
64
+ */
65
+ private $tax_info;
66
+
67
+ /**
68
+ * Payer constructor.
69
+ *
70
+ * @param PayerName $name The name.
71
+ * @param string $email_address The email.
72
+ * @param string $payer_id The payer id.
73
+ * @param Address $address The address.
74
+ * @param \DateTime|null $birthdate The birth date.
75
+ * @param PhoneWithType|null $phone The phone.
76
+ * @param PayerTaxInfo|null $tax_info The tax info.
77
+ */
78
+ public function __construct(
79
+ PayerName $name,
80
+ string $email_address,
81
+ string $payer_id,
82
+ Address $address,
83
+ \DateTime $birthdate = null,
84
+ PhoneWithType $phone = null,
85
+ PayerTaxInfo $tax_info = null
86
+ ) {
87
+
88
+ $this->name = $name;
89
+ $this->email_address = $email_address;
90
+ $this->payer_id = $payer_id;
91
+ $this->birthdate = $birthdate;
92
+ $this->address = $address;
93
+ $this->phone = $phone;
94
+ $this->tax_info = $tax_info;
95
+ }
96
+
97
+ /**
98
+ * Returns the name.
99
+ *
100
+ * @return PayerName
101
+ */
102
+ public function name(): PayerName {
103
+ return $this->name;
104
+ }
105
+
106
+ /**
107
+ * Returns the email address.
108
+ *
109
+ * @return string
110
+ */
111
+ public function email_address(): string {
112
+ return $this->email_address;
113
+ }
114
+
115
+ /**
116
+ * Returns the payer id.
117
+ *
118
+ * @return string
119
+ */
120
+ public function payer_id(): string {
121
+ return $this->payer_id;
122
+ }
123
+
124
+ /**
125
+ * Returns the birth date.
126
+ *
127
+ * @return \DateTime|null
128
+ */
129
+ public function birthdate() {
130
+ return $this->birthdate;
131
+ }
132
+
133
+ /**
134
+ * Returns the address.
135
+ *
136
+ * @return Address
137
+ */
138
+ public function address(): Address {
139
+ return $this->address;
140
+ }
141
+
142
+ /**
143
+ * Returns the phone.
144
+ *
145
+ * @return PhoneWithType|null
146
+ */
147
+ public function phone() {
148
+ return $this->phone;
149
+ }
150
+
151
+ /**
152
+ * Returns the tax info.
153
+ *
154
+ * @return PayerTaxInfo|null
155
+ */
156
+ public function tax_info() {
157
+ return $this->tax_info;
158
+ }
159
+
160
+ /**
161
+ * Returns the object as array.
162
+ *
163
+ * @return array
164
+ */
165
+ public function to_array() {
166
+ $payer = array(
167
+ 'name' => $this->name()->to_array(),
168
+ 'email_address' => $this->email_address(),
169
+ 'address' => $this->address()->to_array(),
170
+ );
171
+ if ( $this->payer_id() ) {
172
+ $payer['payer_id'] = $this->payer_id();
173
+ }
174
+
175
+ if ( $this->phone() ) {
176
+ $payer['phone'] = $this->phone()->to_array();
177
+ }
178
+ if ( $this->tax_info() ) {
179
+ $payer['tax_info'] = $this->tax_info()->to_array();
180
+ }
181
+ if ( $this->birthdate() ) {
182
+ $payer['birth_date'] = $this->birthdate()->format( 'Y-m-d' );
183
+ }
184
+ return $payer;
185
+ }
186
+ }
modules/ppcp-api-client/src/Entity/class-payername.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PayerName object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PayerName
14
+ */
15
+ class PayerName {
16
+
17
+ /**
18
+ * The given name.
19
+ *
20
+ * @var string
21
+ */
22
+ private $given_name;
23
+
24
+ /**
25
+ * The surname.
26
+ *
27
+ * @var string
28
+ */
29
+ private $surname;
30
+
31
+ /**
32
+ * PayerName constructor.
33
+ *
34
+ * @param string $given_name The given name.
35
+ * @param string $surname The surname.
36
+ */
37
+ public function __construct(
38
+ string $given_name,
39
+ string $surname
40
+ ) {
41
+
42
+ $this->given_name = $given_name;
43
+ $this->surname = $surname;
44
+ }
45
+
46
+ /**
47
+ * Returns the given name.
48
+ *
49
+ * @return string
50
+ */
51
+ public function given_name(): string {
52
+ return $this->given_name;
53
+ }
54
+
55
+ /**
56
+ * Returns the surname.
57
+ *
58
+ * @return string
59
+ */
60
+ public function surname(): string {
61
+ return $this->surname;
62
+ }
63
+
64
+ /**
65
+ * Returns the object as array.
66
+ *
67
+ * @return array
68
+ */
69
+ public function to_array(): array {
70
+ return array(
71
+ 'given_name' => $this->given_name(),
72
+ 'surname' => $this->surname(),
73
+ );
74
+ }
75
+ }
modules/ppcp-api-client/src/Entity/class-payertaxinfo.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PayerTaxInfo object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class PayerTaxInfo
16
+ */
17
+ class PayerTaxInfo {
18
+
19
+
20
+ const VALID_TYPES = array(
21
+ 'BR_CPF',
22
+ 'BR_CNPJ',
23
+ );
24
+
25
+ /**
26
+ * The tax id.
27
+ *
28
+ * @var string
29
+ */
30
+ private $tax_id;
31
+
32
+ /**
33
+ * The type.
34
+ *
35
+ * @var string
36
+ */
37
+ private $type;
38
+
39
+ /**
40
+ * PayerTaxInfo constructor.
41
+ *
42
+ * @param string $tax_id The tax id.
43
+ * @param string $type The type.
44
+ * @throws RuntimeException When the type is not valid.
45
+ */
46
+ public function __construct(
47
+ string $tax_id,
48
+ string $type
49
+ ) {
50
+
51
+ if ( ! in_array( $type, self::VALID_TYPES, true ) ) {
52
+ throw new RuntimeException(
53
+ sprintf(
54
+ // translators: %s is the current type.
55
+ __( '%s is not a valid tax type.', 'woocommerce-paypal-payments' ),
56
+ $type
57
+ )
58
+ );
59
+ }
60
+ $this->tax_id = $tax_id;
61
+ $this->type = $type;
62
+ }
63
+
64
+ /**
65
+ * Returns the type.
66
+ *
67
+ * @return string
68
+ */
69
+ public function type(): string {
70
+ return $this->type;
71
+ }
72
+
73
+ /**
74
+ * Returns the tax id
75
+ *
76
+ * @return string
77
+ */
78
+ public function tax_id(): string {
79
+ return $this->tax_id;
80
+ }
81
+
82
+ /**
83
+ * Returns the object as array.
84
+ *
85
+ * @return array
86
+ */
87
+ public function to_array(): array {
88
+ return array(
89
+ 'tax_id' => $this->tax_id(),
90
+ 'tax_id_type' => $this->type(),
91
+ );
92
+ }
93
+ }
modules/ppcp-api-client/src/Entity/class-paymentmethod.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentMethod object
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PaymentMethod
14
+ */
15
+ class PaymentMethod {
16
+
17
+
18
+ const PAYER_SELECTED_DEFAULT = 'PAYPAL';
19
+
20
+ const PAYEE_PREFERRED_UNRESTRICTED = 'UNRESTRICTED';
21
+ const PAYEE_PREFERRED_IMMEDIATE_PAYMENT_REQUIRED = 'IMMEDIATE_PAYMENT_REQUIRED';
22
+
23
+ /**
24
+ * The preferred value.
25
+ *
26
+ * @var string
27
+ */
28
+ private $preferred;
29
+
30
+ /**
31
+ * The selected value.
32
+ *
33
+ * @var string
34
+ */
35
+ private $selected;
36
+
37
+ /**
38
+ * PaymentMethod constructor.
39
+ *
40
+ * @param string $preferred The preferred value.
41
+ * @param string $selected The selected value.
42
+ */
43
+ public function __construct(
44
+ string $preferred = self::PAYEE_PREFERRED_UNRESTRICTED,
45
+ string $selected = self::PAYER_SELECTED_DEFAULT
46
+ ) {
47
+
48
+ $this->preferred = $preferred;
49
+ $this->selected = $selected;
50
+ }
51
+
52
+ /**
53
+ * Returns the payer preferred value.
54
+ *
55
+ * @return string
56
+ */
57
+ public function payee_preferred(): string {
58
+ return $this->preferred;
59
+ }
60
+
61
+ /**
62
+ * Returns the payer selected value.
63
+ *
64
+ * @return string
65
+ */
66
+ public function payer_selected(): string {
67
+ return $this->selected;
68
+ }
69
+
70
+ /**
71
+ * Returns the object as array.
72
+ *
73
+ * @return array
74
+ */
75
+ public function to_array(): array {
76
+ return array(
77
+ 'payee_preferred' => $this->payee_preferred(),
78
+ 'payer_selected' => $this->payer_selected(),
79
+ );
80
+ }
81
+ }
modules/ppcp-api-client/src/Entity/class-payments.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Payments object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Payments
14
+ */
15
+ class Payments {
16
+
17
+ /**
18
+ * The Authorizations.
19
+ *
20
+ * @var Authorization[]
21
+ */
22
+ private $authorizations;
23
+
24
+ /**
25
+ * The Captures.
26
+ *
27
+ * @var Capture[]
28
+ */
29
+ private $captures;
30
+
31
+ /**
32
+ * Payments constructor.
33
+ *
34
+ * @param array $authorizations The Authorizations.
35
+ * @param array $captures The Captures.
36
+ */
37
+ public function __construct( array $authorizations, array $captures ) {
38
+ foreach ( $authorizations as $key => $authorization ) {
39
+ if ( is_a( $authorization, Authorization::class ) ) {
40
+ continue;
41
+ }
42
+ unset( $authorizations[ $key ] );
43
+ }
44
+ foreach ( $captures as $key => $capture ) {
45
+ if ( is_a( $capture, Capture::class ) ) {
46
+ continue;
47
+ }
48
+ unset( $captures[ $key ] );
49
+ }
50
+ $this->authorizations = $authorizations;
51
+ $this->captures = $captures;
52
+ }
53
+
54
+ /**
55
+ * Returns the object as array.
56
+ *
57
+ * @return array
58
+ */
59
+ public function to_array(): array {
60
+ return array(
61
+ 'authorizations' => array_map(
62
+ static function ( Authorization $authorization ): array {
63
+ return $authorization->to_array();
64
+ },
65
+ $this->authorizations()
66
+ ),
67
+ 'captures' => array_map(
68
+ static function ( Capture $capture ): array {
69
+ return $capture->to_array();
70
+ },
71
+ $this->captures()
72
+ ),
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Returns the Authoriatzions.
78
+ *
79
+ * @return Authorization[]
80
+ **/
81
+ public function authorizations(): array {
82
+ return $this->authorizations;
83
+ }
84
+
85
+ /**
86
+ * Returns the Captures.
87
+ *
88
+ * @return Capture[]
89
+ **/
90
+ public function captures(): array {
91
+ return $this->captures;
92
+ }
93
+ }
modules/ppcp-api-client/src/Entity/class-paymentsource.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentSource object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PaymentSource
14
+ */
15
+ class PaymentSource {
16
+
17
+ /**
18
+ * The card.
19
+ *
20
+ * @var PaymentSourceCard|null
21
+ */
22
+ private $card;
23
+
24
+ /**
25
+ * The wallet.
26
+ *
27
+ * @var PaymentSourceWallet|null
28
+ */
29
+ private $wallet;
30
+
31
+ /**
32
+ * PaymentSource constructor.
33
+ *
34
+ * @param PaymentSourceCard|null $card The card.
35
+ * @param PaymentSourceWallet|null $wallet The wallet.
36
+ */
37
+ public function __construct(
38
+ PaymentSourceCard $card = null,
39
+ PaymentSourceWallet $wallet = null
40
+ ) {
41
+
42
+ $this->card = $card;
43
+ $this->wallet = $wallet;
44
+ }
45
+
46
+ /**
47
+ * Returns the card.
48
+ *
49
+ * @return PaymentSourceCard|null
50
+ */
51
+ public function card() {
52
+
53
+ return $this->card;
54
+ }
55
+
56
+ /**
57
+ * Returns the wallet.
58
+ *
59
+ * @return PaymentSourceWallet|null
60
+ */
61
+ public function wallet() {
62
+
63
+ return $this->wallet;
64
+ }
65
+
66
+ /**
67
+ * Returns the array of the object.
68
+ *
69
+ * @return array
70
+ */
71
+ public function to_array(): array {
72
+
73
+ $data = array();
74
+ if ( $this->card() ) {
75
+ $data['card'] = $this->card()->to_array();
76
+ }
77
+ if ( $this->wallet() ) {
78
+ $data['wallet'] = $this->wallet()->to_array();
79
+ }
80
+ return $data;
81
+ }
82
+ }
modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentSourceCard object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PaymentSourceCard
14
+ */
15
+ class PaymentSourceCard {
16
+
17
+ /**
18
+ * The last digits of the card.
19
+ *
20
+ * @var string
21
+ */
22
+ private $last_digits;
23
+
24
+ /**
25
+ * The brand.
26
+ *
27
+ * @var string
28
+ */
29
+ private $brand;
30
+
31
+ /**
32
+ * The type.
33
+ *
34
+ * @var string
35
+ */
36
+ private $type;
37
+
38
+ /**
39
+ * The authentication result.
40
+ *
41
+ * @var CardAuthenticationResult|null
42
+ */
43
+ private $authentication_result;
44
+
45
+ /**
46
+ * PaymentSourceCard constructor.
47
+ *
48
+ * @param string $last_digits The last digits of the card.
49
+ * @param string $brand The brand of the card.
50
+ * @param string $type The type of the card.
51
+ * @param CardAuthenticationResult|null $authentication_result The authentication result.
52
+ */
53
+ public function __construct(
54
+ string $last_digits,
55
+ string $brand,
56
+ string $type,
57
+ CardAuthenticationResult $authentication_result = null
58
+ ) {
59
+
60
+ $this->last_digits = $last_digits;
61
+ $this->brand = $brand;
62
+ $this->type = $type;
63
+ $this->authentication_result = $authentication_result;
64
+ }
65
+
66
+ /**
67
+ * Returns the last digits.
68
+ *
69
+ * @return string
70
+ */
71
+ public function last_digits(): string {
72
+
73
+ return $this->last_digits;
74
+ }
75
+
76
+ /**
77
+ * Returns the brand.
78
+ *
79
+ * @return string
80
+ */
81
+ public function brand(): string {
82
+
83
+ return $this->brand;
84
+ }
85
+
86
+ /**
87
+ * Returns the type.
88
+ *
89
+ * @return string
90
+ */
91
+ public function type(): string {
92
+
93
+ return $this->type;
94
+ }
95
+
96
+ /**
97
+ * Returns the authentication result.
98
+ *
99
+ * @return CardAuthenticationResult|null
100
+ */
101
+ public function authentication_result() {
102
+
103
+ return $this->authentication_result;
104
+ }
105
+
106
+ /**
107
+ * Returns the object as array.
108
+ *
109
+ * @return array
110
+ */
111
+ public function to_array(): array {
112
+
113
+ $data = array(
114
+ 'last_digits' => $this->last_digits(),
115
+ 'brand' => $this->brand(),
116
+ 'type' => $this->type(),
117
+ );
118
+ if ( $this->authentication_result() ) {
119
+ $data['authentication_result'] = $this->authentication_result()->to_array();
120
+ }
121
+ return $data;
122
+ }
123
+ }
modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentSourcewallet.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PaymentSourceWallet
14
+ */
15
+ class PaymentSourceWallet {
16
+
17
+ /**
18
+ * Returns the object as array.
19
+ *
20
+ * @return array
21
+ */
22
+ public function to_array(): array {
23
+ return array();
24
+ }
25
+ }
modules/ppcp-api-client/src/Entity/class-paymenttoken.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentToken object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class PaymentToken
16
+ */
17
+ class PaymentToken {
18
+
19
+
20
+ const TYPE_PAYMENT_METHOD_TOKEN = 'PAYMENT_METHOD_TOKEN';
21
+ const VALID_TYPES = array(
22
+ self::TYPE_PAYMENT_METHOD_TOKEN,
23
+ );
24
+
25
+ /**
26
+ * The Id.
27
+ *
28
+ * @var string
29
+ */
30
+ private $id;
31
+
32
+ /**
33
+ * The type.
34
+ *
35
+ * @var string
36
+ */
37
+ private $type;
38
+
39
+ /**
40
+ * PaymentToken constructor.
41
+ *
42
+ * @param string $id The Id.
43
+ * @param string $type The type.
44
+ * @throws RuntimeException When the type is not valid.
45
+ */
46
+ public function __construct( string $id, string $type = self::TYPE_PAYMENT_METHOD_TOKEN ) {
47
+ if ( ! in_array( $type, self::VALID_TYPES, true ) ) {
48
+ throw new RuntimeException(
49
+ __( 'Not a valid payment source type.', 'woocommerce-paypal-payments' )
50
+ );
51
+ }
52
+ $this->id = $id;
53
+ $this->type = $type;
54
+ }
55
+
56
+ /**
57
+ * Returns the ID.
58
+ *
59
+ * @return string
60
+ */
61
+ public function id(): string {
62
+ return $this->id;
63
+ }
64
+
65
+ /**
66
+ * Returns the type.
67
+ *
68
+ * @return string
69
+ */
70
+ public function type(): string {
71
+ return $this->type;
72
+ }
73
+
74
+ /**
75
+ * Returns the object as array.
76
+ *
77
+ * @return array
78
+ */
79
+ public function to_array(): array {
80
+ return array(
81
+ 'id' => $this->id(),
82
+ 'type' => $this->type(),
83
+ );
84
+ }
85
+ }
modules/ppcp-api-client/src/Entity/class-phone.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Phone object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Phone
14
+ */
15
+ class Phone {
16
+
17
+ /**
18
+ * The number.
19
+ *
20
+ * @var string
21
+ */
22
+ private $national_number;
23
+
24
+ /**
25
+ * Phone constructor.
26
+ *
27
+ * @param string $national_number The number.
28
+ */
29
+ public function __construct( string $national_number ) {
30
+ $this->national_number = $national_number;
31
+ }
32
+
33
+ /**
34
+ * Returns the number.
35
+ *
36
+ * @return string
37
+ */
38
+ public function national_number(): string {
39
+ return $this->national_number;
40
+ }
41
+
42
+ /**
43
+ * Returns the object as array.
44
+ *
45
+ * @return array
46
+ */
47
+ public function to_array(): array {
48
+ return array(
49
+ 'national_number' => $this->national_number(),
50
+ );
51
+ }
52
+ }
modules/ppcp-api-client/src/Entity/class-phonewithtype.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PhoneWithType object
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PhoneWithType
14
+ */
15
+ class PhoneWithType {
16
+
17
+ const VALLID_TYPES = array(
18
+ 'FAX',
19
+ 'HOME',
20
+ 'MOBILE',
21
+ 'OTHER',
22
+ 'PAGER',
23
+ );
24
+
25
+ /**
26
+ * The type.
27
+ *
28
+ * @var string
29
+ */
30
+ private $type;
31
+
32
+ /**
33
+ * The phone.
34
+ *
35
+ * @var Phone
36
+ */
37
+ private $phone;
38
+
39
+ /**
40
+ * PhoneWithType constructor.
41
+ *
42
+ * @param string $type The type.
43
+ * @param Phone $phone The phone.
44
+ */
45
+ public function __construct( string $type, Phone $phone ) {
46
+ $this->type = in_array( $type, self::VALLID_TYPES, true ) ? $type : 'OTHER';
47
+ $this->phone = $phone;
48
+ }
49
+
50
+ /**
51
+ * Returns the type.
52
+ *
53
+ * @return string
54
+ */
55
+ public function type(): string {
56
+ return $this->type;
57
+ }
58
+
59
+ /**
60
+ * Returns the phone.
61
+ *
62
+ * @return Phone
63
+ */
64
+ public function phone(): Phone {
65
+ return $this->phone;
66
+ }
67
+
68
+ /**
69
+ * Returns the object as array.
70
+ *
71
+ * @return array
72
+ */
73
+ public function to_array(): array {
74
+ return array(
75
+ 'phone_type' => $this->type(),
76
+ 'phone_number' => $this->phone()->to_array(),
77
+ );
78
+ }
79
+ }
modules/ppcp-api-client/src/Entity/class-purchaseunit.php ADDED
@@ -0,0 +1,358 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The purchase unit object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class PurchaseUnit
14
+ */
15
+ class PurchaseUnit {
16
+
17
+ /**
18
+ * The amount.
19
+ *
20
+ * @var Amount
21
+ */
22
+ private $amount;
23
+
24
+ /**
25
+ * The Items.
26
+ *
27
+ * @var Item[]
28
+ */
29
+ private $items;
30
+
31
+ /**
32
+ * The shipping.
33
+ *
34
+ * @var Shipping|null
35
+ */
36
+ private $shipping;
37
+
38
+ /**
39
+ * The reference id.
40
+ *
41
+ * @var string
42
+ */
43
+ private $reference_id;
44
+
45
+ /**
46
+ * The description.
47
+ *
48
+ * @var string
49
+ */
50
+ private $description;
51
+
52
+ /**
53
+ * The Payee.
54
+ *
55
+ * @var Payee|null
56
+ */
57
+ private $payee;
58
+
59
+ /**
60
+ * The custom id.
61
+ *
62
+ * @var string
63
+ */
64
+ private $custom_id;
65
+
66
+ /**
67
+ * The invoice id.
68
+ *
69
+ * @var string
70
+ */
71
+ private $invoice_id;
72
+
73
+ /**
74
+ * The soft descriptor.
75
+ *
76
+ * @var string
77
+ */
78
+ private $soft_descriptor;
79
+
80
+ /**
81
+ * The Payments.
82
+ *
83
+ * @var Payments|null
84
+ */
85
+ private $payments;
86
+
87
+ /**
88
+ * Whether the unit contains physical goods.
89
+ *
90
+ * @var bool
91
+ */
92
+ private $contains_physical_goods = false;
93
+
94
+ /**
95
+ * PurchaseUnit constructor.
96
+ *
97
+ * @param Amount $amount The Amount.
98
+ * @param Item[] $items The Items.
99
+ * @param Shipping|null $shipping The Shipping.
100
+ * @param string $reference_id The reference ID.
101
+ * @param string $description The description.
102
+ * @param Payee|null $payee The Payee.
103
+ * @param string $custom_id The custom ID.
104
+ * @param string $invoice_id The invoice ID.
105
+ * @param string $soft_descriptor The soft descriptor.
106
+ * @param Payments|null $payments The Payments.
107
+ */
108
+ public function __construct(
109
+ Amount $amount,
110
+ array $items = array(),
111
+ Shipping $shipping = null,
112
+ string $reference_id = 'default',
113
+ string $description = '',
114
+ Payee $payee = null,
115
+ string $custom_id = '',
116
+ string $invoice_id = '',
117
+ string $soft_descriptor = '',
118
+ Payments $payments = null
119
+ ) {
120
+
121
+ $this->amount = $amount;
122
+ $this->shipping = $shipping;
123
+ $this->reference_id = $reference_id;
124
+ $this->description = $description;
125
+ //phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
126
+ $this->items = array_values(
127
+ array_filter(
128
+ $items,
129
+ function ( $item ): bool {
130
+ $is_item = is_a( $item, Item::class );
131
+ /**
132
+ * The item.
133
+ *
134
+ * @var Item $item
135
+ */
136
+ if ( $is_item && Item::PHYSICAL_GOODS === $item->category() ) {
137
+ $this->contains_physical_goods = true;
138
+ }
139
+
140
+ return $is_item;
141
+ }
142
+ )
143
+ );
144
+ $this->payee = $payee;
145
+ $this->custom_id = $custom_id;
146
+ $this->invoice_id = $invoice_id;
147
+ $this->soft_descriptor = $soft_descriptor;
148
+ $this->payments = $payments;
149
+ }
150
+
151
+ /**
152
+ * Returns the amount.
153
+ *
154
+ * @return Amount
155
+ */
156
+ public function amount(): Amount {
157
+ return $this->amount;
158
+ }
159
+
160
+ /**
161
+ * Returns the shipping.
162
+ *
163
+ * @return Shipping|null
164
+ */
165
+ public function shipping() {
166
+ return $this->shipping;
167
+ }
168
+
169
+ /**
170
+ * Returns the reference id.
171
+ *
172
+ * @return string
173
+ */
174
+ public function reference_id(): string {
175
+ return $this->reference_id;
176
+ }
177
+
178
+ /**
179
+ * Returns the description.
180
+ *
181
+ * @return string
182
+ */
183
+ public function description(): string {
184
+ return $this->description;
185
+ }
186
+
187
+ /**
188
+ * Returns the custom id.
189
+ *
190
+ * @return string
191
+ */
192
+ public function custom_id(): string {
193
+ return $this->custom_id;
194
+ }
195
+
196
+ /**
197
+ * Returns the invoice id.
198
+ *
199
+ * @return string
200
+ */
201
+ public function invoice_id(): string {
202
+ return $this->invoice_id;
203
+ }
204
+
205
+ /**
206
+ * Returns the soft descriptor.
207
+ *
208
+ * @return string
209
+ */
210
+ public function soft_descriptor(): string {
211
+ return $this->soft_descriptor;
212
+ }
213
+
214
+ /**
215
+ * Returns the Payee.
216
+ *
217
+ * @return Payee|null
218
+ */
219
+ public function payee() {
220
+ return $this->payee;
221
+ }
222
+
223
+ /**
224
+ * Returns the Payments.
225
+ *
226
+ * @return Payments|null
227
+ */
228
+ public function payments() {
229
+ return $this->payments;
230
+ }
231
+
232
+ /**
233
+ * Returns the Items.
234
+ *
235
+ * @return Item[]
236
+ */
237
+ public function items(): array {
238
+ return $this->items;
239
+ }
240
+
241
+ /**
242
+ * Whether the unit contains physical goods.
243
+ *
244
+ * @return bool
245
+ */
246
+ public function contains_physical_goods(): bool {
247
+ return $this->contains_physical_goods;
248
+ }
249
+
250
+ /**
251
+ * Returns the object as array.
252
+ *
253
+ * @return array
254
+ */
255
+ public function to_array(): array {
256
+ $purchase_unit = array(
257
+ 'reference_id' => $this->reference_id(),
258
+ 'amount' => $this->amount()->to_array(),
259
+ 'description' => $this->description(),
260
+ 'items' => array_map(
261
+ static function ( Item $item ): array {
262
+ return $item->to_array();
263
+ },
264
+ $this->items()
265
+ ),
266
+ );
267
+ if ( $this->ditch_items_when_mismatch( $this->amount(), ...$this->items() ) ) {
268
+ unset( $purchase_unit['items'] );
269
+ unset( $purchase_unit['amount']['breakdown'] );
270
+ }
271
+
272
+ if ( $this->payee() ) {
273
+ $purchase_unit['payee'] = $this->payee()->to_array();
274
+ }
275
+
276
+ if ( $this->payments() ) {
277
+ $purchase_unit['payments'] = $this->payments()->to_array();
278
+ }
279
+
280
+ if ( $this->shipping() ) {
281
+ $purchase_unit['shipping'] = $this->shipping()->to_array();
282
+ }
283
+ if ( $this->custom_id() ) {
284
+ $purchase_unit['custom_id'] = $this->custom_id();
285
+ }
286
+ if ( $this->invoice_id() ) {
287
+ $purchase_unit['invoice_id'] = $this->invoice_id();
288
+ }
289
+ if ( $this->soft_descriptor() ) {
290
+ $purchase_unit['soft_descriptor'] = $this->soft_descriptor();
291
+ }
292
+ return $purchase_unit;
293
+ }
294
+
295
+ /**
296
+ * All money values send to PayPal can only have 2 decimal points. WooCommerce internally does
297
+ * not have this restriction. Therefore the totals of the cart in WooCommerce and the totals
298
+ * of the rounded money values of the items, we send to PayPal, can differ. In those cases,
299
+ * we can not send the line items.
300
+ *
301
+ * @param Amount $amount The amount.
302
+ * @param Item ...$items The items.
303
+ * @return bool
304
+ */
305
+ private function ditch_items_when_mismatch( Amount $amount, Item ...$items ): bool {
306
+ $fee_items_total = ( $amount->breakdown() && $amount->breakdown()->item_total() ) ?
307
+ $amount->breakdown()->item_total()->value() : null;
308
+ $fee_tax_total = ( $amount->breakdown() && $amount->breakdown()->tax_total() ) ?
309
+ $amount->breakdown()->tax_total()->value() : null;
310
+
311
+ foreach ( $items as $item ) {
312
+ if ( null !== $fee_items_total ) {
313
+ $fee_items_total -= $item->unit_amount()->value() * $item->quantity();
314
+ }
315
+ if ( null !== $fee_tax_total ) {
316
+ $fee_tax_total -= $item->tax()->value() * $item->quantity();
317
+ }
318
+ }
319
+
320
+ $fee_items_total = round( $fee_items_total, 2 );
321
+ $fee_tax_total = round( $fee_tax_total, 2 );
322
+
323
+ if ( 0.0 !== $fee_items_total || 0.0 !== $fee_tax_total ) {
324
+ return true;
325
+ }
326
+
327
+ $breakdown = $this->amount()->breakdown();
328
+ if ( ! $breakdown ) {
329
+ return false;
330
+ }
331
+ $amount_total = 0;
332
+ if ( $breakdown->shipping() ) {
333
+ $amount_total += $breakdown->shipping()->value();
334
+ }
335
+ if ( $breakdown->item_total() ) {
336
+ $amount_total += $breakdown->item_total()->value();
337
+ }
338
+ if ( $breakdown->discount() ) {
339
+ $amount_total -= $breakdown->discount()->value();
340
+ }
341
+ if ( $breakdown->tax_total() ) {
342
+ $amount_total += $breakdown->tax_total()->value();
343
+ }
344
+ if ( $breakdown->shipping_discount() ) {
345
+ $amount_total -= $breakdown->shipping_discount()->value();
346
+ }
347
+ if ( $breakdown->handling() ) {
348
+ $amount_total += $breakdown->handling()->value();
349
+ }
350
+ if ( $breakdown->insurance() ) {
351
+ $amount_total += $breakdown->insurance()->value();
352
+ }
353
+
354
+ $amount_value = $this->amount()->value();
355
+ $needs_to_ditch = (string) $amount_total !== (string) $amount_value;
356
+ return $needs_to_ditch;
357
+ }
358
+ }
modules/ppcp-api-client/src/Entity/class-refund.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The refund object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Refund
14
+ */
15
+ class Refund {
16
+
17
+ /**
18
+ * The Capture.
19
+ *
20
+ * @var Capture
21
+ */
22
+ private $capture;
23
+
24
+ /**
25
+ * The invoice id.
26
+ *
27
+ * @var string
28
+ */
29
+ private $invoice_id;
30
+
31
+ /**
32
+ * The note to the payer.
33
+ *
34
+ * @var string
35
+ */
36
+ private $note_to_payer;
37
+
38
+ /**
39
+ * The Amount.
40
+ *
41
+ * @var Amount|null
42
+ */
43
+ private $amount;
44
+
45
+ /**
46
+ * Refund constructor.
47
+ *
48
+ * @param Capture $capture The capture where the refund is supposed to be applied at.
49
+ * @param string $invoice_id The invoice id.
50
+ * @param string $note_to_payer The note to the payer.
51
+ * @param Amount|null $amount The Amount.
52
+ */
53
+ public function __construct(
54
+ Capture $capture,
55
+ string $invoice_id,
56
+ string $note_to_payer = '',
57
+ Amount $amount = null
58
+ ) {
59
+ $this->capture = $capture;
60
+ $this->invoice_id = $invoice_id;
61
+ $this->note_to_payer = $note_to_payer;
62
+ $this->amount = $amount;
63
+ }
64
+
65
+ /**
66
+ * Returns the capture for the refund.
67
+ *
68
+ * @return Capture
69
+ */
70
+ public function for_capture() : Capture {
71
+ return $this->capture;
72
+ }
73
+
74
+ /**
75
+ * Return the invoice id.
76
+ *
77
+ * @return string
78
+ */
79
+ public function invoice_id() : string {
80
+ return $this->invoice_id;
81
+ }
82
+
83
+ /**
84
+ * Returns the note to the payer.
85
+ *
86
+ * @return string
87
+ */
88
+ public function note_to_payer() : string {
89
+ return $this->note_to_payer;
90
+ }
91
+
92
+ /**
93
+ * Returns the Amount.
94
+ *
95
+ * @return Amount|null
96
+ */
97
+ public function amount() {
98
+ return $this->amount;
99
+ }
100
+
101
+ /**
102
+ * Returns the object as array.
103
+ *
104
+ * @return array
105
+ */
106
+ public function to_array() : array {
107
+ $data = array(
108
+ 'invoice_id' => $this->invoice_id(),
109
+ );
110
+ if ( $this->note_to_payer() ) {
111
+ $data['note_to_payer'] = $this->note_to_payer();
112
+ }
113
+ if ( $this->amount() ) {
114
+ $data['amount'] = $this->amount()->to_array();
115
+ }
116
+ return $data;
117
+ }
118
+ }
modules/ppcp-api-client/src/Entity/class-sellerstatus.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The seller status entity.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class SellerStatus
14
+ */
15
+ class SellerStatus {
16
+
17
+ /**
18
+ * The products.
19
+ *
20
+ * @var SellerStatusProduct[]
21
+ */
22
+ private $products;
23
+
24
+ /**
25
+ * SellerStatus constructor.
26
+ *
27
+ * @param SellerStatusProduct[] $products The products.
28
+ */
29
+ public function __construct( array $products ) {
30
+ foreach ( $products as $key => $product ) {
31
+ if ( is_a( $product, SellerStatusProduct::class ) ) {
32
+ continue;
33
+ }
34
+ unset( $products[ $key ] );
35
+ }
36
+ $this->products = $products;
37
+ }
38
+
39
+ /**
40
+ * Returns the products.
41
+ *
42
+ * @return SellerStatusProduct[]
43
+ */
44
+ public function products() : array {
45
+ return $this->products;
46
+ }
47
+
48
+ /**
49
+ * Returns the enitity as array.
50
+ *
51
+ * @return array
52
+ */
53
+ public function to_array() : array {
54
+ $products = array_map(
55
+ function( SellerStatusProduct $product ) : array {
56
+ return $product->to_array();
57
+ },
58
+ $this->products()
59
+ );
60
+
61
+ return array(
62
+ 'products' => $products,
63
+ );
64
+ }
65
+ }
modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The products of a seller status.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class SellerStatusProduct
14
+ */
15
+ class SellerStatusProduct {
16
+
17
+ const VETTING_STATUS_APPROVED = 'APPROVED';
18
+ const VETTING_STATUS_PENDING = 'PENDING';
19
+ const VETTING_STATUS_DECLINED = 'DECLINED';
20
+ const VETTING_STATUS_SUBSCRIBED = 'SUBSCRIBED';
21
+ const VETTING_STATUS_IN_REVIEW = 'IN_REVIEW';
22
+ const VETTING_STATUS_DENIED = 'DENIED';
23
+ /**
24
+ * The name of the product.
25
+ *
26
+ * @var string
27
+ */
28
+ private $name;
29
+
30
+ /**
31
+ * The vetting status of the product.
32
+ *
33
+ * @var string
34
+ */
35
+ private $vetting_status;
36
+
37
+ /**
38
+ * The capabilities of the product.
39
+ *
40
+ * @var string[]
41
+ */
42
+ private $capabilities;
43
+
44
+ /**
45
+ * SellerStatusProduct constructor.
46
+ *
47
+ * @param string $name The name of the product.
48
+ * @param string $vetting_status The vetting status of the product.
49
+ * @param string[] $capabilities The capabilities of the product.
50
+ */
51
+ public function __construct(
52
+ string $name,
53
+ string $vetting_status,
54
+ array $capabilities
55
+ ) {
56
+ foreach ( $capabilities as $key => $capability ) {
57
+ if ( is_string( $capability ) ) {
58
+ continue;
59
+ }
60
+ unset( $capabilities[ $key ] );
61
+ }
62
+ $this->name = $name;
63
+ $this->vetting_status = $vetting_status;
64
+ $this->capabilities = $capabilities;
65
+ }
66
+
67
+ /**
68
+ * Returns the name of the product.
69
+ *
70
+ * @return string
71
+ */
72
+ public function name() : string {
73
+ return $this->name;
74
+ }
75
+
76
+ /**
77
+ * Returns the vetting status for this product.
78
+ *
79
+ * @return string
80
+ */
81
+ public function vetting_status() : string {
82
+ return $this->vetting_status;
83
+ }
84
+
85
+ /**
86
+ * Returns the capabilities of this product.
87
+ *
88
+ * @return string[]
89
+ */
90
+ public function capabilities() : array {
91
+ return $this->capabilities;
92
+ }
93
+
94
+ /**
95
+ * Returns the entity as array.
96
+ *
97
+ * @return array
98
+ */
99
+ public function to_array() : array {
100
+ return array(
101
+ 'name' => $this->name(),
102
+ 'vetting_status' => $this->vetting_status(),
103
+ 'capabilities' => $this->capabilities(),
104
+ );
105
+ }
106
+
107
+
108
+ }
modules/ppcp-api-client/src/Entity/class-shipping.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Shipping object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Shipping
14
+ */
15
+ class Shipping {
16
+
17
+ /**
18
+ * The name.
19
+ *
20
+ * @var string
21
+ */
22
+ private $name;
23
+
24
+ /**
25
+ * The address.
26
+ *
27
+ * @var Address
28
+ */
29
+ private $address;
30
+
31
+ /**
32
+ * Shipping constructor.
33
+ *
34
+ * @param string $name The name.
35
+ * @param Address $address The address.
36
+ */
37
+ public function __construct( string $name, Address $address ) {
38
+ $this->name = $name;
39
+ $this->address = $address;
40
+ }
41
+
42
+ /**
43
+ * Returns the name.
44
+ *
45
+ * @return string
46
+ */
47
+ public function name(): string {
48
+ return $this->name;
49
+ }
50
+
51
+ /**
52
+ * Returns the shipping address.
53
+ *
54
+ * @return Address
55
+ */
56
+ public function address(): Address {
57
+ return $this->address;
58
+ }
59
+
60
+ /**
61
+ * Returns the object as array.
62
+ *
63
+ * @return array
64
+ */
65
+ public function to_array(): array {
66
+ return array(
67
+ 'name' => array(
68
+ 'full_name' => $this->name(),
69
+ ),
70
+ 'address' => $this->address()->to_array(),
71
+ );
72
+ }
73
+ }
modules/ppcp-api-client/src/Entity/class-token.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Token object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class Token
16
+ */
17
+ class Token {
18
+
19
+ /**
20
+ * The Token data.
21
+ *
22
+ * @var \stdClass
23
+ */
24
+ private $json;
25
+
26
+ /**
27
+ * The timestamp when the Token was created.
28
+ *
29
+ * @var int
30
+ */
31
+ private $created;
32
+
33
+ /**
34
+ * Token constructor.
35
+ *
36
+ * @param \stdClass $json The JSON object.
37
+ * @throws RuntimeException When The JSON object is not valid.
38
+ */
39
+ public function __construct( \stdClass $json ) {
40
+ if ( ! isset( $json->created ) ) {
41
+ $json->created = time();
42
+ }
43
+ if ( ! $this->validate( $json ) ) {
44
+ throw new RuntimeException( 'Token not valid' );
45
+ }
46
+ $this->json = $json;
47
+ }
48
+
49
+ /**
50
+ * Returns the timestamp when the Token is expired.
51
+ *
52
+ * @return int
53
+ */
54
+ public function expiration_timestamp(): int {
55
+
56
+ return $this->json->created + $this->json->expires_in;
57
+ }
58
+
59
+ /**
60
+ * Returns the token.
61
+ *
62
+ * @return string
63
+ */
64
+ public function token(): string {
65
+ return (string) $this->json->token;
66
+ }
67
+
68
+ /**
69
+ * Returns whether the Token is still valid.
70
+ *
71
+ * @return bool
72
+ */
73
+ public function is_valid(): bool {
74
+ return time() < $this->json->created + $this->json->expires_in;
75
+ }
76
+
77
+ /**
78
+ * Returns the Token as JSON string.
79
+ *
80
+ * @return string
81
+ */
82
+ public function as_json(): string {
83
+ return wp_json_encode( $this->json );
84
+ }
85
+
86
+ /**
87
+ * Returns a Token based off a JSON string.
88
+ *
89
+ * @param string $json The JSON string.
90
+ *
91
+ * @return static
92
+ */
93
+ public static function from_json( string $json ): self {
94
+ $json = (object) json_decode( $json );
95
+ if ( isset( $json->access_token ) || isset( $json->client_token ) ) {
96
+ $json->token = isset( $json->access_token ) ? $json->access_token : $json->client_token;
97
+ }
98
+
99
+ return new Token( $json );
100
+ }
101
+
102
+ /**
103
+ * Validates whether a JSON object can be transformed to a Token object.
104
+ *
105
+ * @param \stdClass $json The JSON object.
106
+ *
107
+ * @return bool
108
+ */
109
+ private function validate( \stdClass $json ): bool {
110
+ $property_map = array(
111
+ 'created' => 'is_int',
112
+ 'expires_in' => 'is_int',
113
+ 'token' => 'is_string',
114
+ );
115
+
116
+ foreach ( $property_map as $property => $validator ) {
117
+ if ( ! isset( $json->{$property} ) || ! $validator( $json->{$property} ) ) {
118
+ return false;
119
+ }
120
+ }
121
+ return true;
122
+ }
123
+ }
modules/ppcp-api-client/src/Entity/class-webhook.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Webhook object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
11
+
12
+ /**
13
+ * Class Webhook
14
+ */
15
+ class Webhook {
16
+
17
+ /**
18
+ * The ID of the webhook.
19
+ *
20
+ * @var string
21
+ */
22
+ private $id;
23
+
24
+ /**
25
+ * The URL of the webhook.
26
+ *
27
+ * @var string
28
+ */
29
+ private $url;
30
+
31
+ /**
32
+ * The event types.
33
+ *
34
+ * @var string[]
35
+ */
36
+ private $event_types;
37
+
38
+ /**
39
+ * Webhook constructor.
40
+ *
41
+ * @param string $url The URL of the webhook.
42
+ * @param string[] $event_types The associated event types.
43
+ * @param string $id The id of the webhook.
44
+ */
45
+ public function __construct( string $url, array $event_types, string $id = '' ) {
46
+ $this->url = $url;
47
+ $this->event_types = $event_types;
48
+ $this->id = $id;
49
+ }
50
+
51
+ /**
52
+ * Returns the id of the webhook.
53
+ *
54
+ * @return string
55
+ */
56
+ public function id(): string {
57
+
58
+ return $this->id;
59
+ }
60
+
61
+ /**
62
+ * Returns the URL listening to the hook.
63
+ *
64
+ * @return string
65
+ */
66
+ public function url(): string {
67
+
68
+ return $this->url;
69
+ }
70
+
71
+ /**
72
+ * Returns the event types.
73
+ *
74
+ * @return array
75
+ */
76
+ public function event_types(): array {
77
+
78
+ return $this->event_types;
79
+ }
80
+
81
+ /**
82
+ * Returns the object as array.
83
+ *
84
+ * @return array
85
+ */
86
+ public function to_array(): array {
87
+
88
+ $data = array(
89
+ 'url' => $this->url(),
90
+ 'event_types' => $this->event_types(),
91
+ );
92
+ if ( $this->id() ) {
93
+ $data['id'] = $this->id();
94
+ }
95
+ return $data;
96
+ }
97
+ }
modules/ppcp-api-client/src/Exception/class-notfoundexception.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The modules Not Found exception.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Exception
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Exception;
11
+
12
+ use Psr\Container\NotFoundExceptionInterface;
13
+ use Exception;
14
+
15
+ /**
16
+ * Class NotFoundException
17
+ */
18
+ class NotFoundException extends Exception implements NotFoundExceptionInterface {
19
+
20
+
21
+ }
modules/ppcp-api-client/src/Exception/class-paypalapiexception.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PayPal API Exception.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Exception
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Exception;
11
+
12
+ /**
13
+ * Class PayPalApiException
14
+ */
15
+ class PayPalApiException extends RuntimeException {
16
+
17
+ /**
18
+ * The JSON response object of PayPal.
19
+ *
20
+ * @var \stdClass
21
+ */
22
+ private $response;
23
+
24
+ /**
25
+ * The HTTP status code of the PayPal response.
26
+ *
27
+ * @var int
28
+ */
29
+ private $status_code;
30
+
31
+ /**
32
+ * PayPalApiException constructor.
33
+ *
34
+ * @param \stdClass|null $response The JSON object.
35
+ * @param int $status_code The HTTP status code.
36
+ */
37
+ public function __construct( \stdClass $response = null, int $status_code = 0 ) {
38
+ if ( is_null( $response ) ) {
39
+ $response = new \stdClass();
40
+ }
41
+ if ( ! isset( $response->message ) ) {
42
+ $response->message = __(
43
+ 'Unknown error while connecting to PayPal.',
44
+ 'woocommerce-paypal-payments'
45
+ );
46
+ }
47
+ if ( ! isset( $response->name ) ) {
48
+ $response->name = __( 'Error', 'woocommerce-paypal-payments' );
49
+ }
50
+ if ( ! isset( $response->details ) ) {
51
+ $response->details = array();
52
+ }
53
+ if ( ! isset( $response->links ) || ! is_array( $response->links ) ) {
54
+ $response->links = array();
55
+ }
56
+
57
+ /**
58
+ * The JSON response object.
59
+ *
60
+ * @var \stdClass $response
61
+ */
62
+ $this->response = $response;
63
+ $this->status_code = $status_code;
64
+ $message = $response->message;
65
+ if ( $response->name ) {
66
+ $message = '[' . $response->name . '] ' . $message;
67
+ }
68
+ foreach ( $response->links as $link ) {
69
+ if ( isset( $link->rel ) && 'information_link' === $link->rel ) {
70
+ $message .= ' ' . $link->href;
71
+ }
72
+ }
73
+ parent::__construct( $message, $status_code );
74
+ }
75
+
76
+ /**
77
+ * The name of the exception.
78
+ *
79
+ * @return string
80
+ */
81
+ public function name(): string {
82
+ return $this->response->name;
83
+ }
84
+
85
+ /**
86
+ * The details of the Exception.
87
+ *
88
+ * @return array
89
+ */
90
+ public function details(): array {
91
+ return $this->response->details;
92
+ }
93
+
94
+ /**
95
+ * Whether a certain detail is part of the exception reason.
96
+ *
97
+ * @param string $issue The issue.
98
+ *
99
+ * @return bool
100
+ */
101
+ public function has_detail( string $issue ): bool {
102
+ foreach ( $this->details() as $detail ) {
103
+ if ( isset( $detail->issue ) && $detail->issue === $issue ) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ }
modules/ppcp-api-client/src/Exception/class-runtimeexception.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The modules runtime exception.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Exception
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Exception;
11
+
12
+ /**
13
+ * Class RuntimeException
14
+ */
15
+ class RuntimeException extends \RuntimeException {
16
+
17
+
18
+ }
modules/ppcp-api-client/src/Factory/class-addressfactory.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Address factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Address;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+
15
+ /**
16
+ * Class AddressFactory
17
+ */
18
+ class AddressFactory {
19
+
20
+ /**
21
+ * Returns either the shipping or billing Address object of a customer.
22
+ *
23
+ * @param \WC_Customer $customer The WooCommerce customer.
24
+ * @param string $type Either 'shipping' or 'billing'.
25
+ *
26
+ * @return Address
27
+ */
28
+ public function from_wc_customer( \WC_Customer $customer, string $type = 'shipping' ): Address {
29
+ return new Address(
30
+ ( 'shipping' === $type ) ?
31
+ $customer->get_shipping_country() : $customer->get_billing_country(),
32
+ ( 'shipping' === $type ) ?
33
+ $customer->get_shipping_address_1() : $customer->get_billing_address_1(),
34
+ ( 'shipping' === $type ) ?
35
+ $customer->get_shipping_address_2() : $customer->get_billing_address_2(),
36
+ ( 'shipping' === $type ) ?
37
+ $customer->get_shipping_state() : $customer->get_billing_state(),
38
+ ( 'shipping' === $type ) ?
39
+ $customer->get_shipping_city() : $customer->get_billing_city(),
40
+ ( 'shipping' === $type ) ?
41
+ $customer->get_shipping_postcode() : $customer->get_billing_postcode()
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Returns an Address object based of a WooCommerce order.
47
+ *
48
+ * @param \WC_Order $order The order.
49
+ *
50
+ * @return Address
51
+ */
52
+ public function from_wc_order( \WC_Order $order ): Address {
53
+ return new Address(
54
+ $order->get_shipping_country(),
55
+ $order->get_shipping_address_1(),
56
+ $order->get_shipping_address_2(),
57
+ $order->get_shipping_state(),
58
+ $order->get_shipping_city(),
59
+ $order->get_shipping_postcode()
60
+ );
61
+ }
62
+
63
+ /**
64
+ * Creates an Address object based off a PayPal Response.
65
+ *
66
+ * @param \stdClass $data The JSON object.
67
+ *
68
+ * @return Address
69
+ * @throws RuntimeException When JSON object is malformed.
70
+ */
71
+ public function from_paypal_response( \stdClass $data ): Address {
72
+ if ( ! isset( $data->country_code ) ) {
73
+ throw new RuntimeException(
74
+ __( 'No country given for address.', 'woocommerce-paypal-payments' )
75
+ );
76
+ }
77
+ return new Address(
78
+ $data->country_code,
79
+ ( isset( $data->address_line_1 ) ) ? $data->address_line_1 : '',
80
+ ( isset( $data->address_line_2 ) ) ? $data->address_line_2 : '',
81
+ ( isset( $data->admin_area_1 ) ) ? $data->admin_area_1 : '',
82
+ ( isset( $data->admin_area_2 ) ) ? $data->admin_area_2 : '',
83
+ ( isset( $data->postal_code ) ) ? $data->postal_code : ''
84
+ );
85
+ }
86
+ }
modules/ppcp-api-client/src/Factory/class-amountfactory.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Amount factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\AmountBreakdown;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
17
+
18
+ /**
19
+ * Class AmountFactory
20
+ */
21
+ class AmountFactory {
22
+
23
+
24
+ /**
25
+ * The item factory.
26
+ *
27
+ * @var ItemFactory
28
+ */
29
+ private $item_factory;
30
+
31
+ /**
32
+ * AmountFactory constructor.
33
+ *
34
+ * @param ItemFactory $item_factory The Item factory.
35
+ */
36
+ public function __construct( ItemFactory $item_factory ) {
37
+ $this->item_factory = $item_factory;
38
+ }
39
+
40
+ /**
41
+ * Returns an Amount object based off a WooCommerce cart.
42
+ *
43
+ * @param \WC_Cart $cart The cart.
44
+ *
45
+ * @return Amount
46
+ */
47
+ public function from_wc_cart( \WC_Cart $cart ): Amount {
48
+ $currency = get_woocommerce_currency();
49
+ $total = new Money( (float) $cart->get_total( 'numeric' ), $currency );
50
+ $item_total = $cart->get_cart_contents_total() + $cart->get_discount_total();
51
+ $item_total = new Money( (float) $item_total, $currency );
52
+ $shipping = new Money(
53
+ (float) $cart->get_shipping_total() + $cart->get_shipping_tax(),
54
+ $currency
55
+ );
56
+
57
+ $taxes = new Money(
58
+ (float) $cart->get_cart_contents_tax() + (float) $cart->get_discount_tax(),
59
+ $currency
60
+ );
61
+
62
+ $discount = null;
63
+ if ( $cart->get_discount_total() ) {
64
+ $discount = new Money(
65
+ (float) $cart->get_discount_total() + $cart->get_discount_tax(),
66
+ $currency
67
+ );
68
+ }
69
+
70
+ $breakdown = new AmountBreakdown(
71
+ $item_total,
72
+ $shipping,
73
+ $taxes,
74
+ null, // insurance?
75
+ null, // handling?
76
+ null, // shipping discounts?
77
+ $discount
78
+ );
79
+ $amount = new Amount(
80
+ $total,
81
+ $breakdown
82
+ );
83
+ return $amount;
84
+ }
85
+
86
+ /**
87
+ * Returns an Amount object based off a WooCommerce order.
88
+ *
89
+ * @param \WC_Order $order The order.
90
+ *
91
+ * @return Amount
92
+ */
93
+ public function from_wc_order( \WC_Order $order ): Amount {
94
+ $currency = $order->get_currency();
95
+ $items = $this->item_factory->from_wc_order( $order );
96
+ $total = new Money( (float) $order->get_total(), $currency );
97
+ $item_total = new Money(
98
+ (float) array_reduce(
99
+ $items,
100
+ static function ( float $total, Item $item ): float {
101
+ return $total + $item->quantity() * $item->unit_amount()->value();
102
+ },
103
+ 0
104
+ ),
105
+ $currency
106
+ );
107
+ $shipping = new Money(
108
+ (float) $order->get_shipping_total() + (float) $order->get_shipping_tax(),
109
+ $currency
110
+ );
111
+ $taxes = new Money(
112
+ (float) array_reduce(
113
+ $items,
114
+ static function ( float $total, Item $item ): float {
115
+ return $total + $item->quantity() * $item->tax()->value();
116
+ },
117
+ 0
118
+ ),
119
+ $currency
120
+ );
121
+
122
+ $discount = null;
123
+ if ( (float) $order->get_total_discount( false ) ) {
124
+ $discount = new Money(
125
+ (float) $order->get_total_discount( false ),
126
+ $currency
127
+ );
128
+ }
129
+
130
+ $breakdown = new AmountBreakdown(
131
+ $item_total,
132
+ $shipping,
133
+ $taxes,
134
+ null, // insurance?
135
+ null, // handling?
136
+ null, // shipping discounts?
137
+ $discount
138
+ );
139
+ $amount = new Amount(
140
+ $total,
141
+ $breakdown
142
+ );
143
+ return $amount;
144
+ }
145
+
146
+ /**
147
+ * Returns an Amount object based off a PayPal Response.
148
+ *
149
+ * @param \stdClass $data The JSON object.
150
+ *
151
+ * @return Amount
152
+ * @throws RuntimeException When JSON object is malformed.
153
+ */
154
+ public function from_paypal_response( \stdClass $data ): Amount {
155
+ if ( ! isset( $data->value ) || ! is_numeric( $data->value ) ) {
156
+ throw new RuntimeException( __( 'No value given', 'woocommerce-paypal-payments' ) );
157
+ }
158
+ if ( ! isset( $data->currency_code ) ) {
159
+ throw new RuntimeException(
160
+ __( 'No currency given', 'woocommerce-paypal-payments' )
161
+ );
162
+ }
163
+
164
+ $money = new Money( (float) $data->value, $data->currency_code );
165
+ $breakdown = ( isset( $data->breakdown ) ) ? $this->break_down( $data->breakdown ) : null;
166
+ return new Amount( $money, $breakdown );
167
+ }
168
+
169
+ /**
170
+ * Returns a AmountBreakdown object based off a PayPal response.
171
+ *
172
+ * @param \stdClass $data The JSON object.
173
+ *
174
+ * @return AmountBreakdown
175
+ * @throws RuntimeException When JSON object is malformed.
176
+ */
177
+ private function break_down( \stdClass $data ): AmountBreakdown {
178
+ /**
179
+ * The order of the keys equals the necessary order of the constructor arguments.
180
+ */
181
+ $ordered_constructor_keys = array(
182
+ 'item_total',
183
+ 'shipping',
184
+ 'tax_total',
185
+ 'handling',
186
+ 'insurance',
187
+ 'shipping_discount',
188
+ 'discount',
189
+ );
190
+
191
+ $money = array();
192
+ foreach ( $ordered_constructor_keys as $key ) {
193
+ if ( ! isset( $data->{$key} ) ) {
194
+ $money[] = null;
195
+ continue;
196
+ }
197
+ $item = $data->{$key};
198
+
199
+ if ( ! isset( $item->value ) || ! is_numeric( $item->value ) ) {
200
+ throw new RuntimeException(
201
+ sprintf(
202
+ // translators: %s is the current breakdown key.
203
+ __( 'No value given for breakdown %s', 'woocommerce-paypal-payments' ),
204
+ $key
205
+ )
206
+ );
207
+ }
208
+ if ( ! isset( $item->currency_code ) ) {
209
+ throw new RuntimeException(
210
+ sprintf(
211
+ // translators: %s is the current breakdown key.
212
+ __( 'No currency given for breakdown %s', 'woocommerce-paypal-payments' ),
213
+ $key
214
+ )
215
+ );
216
+ }
217
+ $money[] = new Money( (float) $item->value, $item->currency_code );
218
+ }
219
+
220
+ return new AmountBreakdown( ...$money );
221
+ }
222
+ }
modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The ApplicationContext factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
13
+
14
+ /**
15
+ * Class ApplicationContextFactory
16
+ */
17
+ class ApplicationContextFactory {
18
+
19
+ /**
20
+ * Returns an Application Context based off a PayPal Response.
21
+ *
22
+ * @param \stdClass $data The JSON object.
23
+ *
24
+ * @return ApplicationContext
25
+ */
26
+ public function from_paypal_response( \stdClass $data ): ApplicationContext {
27
+ return new ApplicationContext(
28
+ isset( $data->return_url ) ?
29
+ $data->return_url : '',
30
+ isset( $data->cancel_url ) ?
31
+ $data->cancel_url : '',
32
+ isset( $data->brand_name ) ?
33
+ $data->brand_name : '',
34
+ isset( $data->locale ) ?
35
+ $data->locale : '',
36
+ isset( $data->landing_page ) ?
37
+ $data->landing_page : ApplicationContext::LANDING_PAGE_NO_PREFERENCE,
38
+ isset( $data->shipping_preference ) ?
39
+ $data->shipping_preference : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE,
40
+ isset( $data->user_action ) ?
41
+ $data->user_action : ApplicationContext::USER_ACTION_CONTINUE
42
+ );
43
+ }
44
+ }
modules/ppcp-api-client/src/Factory/class-authorizationfactory.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Authorization factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+
16
+ /**
17
+ * Class AuthorizationFactory
18
+ */
19
+ class AuthorizationFactory {
20
+
21
+ /**
22
+ * Returns an Authorization based off a PayPal response.
23
+ *
24
+ * @param \stdClass $data The JSON object.
25
+ *
26
+ * @return Authorization
27
+ * @throws RuntimeException When JSON object is malformed.
28
+ */
29
+ public function from_paypal_response( \stdClass $data ): Authorization {
30
+ if ( ! isset( $data->id ) ) {
31
+ throw new RuntimeException(
32
+ __( 'Does not contain an id.', 'woocommerce-paypal-payments' )
33
+ );
34
+ }
35
+
36
+ if ( ! isset( $data->status ) ) {
37
+ throw new RuntimeException(
38
+ __( 'Does not contain status.', 'woocommerce-paypal-payments' )
39
+ );
40
+ }
41
+
42
+ return new Authorization(
43
+ $data->id,
44
+ new AuthorizationStatus( $data->status )
45
+ );
46
+ }
47
+ }
modules/ppcp-api-client/src/Factory/class-capturefactory.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The capture factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
13
+
14
+ /**
15
+ * Class CaptureFactory
16
+ */
17
+ class CaptureFactory {
18
+
19
+ /**
20
+ * The Amount factory.
21
+ *
22
+ * @var AmountFactory
23
+ */
24
+ private $amount_factory;
25
+
26
+ /**
27
+ * CaptureFactory constructor.
28
+ *
29
+ * @param AmountFactory $amount_factory The amount factory.
30
+ */
31
+ public function __construct( AmountFactory $amount_factory ) {
32
+
33
+ $this->amount_factory = $amount_factory;
34
+ }
35
+
36
+ /**
37
+ * Returns the capture object based off the PayPal response.
38
+ *
39
+ * @param \stdClass $data The PayPal response.
40
+ *
41
+ * @return Capture
42
+ */
43
+ public function from_paypal_response( \stdClass $data ) : Capture {
44
+
45
+ $reason = isset( $data->status_details->reason ) ? (string) $data->status_details->reason : '';
46
+ return new Capture(
47
+ (string) $data->id,
48
+ (string) $data->status,
49
+ $reason,
50
+ $this->amount_factory->from_paypal_response( $data->amount ),
51
+ (bool) $data->final_capture,
52
+ (string) $data->seller_protection->status,
53
+ (string) $data->invoice_id,
54
+ (string) $data->custom_id
55
+ );
56
+ }
57
+ }
modules/ppcp-api-client/src/Factory/class-itemfactory.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Item factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+
16
+ /**
17
+ * Class ItemFactory
18
+ */
19
+ class ItemFactory {
20
+
21
+
22
+ /**
23
+ * Creates items based off a WooCommerce cart.
24
+ *
25
+ * @param \WC_Cart $cart The cart.
26
+ *
27
+ * @return Item[]
28
+ */
29
+ public function from_wc_cart( \WC_Cart $cart ): array {
30
+ $currency = get_woocommerce_currency();
31
+ $items = array_map(
32
+ static function ( array $item ) use ( $currency ): Item {
33
+ $product = $item['data'];
34
+
35
+ /**
36
+ * The WooCommerce product.
37
+ *
38
+ * @var \WC_Product $product
39
+ */
40
+ $quantity = (int) $item['quantity'];
41
+
42
+ $price = (float) wc_get_price_including_tax( $product );
43
+ $price_without_tax = (float) wc_get_price_excluding_tax( $product );
44
+ $price_without_tax_rounded = round( $price_without_tax, 2 );
45
+ $tax = round( $price - $price_without_tax_rounded, 2 );
46
+ $tax = new Money( $tax, $currency );
47
+ return new Item(
48
+ mb_substr( $product->get_name(), 0, 127 ),
49
+ new Money( $price_without_tax_rounded, $currency ),
50
+ $quantity,
51
+ mb_substr( $product->get_description(), 0, 127 ),
52
+ $tax,
53
+ $product->get_sku(),
54
+ ( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
55
+ );
56
+ },
57
+ $cart->get_cart_contents()
58
+ );
59
+ return $items;
60
+ }
61
+
62
+ /**
63
+ * Creates Items based off a WooCommerce order.
64
+ *
65
+ * @param \WC_Order $order The order.
66
+ * @return Item[]
67
+ */
68
+ public function from_wc_order( \WC_Order $order ): array {
69
+ return array_map(
70
+ function ( \WC_Order_Item_Product $item ) use ( $order ): Item {
71
+ return $this->from_wc_order_line_item( $item, $order );
72
+ },
73
+ $order->get_items( 'line_item' )
74
+ );
75
+ }
76
+
77
+ /**
78
+ * Creates an Item based off a WooCommerce Order Item.
79
+ *
80
+ * @param \WC_Order_Item_Product $item The WooCommerce order item.
81
+ * @param \WC_Order $order The WooCommerce order.
82
+ *
83
+ * @return Item
84
+ */
85
+ private function from_wc_order_line_item( \WC_Order_Item_Product $item, \WC_Order $order ): Item {
86
+ $currency = $order->get_currency();
87
+ $product = $item->get_product();
88
+
89
+ /**
90
+ * The WooCommerce product.
91
+ *
92
+ * @var \WC_Product $product
93
+ */
94
+ $quantity = $item->get_quantity();
95
+
96
+ $price = (float) $order->get_item_subtotal( $item, true );
97
+ $price_without_tax = (float) $order->get_item_subtotal( $item, false );
98
+ $price_without_tax_rounded = round( $price_without_tax, 2 );
99
+ $tax = round( $price - $price_without_tax_rounded, 2 );
100
+ $tax = new Money( $tax, $currency );
101
+ return new Item(
102
+ mb_substr( $product->get_name(), 0, 127 ),
103
+ new Money( $price_without_tax_rounded, $currency ),
104
+ $quantity,
105
+ mb_substr( $product->get_description(), 0, 127 ),
106
+ $tax,
107
+ $product->get_sku(),
108
+ ( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Creates an Item based off a PayPal response.
114
+ *
115
+ * @param \stdClass $data The JSON object.
116
+ *
117
+ * @return Item
118
+ * @throws RuntimeException When JSON object is malformed.
119
+ */
120
+ public function from_paypal_response( \stdClass $data ): Item {
121
+ if ( ! isset( $data->name ) ) {
122
+ throw new RuntimeException(
123
+ __( 'No name for item given', 'woocommerce-paypal-payments' )
124
+ );
125
+ }
126
+ if ( ! isset( $data->quantity ) || ! is_numeric( $data->quantity ) ) {
127
+ throw new RuntimeException(
128
+ __( 'No quantity for item given', 'woocommerce-paypal-payments' )
129
+ );
130
+ }
131
+ if ( ! isset( $data->unit_amount->value ) || ! isset( $data->unit_amount->currency_code ) ) {
132
+ throw new RuntimeException(
133
+ __( 'No money values for item given', 'woocommerce-paypal-payments' )
134
+ );
135
+ }
136
+
137
+ $unit_amount = new Money( (float) $data->unit_amount->value, $data->unit_amount->currency_code );
138
+ $description = ( isset( $data->description ) ) ? $data->description : '';
139
+ $tax = ( isset( $data->tax ) ) ?
140
+ new Money( (float) $data->tax->value, $data->tax->currency_code )
141
+ : null;
142
+ $sku = ( isset( $data->sku ) ) ? $data->sku : '';
143
+ $category = ( isset( $data->category ) ) ? $data->category : 'PHYSICAL_GOODS';
144
+
145
+ return new Item(
146
+ $data->name,
147
+ $unit_amount,
148
+ (int) $data->quantity,
149
+ $description,
150
+ $tax,
151
+ $sku,
152
+ $category
153
+ );
154
+ }
155
+ }
modules/ppcp-api-client/src/Factory/class-orderfactory.php ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Order factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
17
+
18
+ /**
19
+ * Class OrderFactory
20
+ */
21
+ class OrderFactory {
22
+
23
+ /**
24
+ * The PurchaseUnit factory.
25
+ *
26
+ * @var PurchaseUnitFactory
27
+ */
28
+ private $purchase_unit_factory;
29
+
30
+ /**
31
+ * The Payer factory.
32
+ *
33
+ * @var PayerFactory
34
+ */
35
+ private $payer_factory;
36
+
37
+ /**
38
+ * The ApplicationContext repository.
39
+ *
40
+ * @var ApplicationContextRepository
41
+ */
42
+ private $application_context_repository;
43
+
44
+ /**
45
+ * The ApplicationContext factory.
46
+ *
47
+ * @var ApplicationContextFactory
48
+ */
49
+ private $application_context_factory;
50
+
51
+ /**
52
+ * The PaymentSource factory.
53
+ *
54
+ * @var PaymentSourceFactory
55
+ */
56
+ private $payment_source_factory;
57
+
58
+ /**
59
+ * OrderFactory constructor.
60
+ *
61
+ * @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory.
62
+ * @param PayerFactory $payer_factory The Payer factory.
63
+ * @param ApplicationContextRepository $application_context_repository The Application Context repository.
64
+ * @param ApplicationContextFactory $application_context_factory The Application Context factory.
65
+ * @param PaymentSourceFactory $payment_source_factory The Payment Source factory.
66
+ */
67
+ public function __construct(
68
+ PurchaseUnitFactory $purchase_unit_factory,
69
+ PayerFactory $payer_factory,
70
+ ApplicationContextRepository $application_context_repository,
71
+ ApplicationContextFactory $application_context_factory,
72
+ PaymentSourceFactory $payment_source_factory
73
+ ) {
74
+
75
+ $this->purchase_unit_factory = $purchase_unit_factory;
76
+ $this->payer_factory = $payer_factory;
77
+ $this->application_context_repository = $application_context_repository;
78
+ $this->application_context_factory = $application_context_factory;
79
+ $this->payment_source_factory = $payment_source_factory;
80
+ }
81
+
82
+ /**
83
+ * Creates an Order object based off a WooCommerce order and another Order object.
84
+ *
85
+ * @param \WC_Order $wc_order The WooCommerce order.
86
+ * @param Order $order The order object.
87
+ *
88
+ * @return Order
89
+ */
90
+ public function from_wc_order( \WC_Order $wc_order, Order $order ): Order {
91
+ $purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) );
92
+
93
+ return new Order(
94
+ $order->id(),
95
+ $purchase_units,
96
+ $order->status(),
97
+ $order->application_context(),
98
+ $order->payment_source(),
99
+ $order->payer(),
100
+ $order->intent(),
101
+ $order->create_time(),
102
+ $order->update_time()
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Returns an Order object based off a PayPal Response.
108
+ *
109
+ * @param \stdClass $order_data The JSON object.
110
+ *
111
+ * @return Order
112
+ * @throws RuntimeException When JSON object is malformed.
113
+ */
114
+ public function from_paypal_response( \stdClass $order_data ): Order {
115
+ if ( ! isset( $order_data->id ) ) {
116
+ throw new RuntimeException(
117
+ __( 'Order does not contain an id.', 'woocommerce-paypal-payments' )
118
+ );
119
+ }
120
+ if ( ! isset( $order_data->purchase_units ) || ! is_array( $order_data->purchase_units ) ) {
121
+ throw new RuntimeException(
122
+ __( 'Order does not contain items.', 'woocommerce-paypal-payments' )
123
+ );
124
+ }
125
+ if ( ! isset( $order_data->status ) ) {
126
+ throw new RuntimeException(
127
+ __( 'Order does not contain status.', 'woocommerce-paypal-payments' )
128
+ );
129
+ }
130
+ if ( ! isset( $order_data->intent ) ) {
131
+ throw new RuntimeException(
132
+ __( 'Order does not contain intent.', 'woocommerce-paypal-payments' )
133
+ );
134
+ }
135
+
136
+ $purchase_units = array_map(
137
+ function ( \stdClass $data ): PurchaseUnit {
138
+ return $this->purchase_unit_factory->from_paypal_response( $data );
139
+ },
140
+ $order_data->purchase_units
141
+ );
142
+
143
+ $create_time = ( isset( $order_data->create_time ) ) ?
144
+ \DateTime::createFromFormat( 'Y-m-d\TH:i:sO', $order_data->create_time )
145
+ : null;
146
+ $update_time = ( isset( $order_data->update_time ) ) ?
147
+ \DateTime::createFromFormat( 'Y-m-d\TH:i:sO', $order_data->update_time )
148
+ : null;
149
+ $payer = ( isset( $order_data->payer ) ) ?
150
+ $this->payer_factory->from_paypal_response( $order_data->payer )
151
+ : null;
152
+ $application_context = ( isset( $order_data->application_context ) ) ?
153
+ $this->application_context_factory->from_paypal_response( $order_data->application_context )
154
+ : null;
155
+ $payment_source = ( isset( $order_data->payment_source ) ) ?
156
+ $this->payment_source_factory->from_paypal_response( $order_data->payment_source ) :
157
+ null;
158
+
159
+ return new Order(
160
+ $order_data->id,
161
+ $purchase_units,
162
+ new OrderStatus( $order_data->status ),
163
+ $application_context,
164
+ $payment_source,
165
+ $payer,
166
+ $order_data->intent,
167
+ $create_time,
168
+ $update_time
169
+ );
170
+ }
171
+ }
modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PatchCollection factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Patch;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PatchCollection;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
16
+
17
+ /**
18
+ * Class PatchCollectionFactory
19
+ */
20
+ class PatchCollectionFactory {
21
+
22
+
23
+ /**
24
+ * Creates a Patch Collection by comparing two orders.
25
+ *
26
+ * @param Order $from The inital order.
27
+ * @param Order $to The target order.
28
+ *
29
+ * @return PatchCollection
30
+ */
31
+ public function from_orders( Order $from, Order $to ): PatchCollection {
32
+ $all_patches = array();
33
+ $all_patches += $this->purchase_units( $from->purchase_units(), $to->purchase_units() );
34
+
35
+ return new PatchCollection( ...$all_patches );
36
+ }
37
+
38
+ /**
39
+ * Returns patches from purchase units diffs.
40
+ *
41
+ * @param PurchaseUnit[] $from The Purchase Units to start with.
42
+ * @param PurchaseUnit[] $to The Purchase Units to end with after patches where applied.
43
+ *
44
+ * @return Patch[]
45
+ */
46
+ private function purchase_units( array $from, array $to ): array {
47
+ $patches = array();
48
+
49
+ $path = '/purchase_units';
50
+ foreach ( $to as $purchase_unit_to ) {
51
+ $needs_update = ! count(
52
+ array_filter(
53
+ $from,
54
+ static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
55
+ //phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
56
+ // Loose comparison needed to compare two objects.
57
+ return $unit == $purchase_unit_to;
58
+ //phpcs:enable WordPress.PHP.StrictComparisons.LooseComparison
59
+ }
60
+ )
61
+ );
62
+ $needs_update = true;
63
+ if ( ! $needs_update ) {
64
+ continue;
65
+ }
66
+ $purchase_unit_from = current(
67
+ array_filter(
68
+ $from,
69
+ static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
70
+ return $purchase_unit_to->reference_id() === $unit->reference_id();
71
+ }
72
+ )
73
+ );
74
+ $operation = $purchase_unit_from ? 'replace' : 'add';
75
+ $value = $purchase_unit_to->to_array();
76
+ $patches[] = new Patch(
77
+ $operation,
78
+ $path . "/@reference_id=='" . $purchase_unit_to->reference_id() . "'",
79
+ $value
80
+ );
81
+ }
82
+
83
+ return $patches;
84
+ }
85
+ }
modules/ppcp-api-client/src/Factory/class-payeefactory.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Payee Factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payee;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+
15
+ /**
16
+ * Class PayeeFactory
17
+ */
18
+ class PayeeFactory {
19
+
20
+ /**
21
+ * Returns a Payee object based off a PayPal Response.
22
+ *
23
+ * @param \stdClass $data The JSON object.
24
+ *
25
+ * @return Payee|null
26
+ * @throws RuntimeException When JSON object is malformed.
27
+ */
28
+ public function from_paypal_response( \stdClass $data ) {
29
+ if ( ! isset( $data->email_address ) ) {
30
+ throw new RuntimeException(
31
+ __( 'No email for payee given.', 'woocommerce-paypal-payments' )
32
+ );
33
+ }
34
+
35
+ $merchant_id = ( isset( $data->merchant_id ) ) ? $data->merchant_id : '';
36
+ return new Payee( $data->email_address, $merchant_id );
37
+ }
38
+ }
modules/ppcp-api-client/src/Factory/class-payerfactory.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Payer factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerName;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerTaxInfo;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Phone;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PhoneWithType;
17
+
18
+ /**
19
+ * Class PayerFactory
20
+ */
21
+ class PayerFactory {
22
+
23
+ /**
24
+ * The address factory.
25
+ *
26
+ * @var AddressFactory
27
+ */
28
+ private $address_factory;
29
+
30
+ /**
31
+ * PayerFactory constructor.
32
+ *
33
+ * @param AddressFactory $address_factory The Address factory.
34
+ */
35
+ public function __construct( AddressFactory $address_factory ) {
36
+ $this->address_factory = $address_factory;
37
+ }
38
+
39
+ /**
40
+ * Returns a Payer entity from a WooCommerce order.
41
+ *
42
+ * @param \WC_Order $wc_order The WooCommerce order.
43
+ *
44
+ * @return Payer
45
+ */
46
+ public function from_wc_order( \WC_Order $wc_order ): Payer {
47
+ $payer_id = '';
48
+ $birthdate = null;
49
+
50
+ $phone = null;
51
+ if ( $wc_order->get_billing_phone() ) {
52
+ // make sure the phone number contains only numbers and is max 14. chars long.
53
+ $national_number = $wc_order->get_billing_phone();
54
+ $national_number = preg_replace( '/[^0-9]/', '', $national_number );
55
+ $national_number = substr( $national_number, 0, 14 );
56
+
57
+ $phone = new PhoneWithType(
58
+ 'HOME',
59
+ new Phone( $national_number )
60
+ );
61
+ }
62
+ return new Payer(
63
+ new PayerName(
64
+ $wc_order->get_billing_first_name(),
65
+ $wc_order->get_billing_last_name()
66
+ ),
67
+ $wc_order->get_billing_email(),
68
+ $payer_id,
69
+ $this->address_factory->from_wc_order( $wc_order, 'billing' ),
70
+ $birthdate,
71
+ $phone
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Returns a Payer object based off a WooCommerce customer.
77
+ *
78
+ * @param \WC_Customer $customer The WooCommerce customer.
79
+ *
80
+ * @return Payer
81
+ */
82
+ public function from_customer( \WC_Customer $customer ): Payer {
83
+ $payer_id = '';
84
+ $birthdate = null;
85
+
86
+ $phone = null;
87
+ if ( $customer->get_billing_phone() ) {
88
+ // make sure the phone number contains only numbers and is max 14. chars long.
89
+ $national_number = $customer->get_billing_phone();
90
+ $national_number = preg_replace( '/[^0-9]/', '', $national_number );
91
+ $national_number = substr( $national_number, 0, 14 );
92
+
93
+ $phone = new PhoneWithType(
94
+ 'HOME',
95
+ new Phone( $national_number )
96
+ );
97
+ }
98
+ return new Payer(
99
+ new PayerName(
100
+ $customer->get_billing_first_name(),
101
+ $customer->get_billing_last_name()
102
+ ),
103
+ $customer->get_billing_email(),
104
+ $payer_id,
105
+ $this->address_factory->from_wc_customer( $customer, 'billing' ),
106
+ $birthdate,
107
+ $phone
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Returns a Payer object based off a PayPal Response.
113
+ *
114
+ * @param \stdClass $data The JSON object.
115
+ *
116
+ * @return Payer
117
+ */
118
+ public function from_paypal_response( \stdClass $data ): Payer {
119
+ $address = $this->address_factory->from_paypal_response( $data->address );
120
+ $payer_name = new PayerName(
121
+ isset( $data->name->given_name ) ? (string) $data->name->given_name : '',
122
+ isset( $data->name->surname ) ? (string) $data->name->surname : ''
123
+ );
124
+ // TODO deal with phones without type instead of passing a invalid type.
125
+ $phone = ( isset( $data->phone ) ) ? new PhoneWithType(
126
+ ( isset( $data->phone->phone_type ) ) ? $data->phone->phone_type : 'undefined',
127
+ new Phone(
128
+ $data->phone->phone_number->national_number
129
+ )
130
+ ) : null;
131
+ $tax_info = ( isset( $data->tax_info ) ) ?
132
+ new PayerTaxInfo( $data->tax_info->tax_id, $data->tax_info->tax_id_type )
133
+ : null;
134
+ $birth_date = ( isset( $data->birth_date ) ) ?
135
+ \DateTime::createFromFormat( 'Y-m-d', $data->birth_date )
136
+ : null;
137
+ return new Payer(
138
+ $payer_name,
139
+ isset( $data->email_address ) ? $data->email_address : '',
140
+ ( isset( $data->payer_id ) ) ? $data->payer_id : '',
141
+ $address,
142
+ $birth_date,
143
+ $phone,
144
+ $tax_info
145
+ );
146
+ }
147
+ }
modules/ppcp-api-client/src/Factory/class-paymentsfactory.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Payments factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
+ use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
15
+
16
+ /**
17
+ * Class PaymentsFactory
18
+ */
19
+ class PaymentsFactory {
20
+
21
+ /**
22
+ * The Authorization factory.
23
+ *
24
+ * @var AuthorizationFactory
25
+ */
26
+ private $authorization_factory;
27
+
28
+ /**
29
+ * The Capture factory.
30
+ *
31
+ * @var CaptureFactory
32
+ */
33
+ private $capture_factory;
34
+
35
+ /**
36
+ * PaymentsFactory constructor.
37
+ *
38
+ * @param AuthorizationFactory $authorization_factory The Authorization factory.
39
+ * @param CaptureFactory $capture_factory The Capture factory.
40
+ */
41
+ public function __construct(
42
+ AuthorizationFactory $authorization_factory,
43
+ CaptureFactory $capture_factory
44
+ ) {
45
+
46
+ $this->authorization_factory = $authorization_factory;
47
+ $this->capture_factory = $capture_factory;
48
+ }
49
+
50
+ /**
51
+ * Returns a Payments object based off a PayPal response.
52
+ *
53
+ * @param \stdClass $data The JSON object.
54
+ *
55
+ * @return Payments
56
+ */
57
+ public function from_paypal_response( \stdClass $data ): Payments {
58
+ $authorizations = array_map(
59
+ function ( \stdClass $authorization ): Authorization {
60
+ return $this->authorization_factory->from_paypal_response( $authorization );
61
+ },
62
+ isset( $data->authorizations ) ? $data->authorizations : array()
63
+ );
64
+ $captures = array_map(
65
+ function ( \stdClass $authorization ): Capture {
66
+ return $this->capture_factory->from_paypal_response( $authorization );
67
+ },
68
+ isset( $data->captures ) ? $data->captures : array()
69
+ );
70
+ $payments = new Payments( $authorizations, $captures );
71
+ return $payments;
72
+ }
73
+ }
modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentSource factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSourceCard;
15
+
16
+ /**
17
+ * Class PaymentSourceFactory
18
+ */
19
+ class PaymentSourceFactory {
20
+
21
+ /**
22
+ * Returns a PaymentSource for a PayPal Response.
23
+ *
24
+ * @param \stdClass $data The JSON object.
25
+ *
26
+ * @return PaymentSource
27
+ */
28
+ public function from_paypal_response( \stdClass $data ): PaymentSource {
29
+
30
+ $card = null;
31
+ $wallet = null;
32
+ if ( isset( $data->card ) ) {
33
+ $authentication_result = null;
34
+ if ( isset( $data->card->authentication_result ) ) {
35
+ $authentication_result = new CardAuthenticationResult(
36
+ isset( $data->card->authentication_result->liability_shift ) ?
37
+ (string) $data->card->authentication_result->liability_shift : '',
38
+ isset( $data->card->authentication_result->three_d_secure->enrollment_status ) ?
39
+ (string) $data->card->authentication_result->three_d_secure->enrollment_status : '',
40
+ isset( $data->card->authentication_result->three_d_secure->authentication_result ) ?
41
+ (string) $data->card->authentication_result->three_d_secure->authentication_result : ''
42
+ );
43
+ }
44
+ $card = new PaymentSourceCard(
45
+ isset( $data->card->last_digits ) ? (string) $data->card->last_digits : '',
46
+ isset( $data->card->brand ) ? (string) $data->card->brand : '',
47
+ isset( $data->card->type ) ? (string) $data->card->type : '',
48
+ $authentication_result
49
+ );
50
+ }
51
+ return new PaymentSource( $card, $wallet );
52
+ }
53
+ }
modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PaymentToken Factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+
15
+ /**
16
+ * Class PaymentTokenFactory
17
+ */
18
+ class PaymentTokenFactory {
19
+
20
+ /**
21
+ * Returns a PaymentToken based off a PayPal Response object.
22
+ *
23
+ * @param \stdClass $data The JSON object.
24
+ *
25
+ * @return PaymentToken
26
+ * @throws RuntimeException When JSON object is malformed.
27
+ */
28
+ public function from_paypal_response( \stdClass $data ): PaymentToken {
29
+ if ( ! isset( $data->id ) ) {
30
+ throw new RuntimeException(
31
+ __( 'No id for payment token given', 'woocommerce-paypal-payments' )
32
+ );
33
+ }
34
+ return new PaymentToken(
35
+ $data->id,
36
+ ( isset( $data->type ) ) ? $data->type : PaymentToken::TYPE_PAYMENT_METHOD_TOKEN
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Creates a payment token based off a data array.
42
+ *
43
+ * @param array $data The data array.
44
+ *
45
+ * @return PaymentToken
46
+ */
47
+ public function from_array( array $data ): PaymentToken {
48
+ return $this->from_paypal_response( (object) $data );
49
+ }
50
+ }
modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PurchaseUnit factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
16
+
17
+ /**
18
+ * Class PurchaseUnitFactory
19
+ */
20
+ class PurchaseUnitFactory {
21
+
22
+ /**
23
+ * The amount factory.
24
+ *
25
+ * @var AmountFactory
26
+ */
27
+ private $amount_factory;
28
+
29
+ /**
30
+ * The payee repository.
31
+ *
32
+ * @var PayeeRepository
33
+ */
34
+ private $payee_repository;
35
+
36
+ /**
37
+ * The payee factory.
38
+ *
39
+ * @var PayeeFactory
40
+ */
41
+ private $payee_factory;
42
+
43
+ /**
44
+ * The item factory.
45
+ *
46
+ * @var ItemFactory
47
+ */
48
+ private $item_factory;
49
+
50
+ /**
51
+ * The shipping factory.
52
+ *
53
+ * @var ShippingFactory
54
+ */
55
+ private $shipping_factory;
56
+
57
+ /**
58
+ * The payments factory.
59
+ *
60
+ * @var PaymentsFactory
61
+ */
62
+ private $payments_factory;
63
+
64
+ /**
65
+ * The Prefix.
66
+ *
67
+ * @var string
68
+ */
69
+ private $prefix;
70
+
71
+ /**
72
+ * PurchaseUnitFactory constructor.
73
+ *
74
+ * @param AmountFactory $amount_factory The amount factory.
75
+ * @param PayeeRepository $payee_repository The Payee repository.
76
+ * @param PayeeFactory $payee_factory The Payee factory.
77
+ * @param ItemFactory $item_factory The item factory.
78
+ * @param ShippingFactory $shipping_factory The shipping factory.
79
+ * @param PaymentsFactory $payments_factory The payments factory.
80
+ * @param string $prefix The prefix.
81
+ */
82
+ public function __construct(
83
+ AmountFactory $amount_factory,
84
+ PayeeRepository $payee_repository,
85
+ PayeeFactory $payee_factory,
86
+ ItemFactory $item_factory,
87
+ ShippingFactory $shipping_factory,
88
+ PaymentsFactory $payments_factory,
89
+ string $prefix = 'WC-'
90
+ ) {
91
+
92
+ $this->amount_factory = $amount_factory;
93
+ $this->payee_repository = $payee_repository;
94
+ $this->payee_factory = $payee_factory;
95
+ $this->item_factory = $item_factory;
96
+ $this->shipping_factory = $shipping_factory;
97
+ $this->payments_factory = $payments_factory;
98
+ $this->prefix = $prefix;
99
+ }
100
+
101
+ /**
102
+ * Creates a PurchaseUnit based off a WooCommerce order.
103
+ *
104
+ * @param \WC_Order $order The order.
105
+ *
106
+ * @return PurchaseUnit
107
+ */
108
+ public function from_wc_order( \WC_Order $order ): PurchaseUnit {
109
+ $amount = $this->amount_factory->from_wc_order( $order );
110
+ $items = $this->item_factory->from_wc_order( $order );
111
+ $shipping = $this->shipping_factory->from_wc_order( $order );
112
+ if (
113
+ ! $this->shipping_needed( ... array_values( $items ) ) ||
114
+ empty( $shipping->address()->country_code() ) ||
115
+ ( $shipping->address()->country_code() && ! $shipping->address()->postal_code() )
116
+ ) {
117
+ $shipping = null;
118
+ }
119
+ $reference_id = 'default';
120
+ $description = '';
121
+ $payee = $this->payee_repository->payee();
122
+ $wc_order_id = $order->get_id();
123
+ $custom_id = $this->prefix . $wc_order_id;
124
+ $invoice_id = $this->prefix . $wc_order_id;
125
+ $soft_descriptor = '';
126
+ $purchase_unit = new PurchaseUnit(
127
+ $amount,
128
+ $items,
129
+ $shipping,
130
+ $reference_id,
131
+ $description,
132
+ $payee,
133
+ $custom_id,
134
+ $invoice_id,
135
+ $soft_descriptor
136
+ );
137
+ return $purchase_unit;
138
+ }
139
+
140
+ /**
141
+ * Creates a PurchaseUnit based off a WooCommerce cart.
142
+ *
143
+ * @param \WC_Cart $cart The cart.
144
+ *
145
+ * @return PurchaseUnit
146
+ */
147
+ public function from_wc_cart( \WC_Cart $cart ): PurchaseUnit {
148
+ $amount = $this->amount_factory->from_wc_cart( $cart );
149
+ $items = $this->item_factory->from_wc_cart( $cart );
150
+
151
+ $shipping = null;
152
+ $customer = \WC()->customer;
153
+ if ( $this->shipping_needed( ... array_values( $items ) ) && is_a( $customer, \WC_Customer::class ) ) {
154
+ $shipping = $this->shipping_factory->from_wc_customer( \WC()->customer );
155
+ if (
156
+ ! $shipping->address()->country_code()
157
+ || ( $shipping->address()->country_code() && ! $shipping->address()->postal_code() )
158
+ ) {
159
+ $shipping = null;
160
+ }
161
+ }
162
+
163
+ $reference_id = 'default';
164
+ $description = '';
165
+
166
+ $payee = $this->payee_repository->payee();
167
+
168
+ $custom_id = '';
169
+ $invoice_id = '';
170
+ $soft_descriptor = '';
171
+ $purchase_unit = new PurchaseUnit(
172
+ $amount,
173
+ $items,
174
+ $shipping,
175
+ $reference_id,
176
+ $description,
177
+ $payee,
178
+ $custom_id,
179
+ $invoice_id,
180
+ $soft_descriptor
181
+ );
182
+
183
+ return $purchase_unit;
184
+ }
185
+
186
+ /**
187
+ * Builds a Purchase unit based off a PayPal JSON response.
188
+ *
189
+ * @param \stdClass $data The JSON object.
190
+ *
191
+ * @return PurchaseUnit
192
+ * @throws RuntimeException When JSON object is malformed.
193
+ */
194
+ public function from_paypal_response( \stdClass $data ): PurchaseUnit {
195
+ if ( ! isset( $data->reference_id ) || ! is_string( $data->reference_id ) ) {
196
+ throw new RuntimeException(
197
+ __( 'No reference ID given.', 'woocommerce-paypal-payments' )
198
+ );
199
+ }
200
+
201
+ $amount = $this->amount_factory->from_paypal_response( $data->amount );
202
+ $description = ( isset( $data->description ) ) ? $data->description : '';
203
+ $custom_id = ( isset( $data->custom_id ) ) ? $data->custom_id : '';
204
+ $invoice_id = ( isset( $data->invoice_id ) ) ? $data->invoice_id : '';
205
+ $soft_descriptor = ( isset( $data->soft_descriptor ) ) ? $data->soft_descriptor : '';
206
+ $items = array();
207
+ if ( isset( $data->items ) && is_array( $data->items ) ) {
208
+ $items = array_map(
209
+ function ( \stdClass $item ): Item {
210
+ return $this->item_factory->from_paypal_response( $item );
211
+ },
212
+ $data->items
213
+ );
214
+ }
215
+ $payee = isset( $data->payee ) ? $this->payee_factory->from_paypal_response( $data->payee ) : null;
216
+ $shipping = null;
217
+ try {
218
+ if ( isset( $data->shipping ) ) {
219
+ $shipping = $this->shipping_factory->from_paypal_response( $data->shipping );
220
+ }
221
+ } catch ( RuntimeException $error ) {
222
+ ;
223
+ }
224
+ $payments = null;
225
+ try {
226
+ if ( isset( $data->payments ) ) {
227
+ $payments = $this->payments_factory->from_paypal_response( $data->payments );
228
+ }
229
+ } catch ( RuntimeException $error ) {
230
+ ;
231
+ }
232
+
233
+ $purchase_unit = new PurchaseUnit(
234
+ $amount,
235
+ $items,
236
+ $shipping,
237
+ $data->reference_id,
238
+ $description,
239
+ $payee,
240
+ $custom_id,
241
+ $invoice_id,
242
+ $soft_descriptor,
243
+ $payments
244
+ );
245
+ return $purchase_unit;
246
+ }
247
+
248
+ /**
249
+ * Whether we need a shipping address for a set of items or not.
250
+ *
251
+ * @param Item ...$items The items on based which the decision is made.
252
+ *
253
+ * @return bool
254
+ */
255
+ private function shipping_needed( Item ...$items ): bool {
256
+
257
+ foreach ( $items as $item ) {
258
+ if ( $item->category() !== Item::DIGITAL_GOODS ) {
259
+ return true;
260
+ }
261
+ }
262
+ return false;
263
+ }
264
+ }
modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Factory for the SellerStatus object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatus;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
14
+
15
+ /**
16
+ * Class SellerStatusFactory
17
+ */
18
+ class SellerStatusFactory {
19
+
20
+ /**
21
+ * Creates a SellerStatus Object out of a PayPal response.
22
+ *
23
+ * @param \stdClass $json The response object.
24
+ *
25
+ * @return SellerStatus
26
+ */
27
+ public function from_paypal_reponse( \stdClass $json ) : SellerStatus {
28
+ $products = array_map(
29
+ function( $json ) : SellerStatusProduct {
30
+ $product = new SellerStatusProduct(
31
+ isset( $json->name ) ? (string) $json->name : '',
32
+ isset( $json->vetting_status ) ? (string) $json->vetting_status : '',
33
+ isset( $json->capabilities ) ? (array) $json->capabilities : array()
34
+ );
35
+ return $product;
36
+ },
37
+ isset( $json->products ) ? (array) $json->products : array()
38
+ );
39
+
40
+ return new SellerStatus( $products );
41
+ }
42
+ }
modules/ppcp-api-client/src/Factory/class-shippingfactory.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The shipping factory.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+
15
+ /**
16
+ * Class ShippingFactory
17
+ */
18
+ class ShippingFactory {
19
+
20
+ /**
21
+ * The address factory.
22
+ *
23
+ * @var AddressFactory
24
+ */
25
+ private $address_factory;
26
+
27
+ /**
28
+ * ShippingFactory constructor.
29
+ *
30
+ * @param AddressFactory $address_factory The address factory.
31
+ */
32
+ public function __construct( AddressFactory $address_factory ) {
33
+ $this->address_factory = $address_factory;
34
+ }
35
+
36
+ /**
37
+ * Creates a shipping object based off a WooCommerce customer.
38
+ *
39
+ * @param \WC_Customer $customer The WooCommerce customer.
40
+ *
41
+ * @return Shipping
42
+ */
43
+ public function from_wc_customer( \WC_Customer $customer ): Shipping {
44
+ // Replicates the Behavior of \WC_Order::get_formatted_shipping_full_name().
45
+ $full_name = sprintf(
46
+ // translators: %1$s is the first name and %2$s is the second name. wc translation.
47
+ _x( '%1$s %2$s', 'full name', 'woocommerce-paypal-payments' ),
48
+ $customer->get_shipping_first_name(),
49
+ $customer->get_shipping_last_name()
50
+ );
51
+ $address = $this->address_factory->from_wc_customer( $customer );
52
+ return new Shipping(
53
+ $full_name,
54
+ $address
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Creates a Shipping object based off a WooCommerce order.
60
+ *
61
+ * @param \WC_Order $order The WooCommerce order.
62
+ *
63
+ * @return Shipping
64
+ */
65
+ public function from_wc_order( \WC_Order $order ): Shipping {
66
+ $full_name = $order->get_formatted_shipping_full_name();
67
+ $address = $this->address_factory->from_wc_order( $order );
68
+ return new Shipping(
69
+ $full_name,
70
+ $address
71
+ );
72
+ }
73
+
74
+ /**
75
+ * Creates a Shipping object based of from the PayPal JSON response.
76
+ *
77
+ * @param \stdClass $data The JSON object.
78
+ *
79
+ * @return Shipping
80
+ * @throws RuntimeException When JSON object is malformed.
81
+ */
82
+ public function from_paypal_response( \stdClass $data ): Shipping {
83
+ if ( ! isset( $data->name->full_name ) ) {
84
+ throw new RuntimeException(
85
+ __( 'No name was given for shipping.', 'woocommerce-paypal-payments' )
86
+ );
87
+ }
88
+ if ( ! isset( $data->address ) ) {
89
+ throw new RuntimeException(
90
+ __( 'No address was given for shipping.', 'woocommerce-paypal-payments' )
91
+ );
92
+ }
93
+ $address = $this->address_factory->from_paypal_response( $data->address );
94
+ return new Shipping(
95
+ $data->name->full_name,
96
+ $address
97
+ );
98
+ }
99
+ }
modules/ppcp-api-client/src/Factory/class-webhookfactory.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Creates Webhooks.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Factory
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+
15
+ /**
16
+ * Class WebhookFactory
17
+ */
18
+ class WebhookFactory {
19
+
20
+ /**
21
+ * Returns a webhook for a URL with an array of event types associated to this URL.
22
+ *
23
+ * @param string $url The URL.
24
+ * @param array $event_types The event types to which this URL listens to.
25
+ *
26
+ * @return Webhook
27
+ */
28
+ public function for_url_and_events( string $url, array $event_types ): Webhook {
29
+ $event_types = array_map(
30
+ static function ( string $type ): array {
31
+ return array( 'name' => $type );
32
+ },
33
+ $event_types
34
+ );
35
+ return new Webhook(
36
+ $url,
37
+ $event_types
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Returns a webhook from a given data array.
43
+ *
44
+ * @param array $data The data array.
45
+ *
46
+ * @return Webhook
47
+ */
48
+ public function from_array( array $data ): Webhook {
49
+ return $this->from_paypal_response( (object) $data );
50
+ }
51
+
52
+ /**
53
+ * Returns a Webhook based of a PayPal JSON response.
54
+ *
55
+ * @param \stdClass $data The JSON object.
56
+ *
57
+ * @return Webhook
58
+ * @throws RuntimeException When JSON object is malformed.
59
+ */
60
+ public function from_paypal_response( \stdClass $data ): Webhook {
61
+ if ( ! isset( $data->id ) ) {
62
+ throw new RuntimeException(
63
+ __( 'No id for webhook given.', 'woocommerce-paypal-payments' )
64
+ );
65
+ }
66
+ if ( ! isset( $data->url ) ) {
67
+ throw new RuntimeException(
68
+ __( 'No URL for webhook given.', 'woocommerce-paypal-payments' )
69
+ );
70
+ }
71
+ if ( ! isset( $data->event_types ) ) {
72
+ throw new RuntimeException(
73
+ __( 'No event types for webhook given.', 'woocommerce-paypal-payments' )
74
+ );
75
+ }
76
+
77
+ return new Webhook(
78
+ (string) $data->url,
79
+ (array) $data->event_types,
80
+ (string) $data->id
81
+ );
82
+ }
83
+ }
modules/ppcp-api-client/src/Helper/class-cache.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manages caching of values.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Helper
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
11
+
12
+ /**
13
+ * Class Cache
14
+ */
15
+ class Cache {
16
+
17
+ /**
18
+ * The prefix for the value keys.
19
+ *
20
+ * @var string
21
+ */
22
+ private $prefix;
23
+
24
+ /**
25
+ * Cache constructor.
26
+ *
27
+ * @param string $prefix The prefix for the value keys.
28
+ */
29
+ public function __construct( string $prefix ) {
30
+ $this->prefix = $prefix;
31
+ }
32
+
33
+ /**
34
+ * Gets a value.
35
+ *
36
+ * @param string $key The key under which the value is stored.
37
+ *
38
+ * @return mixed
39
+ */
40
+ public function get( string $key ) {
41
+ return get_transient( $this->prefix . $key );
42
+ }
43
+
44
+ /**
45
+ * Whether a value is stored or not.
46
+ *
47
+ * @param string $key The key for the value.
48
+ *
49
+ * @return bool
50
+ */
51
+ public function has( string $key ): bool {
52
+ $value = $this->get( $key );
53
+ return false !== $value;
54
+ }
55
+
56
+ /**
57
+ * Deletes a cache.
58
+ *
59
+ * @param string $key The key.
60
+ */
61
+ public function delete( string $key ) {
62
+ delete_transient( $this->prefix . $key );
63
+ }
64
+
65
+ /**
66
+ * Caches a value.
67
+ *
68
+ * @param string $key The key under which the value should be cached.
69
+ * @param mixed $value The value to cache.
70
+ *
71
+ * @return bool
72
+ */
73
+ public function set( string $key, $value ): bool {
74
+ return (bool) set_transient( $this->prefix . $key, $value );
75
+ }
76
+ }
modules/ppcp-api-client/src/Helper/class-dccapplies.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The DCC Applies helper checks if the current installation can use DCC or not.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Helper
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
11
+
12
+ /**
13
+ * Class DccApplies
14
+ */
15
+ class DccApplies {
16
+
17
+ /**
18
+ * The matrix which countries and currency combinations can be used for DCC.
19
+ *
20
+ * @var array
21
+ */
22
+ private $allowed_country_currency_matrix = array(
23
+ 'AU' => array(
24
+ 'AUD',
25
+ 'CAD',
26
+ 'CHF',
27
+ 'CZK',
28
+ 'DKK',
29
+ 'EUR',
30
+ 'GBP',
31
+ 'HKD',
32
+ 'HUF',
33
+ 'JPY',
34
+ 'NOK',
35
+ 'NZD',
36
+ 'PLN',
37
+ 'SEK',
38
+ 'SGD',
39
+ 'USD',
40
+ ),
41
+ 'ES' => array(
42
+ 'AUD',
43
+ 'CAD',
44
+ 'CHF',
45
+ 'CZK',
46
+ 'DKK',
47
+ 'EUR',
48
+ 'GBP',
49
+ 'HKD',
50
+ 'HUF',
51
+ 'JPY',
52
+ 'NOK',
53
+ 'NZD',
54
+ 'PLN',
55
+ 'SEK',
56
+ 'SGD',
57
+ 'USD',
58
+ ),
59
+ 'FR' => array(
60
+ 'AUD',
61
+ 'CAD',
62
+ 'CHF',
63
+ 'CZK',
64
+ 'DKK',
65
+ 'EUR',
66
+ 'GBP',
67
+ 'HKD',
68
+ 'HUF',
69
+ 'JPY',
70
+ 'NOK',
71
+ 'NZD',
72
+ 'PLN',
73
+ 'SEK',
74
+ 'SGD',
75
+ 'USD',
76
+ ),
77
+ 'GB' => array(
78
+ 'AUD',
79
+ 'CAD',
80
+ 'CHF',
81
+ 'CZK',
82
+ 'DKK',
83
+ 'EUR',
84
+ 'GBP',
85
+ 'HKD',
86
+ 'HUF',
87
+ 'JPY',
88
+ 'NOK',
89
+ 'NZD',
90
+ 'PLN',
91
+ 'SEK',
92
+ 'SGD',
93
+ 'USD',
94
+ ),
95
+ 'IT' => array(
96
+ 'AUD',
97
+ 'CAD',
98
+ 'CHF',
99
+ 'CZK',
100
+ 'DKK',
101
+ 'EUR',
102
+ 'GBP',
103
+ 'HKD',
104
+ 'HUF',
105
+ 'JPY',
106
+ 'NOK',
107
+ 'NZD',
108
+ 'PLN',
109
+ 'SEK',
110
+ 'SGD',
111
+ 'USD',
112
+ ),
113
+ 'US' => array(
114
+ 'AUD',
115
+ 'CAD',
116
+ 'EUR',
117
+ 'GBP',
118
+ 'JPY',
119
+ 'USD',
120
+ ),
121
+ );
122
+
123
+ /**
124
+ * Which countries support which credit cards. Empty credit card arrays mean no restriction on
125
+ * currency. Otherwise only the currencies in the array are supported.
126
+ *
127
+ * @var array
128
+ */
129
+ private $country_card_matrix = array(
130
+ 'AU' => array(
131
+ 'mastercard' => array(),
132
+ 'visa' => array(),
133
+ ),
134
+ 'ES' => array(
135
+ 'mastercard' => array(),
136
+ 'visa' => array(),
137
+ 'amex' => array( 'EUR' ),
138
+ ),
139
+ 'FR' => array(
140
+ 'mastercard' => array(),
141
+ 'visa' => array(),
142
+ 'amex' => array( 'EUR' ),
143
+ ),
144
+ 'GB' => array(
145
+ 'mastercard' => array(),
146
+ 'visa' => array(),
147
+ 'amex' => array( 'GBP', 'USD' ),
148
+ ),
149
+ 'IT' => array(
150
+ 'mastercard' => array(),
151
+ 'visa' => array(),
152
+ 'amex' => array( 'EUR' ),
153
+ ),
154
+ 'US' => array(
155
+ 'mastercard' => array(),
156
+ 'visa' => array(),
157
+ 'amex' => array( 'USD' ),
158
+ 'discover' => array( 'USD' ),
159
+ ),
160
+ );
161
+
162
+ /**
163
+ * Returns whether DCC can be used in the current country and the current currency used.
164
+ *
165
+ * @return bool
166
+ */
167
+ public function for_country_currency(): bool {
168
+ $country = $this->country();
169
+ $currency = get_woocommerce_currency();
170
+ if ( ! in_array( $country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
171
+ return false;
172
+ }
173
+ $applies = in_array( $currency, $this->allowed_country_currency_matrix[ $country ], true );
174
+ return $applies;
175
+ }
176
+
177
+ /**
178
+ * Returns credit cards, which can be used.
179
+ *
180
+ * @return array
181
+ */
182
+ public function valid_cards() : array {
183
+ $country = $this->country();
184
+ $cards = array();
185
+ if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
186
+ return $cards;
187
+ }
188
+
189
+ $supported_currencies = $this->country_card_matrix[ $country ];
190
+ foreach ( $supported_currencies as $card => $currencies ) {
191
+ if ( $this->can_process_card( $card ) ) {
192
+ $cards[] = $card;
193
+ }
194
+ }
195
+ if ( in_array( 'amex', $cards, true ) ) {
196
+ $cards[] = 'american-express';
197
+ }
198
+ if ( in_array( 'mastercard', $cards, true ) ) {
199
+ $cards[] = 'master-card';
200
+ }
201
+ return $cards;
202
+ }
203
+
204
+ /**
205
+ * Whether a card can be used or not.
206
+ *
207
+ * @param string $card The card.
208
+ *
209
+ * @return bool
210
+ */
211
+ public function can_process_card( string $card ) : bool {
212
+ $country = $this->country();
213
+ if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
214
+ return false;
215
+ }
216
+ if ( ! isset( $this->country_card_matrix[ $country ][ $card ] ) ) {
217
+ return false;
218
+ }
219
+
220
+ /**
221
+ * If the supported currencies array is empty, there are no
222
+ * restrictions, which currencies are supported by a card.
223
+ */
224
+ $supported_currencies = $this->country_card_matrix[ $country ][ $card ];
225
+ $currency = get_woocommerce_currency();
226
+ return empty( $supported_currencies ) || in_array( $currency, $supported_currencies, true );
227
+ }
228
+
229
+ /**
230
+ * Returns the country code of the shop.
231
+ *
232
+ * @return string
233
+ */
234
+ private function country() : string {
235
+ $region = wc_get_base_location();
236
+ $country = $region['country'];
237
+ return $country;
238
+ }
239
+ }
modules/ppcp-api-client/src/Helper/class-errorresponse.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A Collection of all error responses for the order endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Helper
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
11
+
12
+ /**
13
+ * Class ErrorResponse
14
+ */
15
+ class ErrorResponse {
16
+
17
+ const UNKNOWN = 'UNKNOWN';
18
+
19
+ /* Order error codes */
20
+ const ACTION_DOES_NOT_MATCH_INTENT = 'ACTION_DOES_NOT_MATCH_INTENT';
21
+ const AGREEMENT_ALREADY_CANCELLED = 'AGREEMENT_ALREADY_CANCELLED';
22
+ const AMOUNT_CANNOT_BE_SPECIFIED = 'AMOUNT_CANNOT_BE_SPECIFIED';
23
+ const AMOUNT_MISMATCH = 'AMOUNT_MISMATCH';
24
+ const AMOUNT_NOT_PATCHABLE = 'AMOUNT_NOT_PATCHABLE';
25
+ const AUTH_CAPTURE_NOT_ENABLED = 'AUTH_CAPTURE_NOT_ENABLED';
26
+ const AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE';
27
+ const AUTHORIZATION_AMOUNT_EXCEEDED = 'AUTHORIZATION_AMOUNT_EXCEEDED';
28
+ const AUTHORIZATION_CURRENCY_MISMATCH = 'AUTHORIZATION_CURRENCY_MISMATCH';
29
+ const BILLING_AGREEMENT_NOT_FOUND = 'BILLING_AGREEMENT_NOT_FOUND';
30
+ const CANNOT_BE_NEGATIVE = 'CANNOT_BE_NEGATIVE';
31
+ const CANNOT_BE_ZERO_OR_NEGATIVE = 'CANNOT_BE_ZERO_OR_NEGATIVE';
32
+ const CARD_TYPE_NOT_SUPPORTED = 'CARD_TYPE_NOT_SUPPORTED';
33
+ const INVALID_SECURITY_CODE_LENGTH = 'INVALID_SECURITY_CODE_LENGTH';
34
+ const CITY_REQUIRED = 'CITY_REQUIRED';
35
+ const COMPLIANCE_VIOLATION = 'COMPLIANCE_VIOLATION';
36
+ const CONSENT_NEEDED = 'CONSENT_NEEDED';
37
+ const CURRENCY_NOT_SUPPORTED_FOR_CARD_TYPE = 'CURRENCY_NOT_SUPPORTED_FOR_CARD_TYPE';
38
+ const CURRENCY_NOT_SUPPORTED_FOR_COUNTRY = 'CURRENCY_NOT_SUPPORTED_FOR_COUNTRY';
39
+ const DECIMAL_PRECISION = 'DECIMAL_PRECISION';
40
+ const DOMESTIC_TRANSACTION_REQUIRED = 'DOMESTIC_TRANSACTION_REQUIRED';
41
+ const DUPLICATE_INVOICE_ID = 'DUPLICATE_INVOICE_ID';
42
+ const DUPLICATE_REQUEST_ID = 'DUPLICATE_REQUEST_ID';
43
+ const FIELD_NOT_PATCHABLE = 'FIELD_NOT_PATCHABLE';
44
+ const INSTRUMENT_DECLINED = 'INSTRUMENT_DECLINED';
45
+ const INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR';
46
+ const INTERNAL_SERVICE_ERROR = 'INTERNAL_SERVICE_ERROR';
47
+ const INVALID_ACCOUNT_STATUS = 'INVALID_ACCOUNT_STATUS';
48
+ const INVALID_ARRAY_MAX_ITEMS = 'INVALID_ARRAY_MAX_ITEMS';
49
+ const INVALID_ARRAY_MIN_ITEMS = 'INVALID_ARRAY_MIN_ITEMS';
50
+ const INVALID_COUNTRY_CODE = 'INVALID_COUNTRY_CODE';
51
+ const INVALID_CURRENCY_CODE = 'INVALID_CURRENCY_CODE';
52
+ const INVALID_JSON_POINTER_FORMAT = 'INVALID_JSON_POINTER_FORMAT';
53
+ const INVALID_PARAMETER_SYNTAX = 'INVALID_PARAMETER_SYNTAX';
54
+ const INVALID_PARAMETER_VALUE = 'INVALID_PARAMETER_VALUE';
55
+ const INVALID_PARAMETER = 'INVALID_PARAMETER';
56
+ const INVALID_PATCH_OPERATION = 'INVALID_PATCH_OPERATION';
57
+ const INVALID_PAYER_ID = 'INVALID_PAYER_ID';
58
+ const INVALID_RESOURCE_ID = 'INVALID_RESOURCE_ID';
59
+ const INVALID_STRING_LENGTH = 'INVALID_STRING_LENGTH';
60
+ const ITEM_TOTAL_MISMATCH = 'ITEM_TOTAL_MISMATCH';
61
+ const ITEM_TOTAL_REQUIRED = 'ITEM_TOTAL_REQUIRED';
62
+ const MAX_AUTHORIZATION_COUNT_EXCEEDED = 'MAX_AUTHORIZATION_COUNT_EXCEEDED';
63
+ const MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED = 'MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED';
64
+ const MAX_VALUE_EXCEEDED = 'MAX_VALUE_EXCEEDED';
65
+ const MISSING_REQUIRED_PARAMETER = 'MISSING_REQUIRED_PARAMETER';
66
+ const MISSING_SHIPPING_ADDRESS = 'MISSING_SHIPPING_ADDRESS';
67
+ const MULTI_CURRENCY_ORDER = 'MULTI_CURRENCY_ORDER';
68
+ const MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED = 'MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED';
69
+ const MULTIPLE_SHIPPING_OPTION_SELECTED = 'MULTIPLE_SHIPPING_OPTION_SELECTED';
70
+ const INVALID_PICKUP_ADDRESS = 'INVALID_PICKUP_ADDRESS';
71
+ const NOT_AUTHORIZED = 'NOT_AUTHORIZED';
72
+ const NOT_ENABLED_FOR_CARD_PROCESSING = 'NOT_ENABLED_FOR_CARD_PROCESSING';
73
+ const NOT_PATCHABLE = 'NOT_PATCHABLE';
74
+ const NOT_SUPPORTED = 'NOT_SUPPORTED';
75
+ const ORDER_ALREADY_AUTHORIZED = 'ORDER_ALREADY_AUTHORIZED';
76
+ const ORDER_ALREADY_CAPTURED = 'ORDER_ALREADY_CAPTURED';
77
+ const ORDER_ALREADY_COMPLETED = 'ORDER_ALREADY_COMPLETED';
78
+ const ORDER_CANNOT_BE_SAVED = 'ORDER_CANNOT_BE_SAVED';
79
+ const ORDER_COMPLETED_OR_VOIDED = 'ORDER_COMPLETED_OR_VOIDED';
80
+ const ORDER_EXPIRED = 'ORDER_EXPIRED';
81
+ const ORDER_NOT_APPROVED = 'ORDER_NOT_APPROVED';
82
+ const ORDER_NOT_SAVED = 'ORDER_NOT_SAVED';
83
+ const ORDER_PREVIOUSLY_VOIDED = 'ORDER_PREVIOUSLY_VOIDED';
84
+ const PARAMETER_VALUE_NOT_SUPPORTED = 'PARAMETER_VALUE_NOT_SUPPORTED';
85
+ const PATCH_PATH_REQUIRED = 'PATCH_PATH_REQUIRED';
86
+ const PATCH_VALUE_REQUIRED = 'PATCH_VALUE_REQUIRED';
87
+ const PAYEE_ACCOUNT_INVALID = 'PAYEE_ACCOUNT_INVALID';
88
+ const PAYEE_ACCOUNT_LOCKED_OR_CLOSED = 'PAYEE_ACCOUNT_LOCKED_OR_CLOSED';
89
+ const PAYEE_ACCOUNT_RESTRICTED = 'PAYEE_ACCOUNT_RESTRICTED';
90
+ const PAYEE_BLOCKED_TRANSACTION = 'PAYEE_BLOCKED_TRANSACTION';
91
+ const PAYER_ACCOUNT_LOCKED_OR_CLOSED = 'PAYER_ACCOUNT_LOCKED_OR_CLOSED';
92
+ const PAYER_ACCOUNT_RESTRICTED = 'PAYER_ACCOUNT_RESTRICTED';
93
+ const PAYER_CANNOT_PAY = 'PAYER_CANNOT_PAY';
94
+ const PAYER_CONSENT_REQUIRED = 'PAYER_CONSENT_REQUIRED';
95
+ const PAYER_COUNTRY_NOT_SUPPORTED = 'PAYER_COUNTRY_NOT_SUPPORTED';
96
+ const PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING = 'PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING';
97
+ const PAYMENT_INSTRUCTION_REQUIRED = 'PAYMENT_INSTRUCTION_REQUIRED';
98
+ const PERMISSION_DENIED = 'PERMISSION_DENIED';
99
+ const POSTAL_CODE_REQUIRED = 'POSTAL_CODE_REQUIRED';
100
+ const PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH = 'PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH';
101
+ const REDIRECT_PAYER_FOR_ALTERNATE_FUNDING = 'REDIRECT_PAYER_FOR_ALTERNATE_FUNDING';
102
+ const REFERENCE_ID_NOT_FOUND = 'REFERENCE_ID_NOT_FOUND';
103
+ const REFERENCE_ID_REQUIRED = 'REFERENCE_ID_REQUIRED';
104
+ const DUPLICATE_REFERENCE_ID = 'DUPLICATE_REFERENCE_ID';
105
+ const SHIPPING_ADDRESS_INVALID = 'SHIPPING_ADDRESS_INVALID';
106
+ const SHIPPING_OPTION_NOT_SELECTED = 'SHIPPING_OPTION_NOT_SELECTED';
107
+ const SHIPPING_OPTIONS_NOT_SUPPORTED = 'SHIPPING_OPTIONS_NOT_SUPPORTED';
108
+ const TAX_TOTAL_MISMATCH = 'TAX_TOTAL_MISMATCH';
109
+ const TAX_TOTAL_REQUIRED = 'TAX_TOTAL_REQUIRED';
110
+ const TRANSACTION_AMOUNT_EXCEEDS_MONTHLY_MAX_LIMIT = 'TRANSACTION_AMOUNT_EXCEEDS_MONTHLY_MAX_LIMIT';
111
+ const TRANSACTION_BLOCKED_BY_PAYEE = 'TRANSACTION_BLOCKED_BY_PAYEE';
112
+ const TRANSACTION_LIMIT_EXCEEDED = 'TRANSACTION_LIMIT_EXCEEDED';
113
+ const TRANSACTION_RECEIVING_LIMIT_EXCEEDED = 'TRANSACTION_RECEIVING_LIMIT_EXCEEDED';
114
+ const TRANSACTION_REFUSED = 'TRANSACTION_REFUSED';
115
+ const UNSUPPORTED_INTENT = 'UNSUPPORTED_INTENT';
116
+ const UNSUPPORTED_PATCH_PARAMETER_VALUE = 'UNSUPPORTED_PATCH_PARAMETER_VALUE';
117
+ const UNSUPPORTED_PAYMENT_INSTRUCTION = 'UNSUPPORTED_PAYMENT_INSTRUCTION';
118
+ const PAYEE_ACCOUNT_NOT_SUPPORTED = 'PAYEE_ACCOUNT_NOT_SUPPORTED';
119
+ const PAYEE_ACCOUNT_NOT_VERIFIED = 'PAYEE_ACCOUNT_NOT_VERIFIED';
120
+ const PAYEE_NOT_CONSENTED = 'PAYEE_NOT_CONSENTED';
121
+ }
modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Returns the current application context.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
14
+ use Psr\Container\ContainerInterface;
15
+
16
+ /**
17
+ * Class ApplicationContextRepository
18
+ */
19
+ class ApplicationContextRepository {
20
+
21
+ /**
22
+ * The Settings.
23
+ *
24
+ * @var ContainerInterface
25
+ */
26
+ private $settings;
27
+
28
+ /**
29
+ * ApplicationContextRepository constructor.
30
+ *
31
+ * @param ContainerInterface $settings The settings.
32
+ */
33
+ public function __construct( ContainerInterface $settings ) {
34
+ $this->settings = $settings;
35
+ }
36
+
37
+ /**
38
+ * Returns the current application context.
39
+ *
40
+ * @param string $shipping_preferences The shipping preferences.
41
+ *
42
+ * @return ApplicationContext
43
+ */
44
+ public function current_context(
45
+ string $shipping_preferences = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING
46
+ ): ApplicationContext {
47
+
48
+ $brand_name = $this->settings->has( 'brand_name' ) ? $this->settings->get( 'brand_name' ) : '';
49
+ $locale = str_replace( '_', '-', get_user_locale() );
50
+ $landingpage = $this->settings->has( 'landing_page' ) ?
51
+ $this->settings->get( 'landing_page' ) : ApplicationContext::LANDING_PAGE_NO_PREFERENCE;
52
+ $context = new ApplicationContext(
53
+ (string) home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) ),
54
+ (string) wc_get_checkout_url(),
55
+ (string) $brand_name,
56
+ $locale,
57
+ (string) $landingpage,
58
+ $shipping_preferences
59
+ );
60
+ return $context;
61
+ }
62
+ }
modules/ppcp-api-client/src/Repository/class-cartrepository.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The cart repository returns the purchase units from the current \WC_Cart.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
15
+
16
+ /**
17
+ * Class CartRepository
18
+ */
19
+ class CartRepository implements PurchaseUnitRepositoryInterface {
20
+
21
+ /**
22
+ * The purchase unit factory.
23
+ *
24
+ * @var PurchaseUnitFactory
25
+ */
26
+ private $factory;
27
+
28
+ /**
29
+ * CartRepository constructor.
30
+ *
31
+ * @param PurchaseUnitFactory $factory The purchase unit factory.
32
+ */
33
+ public function __construct( PurchaseUnitFactory $factory ) {
34
+ $this->factory = $factory;
35
+ }
36
+
37
+ /**
38
+ * Returns all Pur of the WooCommerce cart.
39
+ *
40
+ * @return PurchaseUnit[]
41
+ */
42
+ public function all(): array {
43
+ $cart = WC()->cart ?? new \WC_Cart();
44
+ return array( $this->factory->from_wc_cart( $cart ) );
45
+ }
46
+ }
modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The partner referrals data object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
13
+
14
+ /**
15
+ * Class PartnerReferralsData
16
+ */
17
+ class PartnerReferralsData {
18
+
19
+ /**
20
+ * The merchant email.
21
+ *
22
+ * @var string
23
+ */
24
+ private $merchant_email;
25
+
26
+ /**
27
+ * The DCC Applies Helper object.
28
+ *
29
+ * @var DccApplies
30
+ */
31
+ private $dcc_applies;
32
+
33
+ /**
34
+ * PartnerReferralsData constructor.
35
+ *
36
+ * @param string $merchant_email The email of the merchant.
37
+ * @param DccApplies $dcc_applies The DCC Applies helper.
38
+ */
39
+ public function __construct(
40
+ string $merchant_email,
41
+ DccApplies $dcc_applies
42
+ ) {
43
+
44
+ $this->merchant_email = $merchant_email;
45
+ $this->dcc_applies = $dcc_applies;
46
+ }
47
+
48
+ /**
49
+ * Returns a nonce.
50
+ *
51
+ * @return string
52
+ */
53
+ public function nonce(): string {
54
+ return 'a1233wtergfsdt4365tzrshgfbaewa36AGa1233wtergfsdt4365tzrshgfbaewa36AG';
55
+ }
56
+
57
+ /**
58
+ * Returns the data.
59
+ *
60
+ * @return array
61
+ */
62
+ public function data(): array {
63
+ $data = $this->default_data();
64
+ return $data;
65
+ }
66
+
67
+ /**
68
+ * Returns the default data.
69
+ *
70
+ * @return array
71
+ */
72
+ private function default_data(): array {
73
+
74
+ return array(
75
+ 'partner_config_override' => array(
76
+ 'partner_logo_url' => 'https://connect.woocommerce.com/images/woocommerce_logo.png',
77
+ 'return_url' => admin_url(
78
+ 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway'
79
+ ),
80
+ 'return_url_description' => __(
81
+ 'Return to your shop.',
82
+ 'woocommerce-paypal-payments'
83
+ ),
84
+ 'show_add_credit_card' => true,
85
+ ),
86
+ 'products' => array(
87
+ $this->dcc_applies->for_country_currency() ? 'PPCP' : 'EXPRESS_CHECKOUT',
88
+ ),
89
+ 'legal_consents' => array(
90
+ array(
91
+ 'type' => 'SHARE_DATA_CONSENT',
92
+ 'granted' => true,
93
+ ),
94
+ ),
95
+ 'operations' => array(
96
+ array(
97
+ 'operation' => 'API_INTEGRATION',
98
+ 'api_integration_preference' => array(
99
+ 'rest_api_integration' => array(
100
+ 'integration_method' => 'PAYPAL',
101
+ 'integration_type' => 'FIRST_PARTY',
102
+ 'first_party_details' => array(
103
+ 'features' => array(
104
+ 'PAYMENT',
105
+ 'FUTURE_PAYMENT',
106
+ 'REFUND',
107
+ 'ADVANCED_TRANSACTIONS_SEARCH',
108
+ ),
109
+ 'seller_nonce' => $this->nonce(),
110
+ ),
111
+ ),
112
+ ),
113
+ ),
114
+ ),
115
+ );
116
+ }
117
+ }
modules/ppcp-api-client/src/Repository/class-payeerepository.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Payee Repository.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payee;
13
+
14
+ /**
15
+ * Class PayeeRepository
16
+ */
17
+ class PayeeRepository {
18
+
19
+ /**
20
+ * The merchant email.
21
+ *
22
+ * @var string
23
+ */
24
+ private $merchant_email;
25
+
26
+ /**
27
+ * The merchant ID.
28
+ *
29
+ * @var string
30
+ */
31
+ private $merchant_id;
32
+
33
+ /**
34
+ * PayeeRepository constructor.
35
+ *
36
+ * @param string $merchant_email The email of the merchant.
37
+ * @param string $merchant_id The ID of the merchant.
38
+ */
39
+ public function __construct( string $merchant_email, string $merchant_id ) {
40
+ $this->merchant_email = $merchant_email;
41
+ $this->merchant_id = $merchant_id;
42
+ }
43
+
44
+ /**
45
+ * Returns the current Payee.
46
+ *
47
+ * @return Payee
48
+ */
49
+ public function payee(): Payee {
50
+ return new Payee(
51
+ $this->merchant_email,
52
+ $this->merchant_id
53
+ );
54
+ }
55
+ }
modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The repository for the request IDs.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+
14
+ /**
15
+ * Class PayPalRequestIdRepository
16
+ */
17
+ class PayPalRequestIdRepository {
18
+
19
+ const KEY = 'ppcp-request-ids';
20
+
21
+ /**
22
+ * Returns a request ID based on the order ID.
23
+ *
24
+ * @param string $order_id The order ID.
25
+ *
26
+ * @return string
27
+ */
28
+ public function get_for_order_id( string $order_id ): string {
29
+ $all = $this->all();
30
+ return isset( $all[ $order_id ] ) ? (string) $all[ $order_id ]['id'] : '';
31
+ }
32
+
33
+ /**
34
+ * Returns the request ID for an order.
35
+ *
36
+ * @param Order $order The order.
37
+ *
38
+ * @return string
39
+ */
40
+ public function get_for_order( Order $order ): string {
41
+ return $this->get_for_order_id( $order->id() );
42
+ }
43
+
44
+ /**
45
+ * Sets a request ID for a specific order.
46
+ *
47
+ * @param Order $order The order.
48
+ * @param string $request_id The ID.
49
+ *
50
+ * @return bool
51
+ */
52
+ public function set_for_order( Order $order, string $request_id ): bool {
53
+ $all = $this->all();
54
+ $all[ $order->id() ] = array(
55
+ 'id' => $request_id,
56
+ 'expiration' => time() + 10 * DAY_IN_SECONDS,
57
+ );
58
+ $all = $this->cleanup( $all );
59
+ update_option( self::KEY, $all );
60
+ return true;
61
+ }
62
+
63
+ /**
64
+ * Return all IDs.
65
+ *
66
+ * @return array
67
+ */
68
+ private function all(): array {
69
+
70
+ return (array) get_option( 'ppcp-request-ids', array() );
71
+ }
72
+
73
+ /**
74
+ * Clean up outdated request IDs.
75
+ *
76
+ * @param array $all All request IDs.
77
+ *
78
+ * @return array
79
+ */
80
+ private function cleanup( array $all ): array {
81
+
82
+ foreach ( $all as $order_id => $value ) {
83
+ if ( time() < $value['expiration'] ) {
84
+ continue;
85
+ }
86
+ unset( $all[ $order_id ] );
87
+ }
88
+ return $all;
89
+ }
90
+ }
modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Purchase Unit Repository interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
13
+
14
+ /**
15
+ * Interface PurchaseUnitRepositoryInterface
16
+ */
17
+ interface PurchaseUnitRepositoryInterface {
18
+
19
+
20
+ /**
21
+ * Returns all purchase units.
22
+ *
23
+ * @return PurchaseUnit[]
24
+ */
25
+ public function all(): array;
26
+ }
modules/ppcp-api-client/src/class-apimodule.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The API module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\Exception\ModuleExceptionInterface;
14
+ use Dhii\Modular\Module\ModuleInterface;
15
+ use Interop\Container\ServiceProviderInterface;
16
+ use Psr\Container\ContainerInterface;
17
+
18
+ /**
19
+ * Class ApiModule
20
+ */
21
+ class ApiModule implements ModuleInterface {
22
+
23
+ /**
24
+ * Sets up the module.
25
+ *
26
+ * @return ServiceProviderInterface
27
+ */
28
+ public function setup(): ServiceProviderInterface {
29
+ return new ServiceProvider(
30
+ require __DIR__ . '/../services.php',
31
+ require __DIR__ . '/../extensions.php'
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Runs the module.
37
+ *
38
+ * @param ContainerInterface $container The container.
39
+ */
40
+ public function run( ContainerInterface $container = null ) {
41
+ }
42
+
43
+ /**
44
+ * Returns the key for the module.
45
+ *
46
+ * @return string|void
47
+ */
48
+ public function getKey() {
49
+ }
50
+ }
modules/ppcp-button/assets/css/hosted-fields.css ADDED
@@ -0,0 +1 @@
 
1
+ #payment ul.payment_methods li img.ppcp-card-icon{padding:0 0 3px 3px;max-height:25px;display:inline-block}
modules/ppcp-button/assets/js/button.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([,function(e,t,r){"use strict";r.r(t);var n=class{constructor(e){this.genericErrorText=e,this.wrapper=document.querySelector(".woocommerce-notices-wrapper")}genericError(){this.wrapper.classList.contains("ppcp-persist")||(this.clear(),this.message(this.genericErrorText))}message(e,t=!1){this.wrapper.classList.add("woocommerce-error"),t?this.wrapper.classList.add("ppcp-persist"):this.wrapper.classList.remove("ppcp-persist"),this.wrapper.innerText=this.sanitize(e),jQuery.scroll_to_notices(jQuery(".woocommerce-notices-wrapper"))}sanitize(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value.replace("Error: ","")}clear(){this.wrapper.classList.contains("woocommerce-error")&&(this.wrapper.classList.remove("woocommerce-error"),this.wrapper.innerText="")}};var a=(e,t)=>(r,n)=>fetch(e.config.ajax.approve_order.endpoint,{method:"POST",body:JSON.stringify({nonce:e.config.ajax.approve_order.nonce,order_id:r.orderID})}).then(e=>e.json()).then(r=>{if(!r.success)return t.genericError(),n.restart().catch(e=>{t.genericError()});location.href=e.config.redirect});const o=()=>{const e=PayPalCommerceGateway.payer;if(!e)return null;const t=document.querySelector("#billing_phone")||void 0!==e.phone?{phone_type:"HOME",phone_number:{national_number:document.querySelector("#billing_phone")?document.querySelector("#billing_phone").value:e.phone.phone_number.national_number}}:null,r={email_address:document.querySelector("#billing_email")?document.querySelector("#billing_email").value:e.email_address,name:{surname:document.querySelector("#billing_last_name")?document.querySelector("#billing_last_name").value:e.name.surname,given_name:document.querySelector("#billing_first_name")?document.querySelector("#billing_first_name").value:e.name.given_name},address:{country_code:document.querySelector("#billing_country")?document.querySelector("#billing_country").value:e.address.country_code,address_line_1:document.querySelector("#billing_address_1")?document.querySelector("#billing_address_1").value:e.address.address_line_1,address_line_2:document.querySelector("#billing_address_2")?document.querySelector("#billing_address_2").value:e.address.address_line_2,admin_area_1:document.querySelector("#billing_state")?document.querySelector("#billing_state").value:e.address.admin_area_1,admin_area_2:document.querySelector("#billing_city")?document.querySelector("#billing_city").value:e.address.admin_area_2,postal_code:document.querySelector("#billing_postcode")?document.querySelector("#billing_postcode").value:e.address.postal_code}};return t&&(r.phone=t),r};var s=class{constructor(e,t){this.config=e,this.errorHandler=t}configuration(){return{createOrder:(e,t)=>{const r=o(),n=void 0!==this.config.bn_codes[this.config.context]?this.config.bn_codes[this.config.context]:"";return fetch(this.config.ajax.create_order.endpoint,{method:"POST",body:JSON.stringify({nonce:this.config.ajax.create_order.nonce,purchase_units:[],bn_code:n,payer:r,context:this.config.context})}).then((function(e){return e.json()})).then((function(e){if(!e.success)throw console.error(e),Error(e.data.message);return e.data.id}))},onApprove:a(this,this.errorHandler),onError:e=>{this.errorHandler.genericError()}}}};var i=class{constructor(e,t){this.gateway=e,this.renderer=t,this.actionHandler=null}init(){this.actionHandler=new s(PayPalCommerceGateway,new n(this.gateway.labels.error.generic)),this.render(),jQuery(document.body).on("wc_fragments_loaded wc_fragments_refreshed",()=>{this.render()})}shouldRender(){return null!==document.querySelector(this.gateway.button.mini_cart_wrapper)||null!==document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper)}render(){this.shouldRender()&&this.renderer.render(this.gateway.button.mini_cart_wrapper,this.gateway.hosted_fields.mini_cart_wrapper,this.actionHandler.configuration())}};var c=class{constructor(e,t,r){this.id=e,this.quantity=t,this.variations=r}data(){return{id:this.id,quantity:this.quantity,variations:this.variations}}};var d=class{constructor(e,t){this.endpoint=e,this.nonce=t}update(e,t){return new Promise((r,n)=>{fetch(this.endpoint,{method:"POST",body:JSON.stringify({nonce:this.nonce,products:t})}).then(e=>e.json()).then(t=>{if(!t.success)return void n(t.data);const a=e(t.data);r(a)})})}};var u=class{constructor(e,t,r){this.element=e,this.showCallback=t,this.hideCallback=r,this.observer=null}init(){const e=()=>{this.element.classList.contains("disabled")?this.hideCallback():this.showCallback()};this.observer=new MutationObserver(e),this.observer.observe(this.element,{attributes:!0}),e()}disconnect(){this.observer.disconnect()}};var l=class{constructor(e,t,r,n,a,o){this.config=e,this.updateCart=t,this.showButtonCallback=r,this.hideButtonCallback=n,this.formElement=a,this.errorHandler=o}configuration(){if(this.hasVariations()){new u(this.formElement.querySelector(".single_add_to_cart_button"),this.showButtonCallback,this.hideButtonCallback).init()}return{createOrder:this.createOrder(),onApprove:a(this,this.errorHandler),onError:e=>{this.errorHandler.genericError()}}}createOrder(){var e=null;e=this.isGroupedProduct()?()=>{const e=[];return this.formElement.querySelectorAll('input[type="number"]').forEach(t=>{if(!t.value)return;const r=t.getAttribute("name").match(/quantity\[([\d]*)\]/);if(2!==r.length)return;const n=parseInt(r[1]),a=parseInt(t.value);e.push(new c(n,a,null))}),e}:()=>{const e=document.querySelector('[name="add-to-cart"]').value,t=document.querySelector('[name="quantity"]').value,r=this.variations();return[new c(e,t,r)]};return(t,r)=>{this.errorHandler.clear();return this.updateCart.update(e=>{const t=o(),r=void 0!==this.config.bn_codes[this.config.context]?this.config.bn_codes[this.config.context]:"";return fetch(this.config.ajax.create_order.endpoint,{method:"POST",body:JSON.stringify({nonce:this.config.ajax.create_order.nonce,purchase_units:e,payer:t,bn_code:r,context:this.config.context})}).then((function(e){return e.json()})).then((function(e){if(!e.success)throw console.error(e),Error(e.data.message);return e.data.id}))},e())}}variations(){if(!this.hasVariations())return null;return[...this.formElement.querySelectorAll("[name^='attribute_']")].map(e=>({value:e.value,name:e.name}))}hasVariations(){return this.formElement.classList.contains("variations_form")}isGroupedProduct(){return this.formElement.classList.contains("grouped_form")}};var h=class{constructor(e,t,r){this.gateway=e,this.renderer=t,this.messages=r}init(){this.shouldRender()?this.render():this.renderer.hideButtons(this.gateway.hosted_fields.wrapper)}shouldRender(){return null!==document.querySelector("form.cart")}render(){const e=new l(this.gateway,new d(this.gateway.ajax.change_cart.endpoint,this.gateway.ajax.change_cart.nonce),()=>{this.renderer.showButtons(this.gateway.button.wrapper),this.renderer.showButtons(this.gateway.hosted_fields.wrapper);let e="0";document.querySelector("form.cart ins .woocommerce-Price-amount")?e=document.querySelector("form.cart ins .woocommerce-Price-amount").innerText:document.querySelector("form.cart .woocommerce-Price-amount")&&(e=document.querySelector("form.cart .woocommerce-Price-amount").innerText);const t=parseInt(e.replace(/([^\d,\.\s]*)/g,""));this.messages.renderWithAmount(t)},()=>{this.renderer.hideButtons(this.gateway.button.wrapper),this.renderer.hideButtons(this.gateway.hosted_fields.wrapper)},document.querySelector("form.cart"),new n(this.gateway.labels.error.generic));this.renderer.render(this.gateway.button.wrapper,this.gateway.hosted_fields.wrapper,e.configuration())}};var p=class{constructor(e,t){this.gateway=e,this.renderer=t}init(){this.shouldRender()&&(this.render(),jQuery(document.body).on("updated_cart_totals updated_checkout",()=>{this.render()}))}shouldRender(){return null!==document.querySelector(this.gateway.button.wrapper)||null!==document.querySelector(this.gateway.hosted_fields.wrapper)}render(){const e=new s(PayPalCommerceGateway,new n(this.gateway.labels.error.generic));this.renderer.render(this.gateway.button.wrapper,this.gateway.hosted_fields.wrapper,e.configuration())}};var y=(e,t,r)=>(n,a)=>(r.block(),fetch(e.config.ajax.approve_order.endpoint,{method:"POST",body:JSON.stringify({nonce:e.config.ajax.approve_order.nonce,order_id:n.orderID})}).then(e=>e.json()).then(e=>{if(r.unblock(),!e.success){if(100===e.data.code?t.message(e.data.message):t.genericError(),void 0!==a&&void 0!==a.restart)return a.restart();throw new Error(e.data.message)}document.querySelector("#place_order").click()}));var m=class{constructor(e,t,r){this.config=e,this.errorHandler=t,this.spinner=r}configuration(){const e=this.spinner;return{createOrder:(t,r)=>{const n=o(),a=void 0!==this.config.bn_codes[this.config.context]?this.config.bn_codes[this.config.context]:"",s=this.errorHandler,i="checkout"===this.config.context?"form.checkout":"form#order_review",c=jQuery(i).serialize();return fetch(this.config.ajax.create_order.endpoint,{method:"POST",body:JSON.stringify({nonce:this.config.ajax.create_order.nonce,payer:n,bn_code:a,context:this.config.context,order_id:this.config.order_id,form:c})}).then((function(e){return e.json()})).then((function(t){if(!t.success)return e.unblock(),void s.message(t.data.message,!0);const r=document.createElement("input");return r.setAttribute("type","hidden"),r.setAttribute("name","ppcp-resume-order"),r.setAttribute("value",t.data.purchase_units[0].custom_id),document.querySelector(i).append(r),t.data.id}))},onApprove:y(this,this.errorHandler,this.spinner),onError:e=>{this.errorHandler.genericError()}}}};var g=class{constructor(e,t,r,n){this.gateway=e,this.renderer=t,this.messages=r,this.spinner=n}init(){this.render(),jQuery(document.body).on("updated_checkout",()=>{this.render()}),jQuery(document.body).on("updated_checkout payment_method_selected",()=>{this.switchBetweenPayPalandOrderButton()}),this.switchBetweenPayPalandOrderButton()}shouldRender(){return!document.querySelector(this.gateway.button.cancel_wrapper)&&(null!==document.querySelector(this.gateway.button.wrapper)||null!==document.querySelector(this.gateway.hosted_fields.wrapper))}render(){if(!this.shouldRender())return;document.querySelector(this.gateway.hosted_fields.wrapper+">div")&&document.querySelector(this.gateway.hosted_fields.wrapper+">div").setAttribute("style","");const e=new m(PayPalCommerceGateway,new n(this.gateway.labels.error.generic),this.spinner);this.renderer.render(this.gateway.button.wrapper,this.gateway.hosted_fields.wrapper,e.configuration())}switchBetweenPayPalandOrderButton(){const e=jQuery('input[name="payment_method"]:checked').val();"ppcp-gateway"!==e&&"ppcp-credit-card-gateway"!==e?(this.renderer.hideButtons(this.gateway.button.wrapper),this.renderer.hideButtons(this.gateway.messages.wrapper),this.renderer.hideButtons(this.gateway.hosted_fields.wrapper),jQuery("#place_order").show()):(jQuery("#place_order").hide(),"ppcp-gateway"===e&&(this.renderer.showButtons(this.gateway.button.wrapper),this.renderer.showButtons(this.gateway.messages.wrapper),this.messages.render(),this.renderer.hideButtons(this.gateway.hosted_fields.wrapper)),"ppcp-credit-card-gateway"===e&&(this.renderer.hideButtons(this.gateway.button.wrapper),this.renderer.hideButtons(this.gateway.messages.wrapper),this.renderer.showButtons(this.gateway.hosted_fields.wrapper)))}};var w=class{constructor(e,t,r){this.gateway=e,this.renderer=t,this.messages=r}init(){this.render(),jQuery(document.body).on("updated_checkout",()=>{this.render()}),jQuery(document.body).on("updated_checkout payment_method_selected",()=>{this.switchBetweenPayPalandOrderButton()}),this.switchBetweenPayPalandOrderButton()}shouldRender(){return!document.querySelector(this.gateway.button.cancel_wrapper)&&(null!==document.querySelector(this.gateway.button.wrapper)||null!==document.querySelector(this.gateway.hosted_fields.wrapper))}render(){if(!this.shouldRender())return;document.querySelector(this.gateway.hosted_fields.wrapper+">div")&&document.querySelector(this.gateway.hosted_fields.wrapper+">div").setAttribute("style","");const e=new m(PayPalCommerceGateway,new n(this.gateway.labels.error.generic));this.renderer.render(this.gateway.button.wrapper,this.gateway.hosted_fields.wrapper,e.configuration())}switchBetweenPayPalandOrderButton(){const e=jQuery('input[name="payment_method"]:checked').val();"ppcp-gateway"!==e&&"ppcp-credit-card-gateway"!==e?(this.renderer.hideButtons(this.gateway.button.wrapper),this.renderer.hideButtons(this.gateway.messages.wrapper),this.renderer.hideButtons(this.gateway.hosted_fields.wrapper),jQuery("#place_order").show()):(jQuery("#place_order").hide(),"ppcp-gateway"===e&&(this.renderer.showButtons(this.gateway.button.wrapper),this.renderer.showButtons(this.gateway.messages.wrapper),this.messages.render(),this.renderer.hideButtons(this.gateway.hosted_fields.wrapper)),"ppcp-credit-card-gateway"===e&&(this.renderer.hideButtons(this.gateway.button.wrapper),this.renderer.hideButtons(this.gateway.messages.wrapper),this.renderer.showButtons(this.gateway.hosted_fields.wrapper)))}};var f=class{constructor(e,t){this.defaultConfig=t,this.creditCardRenderer=e}render(e,t,r){this.renderButtons(e,r),this.creditCardRenderer.render(t,r)}renderButtons(e,t){if(!document.querySelector(e)||this.isAlreadyRendered(e)||void 0===paypal.Buttons)return;const r=e===this.defaultConfig.button.wrapper?this.defaultConfig.button.style:this.defaultConfig.button.mini_cart_style;paypal.Buttons({style:r,...t}).render(e)}isAlreadyRendered(e){return document.querySelector(e).hasChildNodes()}hideButtons(e){const t=document.querySelector(e);return!!t&&(t.style.display="none",!0)}showButtons(e){const t=document.querySelector(e);return!!t&&(t.style.display="block",!0)}};var _=e=>{const t=window.getComputedStyle(e),r=document.createElement("span");return r.setAttribute("id",e.id),Object.values(t).forEach(e=>{t[e]&&isNaN(e)&&r.style.setProperty(e,""+t[e])}),r};var b=class{constructor(e,t,r){this.defaultConfig=e,this.errorHandler=t,this.spinner=r,this.cardValid=!1}render(e,t){if("checkout"!==this.defaultConfig.context&&"pay-now"!==this.defaultConfig.context||null===e||null===document.querySelector(e))return;if(void 0===paypal.HostedFields||!paypal.HostedFields.isEligible()){const t=document.querySelector(e);return void t.parentNode.removeChild(t)}const r=document.querySelector(".payment_box.payment_method_ppcp-credit-card-gateway"),n=r.style.display;r.style.display="block";const a=document.querySelector("#ppcp-hide-dcc");a&&a.parentNode.removeChild(a);const o=document.querySelector("#ppcp-credit-card-gateway-card-number"),s=window.getComputedStyle(o);let i={};Object.values(s).forEach(e=>{s[e]&&(i[e]=""+s[e])});const c=_(o);o.parentNode.replaceChild(c,o);const d=document.querySelector("#ppcp-credit-card-gateway-card-expiry"),u=_(d);d.parentNode.replaceChild(u,d);const l=document.querySelector("#ppcp-credit-card-gateway-card-cvc"),h=_(l);l.parentNode.replaceChild(h,l),r.style.display=n;const p=".payment_box payment_method_ppcp-credit-card-gateway";this.defaultConfig.enforce_vault&&document.querySelector(p+" .ppcp-credit-card-vault")&&(document.querySelector(p+" .ppcp-credit-card-vault").checked=!0,document.querySelector(p+" .ppcp-credit-card-vault").setAttribute("disabled",!0)),paypal.HostedFields.render({createOrder:t.createOrder,styles:{input:i},fields:{number:{selector:"#ppcp-credit-card-gateway-card-number",placeholder:this.defaultConfig.hosted_fields.labels.credit_card_number},cvv:{selector:"#ppcp-credit-card-gateway-card-cvc",placeholder:this.defaultConfig.hosted_fields.labels.cvv},expirationDate:{selector:"#ppcp-credit-card-gateway-card-expiry",placeholder:this.defaultConfig.hosted_fields.labels.mm_yyyy}}}).then(r=>{const n=n=>{this.spinner.block(),n&&n.preventDefault(),this.errorHandler.clear();const a=r.getState();if(Object.keys(a.fields).every((function(e){return a.fields[e].isValid}))&&this.cardValid){let n=!!document.querySelector(e+" .ppcp-credit-card-vault")&&document.querySelector(e+" .ppcp-credit-card-vault").checked;n=this.defaultConfig.enforce_vault||n,r.submit({contingencies:["3D_SECURE"],vault:n}).then(e=>(e.orderID=e.orderId,this.spinner.unblock(),t.onApprove(e)))}else{this.spinner.unblock();const e=this.cardValid?this.defaultConfig.hosted_fields.labels.fields_not_valid:this.defaultConfig.hosted_fields.labels.card_not_supported;this.errorHandler.message(e)}};r.on("inputSubmitRequest",(function(){n(null)})),r.on("cardTypeChange",e=>{if(!e.cards.length)return void(this.cardValid=!1);const t=this.defaultConfig.hosted_fields.valid_cards;this.cardValid=-1!==t.indexOf(e.cards[0].type)}),document.querySelector(e+" button").addEventListener("click",n)}),document.querySelector("#payment_method_ppcp-credit-card-gateway").addEventListener("click",()=>{document.querySelector("label[for=ppcp-credit-card-gateway-card-number]").click()})}};const v=(e,t)=>{if(!e)return!1;if(e.user!==t)return!1;return!((new Date).getTime()>=1e3*e.expiration)};var S=(e,t)=>{const r=(e=>{const t=JSON.parse(sessionStorage.getItem("ppcp-data-client-id"));return v(t,e)?t.token:null})(t.user);if(r)return e.setAttribute("data-client-token",r),void document.body.append(e);fetch(t.endpoint,{method:"POST",body:JSON.stringify({nonce:t.nonce})}).then(e=>e.json()).then(r=>{v(r,t.user)&&((e=>{sessionStorage.setItem("ppcp-data-client-id",JSON.stringify(e))})(r),e.setAttribute("data-client-token",r.token),document.body.append(e))})};var q=class{constructor(e){this.config=e}render(){this.shouldRender()&&paypal.Messages({amount:this.config.amount,placement:this.config.placement,style:this.config.style}).render(this.config.wrapper)}renderWithAmount(e){if(!this.shouldRender())return;const t=document.createElement("div");t.setAttribute("id",this.config.wrapper.replace("#",""));const r=document.querySelector(this.config.wrapper).nextSibling;document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper)),r.parentElement.insertBefore(t,r),paypal.Messages({amount:e,placement:this.config.placement,style:this.config.style}).render(this.config.wrapper)}shouldRender(){return void 0!==paypal.Messages&&void 0!==this.config.wrapper&&!!document.querySelector(this.config.wrapper)}};var P=class{constructor(){this.target="form.woocommerce-checkout"}block(){jQuery(this.target).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}unblock(){jQuery(this.target).unblock()}};document.addEventListener("DOMContentLoaded",()=>{const e=document.createElement("script");e.addEventListener("load",e=>{(()=>{const e=new n(PayPalCommerceGateway.labels.error.generic),t=new P,r=new b(PayPalCommerceGateway,e,t),a=new f(r,PayPalCommerceGateway),o=new q(PayPalCommerceGateway.messages),s=PayPalCommerceGateway.context;if("mini-cart"===s||"product"===s){new i(PayPalCommerceGateway,a).init()}if("product"===s){new h(PayPalCommerceGateway,a,o).init()}if("cart"===s){new p(PayPalCommerceGateway,a).init()}if("checkout"===s){new g(PayPalCommerceGateway,a,o,t).init()}if("pay-now"===s){new w(PayPalCommerceGateway,a,o).init()}"checkout"!==s&&o.render()})()}),e.setAttribute("src",PayPalCommerceGateway.button.url),Object.entries(PayPalCommerceGateway.script_attributes).forEach(t=>{e.setAttribute(t[0],t[1])}),PayPalCommerceGateway.data_client_id.set_attribute?S(e,PayPalCommerceGateway.data_client_id):document.body.append(e)})}]);
2
+ //# sourceMappingURL=button.js.map
modules/ppcp-button/assets/js/button.js.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./resources/js/modules/ErrorHandler.js","webpack:///./resources/js/modules/OnApproveHandler/onApproveForContinue.js","webpack:///./resources/js/modules/Helper/PayerData.js","webpack:///./resources/js/modules/ActionHandler/CartActionHandler.js","webpack:///./resources/js/modules/ContextBootstrap/MiniCartBootstap.js","webpack:///./resources/js/modules/Entity/Product.js","webpack:///./resources/js/modules/Helper/UpdateCart.js","webpack:///./resources/js/modules/Helper/ButtonsToggleListener.js","webpack:///./resources/js/modules/ActionHandler/SingleProductActionHandler.js","webpack:///./resources/js/modules/ContextBootstrap/SingleProductBootstap.js","webpack:///./resources/js/modules/ContextBootstrap/CartBootstap.js","webpack:///./resources/js/modules/OnApproveHandler/onApproveForPayNow.js","webpack:///./resources/js/modules/ActionHandler/CheckoutActionHandler.js","webpack:///./resources/js/modules/ContextBootstrap/CheckoutBootstap.js","webpack:///./resources/js/modules/ContextBootstrap/PayNowBootstrap.js","webpack:///./resources/js/modules/Renderer/Renderer.js","webpack:///./resources/js/modules/Helper/DccInputFactory.js","webpack:///./resources/js/modules/Renderer/CreditCardRenderer.js","webpack:///./resources/js/modules/DataClientIdAttributeHandler.js","webpack:///./resources/js/modules/Renderer/MessageRenderer.js","webpack:///./resources/js/modules/Helper/Spinner.js","webpack:///./resources/js/button.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","ErrorHandler","constructor","genericErrorText","this","wrapper","document","querySelector","genericError","classList","contains","clear","message","text","persist","add","remove","innerText","sanitize","jQuery","scroll_to_notices","textarea","createElement","innerHTML","replace","onApprove","context","errorHandler","data","actions","fetch","config","ajax","approve_order","endpoint","method","body","JSON","stringify","nonce","order_id","orderID","then","res","json","success","restart","catch","err","location","href","redirect","payerData","payer","PayPalCommerceGateway","phone","phone_type","phone_number","national_number","email_address","surname","given_name","address","country_code","address_line_1","address_line_2","admin_area_1","admin_area_2","postal_code","CartActionHandler","configuration","createOrder","bnCode","bn_codes","create_order","purchase_units","bn_code","console","error","Error","id","onError","MiniCartBootstap","gateway","renderer","actionHandler","init","labels","generic","render","on","shouldRender","button","mini_cart_wrapper","hosted_fields","Product","quantity","variations","UpdateCart","update","onResolve","products","Promise","resolve","reject","result","resolved","ButtonsToggleListener","element","showCallback","hideCallback","observer","callback","MutationObserver","observe","attributes","disconnect","SingleProductActionHandler","updateCart","showButtonCallback","hideButtonCallback","formElement","hasVariations","getProducts","isGroupedProduct","querySelectorAll","forEach","elementName","getAttribute","match","length","parseInt","push","qty","map","SingleProductBootstap","messages","hideButtons","change_cart","showButtons","priceText","amount","renderWithAmount","CartBootstrap","spinner","block","unblock","code","click","CheckoutActionHandler","formSelector","formValues","serialize","form","input","setAttribute","custom_id","append","CheckoutBootstap","switchBetweenPayPalandOrderButton","cancel_wrapper","currentPaymentMethod","val","show","hide","PayNowBootstrap","Renderer","creditCardRenderer","defaultConfig","hostedFieldsWrapper","contextConfig","renderButtons","isAlreadyRendered","paypal","Buttons","style","mini_cart_style","hasChildNodes","domElement","display","dccInputFactory","original","styles","window","getComputedStyle","newElement","values","prop","isNaN","setProperty","CreditCardRenderer","cardValid","HostedFields","isEligible","wrapperElement","parentNode","removeChild","gateWayBox","oldDisplayStyle","hideDccGateway","cardNumberField","stylesRaw","cardNumber","replaceChild","cardExpiryField","cardExpiry","cardCodeField","cardCode","formWrapper","enforce_vault","checked","fields","number","selector","placeholder","credit_card_number","cvv","expirationDate","mm_yyyy","hostedFields","submitEvent","event","preventDefault","state","getState","keys","every","isValid","vault","submit","contingencies","payload","orderId","fields_not_valid","card_not_supported","cards","validCards","valid_cards","indexOf","type","addEventListener","validateToken","token","user","Date","getTime","expiration","dataClientIdAttributeHandler","script","parse","sessionStorage","getItem","storedTokenForUser","setItem","storeToken","MessageRenderer","Messages","placement","newWrapper","sibling","nextSibling","parentElement","insertBefore","Spinner","target","overlayCSS","background","opacity","messageRenderer","bootstrap","url","entries","script_attributes","keyValue","data_client_id","set_attribute"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,uCCrCtCC,MA7Cf,MAEIC,YAAYC,GAERC,KAAKD,iBAAmBA,EACxBC,KAAKC,QAAUC,SAASC,cAAc,gCAG1CC,eACQJ,KAAKC,QAAQI,UAAUC,SAAS,kBAGpCN,KAAKO,QACLP,KAAKQ,QAAQR,KAAKD,mBAGtBS,QAAQC,EAAMC,GAAU,GAEpBV,KAAKC,QAAQI,UAAUM,IAAI,qBACvBD,EACAV,KAAKC,QAAQI,UAAUM,IAAI,gBAE3BX,KAAKC,QAAQI,UAAUO,OAAO,gBAElCZ,KAAKC,QAAQY,UAAYb,KAAKc,SAASL,GACvCM,OAAOC,kBAAkBD,OAAO,iCAGpCD,SAASL,GAEL,MAAMQ,EAAWf,SAASgB,cAAc,YAExC,OADAD,EAASE,UAAYV,EACdQ,EAASnC,MAAMsC,QAAQ,UAAW,IAG7Cb,QAEUP,KAAKC,QAAQI,UAAUC,SAAS,uBAGtCN,KAAKC,QAAQI,UAAUO,OAAO,qBAC9BZ,KAAKC,QAAQY,UAAY,MClBlBQ,MAvBG,CAACC,EAASC,IACjB,CAACC,EAAMC,IACHC,MAAMJ,EAAQK,OAAOC,KAAKC,cAAcC,SAAU,CACrDC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOb,EAAQK,OAAOC,KAAKC,cAAcM,MACzCC,SAASZ,EAAKa,YAEnBC,KAAMC,GACEA,EAAIC,QACZF,KAAMd,IACL,IAAKA,EAAKiB,QAEN,OADAlB,EAAanB,eACNqB,EAAQiB,UAAUC,MAAMC,IAC3BrB,EAAanB,iBAGrByC,SAASC,KAAOxB,EAAQK,OAAOoB,WCjBpC,MAAMC,EAAY,KACrB,MAAMC,EAAQC,sBAAsBD,MACpC,IAAMA,EACF,OAAO,KAGX,MAAME,EAASjD,SAASC,cAAc,wBAA4C,IAAhB8C,EAAME,MACxE,CACIC,WAAW,OACPC,aAAa,CACbC,gBAAmBpD,SAASC,cAAc,kBAAqBD,SAASC,cAAc,kBAAkBrB,MAAQmE,EAAME,MAAME,aAAaC,kBAE7I,KACEN,EAAY,CACdO,cAAerD,SAASC,cAAc,kBAAqBD,SAASC,cAAc,kBAAkBrB,MAAQmE,EAAMM,cAClHnF,KAAO,CACHoF,QAAUtD,SAASC,cAAc,sBAAyBD,SAASC,cAAc,sBAAsBrB,MAAQmE,EAAM7E,KAAKoF,QAC1HC,WAAavD,SAASC,cAAc,uBAA0BD,SAASC,cAAc,uBAAuBrB,MAAQmE,EAAM7E,KAAKqF,YAEnIC,QAAU,CACNC,aAAgBzD,SAASC,cAAc,oBAAuBD,SAASC,cAAc,oBAAoBrB,MAAQmE,EAAMS,QAAQC,aAC/HC,eAAkB1D,SAASC,cAAc,sBAAyBD,SAASC,cAAc,sBAAsBrB,MAAQmE,EAAMS,QAAQE,eACrIC,eAAkB3D,SAASC,cAAc,sBAAyBD,SAASC,cAAc,sBAAsBrB,MAAQmE,EAAMS,QAAQG,eACrIC,aAAgB5D,SAASC,cAAc,kBAAqBD,SAASC,cAAc,kBAAkBrB,MAAQmE,EAAMS,QAAQI,aAC3HC,aAAgB7D,SAASC,cAAc,iBAAoBD,SAASC,cAAc,iBAAiBrB,MAAQmE,EAAMS,QAAQK,aACzHC,YAAe9D,SAASC,cAAc,qBAAwBD,SAASC,cAAc,qBAAqBrB,MAAQmE,EAAMS,QAAQM,cAOxI,OAHIb,IACAH,EAAUG,MAAQA,GAEfH,GCaIiB,MA1Cf,MAEInE,YAAY6B,EAAQJ,GAChBvB,KAAK2B,OAASA,EACd3B,KAAKuB,aAAeA,EAGxB2C,gBAyBI,MAAO,CACHC,YAzBgB,CAAC3C,EAAMC,KACvB,MAAMwB,EAAQD,IACRoB,OAA8D,IAA9CpE,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SACnDtB,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SAAW,GAChD,OAAOI,MAAM1B,KAAK2B,OAAOC,KAAK0C,aAAaxC,SAAU,CACjDC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOnC,KAAK2B,OAAOC,KAAK0C,aAAanC,MACrCoC,eAAgB,GAChBC,QAAQJ,EACRnB,QACA3B,QAAQtB,KAAK2B,OAAOL,YAEzBgB,MAAK,SAASC,GACb,OAAOA,EAAIC,UACZF,MAAK,SAASd,GACb,IAAKA,EAAKiB,QAEN,MADAgC,QAAQC,MAAMlD,GACRmD,MAAMnD,EAAKA,KAAKhB,SAE1B,OAAOgB,EAAKA,KAAKoD,OAMrBvD,UAAWA,EAAUrB,KAAMA,KAAKuB,cAChCsD,QAAUH,IACN1E,KAAKuB,aAAanB,mBCGnB0E,MAvCf,MACIhF,YAAYiF,EAASC,GACjBhF,KAAK+E,QAAUA,EACf/E,KAAKgF,SAAWA,EAChBhF,KAAKiF,cAAgB,KAGzBC,OAEIlF,KAAKiF,cAAgB,IAAIhB,EACrBf,sBACA,IAAIrD,EAAaG,KAAK+E,QAAQI,OAAOT,MAAMU,UAE/CpF,KAAKqF,SAELtE,OAAOb,SAAS8B,MAAMsD,GAAG,6CAA8C,KACnEtF,KAAKqF,WAIbE,eACI,OACI,OADGrF,SAASC,cAAcH,KAAK+E,QAAQS,OAAOC,oBAElD,OADYvF,SAASC,cAAcH,KAAK+E,QAAQW,cAAcD,mBAIlEJ,SACSrF,KAAKuF,gBAIVvF,KAAKgF,SAASK,OACVrF,KAAK+E,QAAQS,OAAOC,kBACpBzF,KAAK+E,QAAQW,cAAcD,kBAC3BzF,KAAKiF,cAAcf,mBCpBhByB,MAjBf,MAEI7F,YAAY8E,EAAIgB,EAAUC,GACtB7F,KAAK4E,GAAKA,EACV5E,KAAK4F,SAAWA,EAChB5F,KAAK6F,WAAaA,EAGtBrE,OACI,MAAO,CACHoD,GAAG5E,KAAK4E,GACRgB,SAAS5F,KAAK4F,SACdC,WAAW7F,KAAK6F,cCgCbC,MA3Cf,MAEIhG,YAAYgC,EAAUK,GAElBnC,KAAK8B,SAAWA,EAChB9B,KAAKmC,MAAQA,EASjB4D,OAAOC,EAAWC,GAEd,OAAO,IAAIC,QAAQ,CAACC,EAASC,KACzB1E,MACI1B,KAAK8B,SACL,CACIC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOnC,KAAKmC,MACZ8D,eAGV3D,KACG+D,GACMA,EAAO7D,QAEhBF,KAAM+D,IACJ,IAAMA,EAAO5D,QAET,YADA2D,EAAOC,EAAO7E,MAId,MAAM8E,EAAWN,EAAUK,EAAO7E,MAClC2E,EAAQG,SCHbC,MA9Bf,MACIzG,YAAY0G,EAASC,EAAcC,GAE/B1G,KAAKwG,QAAUA,EACfxG,KAAKyG,aAAeA,EACpBzG,KAAK0G,aAAeA,EACpB1G,KAAK2G,SAAW,KAGpBzB,OAEI,MACM0B,EAAW,KACT5G,KAAKwG,QAAQnG,UAAUC,SAAS,YAChCN,KAAK0G,eAGT1G,KAAKyG,gBAETzG,KAAK2G,SAAW,IAAIE,iBAAiBD,GACrC5G,KAAK2G,SAASG,QAAQ9G,KAAKwG,QATZ,CAAEO,YAAa,IAU9BH,IAGJI,aAEIhH,KAAK2G,SAASK,eCqGPC,MA/Hf,MAEInH,YACI6B,EACAuF,EACAC,EACAC,EACAC,EACA9F,GAEAvB,KAAK2B,OAASA,EACd3B,KAAKkH,WAAaA,EAClBlH,KAAKmH,mBAAqBA,EAC1BnH,KAAKoH,mBAAqBA,EAC1BpH,KAAKqH,YAAcA,EACnBrH,KAAKuB,aAAeA,EAGxB2C,gBAGI,GAAKlE,KAAKsH,gBAAkB,CACP,IAAIf,EACjBvG,KAAKqH,YAAYlH,cAAc,8BAC/BH,KAAKmH,mBACLnH,KAAKoH,oBAEAlC,OAGb,MAAO,CACHf,YAAanE,KAAKmE,cAClB9C,UAAWA,EAAUrB,KAAMA,KAAKuB,cAChCsD,QAAUH,IACN1E,KAAKuB,aAAanB,iBAK9B+D,cAEI,IAAIoD,EAAc,KASdA,EAREvH,KAAKwH,mBAQO,KACV,MAAMvB,EAAW,GAajB,OAZAjG,KAAKqH,YAAYI,iBAAiB,wBAAwBC,QAASlB,IAC/D,IAAMA,EAAQ1H,MACV,OAEJ,MAAM6I,EAAcnB,EAAQoB,aAAa,QAAQC,MAAM,uBACvD,GAA2B,IAAvBF,EAAYG,OACZ,OAEJ,MAAMlD,EAAKmD,SAASJ,EAAY,IAC1B/B,EAAWmC,SAASvB,EAAQ1H,OAClCmH,EAAS+B,KAAK,IAAIrC,EAAQf,EAAIgB,EAAU,SAErCK,GArBG,KACV,MAAMrB,EAAK1E,SAASC,cAAc,wBAAwBrB,MACpDmJ,EAAM/H,SAASC,cAAc,qBAAqBrB,MAClD+G,EAAa7F,KAAK6F,aACxB,MAAO,CAAC,IAAIF,EAAQf,EAAIqD,EAAKpC,KAkDrC,MA9BoB,CAACrE,EAAMC,KACvBzB,KAAKuB,aAAahB,QA2BlB,OADgBP,KAAKkH,WAAWnB,OAxBbxB,IACf,MAAMtB,EAAQD,IACRoB,OAA8D,IAA9CpE,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SACnDtB,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SAAW,GAChD,OAAOI,MAAM1B,KAAK2B,OAAOC,KAAK0C,aAAaxC,SAAU,CACjDC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOnC,KAAK2B,OAAOC,KAAK0C,aAAanC,MACrCoC,iBACAtB,QACAuB,QAAQJ,EACR9C,QAAQtB,KAAK2B,OAAOL,YAEzBgB,MAAK,SAAUC,GACd,OAAOA,EAAIC,UACZF,MAAK,SAAUd,GACd,IAAKA,EAAKiB,QAEN,MADAgC,QAAQC,MAAMlD,GACRmD,MAAMnD,EAAKA,KAAKhB,SAE1B,OAAOgB,EAAKA,KAAKoD,OAIyB2C,MAM1D1B,aAGI,IAAM7F,KAAKsH,gBACP,OAAO,KAUX,MARmB,IAAItH,KAAKqH,YAAYI,iBAAiB,yBAAyBS,IAC7E1B,IACM,CACC1H,MAAM0H,EAAQ1H,MACdV,KAAKoI,EAAQpI,QAO7BkJ,gBAEI,OAAOtH,KAAKqH,YAAYhH,UAAUC,SAAS,mBAG/CkH,mBAEI,OAAOxH,KAAKqH,YAAYhH,UAAUC,SAAS,kBCjEpC6H,MA5Df,MACIrI,YAAYiF,EAASC,EAAUoD,GAC3BpI,KAAK+E,QAAUA,EACf/E,KAAKgF,SAAWA,EAChBhF,KAAKoI,SAAWA,EAGpBlD,OACSlF,KAAKuF,eAKVvF,KAAKqF,SAJFrF,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,SAO5DsF,eACI,OAA4C,OAAxCrF,SAASC,cAAc,aAO/BkF,SACI,MAAMJ,EAAgB,IAAIgC,EACtBjH,KAAK+E,QACL,IAAIe,EACA9F,KAAK+E,QAAQnD,KAAK0G,YAAYxG,SAC9B9B,KAAK+E,QAAQnD,KAAK0G,YAAYnG,OAElC,KACInC,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQW,cAAczF,SACrD,IAAIuI,EAAY,IACZtI,SAASC,cAAc,2CACvBqI,EAAYtI,SAASC,cAAc,2CAA2CU,UAEzEX,SAASC,cAAc,yCAC5BqI,EAAYtI,SAASC,cAAc,uCAAuCU,WAE9E,MAAM4H,EAASV,SAASS,EAAUpH,QAAQ,iBAAkB,KAC5DpB,KAAKoI,SAASM,iBAAiBD,IAEnC,KACIzI,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,UAEzDC,SAASC,cAAc,aACvB,IAAIN,EAAaG,KAAK+E,QAAQI,OAAOT,MAAMU,UAG/CpF,KAAKgF,SAASK,OACVrF,KAAK+E,QAAQS,OAAOvF,QACpBD,KAAK+E,QAAQW,cAAczF,QAC3BgF,EAAcf,mBClBXyE,MAtCf,MACI7I,YAAYiF,EAASC,GACjBhF,KAAK+E,QAAUA,EACf/E,KAAKgF,SAAWA,EAGpBE,OACSlF,KAAKuF,iBAIVvF,KAAKqF,SAELtE,OAAOb,SAAS8B,MAAMsD,GAAG,uCAAwC,KAC7DtF,KAAKqF,YAIbE,eACI,OACI,OADGrF,SAASC,cAAcH,KAAK+E,QAAQS,OAAOvF,UAE9C,OADQC,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,SAIlEoF,SACI,MAAMJ,EAAgB,IAAIhB,EACtBf,sBACA,IAAIrD,EAAaG,KAAK+E,QAAQI,OAAOT,MAAMU,UAG/CpF,KAAKgF,SAASK,OACVrF,KAAK+E,QAAQS,OAAOvF,QACpBD,KAAK+E,QAAQW,cAAczF,QAC3BgF,EAAcf,mBCNX7C,MA9BG,CAACC,EAASC,EAAcqH,IAC/B,CAACpH,EAAMC,KACVmH,EAAQC,QACDnH,MAAMJ,EAAQK,OAAOC,KAAKC,cAAcC,SAAU,CACrDC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOb,EAAQK,OAAOC,KAAKC,cAAcM,MACzCC,SAASZ,EAAKa,YAEnBC,KAAMC,GACEA,EAAIC,QACZF,KAAMd,IAEL,GADAoH,EAAQE,WACHtH,EAAKiB,QAAS,CAMf,GALuB,MAAnBjB,EAAKA,KAAKuH,KACVxH,EAAaf,QAAQgB,EAAKA,KAAKhB,SAE/Be,EAAanB,oBAEM,IAAZqB,QAAsD,IAApBA,EAAQiB,QACjD,OAAOjB,EAAQiB,UAEnB,MAAM,IAAIiC,MAAMnD,EAAKA,KAAKhB,SAE9BN,SAASC,cAAc,gBAAgB6I,WCmCpCC,MAxDf,MAEInJ,YAAY6B,EAAQJ,EAAcqH,GAC9B5I,KAAK2B,OAASA,EACd3B,KAAKuB,aAAeA,EACpBvB,KAAK4I,QAAUA,EAGnB1E,gBACI,MAAM0E,EAAU5I,KAAK4I,QAqCrB,MAAO,CACHzE,YArCgB,CAAC3C,EAAMC,KACvB,MAAMwB,EAAQD,IACRoB,OAA8D,IAA9CpE,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SACnDtB,KAAK2B,OAAO0C,SAASrE,KAAK2B,OAAOL,SAAW,GAG1CC,EAAevB,KAAKuB,aACpB2H,EAAuC,aAAxBlJ,KAAK2B,OAAOL,QAAyB,gBAAkB,oBACtE6H,EAAapI,OAAOmI,GAAcE,YAExC,OAAO1H,MAAM1B,KAAK2B,OAAOC,KAAK0C,aAAaxC,SAAU,CACjDC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOnC,KAAK2B,OAAOC,KAAK0C,aAAanC,MACrCc,QACAuB,QAAQJ,EACR9C,QAAQtB,KAAK2B,OAAOL,QACpBc,SAASpC,KAAK2B,OAAOS,SACrBiH,KAAKF,MAEV7G,MAAK,SAAUC,GACd,OAAOA,EAAIC,UACZF,MAAK,SAAUd,GACd,IAAKA,EAAKiB,QAGN,OAFAmG,EAAQE,eACRvH,EAAaf,QAAQgB,EAAKA,KAAKhB,SAAS,GAG5C,MAAM8I,EAAQpJ,SAASgB,cAAc,SAKrC,OAJAoI,EAAMC,aAAa,OAAQ,UAC3BD,EAAMC,aAAa,OAAQ,qBAC3BD,EAAMC,aAAa,QAAS/H,EAAKA,KAAK+C,eAAe,GAAGiF,WACxDtJ,SAASC,cAAc+I,GAAcO,OAAOH,GACrC9H,EAAKA,KAAKoD,OAKrBvD,UAAUA,EAAUrB,KAAMA,KAAKuB,aAAcvB,KAAK4I,SAClD/D,QAAUH,IACN1E,KAAKuB,aAAanB,mBC4BnBsJ,MA9Ef,MACI5J,YAAYiF,EAASC,EAAUoD,EAAUQ,GACrC5I,KAAK+E,QAAUA,EACf/E,KAAKgF,SAAWA,EAChBhF,KAAKoI,SAAWA,EAChBpI,KAAK4I,QAAUA,EAGnB1D,OAEIlF,KAAKqF,SAELtE,OAAOb,SAAS8B,MAAMsD,GAAG,mBAAoB,KACzCtF,KAAKqF,WAGTtE,OAAOb,SAAS8B,MACZsD,GAAG,2CAA4C,KAC3CtF,KAAK2J,sCAEb3J,KAAK2J,oCAGTpE,eACI,OAAIrF,SAASC,cAAcH,KAAK+E,QAAQS,OAAOoE,kBAIgB,OAAxD1J,SAASC,cAAcH,KAAK+E,QAAQS,OAAOvF,UAAoF,OAA/DC,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,UAG7HoF,SACI,IAAKrF,KAAKuF,eACN,OAEArF,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,QAAU,SAC5DC,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,QAAU,QAAQsJ,aAAa,QAAS,IAE9F,MAAMtE,EAAgB,IAAIgE,EACtB/F,sBACA,IAAIrD,EAAaG,KAAK+E,QAAQI,OAAOT,MAAMU,SAC3CpF,KAAK4I,SAGT5I,KAAKgF,SAASK,OACVrF,KAAK+E,QAAQS,OAAOvF,QACpBD,KAAK+E,QAAQW,cAAczF,QAC3BgF,EAAcf,iBAItByF,oCACI,MAAME,EAAuB9I,OACzB,wCAAwC+I,MAEf,iBAAzBD,GAAoE,6BAAzBA,GAC3C7J,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,SACrDc,OAAO,gBAAgBgJ,SAGvBhJ,OAAO,gBAAgBiJ,OACM,iBAAzBH,IACA7J,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKoI,SAAS/C,SACdrF,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,UAE5B,6BAAzB4J,IACA7J,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQW,cAAczF,aCItDgK,MA5Ef,MACInK,YAAYiF,EAASC,EAAUoD,GAC3BpI,KAAK+E,QAAUA,EACf/E,KAAKgF,SAAWA,EAChBhF,KAAKoI,SAAWA,EAGpBlD,OAEIlF,KAAKqF,SAELtE,OAAOb,SAAS8B,MAAMsD,GAAG,mBAAoB,KACzCtF,KAAKqF,WAGTtE,OAAOb,SAAS8B,MAChBsD,GAAG,2CAA4C,KAC3CtF,KAAK2J,sCAET3J,KAAK2J,oCAGTpE,eACI,OAAIrF,SAASC,cAAcH,KAAK+E,QAAQS,OAAOoE,kBAIgB,OAAxD1J,SAASC,cAAcH,KAAK+E,QAAQS,OAAOvF,UAAoF,OAA/DC,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,UAG7HoF,SACI,IAAKrF,KAAKuF,eACN,OAEArF,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,QAAU,SAC5DC,SAASC,cAAcH,KAAK+E,QAAQW,cAAczF,QAAU,QAAQsJ,aAAa,QAAS,IAE9F,MAAMtE,EAAgB,IAAIgE,EACtB/F,sBACA,IAAIrD,EAAaG,KAAK+E,QAAQI,OAAOT,MAAMU,UAG/CpF,KAAKgF,SAASK,OACVrF,KAAK+E,QAAQS,OAAOvF,QACpBD,KAAK+E,QAAQW,cAAczF,QAC3BgF,EAAcf,iBAItByF,oCACI,MAAME,EAAuB9I,OACzB,wCAAwC+I,MAEf,iBAAzBD,GAAoE,6BAAzBA,GAC3C7J,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,SACrDc,OAAO,gBAAgBgJ,SAGvBhJ,OAAO,gBAAgBiJ,OACM,iBAAzBH,IACA7J,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKoI,SAAS/C,SACdrF,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQW,cAAczF,UAE5B,6BAAzB4J,IACA7J,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQS,OAAOvF,SAC9CD,KAAKgF,SAASqD,YAAYrI,KAAK+E,QAAQqD,SAASnI,SAChDD,KAAKgF,SAASuD,YAAYvI,KAAK+E,QAAQW,cAAczF,aC1BtDiK,MA/Cf,MACIpK,YAAYqK,EAAoBC,GAC5BpK,KAAKoK,cAAgBA,EACrBpK,KAAKmK,mBAAqBA,EAG9B9E,OAAOpF,EAASoK,EAAqBC,GAEjCtK,KAAKuK,cAActK,EAASqK,GAC5BtK,KAAKmK,mBAAmB9E,OAAOgF,EAAqBC,GAGxDC,cAActK,EAASqK,GACnB,IAAMpK,SAASC,cAAcF,IAAYD,KAAKwK,kBAAkBvK,SAAY,IAAuBwK,OAAOC,QACtG,OAGJ,MAAMC,EAAQ1K,IAAYD,KAAKoK,cAAc5E,OAAOvF,QAAUD,KAAKoK,cAAc5E,OAAOmF,MAAQ3K,KAAKoK,cAAc5E,OAAOoF,gBAC1HH,OAAOC,QAAQ,CACXC,WACGL,IACJjF,OAAOpF,GAGduK,kBAAkBvK,GACd,OAAOC,SAASC,cAAcF,GAAS4K,gBAG3CxC,YAAY7B,GACR,MAAMsE,EAAa5K,SAASC,cAAcqG,GAC1C,QAAMsE,IAGNA,EAAWH,MAAMI,QAAU,QACpB,GAGXxC,YAAY/B,GACR,MAAMsE,EAAa5K,SAASC,cAAcqG,GAC1C,QAAMsE,IAGNA,EAAWH,MAAMI,QAAU,SACpB,KC9BAC,MAbUC,IACrB,MAAMC,EAASC,OAAOC,iBAAiBH,GACjCI,EAAanL,SAASgB,cAAc,QAQ1C,OAPAmK,EAAW9B,aAAa,KAAM0B,EAASrG,IACvCrG,OAAO+M,OAAOJ,GAAQxD,QAAU6D,IACtBL,EAAOK,IAAWC,MAAMD,IAG9BF,EAAWV,MAAMc,YAAYF,EAAK,GAAKL,EAAOK,MAE3CF,GC2IIK,MAnJf,MAEI5L,YAAYsK,EAAe7I,EAAcqH,GACrC5I,KAAKoK,cAAgBA,EACrBpK,KAAKuB,aAAeA,EACpBvB,KAAK4I,QAAUA,EACf5I,KAAK2L,WAAY,EAGrBtG,OAAOpF,EAASqK,GAEZ,GAEuC,aAA/BtK,KAAKoK,cAAc9I,SACe,YAA/BtB,KAAKoK,cAAc9I,SAEX,OAAZrB,GACoC,OAApCC,SAASC,cAAcF,GAE1B,OAEJ,QACmC,IAAxBwK,OAAOmB,eACTnB,OAAOmB,aAAaC,aAC3B,CACE,MAAMC,EAAiB5L,SAASC,cAAcF,GAE9C,YADA6L,EAAeC,WAAWC,YAAYF,GAI1C,MAAMG,EAAa/L,SAASC,cAAc,wDACpC+L,EAAkBD,EAAWtB,MAAMI,QACzCkB,EAAWtB,MAAMI,QAAU,QAE3B,MAAMoB,EAAiBjM,SAASC,cAAc,kBAC1CgM,GACAA,EAAeJ,WAAWC,YAAYG,GAG1C,MAAMC,EAAkBlM,SAASC,cAAc,yCAEzCkM,EAAYlB,OAAOC,iBAAiBgB,GAC1C,IAAIlB,EAAS,GACb3M,OAAO+M,OAAOe,GAAW3E,QAAU6D,IACzBc,EAAUd,KAGhBL,EAAOK,GAAQ,GAAKc,EAAUd,MAGlC,MAAMe,EAAatB,EAAgBoB,GACnCA,EAAgBL,WAAWQ,aAAaD,EAAYF,GAEpD,MAAMI,EAAkBtM,SAASC,cAAc,yCACzCsM,EAAazB,EAAgBwB,GACnCA,EAAgBT,WAAWQ,aAAaE,EAAYD,GAEpD,MAAME,EAAgBxM,SAASC,cAAc,sCACvCwM,EAAW3B,EAAgB0B,GACjCA,EAAcX,WAAWQ,aAAaI,EAAUD,GAEhDT,EAAWtB,MAAMI,QAAUmB,EAE3B,MAAMU,EAAc,uDAEhB5M,KAAKoK,cAAcyC,eAChB3M,SAASC,cAAcyM,EAAc,8BAExC1M,SAASC,cAAcyM,EAAc,4BAA4BE,SAAU,EAC3E5M,SAASC,cAAcyM,EAAc,4BAA4BrD,aAAa,YAAY,IAE9FkB,OAAOmB,aAAavG,OAAO,CACvBlB,YAAamG,EAAcnG,YAC3B+G,OAAQ,CACJ,MAASA,GAEb6B,OAAQ,CACJC,OAAQ,CACJC,SAAU,wCACVC,YAAalN,KAAKoK,cAAc1E,cAAcP,OAAOgI,oBAEzDC,IAAK,CACDH,SAAU,qCACVC,YAAalN,KAAKoK,cAAc1E,cAAcP,OAAOiI,KAEzDC,eAAgB,CACZJ,SAAU,wCACVC,YAAalN,KAAKoK,cAAc1E,cAAcP,OAAOmI,YAG9DhL,KAAKiL,IACJ,MAAMC,EAAeC,IACjBzN,KAAK4I,QAAQC,QACT4E,GACAA,EAAMC,iBAEV1N,KAAKuB,aAAahB,QAClB,MAAMoN,EAAQJ,EAAaK,WAK3B,GAJkBrP,OAAOsP,KAAKF,EAAMZ,QAAQe,OAAM,SAAU1O,GACxD,OAAOuO,EAAMZ,OAAO3N,GAAK2O,YAGZ/N,KAAK2L,UAAW,CAE7B,IAAIqC,IAAQ9N,SAASC,cAAcF,EAAU,6BACzCC,SAASC,cAAcF,EAAU,4BAA4B6M,QACjEkB,EAAQhO,KAAKoK,cAAcyC,eAAiBmB,EAE5CT,EAAaU,OAAO,CAChBC,cAAe,CAAC,aAChBF,UACD1L,KAAM6L,IACLA,EAAQ9L,QAAU8L,EAAQC,QAC1BpO,KAAK4I,QAAQE,UACNwB,EAAcjJ,UAAU8M,SAEhC,CACHnO,KAAK4I,QAAQE,UACb,MAAMtI,EAAYR,KAAK2L,UAAyE3L,KAAKoK,cAAc1E,cAAcP,OAAOkJ,iBAArGrO,KAAKoK,cAAc1E,cAAcP,OAAOmJ,mBAC3EtO,KAAKuB,aAAaf,QAAQA,KAGlC+M,EAAajI,GAAG,sBAAsB,WAClCkI,EAAY,SAEhBD,EAAajI,GAAG,iBAAmBmI,IAC/B,IAAOA,EAAMc,MAAMzG,OAEf,YADA9H,KAAK2L,WAAY,GAGrB,MAAM6C,EAAaxO,KAAKoK,cAAc1E,cAAc+I,YACpDzO,KAAK2L,WAAyD,IAA7C6C,EAAWE,QAAQjB,EAAMc,MAAM,GAAGI,QAEvDzO,SAASC,cAAcF,EAAU,WAAW2O,iBACxC,QACApB,KAIRtN,SAASC,cAAc,4CAA4CyO,iBAC/D,QACA,KACI1O,SAASC,cAAc,mDAAmD6I,YChJ1F,MAEM6F,EAAgB,CAACC,EAAOC,KAC1B,IAAMD,EACF,OAAO,EAEX,GAAIA,EAAMC,OAASA,EACf,OAAO,EAIX,SAFoB,IAAIC,MAAOC,WACqB,IAAnBH,EAAMI,aAyC5BC,MAzBsB,CAACC,EAAQzN,KAC1C,MAAMmN,EAbkBC,KACxB,MAAMD,EAAQ7M,KAAKoN,MAAMC,eAAeC,QAfzB,wBAgBf,OAAIV,EAAcC,EAAOC,GACdD,EAAMA,MAEV,MAQOU,CAAmB7N,EAAOoN,MACxC,GAAID,EAGA,OAFAM,EAAO7F,aAAa,oBAAqBuF,QACzC5O,SAAS8B,KAAKyH,OAAO2F,GAGzB1N,MAAMC,EAAOG,SAAU,CACnBC,OAAQ,OACRC,KAAMC,KAAKC,UAAU,CACjBC,MAAOR,EAAOQ,UAEnBG,KAAMC,GACEA,EAAIC,QACZF,KAAMd,IACWqN,EAAcrN,EAAMG,EAAOoN,QAnB/BD,KAChBQ,eAAeG,QAvBA,sBAuBoBxN,KAAKC,UAAU4M,KAsB9CY,CAAWlO,GACX4N,EAAO7F,aAAa,oBAAqB/H,EAAKsN,OAC9C5O,SAAS8B,KAAKyH,OAAO2F,OCCdO,MAhDf,MAEI7P,YAAY6B,GACR3B,KAAK2B,OAASA,EAGlB0D,SACUrF,KAAKuF,gBAIXkF,OAAOmF,SAAS,CACZnH,OAAQzI,KAAK2B,OAAO8G,OACpBoH,UAAW7P,KAAK2B,OAAOkO,UACvBlF,MAAO3K,KAAK2B,OAAOgJ,QACpBtF,OAAOrF,KAAK2B,OAAO1B,SAG1ByI,iBAAiBD,GAEb,IAAMzI,KAAKuF,eACP,OAGJ,MAAMuK,EAAa5P,SAASgB,cAAc,OAC1C4O,EAAWvG,aAAa,KAAMvJ,KAAK2B,OAAO1B,QAAQmB,QAAQ,IAAK,KAE/D,MAAM2O,EAAU7P,SAASC,cAAcH,KAAK2B,OAAO1B,SAAS+P,YAC5D9P,SAASC,cAAcH,KAAK2B,OAAO1B,SAASgQ,cAAcjE,YAAY9L,SAASC,cAAcH,KAAK2B,OAAO1B,UACzG8P,EAAQE,cAAcC,aAAaJ,EAAYC,GAC/CtF,OAAOmF,SAAS,CACZnH,SACAoH,UAAW7P,KAAK2B,OAAOkO,UACvBlF,MAAO3K,KAAK2B,OAAOgJ,QACpBtF,OAAOrF,KAAK2B,OAAO1B,SAG1BsF,eAEI,YAA+B,IAApBkF,OAAOmF,eAA2D,IAAxB5P,KAAK2B,OAAO1B,WAG3DC,SAASC,cAAcH,KAAK2B,OAAO1B,WCpBlCkQ,MAtBf,MAEIrQ,cACIE,KAAKoQ,OAAS,4BAElBvH,QAEI9H,OAAQf,KAAKoQ,QAASvH,MAAM,CACxBrI,QAAS,KACT6P,WAAY,CACRC,WAAY,OACZC,QAAS,MAKrBzH,UAEI/H,OAAQf,KAAKoQ,QAAStH,YCqD9B5I,SAAS0O,iBACL,mBACA,KAKI,MAAMQ,EAASlP,SAASgB,cAAc,UAEtCkO,EAAOR,iBAAiB,OAASnB,IApEvB,MACd,MAAMlM,EAAe,IAAI1B,EAAaqD,sBAAsBiC,OAAOT,MAAMU,SACnEwD,EAAU,IAAIuH,EACdhG,EAAqB,IAAIuB,EAAmBxI,sBAAuB3B,EAAcqH,GACjF5D,EAAW,IAAIkF,EAASC,EAAoBjH,uBAC5CsN,EAAkB,IAAIb,EAAgBzM,sBAAsBkF,UAC5D9G,EAAU4B,sBAAsB5B,QACtC,GAAgB,cAAZA,GAAuC,YAAZA,EAAuB,CACxB,IAAIwD,EAC1B5B,sBACA8B,GAGcE,OAGtB,GAAgB,YAAZ5D,EAAuB,CACQ,IAAI6G,EAC/BjF,sBACA8B,EACAwL,GAGmBtL,OAG3B,GAAgB,SAAZ5D,EAAoB,CACE,IAAIqH,EACtBzF,sBACA8B,GAGUE,OAGlB,GAAgB,aAAZ5D,EAAwB,CACC,IAAIoI,EACzBxG,sBACA8B,EACAwL,EACA5H,GAGa1D,OAGrB,GAAgB,YAAZ5D,EAAwB,CACA,IAAI2I,EACxB/G,sBACA8B,EACAwL,GAEYtL,OAGJ,aAAZ5D,GACAkP,EAAgBnL,UAaZoL,KAEJrB,EAAO7F,aAAa,MAAOrG,sBAAsBsC,OAAOkL,KACxDnS,OAAOoS,QAAQzN,sBAAsB0N,mBAAmBlJ,QACnDmJ,IACGzB,EAAO7F,aAAasH,EAAS,GAAIA,EAAS,MAI9C3N,sBAAsB4N,eAAeC,cACrC5B,EAA6BC,EAAQlM,sBAAsB4N,gBAI/D5Q,SAAS8B,KAAKyH,OAAO2F","file":"js/button.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","class ErrorHandler {\n\n constructor(genericErrorText)\n {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n this.clear();\n this.message(this.genericErrorText)\n }\n\n message(text, persist = false)\n {\n this.wrapper.classList.add('woocommerce-error');\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n this.wrapper.innerText = this.sanitize(text);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'))\n }\n\n sanitize(text)\n {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear()\n {\n if (! this.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\n }\n}\n\nexport default ErrorHandler;\n","const onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id:data.orderID\n })\n }).then((res)=>{\n return res.json();\n }).then((data)=>{\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });;\n }\n location.href = context.config.redirect;\n });\n\n }\n}\n\nexport default onApprove;\n","export const payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n if (! payer) {\n return null;\n }\n\n const phone = (document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined') ?\n {\n phone_type:\"HOME\",\n phone_number:{\n national_number : (document.querySelector('#billing_phone')) ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address:(document.querySelector('#billing_email')) ? document.querySelector('#billing_email').value : payer.email_address,\n name : {\n surname: (document.querySelector('#billing_last_name')) ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: (document.querySelector('#billing_first_name')) ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address : {\n country_code : (document.querySelector('#billing_country')) ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1 : (document.querySelector('#billing_address_1')) ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2 : (document.querySelector('#billing_address_2')) ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1 : (document.querySelector('#billing_state')) ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2 : (document.querySelector('#billing_city')) ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code : (document.querySelector('#billing_postcode')) ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n return payerData;\n}\n","import onApprove from '../OnApproveHandler/onApproveForContinue.js';\nimport {payerData} from \"../Helper/PayerData\";\n\nclass CartActionHandler {\n\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?\n this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code:bnCode,\n payer,\n context:this.config.context\n }),\n }).then(function(res) {\n return res.json();\n }).then(function(data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApprove(this, this.errorHandler),\n onError: (error) => {\n this.errorHandler.genericError();\n }\n };\n }\n}\n\nexport default CartActionHandler;\n","import ErrorHandler from '../ErrorHandler';\nimport CartActionHandler from '../ActionHandler/CartActionHandler';\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n\n this.actionHandler = new CartActionHandler(\n PayPalCommerceGateway,\n new ErrorHandler(this.gateway.labels.error.generic),\n );\n this.render();\n\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !==\n null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !==\n null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(\n this.gateway.button.mini_cart_wrapper,\n this.gateway.hosted_fields.mini_cart_wrapper,\n this.actionHandler.configuration()\n );\n }\n}\n\nexport default MiniCartBootstap;","class Product {\n\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id:this.id,\n quantity:this.quantity,\n variations:this.variations\n }\n }\n}\n\nexport default Product;","import Product from \"../Entity/Product\";\nclass UpdateCart {\n\n constructor(endpoint, nonce)\n {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n update(onResolve, products)\n {\n return new Promise((resolve, reject) => {\n fetch(\n this.endpoint,\n {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products,\n })\n }\n ).then(\n (result) => {\n return result.json();\n }\n ).then((result) => {\n if (! result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n })\n });\n }\n}\n\nexport default UpdateCart;","/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\n\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback)\n {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init()\n {\n const config = { attributes : true };\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n this.showCallback();\n }\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect()\n {\n this.observer.disconnect();\n }\n}\n\nexport default ButtonsToggleListener;","import ButtonsToggleListener from '../Helper/ButtonsToggleListener';\nimport Product from '../Entity/Product';\nimport onApprove from '../OnApproveHandler/onApproveForContinue';\nimport {payerData} from \"../Helper/PayerData\";\n\nclass SingleProductActionHandler {\n\n constructor(\n config,\n updateCart,\n showButtonCallback,\n hideButtonCallback,\n formElement,\n errorHandler\n ) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration()\n {\n\n if ( this.hasVariations() ) {\n const observer = new ButtonsToggleListener(\n this.formElement.querySelector('.single_add_to_cart_button'),\n this.showButtonCallback,\n this.hideButtonCallback\n );\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApprove(this, this.errorHandler),\n onError: (error) => {\n this.errorHandler.genericError();\n }\n }\n }\n\n createOrder()\n {\n var getProducts = null;\n if (! this.isGroupedProduct() ) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Product(id, qty, variations)];\n }\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach((element) => {\n if (! element.value) {\n return;\n }\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n if (elementName.length !== 2) {\n return;\n }\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Product(id, quantity, null));\n })\n return products;\n }\n }\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = (purchase_units) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?\n this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code:bnCode,\n context:this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n return createOrder;\n }\n\n variations()\n {\n\n if (! this.hasVariations()) {\n return null;\n }\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(\n (element) => {\n return {\n value:element.value,\n name:element.name\n }\n }\n );\n return attributes;\n }\n\n hasVariations()\n {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct()\n {\n return this.formElement.classList.contains('grouped_form');\n }\n}\nexport default SingleProductActionHandler;\n","import ErrorHandler from '../ErrorHandler';\nimport UpdateCart from \"../Helper/UpdateCart\";\nimport SingleProductActionHandler from \"../ActionHandler/SingleProductActionHandler\";\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new SingleProductActionHandler(\n this.gateway,\n new UpdateCart(\n this.gateway.ajax.change_cart.endpoint,\n this.gateway.ajax.change_cart.nonce,\n ),\n () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n }\n else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount)\n },\n () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n },\n document.querySelector('form.cart'),\n new ErrorHandler(this.gateway.labels.error.generic),\n );\n\n this.renderer.render(\n this.gateway.button.wrapper,\n this.gateway.hosted_fields.wrapper,\n actionHandler.configuration(),\n );\n }\n}\n\nexport default SingleProductBootstap;","import CartActionHandler from '../ActionHandler/CartActionHandler';\nimport ErrorHandler from '../ErrorHandler';\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !==\n null || document.querySelector(this.gateway.hosted_fields.wrapper) !==\n null;\n }\n\n render() {\n const actionHandler = new CartActionHandler(\n PayPalCommerceGateway,\n new ErrorHandler(this.gateway.labels.error.generic),\n );\n\n this.renderer.render(\n this.gateway.button.wrapper,\n this.gateway.hosted_fields.wrapper,\n actionHandler.configuration(),\n );\n }\n}\n\nexport default CartBootstrap;","const onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id:data.orderID\n })\n }).then((res)=>{\n return res.json();\n }).then((data)=>{\n spinner.unblock();\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n throw new Error(data.data.message);\n }\n document.querySelector('#place_order').click()\n });\n\n }\n}\n\nexport default onApprove;\n","import onApprove from '../OnApproveHandler/onApproveForPayNow.js';\nimport {payerData} from \"../Helper/PayerData\";\n\nclass CheckoutActionHandler {\n\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?\n this.config.bn_codes[this.config.context] : '';\n\n\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code:bnCode,\n context:this.config.context,\n order_id:this.config.order_id,\n form:formValues\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock();\n errorHandler.message(data.data.message, true);\n return;\n }\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n }\n return {\n createOrder,\n onApprove:onApprove(this, this.errorHandler, this.spinner),\n onError: (error) => {\n this.errorHandler.genericError();\n }\n }\n }\n}\n\nexport default CheckoutActionHandler;\n","import ErrorHandler from '../ErrorHandler';\nimport CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n\n this.render();\n\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n\n jQuery(document.body).\n on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n const actionHandler = new CheckoutActionHandler(\n PayPalCommerceGateway,\n new ErrorHandler(this.gateway.labels.error.generic),\n this.spinner\n );\n\n this.renderer.render(\n this.gateway.button.wrapper,\n this.gateway.hosted_fields.wrapper,\n actionHandler.configuration(),\n );\n }\n\n switchBetweenPayPalandOrderButton() {\n const currentPaymentMethod = jQuery(\n 'input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n }\n else {\n jQuery('#place_order').hide();\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n}\n\nexport default CheckoutBootstap;","import ErrorHandler from '../ErrorHandler';\nimport CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages\n }\n\n init() {\n\n this.render();\n\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n\n jQuery(document.body).\n on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n const actionHandler = new CheckoutActionHandler(\n PayPalCommerceGateway,\n new ErrorHandler(this.gateway.labels.error.generic),\n );\n\n this.renderer.render(\n this.gateway.button.wrapper,\n this.gateway.hosted_fields.wrapper,\n actionHandler.configuration(),\n );\n }\n\n switchBetweenPayPalandOrderButton() {\n const currentPaymentMethod = jQuery(\n 'input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n }\n else {\n jQuery('#place_order').hide();\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n}\n\nexport default PayNowBootstrap;","class Renderer {\n constructor(creditCardRenderer, defaultConfig) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (! document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons ) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n if (! domElement ) {\n return false;\n }\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n if (! domElement ) {\n return false;\n }\n domElement.style.display = 'block';\n return true;\n }\n}\n\nexport default Renderer;","const dccInputFactory = (original) => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach( (prop) => {\n if (! styles[prop] || ! isNaN(prop) ) {\n return;\n }\n newElement.style.setProperty(prop,'' + styles[prop]);\n });\n return newElement;\n}\n\nexport default dccInputFactory;","import dccInputFactory from \"../Helper/DccInputFactory\";\n\nclass CreditCardRenderer {\n\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n }\n\n render(wrapper, contextConfig) {\n\n if (\n (\n this.defaultConfig.context !== 'checkout'\n && this.defaultConfig.context !== 'pay-now'\n )\n || wrapper === null\n || document.querySelector(wrapper) === null\n ) {\n return;\n }\n if (\n typeof paypal.HostedFields === 'undefined'\n || ! paypal.HostedFields.isEligible()\n ) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach( (prop) => {\n if (! stylesRaw[prop]) {\n return;\n }\n styles[prop] = '' + stylesRaw[prop];\n });\n\n const cardNumber = dccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = dccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = dccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n\n gateWayBox.style.display = oldDisplayStyle;\n\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n if (\n this.defaultConfig.enforce_vault\n && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')\n ) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv,\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yyyy,\n }\n }\n }).then(hostedFields => {\n const submitEvent = (event) => {\n this.spinner.block();\n if (event) {\n event.preventDefault();\n }\n this.errorHandler.clear();\n const state = hostedFields.getState();\n const formValid = Object.keys(state.fields).every(function (key) {\n return state.fields[key].isValid;\n });\n\n if (formValid && this.cardValid) {\n\n let vault = document.querySelector(wrapper + ' .ppcp-credit-card-vault') ?\n document.querySelector(wrapper + ' .ppcp-credit-card-vault').checked : false;\n vault = this.defaultConfig.enforce_vault || vault;\n\n hostedFields.submit({\n contingencies: ['3D_SECURE'],\n vault\n }).then((payload) => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n });\n } else {\n this.spinner.unblock();\n const message = ! this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n hostedFields.on('inputSubmitRequest', function () {\n submitEvent(null);\n });\n hostedFields.on('cardTypeChange', (event) => {\n if ( ! event.cards.length ) {\n this.cardValid = false;\n return;\n }\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n })\n document.querySelector(wrapper + ' button').addEventListener(\n 'click',\n submitEvent\n );\n });\n\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(\n 'click',\n () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n }\n )\n }\n}\nexport default CreditCardRenderer;","const storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (! token) {\n return false;\n }\n if (token.user !== user) {\n return false;\n }\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return ! isExpired;\n}\n\nconst storedTokenForUser = (user) => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n if (validateToken(token, user)) {\n return token.token;\n }\n return null;\n}\n\nconst storeToken = (token) => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n}\n\nconst dataClientIdAttributeHandler = (script, config) => {\n const token = storedTokenForUser(config.user);\n if (token) {\n script.setAttribute('data-client-token', token);\n document.body.append(script);\n return;\n }\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then((res)=>{\n return res.json();\n }).then((data)=>{\n const isValid = validateToken(data, config.user);\n if (!isValid) {\n return;\n }\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n}\n\nexport default dataClientIdAttributeHandler;","class MessageRenderer {\n\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (! this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n\n if (! this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined' ) {\n return false;\n }\n if (! document.querySelector(this.config.wrapper)) {\n return false;\n }\n return true;\n }\n}\nexport default MessageRenderer;","class Spinner {\n\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n block() {\n\n jQuery( this.target ).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n\n jQuery( this.target ).unblock();\n }\n}\n\nexport default Spinner;","import MiniCartBootstap from './modules/ContextBootstrap/MiniCartBootstap';\nimport SingleProductBootstap from './modules/ContextBootstrap/SingleProductBootstap';\nimport CartBootstrap from './modules/ContextBootstrap/CartBootstap';\nimport CheckoutBootstap from './modules/ContextBootstrap/CheckoutBootstap';\nimport PayNowBootstrap from \"./modules/ContextBootstrap/PayNowBootstrap\";\nimport Renderer from './modules/Renderer/Renderer';\nimport ErrorHandler from './modules/ErrorHandler';\nimport CreditCardRenderer from \"./modules/Renderer/CreditCardRenderer\";\nimport dataClientIdAttributeHandler from \"./modules/DataClientIdAttributeHandler\";\nimport MessageRenderer from \"./modules/Renderer/MessageRenderer\";\nimport Spinner from \"./modules/Helper/Spinner\";\n\nconst bootstrap = () => {\n const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Spinner();\n const creditCardRenderer = new CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway);\n const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n if (context === 'mini-cart' || context === 'product') {\n const miniCartBootstrap = new MiniCartBootstap(\n PayPalCommerceGateway,\n renderer\n );\n\n miniCartBootstrap.init();\n }\n\n if (context === 'product') {\n const singleProductBootstrap = new SingleProductBootstap(\n PayPalCommerceGateway,\n renderer,\n messageRenderer,\n );\n\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstrap(\n PayPalCommerceGateway,\n renderer,\n );\n\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new CheckoutBootstap(\n PayPalCommerceGateway,\n renderer,\n messageRenderer,\n spinner\n );\n\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now' ) {\n const payNowBootstrap = new PayNowBootstrap(\n PayPalCommerceGateway,\n renderer,\n messageRenderer\n );\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\ndocument.addEventListener(\n 'DOMContentLoaded',\n () => {\n if (!typeof (PayPalCommerceGateway)) {\n console.error('PayPal button could not be configured.');\n return;\n }\n const script = document.createElement('script');\n\n script.addEventListener('load', (event) => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(\n (keyValue) => {\n script.setAttribute(keyValue[0], keyValue[1]);\n }\n );\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n },\n);"],"sourceRoot":""}
modules/ppcp-button/assets/js/hosted-fields.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){e.exports=r.p+"css/hosted-fields.css"}]);
2
+ //# sourceMappingURL=hosted-fields.js.map
modules/ppcp-button/assets/js/hosted-fields.js.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./resources/css/hosted-fields.scss"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,kBClFrDhC,EAAOD,QAAU,IAA0B","file":"js/hosted-fields.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","module.exports = __webpack_public_path__ + \"css/hosted-fields.css\";"],"sourceRoot":""}
modules/ppcp-button/assets/js/hostedfields.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){e.exports=r.p+"css/hosted-fields.css"}]);
2
+ //# sourceMappingURL=hostedfields.js.map
modules/ppcp-button/assets/js/hostedfields.js.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./resources/css/hosted-fields.scss"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,kBClFrDhC,EAAOD,QAAU,IAA0B","file":"js/hostedfields.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","module.exports = __webpack_public_path__ + \"css/hosted-fields.css\";"],"sourceRoot":""}
modules/ppcp-button/extensions.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The button module extensions.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ return array();
modules/ppcp-button/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The button module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new ButtonModule();
16
+ };
modules/ppcp-button/resources/css/hosted-fields.scss ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ #payment ul.payment_methods li img.ppcp-card-icon {
2
+ padding: 0 0 3px 3px;
3
+ max-height: 25px;
4
+ display: inline-block;
5
+ }
modules/ppcp-button/resources/js/button.js ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import MiniCartBootstap from './modules/ContextBootstrap/MiniCartBootstap';
2
+ import SingleProductBootstap from './modules/ContextBootstrap/SingleProductBootstap';
3
+ import CartBootstrap from './modules/ContextBootstrap/CartBootstap';
4
+ import CheckoutBootstap from './modules/ContextBootstrap/CheckoutBootstap';
5
+ import PayNowBootstrap from "./modules/ContextBootstrap/PayNowBootstrap";
6
+ import Renderer from './modules/Renderer/Renderer';
7
+ import ErrorHandler from './modules/ErrorHandler';
8
+ import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
9
+ import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
10
+ import MessageRenderer from "./modules/Renderer/MessageRenderer";
11
+ import Spinner from "./modules/Helper/Spinner";
12
+
13
+ const bootstrap = () => {
14
+ const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
15
+ const spinner = new Spinner();
16
+ const creditCardRenderer = new CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);
17
+ const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway);
18
+ const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
19
+ const context = PayPalCommerceGateway.context;
20
+ if (context === 'mini-cart' || context === 'product') {
21
+ const miniCartBootstrap = new MiniCartBootstap(
22
+ PayPalCommerceGateway,
23
+ renderer
24
+ );
25
+
26
+ miniCartBootstrap.init();
27
+ }
28
+
29
+ if (context === 'product') {
30
+ const singleProductBootstrap = new SingleProductBootstap(
31
+ PayPalCommerceGateway,
32
+ renderer,
33
+ messageRenderer,
34
+ );
35
+
36
+ singleProductBootstrap.init();
37
+ }
38
+
39
+ if (context === 'cart') {
40
+ const cartBootstrap = new CartBootstrap(
41
+ PayPalCommerceGateway,
42
+ renderer,
43
+ );
44
+
45
+ cartBootstrap.init();
46
+ }
47
+
48
+ if (context === 'checkout') {
49
+ const checkoutBootstap = new CheckoutBootstap(
50
+ PayPalCommerceGateway,
51
+ renderer,
52
+ messageRenderer,
53
+ spinner
54
+ );
55
+
56
+ checkoutBootstap.init();
57
+ }
58
+
59
+ if (context === 'pay-now' ) {
60
+ const payNowBootstrap = new PayNowBootstrap(
61
+ PayPalCommerceGateway,
62
+ renderer,
63
+ messageRenderer
64
+ );
65
+ payNowBootstrap.init();
66
+ }
67
+
68
+ if (context !== 'checkout') {
69
+ messageRenderer.render();
70
+ }
71
+ };
72
+ document.addEventListener(
73
+ 'DOMContentLoaded',
74
+ () => {
75
+ if (!typeof (PayPalCommerceGateway)) {
76
+ console.error('PayPal button could not be configured.');
77
+ return;
78
+ }
79
+ const script = document.createElement('script');
80
+
81
+ script.addEventListener('load', (event) => {
82
+ bootstrap();
83
+ });
84
+ script.setAttribute('src', PayPalCommerceGateway.button.url);
85
+ Object.entries(PayPalCommerceGateway.script_attributes).forEach(
86
+ (keyValue) => {
87
+ script.setAttribute(keyValue[0], keyValue[1]);
88
+ }
89
+ );
90
+
91
+ if (PayPalCommerceGateway.data_client_id.set_attribute) {
92
+ dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);
93
+ return;
94
+ }
95
+
96
+ document.body.append(script);
97
+ },
98
+ );
modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import onApprove from '../OnApproveHandler/onApproveForContinue.js';
2
+ import {payerData} from "../Helper/PayerData";
3
+
4
+ class CartActionHandler {
5
+
6
+ constructor(config, errorHandler) {
7
+ this.config = config;
8
+ this.errorHandler = errorHandler;
9
+ }
10
+
11
+ configuration() {
12
+ const createOrder = (data, actions) => {
13
+ const payer = payerData();
14
+ const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
15
+ this.config.bn_codes[this.config.context] : '';
16
+ return fetch(this.config.ajax.create_order.endpoint, {
17
+ method: 'POST',
18
+ body: JSON.stringify({
19
+ nonce: this.config.ajax.create_order.nonce,
20
+ purchase_units: [],
21
+ bn_code:bnCode,
22
+ payer,
23
+ context:this.config.context
24
+ }),
25
+ }).then(function(res) {
26
+ return res.json();
27
+ }).then(function(data) {
28
+ if (!data.success) {
29
+ console.error(data);
30
+ throw Error(data.data.message);
31
+ }
32
+ return data.data.id;
33
+ });
34
+ };
35
+
36
+ return {
37
+ createOrder,
38
+ onApprove: onApprove(this, this.errorHandler),
39
+ onError: (error) => {
40
+ this.errorHandler.genericError();
41
+ }
42
+ };
43
+ }
44
+ }
45
+
46
+ export default CartActionHandler;
modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import onApprove from '../OnApproveHandler/onApproveForPayNow.js';
2
+ import {payerData} from "../Helper/PayerData";
3
+
4
+ class CheckoutActionHandler {
5
+
6
+ constructor(config, errorHandler, spinner) {
7
+ this.config = config;
8
+ this.errorHandler = errorHandler;
9
+ this.spinner = spinner;
10
+ }
11
+
12
+ configuration() {
13
+ const spinner = this.spinner;
14
+ const createOrder = (data, actions) => {
15
+ const payer = payerData();
16
+ const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
17
+ this.config.bn_codes[this.config.context] : '';
18
+
19
+
20
+ const errorHandler = this.errorHandler;
21
+ const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';
22
+ const formValues = jQuery(formSelector).serialize();
23
+
24
+ return fetch(this.config.ajax.create_order.endpoint, {
25
+ method: 'POST',
26
+ body: JSON.stringify({
27
+ nonce: this.config.ajax.create_order.nonce,
28
+ payer,
29
+ bn_code:bnCode,
30
+ context:this.config.context,
31
+ order_id:this.config.order_id,
32
+ form:formValues
33
+ })
34
+ }).then(function (res) {
35
+ return res.json();
36
+ }).then(function (data) {
37
+ if (!data.success) {
38
+ spinner.unblock();
39
+ errorHandler.message(data.data.message, true);
40
+ return;
41
+ }
42
+ const input = document.createElement('input');
43
+ input.setAttribute('type', 'hidden');
44
+ input.setAttribute('name', 'ppcp-resume-order');
45
+ input.setAttribute('value', data.data.purchase_units[0].custom_id);
46
+ document.querySelector(formSelector).append(input);
47
+ return data.data.id;
48
+ });
49
+ }
50
+ return {
51
+ createOrder,
52
+ onApprove:onApprove(this, this.errorHandler, this.spinner),
53
+ onError: (error) => {
54
+ this.errorHandler.genericError();
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ export default CheckoutActionHandler;
modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ButtonsToggleListener from '../Helper/ButtonsToggleListener';
2
+ import Product from '../Entity/Product';
3
+ import onApprove from '../OnApproveHandler/onApproveForContinue';
4
+ import {payerData} from "../Helper/PayerData";
5
+
6
+ class SingleProductActionHandler {
7
+
8
+ constructor(
9
+ config,
10
+ updateCart,
11
+ showButtonCallback,
12
+ hideButtonCallback,
13
+ formElement,
14
+ errorHandler
15
+ ) {
16
+ this.config = config;
17
+ this.updateCart = updateCart;
18
+ this.showButtonCallback = showButtonCallback;
19
+ this.hideButtonCallback = hideButtonCallback;
20
+ this.formElement = formElement;
21
+ this.errorHandler = errorHandler;
22
+ }
23
+
24
+ configuration()
25
+ {
26
+
27
+ if ( this.hasVariations() ) {
28
+ const observer = new ButtonsToggleListener(
29
+ this.formElement.querySelector('.single_add_to_cart_button'),
30
+ this.showButtonCallback,
31
+ this.hideButtonCallback
32
+ );
33
+ observer.init();
34
+ }
35
+
36
+ return {
37
+ createOrder: this.createOrder(),
38
+ onApprove: onApprove(this, this.errorHandler),
39
+ onError: (error) => {
40
+ this.errorHandler.genericError();
41
+ }
42
+ }
43
+ }
44
+
45
+ createOrder()
46
+ {
47
+ var getProducts = null;
48
+ if (! this.isGroupedProduct() ) {
49
+ getProducts = () => {
50
+ const id = document.querySelector('[name="add-to-cart"]').value;
51
+ const qty = document.querySelector('[name="quantity"]').value;
52
+ const variations = this.variations();
53
+ return [new Product(id, qty, variations)];
54
+ }
55
+ } else {
56
+ getProducts = () => {
57
+ const products = [];
58
+ this.formElement.querySelectorAll('input[type="number"]').forEach((element) => {
59
+ if (! element.value) {
60
+ return;
61
+ }
62
+ const elementName = element.getAttribute('name').match(/quantity\[([\d]*)\]/);
63
+ if (elementName.length !== 2) {
64
+ return;
65
+ }
66
+ const id = parseInt(elementName[1]);
67
+ const quantity = parseInt(element.value);
68
+ products.push(new Product(id, quantity, null));
69
+ })
70
+ return products;
71
+ }
72
+ }
73
+ const createOrder = (data, actions) => {
74
+ this.errorHandler.clear();
75
+
76
+ const onResolve = (purchase_units) => {
77
+ const payer = payerData();
78
+ const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
79
+ this.config.bn_codes[this.config.context] : '';
80
+ return fetch(this.config.ajax.create_order.endpoint, {
81
+ method: 'POST',
82
+ body: JSON.stringify({
83
+ nonce: this.config.ajax.create_order.nonce,
84
+ purchase_units,
85
+ payer,
86
+ bn_code:bnCode,
87
+ context:this.config.context
88
+ })
89
+ }).then(function (res) {
90
+ return res.json();
91
+ }).then(function (data) {
92
+ if (!data.success) {
93
+ console.error(data);
94
+ throw Error(data.data.message);
95
+ }
96
+ return data.data.id;
97
+ });
98
+ };
99
+
100
+ const promise = this.updateCart.update(onResolve, getProducts());
101
+ return promise;
102
+ };
103
+ return createOrder;
104
+ }
105
+
106
+ variations()
107
+ {
108
+
109
+ if (! this.hasVariations()) {
110
+ return null;
111
+ }
112
+ const attributes = [...this.formElement.querySelectorAll("[name^='attribute_']")].map(
113
+ (element) => {
114
+ return {
115
+ value:element.value,
116
+ name:element.name
117
+ }
118
+ }
119
+ );
120
+ return attributes;
121
+ }
122
+
123
+ hasVariations()
124
+ {
125
+ return this.formElement.classList.contains('variations_form');
126
+ }
127
+
128
+ isGroupedProduct()
129
+ {
130
+ return this.formElement.classList.contains('grouped_form');
131
+ }
132
+ }
133
+ export default SingleProductActionHandler;
modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import CartActionHandler from '../ActionHandler/CartActionHandler';
2
+ import ErrorHandler from '../ErrorHandler';
3
+
4
+ class CartBootstrap {
5
+ constructor(gateway, renderer) {
6
+ this.gateway = gateway;
7
+ this.renderer = renderer;
8
+ }
9
+
10
+ init() {
11
+ if (!this.shouldRender()) {
12
+ return;
13
+ }
14
+
15
+ this.render();
16
+
17
+ jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
18
+ this.render();
19
+ });
20
+ }
21
+
22
+ shouldRender() {
23
+ return document.querySelector(this.gateway.button.wrapper) !==
24
+ null || document.querySelector(this.gateway.hosted_fields.wrapper) !==
25
+ null;
26
+ }
27
+
28
+ render() {
29
+ const actionHandler = new CartActionHandler(
30
+ PayPalCommerceGateway,
31
+ new ErrorHandler(this.gateway.labels.error.generic),
32
+ );
33
+
34
+ this.renderer.render(
35
+ this.gateway.button.wrapper,
36
+ this.gateway.hosted_fields.wrapper,
37
+ actionHandler.configuration(),
38
+ );
39
+ }
40
+ }
41
+
42
+ export default CartBootstrap;
modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ErrorHandler from '../ErrorHandler';
2
+ import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
3
+
4
+ class CheckoutBootstap {
5
+ constructor(gateway, renderer, messages, spinner) {
6
+ this.gateway = gateway;
7
+ this.renderer = renderer;
8
+ this.messages = messages;
9
+ this.spinner = spinner;
10
+ }
11
+
12
+ init() {
13
+
14
+ this.render();
15
+
16
+ jQuery(document.body).on('updated_checkout', () => {
17
+ this.render();
18
+ });
19
+
20
+ jQuery(document.body).
21
+ on('updated_checkout payment_method_selected', () => {
22
+ this.switchBetweenPayPalandOrderButton();
23
+ });
24
+ this.switchBetweenPayPalandOrderButton();
25
+ }
26
+
27
+ shouldRender() {
28
+ if (document.querySelector(this.gateway.button.cancel_wrapper)) {
29
+ return false;
30
+ }
31
+
32
+ return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;
33
+ }
34
+
35
+ render() {
36
+ if (!this.shouldRender()) {
37
+ return;
38
+ }
39
+ if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {
40
+ document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');
41
+ }
42
+ const actionHandler = new CheckoutActionHandler(
43
+ PayPalCommerceGateway,
44
+ new ErrorHandler(this.gateway.labels.error.generic),
45
+ this.spinner
46
+ );
47
+
48
+ this.renderer.render(
49
+ this.gateway.button.wrapper,
50
+ this.gateway.hosted_fields.wrapper,
51
+ actionHandler.configuration(),
52
+ );
53
+ }
54
+
55
+ switchBetweenPayPalandOrderButton() {
56
+ const currentPaymentMethod = jQuery(
57
+ 'input[name="payment_method"]:checked').val();
58
+
59
+ if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {
60
+ this.renderer.hideButtons(this.gateway.button.wrapper);
61
+ this.renderer.hideButtons(this.gateway.messages.wrapper);
62
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
63
+ jQuery('#place_order').show();
64
+ }
65
+ else {
66
+ jQuery('#place_order').hide();
67
+ if (currentPaymentMethod === 'ppcp-gateway') {
68
+ this.renderer.showButtons(this.gateway.button.wrapper);
69
+ this.renderer.showButtons(this.gateway.messages.wrapper);
70
+ this.messages.render();
71
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
72
+ }
73
+ if (currentPaymentMethod === 'ppcp-credit-card-gateway') {
74
+ this.renderer.hideButtons(this.gateway.button.wrapper);
75
+ this.renderer.hideButtons(this.gateway.messages.wrapper);
76
+ this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ export default CheckoutBootstap;
modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ErrorHandler from '../ErrorHandler';
2
+ import CartActionHandler from '../ActionHandler/CartActionHandler';
3
+
4
+ class MiniCartBootstap {
5
+ constructor(gateway, renderer) {
6
+ this.gateway = gateway;
7
+ this.renderer = renderer;
8
+ this.actionHandler = null;
9
+ }
10
+
11
+ init() {
12
+
13
+ this.actionHandler = new CartActionHandler(
14
+ PayPalCommerceGateway,
15
+ new ErrorHandler(this.gateway.labels.error.generic),
16
+ );
17
+ this.render();
18
+
19
+ jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {
20
+ this.render();
21
+ });
22
+ }
23
+
24
+ shouldRender() {
25
+ return document.querySelector(this.gateway.button.mini_cart_wrapper) !==
26
+ null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !==
27
+ null;
28
+ }
29
+
30
+ render() {
31
+ if (!this.shouldRender()) {
32
+ return;
33
+ }
34
+
35
+ this.renderer.render(
36
+ this.gateway.button.mini_cart_wrapper,
37
+ this.gateway.hosted_fields.mini_cart_wrapper,
38
+ this.actionHandler.configuration()
39
+ );
40
+ }
41
+ }
42
+
43
+ export default MiniCartBootstap;
modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ErrorHandler from '../ErrorHandler';
2
+ import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
3
+
4
+ class PayNowBootstrap {
5
+ constructor(gateway, renderer, messages) {
6
+ this.gateway = gateway;
7
+ this.renderer = renderer;
8
+ this.messages = messages
9
+ }
10
+
11
+ init() {
12
+
13
+ this.render();
14
+
15
+ jQuery(document.body).on('updated_checkout', () => {
16
+ this.render();
17
+ });
18
+
19
+ jQuery(document.body).
20
+ on('updated_checkout payment_method_selected', () => {
21
+ this.switchBetweenPayPalandOrderButton();
22
+ });
23
+ this.switchBetweenPayPalandOrderButton();
24
+ }
25
+
26
+ shouldRender() {
27
+ if (document.querySelector(this.gateway.button.cancel_wrapper)) {
28
+ return false;
29
+ }
30
+
31
+ return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;
32
+ }
33
+
34
+ render() {
35
+ if (!this.shouldRender()) {
36
+ return;
37
+ }
38
+ if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {
39
+ document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');
40
+ }
41
+ const actionHandler = new CheckoutActionHandler(
42
+ PayPalCommerceGateway,
43
+ new ErrorHandler(this.gateway.labels.error.generic),
44
+ );
45
+
46
+ this.renderer.render(
47
+ this.gateway.button.wrapper,
48
+ this.gateway.hosted_fields.wrapper,
49
+ actionHandler.configuration(),
50
+ );
51
+ }
52
+
53
+ switchBetweenPayPalandOrderButton() {
54
+ const currentPaymentMethod = jQuery(
55
+ 'input[name="payment_method"]:checked').val();
56
+
57
+ if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {
58
+ this.renderer.hideButtons(this.gateway.button.wrapper);
59
+ this.renderer.hideButtons(this.gateway.messages.wrapper);
60
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
61
+ jQuery('#place_order').show();
62
+ }
63
+ else {
64
+ jQuery('#place_order').hide();
65
+ if (currentPaymentMethod === 'ppcp-gateway') {
66
+ this.renderer.showButtons(this.gateway.button.wrapper);
67
+ this.renderer.showButtons(this.gateway.messages.wrapper);
68
+ this.messages.render();
69
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
70
+ }
71
+ if (currentPaymentMethod === 'ppcp-credit-card-gateway') {
72
+ this.renderer.hideButtons(this.gateway.button.wrapper);
73
+ this.renderer.hideButtons(this.gateway.messages.wrapper);
74
+ this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ export default PayNowBootstrap;
modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ErrorHandler from '../ErrorHandler';
2
+ import UpdateCart from "../Helper/UpdateCart";
3
+ import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler";
4
+
5
+ class SingleProductBootstap {
6
+ constructor(gateway, renderer, messages) {
7
+ this.gateway = gateway;
8
+ this.renderer = renderer;
9
+ this.messages = messages;
10
+ }
11
+
12
+ init() {
13
+ if (!this.shouldRender()) {
14
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
15
+ return;
16
+ }
17
+
18
+ this.render();
19
+ }
20
+
21
+ shouldRender() {
22
+ if (document.querySelector('form.cart') === null) {
23
+ return false;
24
+ }
25
+
26
+ return true;
27
+ }
28
+
29
+ render() {
30
+ const actionHandler = new SingleProductActionHandler(
31
+ this.gateway,
32
+ new UpdateCart(
33
+ this.gateway.ajax.change_cart.endpoint,
34
+ this.gateway.ajax.change_cart.nonce,
35
+ ),
36
+ () => {
37
+ this.renderer.showButtons(this.gateway.button.wrapper);
38
+ this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
39
+ let priceText = "0";
40
+ if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {
41
+ priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;
42
+ }
43
+ else if (document.querySelector('form.cart .woocommerce-Price-amount')) {
44
+ priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;
45
+ }
46
+ const amount = parseInt(priceText.replace(/([^\d,\.\s]*)/g, ''));
47
+ this.messages.renderWithAmount(amount)
48
+ },
49
+ () => {
50
+ this.renderer.hideButtons(this.gateway.button.wrapper);
51
+ this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
52
+ },
53
+ document.querySelector('form.cart'),
54
+ new ErrorHandler(this.gateway.labels.error.generic),
55
+ );
56
+
57
+ this.renderer.render(
58
+ this.gateway.button.wrapper,
59
+ this.gateway.hosted_fields.wrapper,
60
+ actionHandler.configuration(),
61
+ );
62
+ }
63
+ }
64
+
65
+ export default SingleProductBootstap;
modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const storageKey = 'ppcp-data-client-id';
2
+
3
+ const validateToken = (token, user) => {
4
+ if (! token) {
5
+ return false;
6
+ }
7
+ if (token.user !== user) {
8
+ return false;
9
+ }
10
+ const currentTime = new Date().getTime();
11
+ const isExpired = currentTime >= token.expiration * 1000;
12
+ return ! isExpired;
13
+ }
14
+
15
+ const storedTokenForUser = (user) => {
16
+ const token = JSON.parse(sessionStorage.getItem(storageKey));
17
+ if (validateToken(token, user)) {
18
+ return token.token;
19
+ }
20
+ return null;
21
+ }
22
+
23
+ const storeToken = (token) => {
24
+ sessionStorage.setItem(storageKey, JSON.stringify(token));
25
+ }
26
+
27
+ const dataClientIdAttributeHandler = (script, config) => {
28
+ const token = storedTokenForUser(config.user);
29
+ if (token) {
30
+ script.setAttribute('data-client-token', token);
31
+ document.body.append(script);
32
+ return;
33
+ }
34
+ fetch(config.endpoint, {
35
+ method: 'POST',
36
+ body: JSON.stringify({
37
+ nonce: config.nonce
38
+ })
39
+ }).then((res)=>{
40
+ return res.json();
41
+ }).then((data)=>{
42
+ const isValid = validateToken(data, config.user);
43
+ if (!isValid) {
44
+ return;
45
+ }
46
+ storeToken(data);
47
+ script.setAttribute('data-client-token', data.token);
48
+ document.body.append(script);
49
+ });
50
+ }
51
+
52
+ export default dataClientIdAttributeHandler;
modules/ppcp-button/resources/js/modules/Entity/Product.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Product {
2
+
3
+ constructor(id, quantity, variations) {
4
+ this.id = id;
5
+ this.quantity = quantity;
6
+ this.variations = variations;
7
+ }
8
+
9
+ data() {
10
+ return {
11
+ id:this.id,
12
+ quantity:this.quantity,
13
+ variations:this.variations
14
+ }
15
+ }
16
+ }
17
+
18
+ export default Product;
modules/ppcp-button/resources/js/modules/ErrorHandler.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class ErrorHandler {
2
+
3
+ constructor(genericErrorText)
4
+ {
5
+ this.genericErrorText = genericErrorText;
6
+ this.wrapper = document.querySelector('.woocommerce-notices-wrapper');
7
+ }
8
+
9
+ genericError() {
10
+ if (this.wrapper.classList.contains('ppcp-persist')) {
11
+ return;
12
+ }
13
+ this.clear();
14
+ this.message(this.genericErrorText)
15
+ }
16
+
17
+ message(text, persist = false)
18
+ {
19
+ this.wrapper.classList.add('woocommerce-error');
20
+ if (persist) {
21
+ this.wrapper.classList.add('ppcp-persist');
22
+ } else {
23
+ this.wrapper.classList.remove('ppcp-persist');
24
+ }
25
+ this.wrapper.innerText = this.sanitize(text);
26
+ jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'))
27
+ }
28
+
29
+ sanitize(text)
30
+ {
31
+ const textarea = document.createElement('textarea');
32
+ textarea.innerHTML = text;
33
+ return textarea.value.replace('Error: ', '');
34
+ }
35
+
36
+ clear()
37
+ {
38
+ if (! this.wrapper.classList.contains('woocommerce-error')) {
39
+ return;
40
+ }
41
+ this.wrapper.classList.remove('woocommerce-error');
42
+ this.wrapper.innerText = '';
43
+ }
44
+ }
45
+
46
+ export default ErrorHandler;
modules/ppcp-button/resources/js/modules/Helper/ButtonsToggleListener.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * When you can't add something to the cart, the PayPal buttons should not show.
3
+ * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.
4
+ */
5
+
6
+ class ButtonsToggleListener {
7
+ constructor(element, showCallback, hideCallback)
8
+ {
9
+ this.element = element;
10
+ this.showCallback = showCallback;
11
+ this.hideCallback = hideCallback;
12
+ this.observer = null;
13
+ }
14
+
15
+ init()
16
+ {
17
+ const config = { attributes : true };
18
+ const callback = () => {
19
+ if (this.element.classList.contains('disabled')) {
20
+ this.hideCallback();
21
+ return;
22
+ }
23
+ this.showCallback();
24
+ }
25
+ this.observer = new MutationObserver(callback);
26
+ this.observer.observe(this.element, config);
27
+ callback();
28
+ }
29
+
30
+ disconnect()
31
+ {
32
+ this.observer.disconnect();
33
+ }
34
+ }
35
+
36
+ export default ButtonsToggleListener;
modules/ppcp-button/resources/js/modules/Helper/DccInputFactory.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const dccInputFactory = (original) => {
2
+ const styles = window.getComputedStyle(original);
3
+ const newElement = document.createElement('span');
4
+ newElement.setAttribute('id', original.id);
5
+ Object.values(styles).forEach( (prop) => {
6
+ if (! styles[prop] || ! isNaN(prop) ) {
7
+ return;
8
+ }
9
+ newElement.style.setProperty(prop,'' + styles[prop]);
10
+ });
11
+ return newElement;
12
+ }
13
+
14
+ export default dccInputFactory;
modules/ppcp-button/resources/js/modules/Helper/PayerData.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const payerData = () => {
2
+ const payer = PayPalCommerceGateway.payer;
3
+ if (! payer) {
4
+ return null;
5
+ }
6
+
7
+ const phone = (document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined') ?
8
+ {
9
+ phone_type:"HOME",
10
+ phone_number:{
11
+ national_number : (document.querySelector('#billing_phone')) ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number
12
+ }
13
+ } : null;
14
+ const payerData = {
15
+ email_address:(document.querySelector('#billing_email')) ? document.querySelector('#billing_email').value : payer.email_address,
16
+ name : {
17
+ surname: (document.querySelector('#billing_last_name')) ? document.querySelector('#billing_last_name').value : payer.name.surname,
18
+ given_name: (document.querySelector('#billing_first_name')) ? document.querySelector('#billing_first_name').value : payer.name.given_name
19
+ },
20
+ address : {
21
+ country_code : (document.querySelector('#billing_country')) ? document.querySelector('#billing_country').value : payer.address.country_code,
22
+ address_line_1 : (document.querySelector('#billing_address_1')) ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,
23
+ address_line_2 : (document.querySelector('#billing_address_2')) ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,
24
+ admin_area_1 : (document.querySelector('#billing_state')) ? document.querySelector('#billing_state').value : payer.address.admin_area_1,
25
+ admin_area_2 : (document.querySelector('#billing_city')) ? document.querySelector('#billing_city').value : payer.address.admin_area_2,
26
+ postal_code : (document.querySelector('#billing_postcode')) ? document.querySelector('#billing_postcode').value : payer.address.postal_code
27
+ }
28
+ };
29
+
30
+ if (phone) {
31
+ payerData.phone = phone;
32
+ }
33
+ return payerData;
34
+ }
modules/ppcp-button/resources/js/modules/Helper/Spinner.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Spinner {
2
+
3
+ constructor() {
4
+ this.target = 'form.woocommerce-checkout';
5
+ }
6
+ block() {
7
+
8
+ jQuery( this.target ).block({
9
+ message: null,
10
+ overlayCSS: {
11
+ background: '#fff',
12
+ opacity: 0.6
13
+ }
14
+ });
15
+ }
16
+
17
+ unblock() {
18
+
19
+ jQuery( this.target ).unblock();
20
+ }
21
+ }
22
+
23
+ export default Spinner;
modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Product from "../Entity/Product";
2
+ class UpdateCart {
3
+
4
+ constructor(endpoint, nonce)
5
+ {
6
+ this.endpoint = endpoint;
7
+ this.nonce = nonce;
8
+ }
9
+
10
+ /**
11
+ *
12
+ * @param onResolve
13
+ * @param {Product[]} products
14
+ * @returns {Promise<unknown>}
15
+ */
16
+ update(onResolve, products)
17
+ {
18
+ return new Promise((resolve, reject) => {
19
+ fetch(
20
+ this.endpoint,
21
+ {
22
+ method: 'POST',
23
+ body: JSON.stringify({
24
+ nonce: this.nonce,
25
+ products,
26
+ })
27
+ }
28
+ ).then(
29
+ (result) => {
30
+ return result.json();
31
+ }
32
+ ).then((result) => {
33
+ if (! result.success) {
34
+ reject(result.data);
35
+ return;
36
+ }
37
+
38
+ const resolved = onResolve(result.data);
39
+ resolve(resolved);
40
+ })
41
+ });
42
+ }
43
+ }
44
+
45
+ export default UpdateCart;
modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const onApprove = (context, errorHandler) => {
2
+ return (data, actions) => {
3
+ return fetch(context.config.ajax.approve_order.endpoint, {
4
+ method: 'POST',
5
+ body: JSON.stringify({
6
+ nonce: context.config.ajax.approve_order.nonce,
7
+ order_id:data.orderID
8
+ })
9
+ }).then((res)=>{
10
+ return res.json();
11
+ }).then((data)=>{
12
+ if (!data.success) {
13
+ errorHandler.genericError();
14
+ return actions.restart().catch(err => {
15
+ errorHandler.genericError();
16
+ });;
17
+ }
18
+ location.href = context.config.redirect;
19
+ });
20
+
21
+ }
22
+ }
23
+
24
+ export default onApprove;
modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const onApprove = (context, errorHandler, spinner) => {
2
+ return (data, actions) => {
3
+ spinner.block();
4
+ return fetch(context.config.ajax.approve_order.endpoint, {
5
+ method: 'POST',
6
+ body: JSON.stringify({
7
+ nonce: context.config.ajax.approve_order.nonce,
8
+ order_id:data.orderID
9
+ })
10
+ }).then((res)=>{
11
+ return res.json();
12
+ }).then((data)=>{
13
+ spinner.unblock();
14
+ if (!data.success) {
15
+ if (data.data.code === 100) {
16
+ errorHandler.message(data.data.message);
17
+ } else {
18
+ errorHandler.genericError();
19
+ }
20
+ if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {
21
+ return actions.restart();
22
+ }
23
+ throw new Error(data.data.message);
24
+ }
25
+ document.querySelector('#place_order').click()
26
+ });
27
+
28
+ }
29
+ }
30
+
31
+ export default onApprove;
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dccInputFactory from "../Helper/DccInputFactory";
2
+
3
+ class CreditCardRenderer {
4
+
5
+ constructor(defaultConfig, errorHandler, spinner) {
6
+ this.defaultConfig = defaultConfig;
7
+ this.errorHandler = errorHandler;
8
+ this.spinner = spinner;
9
+ this.cardValid = false;
10
+ }
11
+
12
+ render(wrapper, contextConfig) {
13
+
14
+ if (
15
+ (
16
+ this.defaultConfig.context !== 'checkout'
17
+ && this.defaultConfig.context !== 'pay-now'
18
+ )
19
+ || wrapper === null
20
+ || document.querySelector(wrapper) === null
21
+ ) {
22
+ return;
23
+ }
24
+ if (
25
+ typeof paypal.HostedFields === 'undefined'
26
+ || ! paypal.HostedFields.isEligible()
27
+ ) {
28
+ const wrapperElement = document.querySelector(wrapper);
29
+ wrapperElement.parentNode.removeChild(wrapperElement);
30
+ return;
31
+ }
32
+
33
+ const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
34
+ const oldDisplayStyle = gateWayBox.style.display;
35
+ gateWayBox.style.display = 'block';
36
+
37
+ const hideDccGateway = document.querySelector('#ppcp-hide-dcc');
38
+ if (hideDccGateway) {
39
+ hideDccGateway.parentNode.removeChild(hideDccGateway);
40
+ }
41
+
42
+ const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');
43
+
44
+ const stylesRaw = window.getComputedStyle(cardNumberField);
45
+ let styles = {};
46
+ Object.values(stylesRaw).forEach( (prop) => {
47
+ if (! stylesRaw[prop]) {
48
+ return;
49
+ }
50
+ styles[prop] = '' + stylesRaw[prop];
51
+ });
52
+
53
+ const cardNumber = dccInputFactory(cardNumberField);
54
+ cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);
55
+
56
+ const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');
57
+ const cardExpiry = dccInputFactory(cardExpiryField);
58
+ cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);
59
+
60
+ const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');
61
+ const cardCode = dccInputFactory(cardCodeField);
62
+ cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);
63
+
64
+ gateWayBox.style.display = oldDisplayStyle;
65
+
66
+ const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';
67
+ if (
68
+ this.defaultConfig.enforce_vault
69
+ && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')
70
+ ) {
71
+ document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;
72
+ document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);
73
+ }
74
+ paypal.HostedFields.render({
75
+ createOrder: contextConfig.createOrder,
76
+ styles: {
77
+ 'input': styles
78
+ },
79
+ fields: {
80
+ number: {
81
+ selector: '#ppcp-credit-card-gateway-card-number',
82
+ placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,
83
+ },
84
+ cvv: {
85
+ selector: '#ppcp-credit-card-gateway-card-cvc',
86
+ placeholder: this.defaultConfig.hosted_fields.labels.cvv,
87
+ },
88
+ expirationDate: {
89
+ selector: '#ppcp-credit-card-gateway-card-expiry',
90
+ placeholder: this.defaultConfig.hosted_fields.labels.mm_yyyy,
91
+ }
92
+ }
93
+ }).then(hostedFields => {
94
+ const submitEvent = (event) => {
95
+ this.spinner.block();
96
+ if (event) {
97
+ event.preventDefault();
98
+ }
99
+ this.errorHandler.clear();
100
+ const state = hostedFields.getState();
101
+ const formValid = Object.keys(state.fields).every(function (key) {
102
+ return state.fields[key].isValid;
103
+ });
104
+
105
+ if (formValid && this.cardValid) {
106
+
107
+ let vault = document.querySelector(wrapper + ' .ppcp-credit-card-vault') ?
108
+ document.querySelector(wrapper + ' .ppcp-credit-card-vault').checked : false;
109
+ vault = this.defaultConfig.enforce_vault || vault;
110
+
111
+ hostedFields.submit({
112
+ contingencies: ['3D_SECURE'],
113
+ vault
114
+ }).then((payload) => {
115
+ payload.orderID = payload.orderId;
116
+ this.spinner.unblock();
117
+ return contextConfig.onApprove(payload);
118
+ });
119
+ } else {
120
+ this.spinner.unblock();
121
+ const message = ! this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;
122
+ this.errorHandler.message(message);
123
+ }
124
+ }
125
+ hostedFields.on('inputSubmitRequest', function () {
126
+ submitEvent(null);
127
+ });
128
+ hostedFields.on('cardTypeChange', (event) => {
129
+ if ( ! event.cards.length ) {
130
+ this.cardValid = false;
131
+ return;
132
+ }
133
+ const validCards = this.defaultConfig.hosted_fields.valid_cards;
134
+ this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;
135
+ })
136
+ document.querySelector(wrapper + ' button').addEventListener(
137
+ 'click',
138
+ submitEvent
139
+ );
140
+ });
141
+
142
+ document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(
143
+ 'click',
144
+ () => {
145
+ document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();
146
+ }
147
+ )
148
+ }
149
+ }
150
+ export default CreditCardRenderer;
modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class MessageRenderer {
2
+
3
+ constructor(config) {
4
+ this.config = config;
5
+ }
6
+
7
+ render() {
8
+ if (! this.shouldRender()) {
9
+ return;
10
+ }
11
+
12
+ paypal.Messages({
13
+ amount: this.config.amount,
14
+ placement: this.config.placement,
15
+ style: this.config.style
16
+ }).render(this.config.wrapper);
17
+ }
18
+
19
+ renderWithAmount(amount) {
20
+
21
+ if (! this.shouldRender()) {
22
+ return;
23
+ }
24
+
25
+ const newWrapper = document.createElement('div');
26
+ newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));
27
+
28
+ const sibling = document.querySelector(this.config.wrapper).nextSibling;
29
+ document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));
30
+ sibling.parentElement.insertBefore(newWrapper, sibling);
31
+ paypal.Messages({
32
+ amount,
33
+ placement: this.config.placement,
34
+ style: this.config.style
35
+ }).render(this.config.wrapper);
36
+ }
37
+
38
+ shouldRender() {
39
+
40
+ if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined' ) {
41
+ return false;
42
+ }
43
+ if (! document.querySelector(this.config.wrapper)) {
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+ }
49
+ export default MessageRenderer;
modules/ppcp-button/resources/js/modules/Renderer/Renderer.js ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Renderer {
2
+ constructor(creditCardRenderer, defaultConfig) {
3
+ this.defaultConfig = defaultConfig;
4
+ this.creditCardRenderer = creditCardRenderer;
5
+ }
6
+
7
+ render(wrapper, hostedFieldsWrapper, contextConfig) {
8
+
9
+ this.renderButtons(wrapper, contextConfig);
10
+ this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);
11
+ }
12
+
13
+ renderButtons(wrapper, contextConfig) {
14
+ if (! document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons ) {
15
+ return;
16
+ }
17
+
18
+ const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;
19
+ paypal.Buttons({
20
+ style,
21
+ ...contextConfig,
22
+ }).render(wrapper);
23
+ }
24
+
25
+ isAlreadyRendered(wrapper) {
26
+ return document.querySelector(wrapper).hasChildNodes();
27
+ }
28
+
29
+ hideButtons(element) {
30
+ const domElement = document.querySelector(element);
31
+ if (! domElement ) {
32
+ return false;
33
+ }
34
+ domElement.style.display = 'none';
35
+ return true;
36
+ }
37
+
38
+ showButtons(element) {
39
+ const domElement = document.querySelector(element);
40
+ if (! domElement ) {
41
+ return false;
42
+ }
43
+ domElement.style.display = 'block';
44
+ return true;
45
+ }
46
+ }
47
+
48
+ export default Renderer;
modules/ppcp-button/services.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The button module services.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button;
11
+
12
+ use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
13
+ use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
14
+ use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
15
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
16
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
17
+ use WooCommerce\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
18
+ use WooCommerce\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
19
+ use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
20
+ use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
21
+ use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
22
+ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
23
+ use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
24
+ use WooCommerce\PayPalCommerce\Onboarding\Environment;
25
+ use WooCommerce\PayPalCommerce\Onboarding\State;
26
+
27
+ return array(
28
+ 'button.client_id' => static function ( $container ): string {
29
+
30
+ $settings = $container->get( 'wcgateway.settings' );
31
+ $client_id = $settings->has( 'client_id' ) ? $settings->get( 'client_id' ) : '';
32
+ if ( $client_id ) {
33
+ return $client_id;
34
+ }
35
+
36
+ $env = $container->get( 'onboarding.environment' );
37
+ /**
38
+ * The environment.
39
+ *
40
+ * @var Environment $env
41
+ */
42
+
43
+ return $env->current_environment_is( Environment::SANDBOX ) ?
44
+ CONNECT_WOO_SANDBOX_CLIENT_ID : CONNECT_WOO_CLIENT_ID;
45
+ },
46
+ 'button.smart-button' => static function ( $container ): SmartButtonInterface {
47
+
48
+ $state = $container->get( 'onboarding.state' );
49
+ /**
50
+ * The state.
51
+ *
52
+ * @var State $state
53
+ */
54
+ if ( $state->current_state() < State::STATE_PROGRESSIVE ) {
55
+ return new DisabledSmartButton();
56
+ }
57
+ $settings = $container->get( 'wcgateway.settings' );
58
+ $paypal_disabled = ! $settings->has( 'enabled' ) || ! $settings->get( 'enabled' );
59
+ if ( $paypal_disabled ) {
60
+ return new DisabledSmartButton();
61
+ }
62
+ $payee_repository = $container->get( 'api.repository.payee' );
63
+ $identity_token = $container->get( 'api.endpoint.identity-token' );
64
+ $payer_factory = $container->get( 'api.factory.payer' );
65
+ $request_data = $container->get( 'button.request-data' );
66
+
67
+ $client_id = $container->get( 'button.client_id' );
68
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
69
+ $subscription_helper = $container->get( 'subscription.helper' );
70
+ $messages_apply = $container->get( 'button.helper.messages-apply' );
71
+ return new SmartButton(
72
+ $container->get( 'button.url' ),
73
+ $container->get( 'session.handler' ),
74
+ $settings,
75
+ $payee_repository,
76
+ $identity_token,
77
+ $payer_factory,
78
+ $client_id,
79
+ $request_data,
80
+ $dcc_applies,
81
+ $subscription_helper,
82
+ $messages_apply
83
+ );
84
+ },
85
+ 'button.url' => static function ( $container ): string {
86
+ return plugins_url(
87
+ '/modules/ppcp-button/',
88
+ dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
89
+ );
90
+ },
91
+ 'button.request-data' => static function ( $container ): RequestData {
92
+ return new RequestData();
93
+ },
94
+ 'button.endpoint.change-cart' => static function ( $container ): ChangeCartEndpoint {
95
+ if ( ! \WC()->cart ) {
96
+ throw new RuntimeException( 'cant initialize endpoint at this moment' );
97
+ }
98
+ $cart = WC()->cart;
99
+ $shipping = WC()->shipping();
100
+ $request_data = $container->get( 'button.request-data' );
101
+ $repository = $container->get( 'api.repository.cart' );
102
+ $data_store = \WC_Data_Store::load( 'product' );
103
+ return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store );
104
+ },
105
+ 'button.endpoint.create-order' => static function ( $container ): CreateOrderEndpoint {
106
+ $request_data = $container->get( 'button.request-data' );
107
+ $cart_repository = $container->get( 'api.repository.cart' );
108
+ $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
109
+ $order_endpoint = $container->get( 'api.endpoint.order' );
110
+ $payer_factory = $container->get( 'api.factory.payer' );
111
+ $session_handler = $container->get( 'session.handler' );
112
+ $settings = $container->get( 'wcgateway.settings' );
113
+ $early_order_handler = $container->get( 'button.helper.early-order-handler' );
114
+ return new CreateOrderEndpoint(
115
+ $request_data,
116
+ $cart_repository,
117
+ $purchase_unit_factory,
118
+ $order_endpoint,
119
+ $payer_factory,
120
+ $session_handler,
121
+ $settings,
122
+ $early_order_handler
123
+ );
124
+ },
125
+ 'button.helper.early-order-handler' => static function ( $container ) : EarlyOrderHandler {
126
+
127
+ $state = $container->get( 'onboarding.state' );
128
+ $order_processor = $container->get( 'wcgateway.order-processor' );
129
+ $session_handler = $container->get( 'session.handler' );
130
+ $prefix = $container->get( 'api.prefix' );
131
+ return new EarlyOrderHandler( $state, $order_processor, $session_handler, $prefix );
132
+ },
133
+ 'button.endpoint.approve-order' => static function ( $container ): ApproveOrderEndpoint {
134
+ $request_data = $container->get( 'button.request-data' );
135
+ $order_endpoint = $container->get( 'api.endpoint.order' );
136
+ $session_handler = $container->get( 'session.handler' );
137
+ $three_d_secure = $container->get( 'button.helper.three-d-secure' );
138
+ $settings = $container->get( 'wcgateway.settings' );
139
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
140
+ return new ApproveOrderEndpoint(
141
+ $request_data,
142
+ $order_endpoint,
143
+ $session_handler,
144
+ $three_d_secure,
145
+ $settings,
146
+ $dcc_applies
147
+ );
148
+ },
149
+ 'button.endpoint.data-client-id' => static function( $container ) : DataClientIdEndpoint {
150
+ $request_data = $container->get( 'button.request-data' );
151
+ $identity_token = $container->get( 'api.endpoint.identity-token' );
152
+ return new DataClientIdEndpoint(
153
+ $request_data,
154
+ $identity_token
155
+ );
156
+ },
157
+ 'button.helper.three-d-secure' => static function ( $container ): ThreeDSecure {
158
+ return new ThreeDSecure();
159
+ },
160
+ 'button.helper.messages-apply' => static function ( $container ): MessagesApply {
161
+ return new MessagesApply();
162
+ },
163
+ );
modules/ppcp-button/src/Assets/class-disabledsmartbutton.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * If we can't render our buttons, this Null object will be used.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Assets
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Assets;
11
+
12
+ /**
13
+ * Class DisabledSmartButton
14
+ */
15
+ class DisabledSmartButton implements SmartButtonInterface {
16
+
17
+ /**
18
+ * Renders the necessary HTML.
19
+ *
20
+ * @return bool
21
+ */
22
+ public function render_wrapper(): bool {
23
+ return true;
24
+ }
25
+
26
+ /**
27
+ * Enqueues necessary scripts.
28
+ *
29
+ * @return bool
30
+ */
31
+ public function enqueue(): bool {
32
+ return true;
33
+ }
34
+
35
+ /**
36
+ * Whether tokens can be stored or not.
37
+ *
38
+ * @return bool
39
+ */
40
+ public function can_save_vault_token(): bool {
41
+
42
+ return false;
43
+ }
44
+ }
modules/ppcp-button/src/Assets/class-smartbutton.php ADDED
@@ -0,0 +1,912 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Registers and configures the necessary Javascript for the button, credit messaging and DCC fields.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Assets
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Assets;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
16
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
17
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
18
+ use WooCommerce\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
19
+ use WooCommerce\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
20
+ use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
21
+ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
22
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
23
+ use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
24
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
25
+
26
+ /**
27
+ * Class SmartButton
28
+ */
29
+ class SmartButton implements SmartButtonInterface {
30
+
31
+ /**
32
+ * The URL to the module.
33
+ *
34
+ * @var string
35
+ */
36
+ private $module_url;
37
+
38
+ /**
39
+ * The Session Handler.
40
+ *
41
+ * @var SessionHandler
42
+ */
43
+ private $session_handler;
44
+
45
+ /**
46
+ * The settings.
47
+ *
48
+ * @var Settings
49
+ */
50
+ private $settings;
51
+
52
+ /**
53
+ * The Payee Repository.
54
+ *
55
+ * @var PayeeRepository
56
+ */
57
+ private $payee_repository;
58
+
59
+ /**
60
+ * The Identity Token.
61
+ *
62
+ * @var IdentityToken
63
+ */
64
+ private $identity_token;
65
+
66
+ /**
67
+ * The Payer Factory.
68
+ *
69
+ * @var PayerFactory
70
+ */
71
+ private $payer_factory;
72
+
73
+ /**
74
+ * The client ID.
75
+ *
76
+ * @var string
77
+ */
78
+ private $client_id;
79
+
80
+ /**
81
+ * The Request Data.
82
+ *
83
+ * @var RequestData
84
+ */
85
+ private $request_data;
86
+
87
+ /**
88
+ * The DCC Applies helper.
89
+ *
90
+ * @var DccApplies
91
+ */
92
+ private $dcc_applies;
93
+
94
+ /**
95
+ * The Subscription Helper.
96
+ *
97
+ * @var SubscriptionHelper
98
+ */
99
+ private $subscription_helper;
100
+
101
+ /**
102
+ * The Messages apply helper.
103
+ *
104
+ * @var MessagesApply
105
+ */
106
+ private $messages_apply;
107
+
108
+ /**
109
+ * SmartButton constructor.
110
+ *
111
+ * @param string $module_url The URL to the module.
112
+ * @param SessionHandler $session_handler The Session Handler.
113
+ * @param Settings $settings The Settings.
114
+ * @param PayeeRepository $payee_repository The Payee Repository.
115
+ * @param IdentityToken $identity_token The Identity Token.
116
+ * @param PayerFactory $payer_factory The Payer factory.
117
+ * @param string $client_id The client ID.
118
+ * @param RequestData $request_data The Request Data helper.
119
+ * @param DccApplies $dcc_applies The DCC applies helper.
120
+ * @param SubscriptionHelper $subscription_helper The subscription helper.
121
+ * @param MessagesApply $messages_apply The Messages apply helper.
122
+ */
123
+ public function __construct(
124
+ string $module_url,
125
+ SessionHandler $session_handler,
126
+ Settings $settings,
127
+ PayeeRepository $payee_repository,
128
+ IdentityToken $identity_token,
129
+ PayerFactory $payer_factory,
130
+ string $client_id,
131
+ RequestData $request_data,
132
+ DccApplies $dcc_applies,
133
+ SubscriptionHelper $subscription_helper,
134
+ MessagesApply $messages_apply
135
+ ) {
136
+
137
+ $this->module_url = $module_url;
138
+ $this->session_handler = $session_handler;
139
+ $this->settings = $settings;
140
+ $this->payee_repository = $payee_repository;
141
+ $this->identity_token = $identity_token;
142
+ $this->payer_factory = $payer_factory;
143
+ $this->client_id = $client_id;
144
+ $this->request_data = $request_data;
145
+ $this->dcc_applies = $dcc_applies;
146
+ $this->subscription_helper = $subscription_helper;
147
+ $this->messages_apply = $messages_apply;
148
+ }
149
+
150
+ /**
151
+ * Registers the necessary action hooks to render the HTML depending on the settings.
152
+ *
153
+ * @return bool
154
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
155
+ */
156
+ public function render_wrapper(): bool {
157
+
158
+ if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
159
+ return false;
160
+ }
161
+
162
+ if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
163
+ $this->render_button_wrapper_registrar();
164
+ $this->render_message_wrapper_registrar();
165
+ }
166
+
167
+ if (
168
+ $this->settings->has( 'dcc_enabled' )
169
+ && $this->settings->get( 'dcc_enabled' )
170
+ && ! $this->session_handler->order()
171
+ ) {
172
+ add_action(
173
+ 'woocommerce_review_order_after_submit',
174
+ array(
175
+ $this,
176
+ 'dcc_renderer',
177
+ ),
178
+ 11
179
+ );
180
+
181
+ add_action(
182
+ 'woocommerce_pay_order_after_submit',
183
+ array(
184
+ $this,
185
+ 'dcc_renderer',
186
+ ),
187
+ 11
188
+ );
189
+ }
190
+ return true;
191
+ }
192
+
193
+ /**
194
+ * Registers the hooks to render the credit messaging HTML depending on the settings.
195
+ *
196
+ * @return bool
197
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
198
+ */
199
+ private function render_message_wrapper_registrar(): bool {
200
+
201
+ $not_enabled_on_cart = $this->settings->has( 'message_cart_enabled' ) &&
202
+ ! $this->settings->get( 'message_cart_enabled' );
203
+ if (
204
+ is_cart()
205
+ && ! $not_enabled_on_cart
206
+ ) {
207
+ add_action(
208
+ 'woocommerce_proceed_to_checkout',
209
+ array(
210
+ $this,
211
+ 'message_renderer',
212
+ ),
213
+ 19
214
+ );
215
+ }
216
+
217
+ $not_enabled_on_product_page = $this->settings->has( 'message_product_enabled' ) &&
218
+ ! $this->settings->get( 'message_product_enabled' );
219
+ if (
220
+ ( is_product() || wc_post_content_has_shortcode( 'product_page' ) )
221
+ && ! $not_enabled_on_product_page
222
+ ) {
223
+ add_action(
224
+ 'woocommerce_single_product_summary',
225
+ array(
226
+ $this,
227
+ 'message_renderer',
228
+ ),
229
+ 30
230
+ );
231
+ }
232
+
233
+ $not_enabled_on_checkout = $this->settings->has( 'message_enabled' ) &&
234
+ ! $this->settings->get( 'message_enabled' );
235
+ if ( ! $not_enabled_on_checkout ) {
236
+ add_action(
237
+ 'woocommerce_review_order_after_submit',
238
+ array(
239
+ $this,
240
+ 'message_renderer',
241
+ ),
242
+ 11
243
+ );
244
+ add_action(
245
+ 'woocommerce_pay_order_after_submit',
246
+ array(
247
+ $this,
248
+ 'message_renderer',
249
+ ),
250
+ 11
251
+ );
252
+ }
253
+ return true;
254
+ }
255
+
256
+ /**
257
+ * Registers the hooks where to render the button HTML according to the settings.
258
+ *
259
+ * @return bool
260
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
261
+ */
262
+ private function render_button_wrapper_registrar(): bool {
263
+
264
+ $not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
265
+ ! $this->settings->get( 'button_cart_enabled' );
266
+ if (
267
+ is_cart()
268
+ && ! $not_enabled_on_cart
269
+ ) {
270
+ add_action(
271
+ 'woocommerce_proceed_to_checkout',
272
+ array(
273
+ $this,
274
+ 'button_renderer',
275
+ ),
276
+ 20
277
+ );
278
+ }
279
+
280
+ $not_enabled_on_product_page = $this->settings->has( 'button_single_product_enabled' ) &&
281
+ ! $this->settings->get( 'button_single_product_enabled' );
282
+ if (
283
+ ( is_product() || wc_post_content_has_shortcode( 'product_page' ) )
284
+ && ! $not_enabled_on_product_page
285
+ ) {
286
+ add_action(
287
+ 'woocommerce_single_product_summary',
288
+ array(
289
+ $this,
290
+ 'button_renderer',
291
+ ),
292
+ 31
293
+ );
294
+ }
295
+
296
+ $not_enabled_on_minicart = $this->settings->has( 'button_mini_cart_enabled' ) &&
297
+ ! $this->settings->get( 'button_mini_cart_enabled' );
298
+ if (
299
+ ! $not_enabled_on_minicart
300
+ ) {
301
+ add_action(
302
+ 'woocommerce_widget_shopping_cart_after_buttons',
303
+ static function () {
304
+ echo '<p
305
+ id="ppc-button-minicart"
306
+ class="woocommerce-mini-cart__buttons buttons"
307
+ ></p>';
308
+ },
309
+ 30
310
+ );
311
+ }
312
+
313
+ add_action( 'woocommerce_review_order_after_submit', array( $this, 'button_renderer' ), 10 );
314
+ add_action( 'woocommerce_pay_order_after_submit', array( $this, 'button_renderer' ), 10 );
315
+
316
+ return true;
317
+ }
318
+
319
+ /**
320
+ * Enqueues the script.
321
+ *
322
+ * @return bool
323
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
324
+ */
325
+ public function enqueue(): bool {
326
+ $buttons_enabled = $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' );
327
+ if ( ! is_checkout() && ! $buttons_enabled ) {
328
+ return false;
329
+ }
330
+ if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
331
+ return false;
332
+ }
333
+
334
+ $load_script = false;
335
+ if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
336
+ $load_script = true;
337
+ }
338
+ if ( $this->load_button_component() ) {
339
+ $load_script = true;
340
+ }
341
+
342
+ if ( in_array( $this->context(), array( 'pay-now', 'checkout' ), true ) && $this->can_render_dcc() ) {
343
+ wp_enqueue_style(
344
+ 'ppcp-hosted-fields',
345
+ $this->module_url . '/assets/css/hosted-fields.css',
346
+ array(),
347
+ 1
348
+ );
349
+ }
350
+ if ( $load_script ) {
351
+ wp_enqueue_script(
352
+ 'ppcp-smart-button',
353
+ $this->module_url . '/assets/js/button.js',
354
+ array( 'jquery' ),
355
+ 1,
356
+ true
357
+ );
358
+
359
+ wp_localize_script(
360
+ 'ppcp-smart-button',
361
+ 'PayPalCommerceGateway',
362
+ $this->localize_script()
363
+ );
364
+ }
365
+ return true;
366
+ }
367
+
368
+ /**
369
+ * Renders the HTML for the buttons.
370
+ */
371
+ public function button_renderer() {
372
+ $product = wc_get_product();
373
+ if (
374
+ ! is_checkout() && is_a( $product, \WC_Product::class )
375
+ && (
376
+ $product->is_type( array( 'external', 'grouped' ) )
377
+ || ! $product->is_in_stock()
378
+ )
379
+ ) {
380
+ return;
381
+ }
382
+
383
+ echo '<div id="ppc-button"></div>';
384
+ }
385
+
386
+ /**
387
+ * Renders the HTML for the credit messaging.
388
+ */
389
+ public function message_renderer() {
390
+
391
+ echo '<div id="ppcp-messages"></div>';
392
+ }
393
+
394
+ /**
395
+ * The values for the credit messaging.
396
+ *
397
+ * @return array
398
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
399
+ */
400
+ private function message_values(): array {
401
+
402
+ if (
403
+ $this->settings->has( 'disable_funding' )
404
+ && in_array( 'credit', (array) $this->settings->get( 'disable_funding' ), true )
405
+ ) {
406
+ return array();
407
+ }
408
+ $placement = 'product';
409
+ $product = wc_get_product();
410
+ $amount = ( is_a( $product, \WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
411
+ $layout = $this->settings->has( 'message_product_layout' ) ?
412
+ $this->settings->get( 'message_product_layout' ) : 'text';
413
+ $logo_type = $this->settings->has( 'message_product_logo' ) ?
414
+ $this->settings->get( 'message_product_logo' ) : 'primary';
415
+ $logo_position = $this->settings->has( 'message_product_position' ) ?
416
+ $this->settings->get( 'message_product_position' ) : 'left';
417
+ $text_color = $this->settings->has( 'message_product_color' ) ?
418
+ $this->settings->get( 'message_product_color' ) : 'black';
419
+ $style_color = $this->settings->has( 'message_product_flex_color' ) ?
420
+ $this->settings->get( 'message_product_flex_color' ) : 'blue';
421
+ $ratio = $this->settings->has( 'message_product_flex_ratio' ) ?
422
+ $this->settings->get( 'message_product_flex_ratio' ) : '1x1';
423
+ $should_show = $this->settings->has( 'message_product_enabled' )
424
+ && $this->settings->get( 'message_product_enabled' );
425
+ if ( is_checkout() ) {
426
+ $placement = 'payment';
427
+ $amount = WC()->cart->get_total( 'raw' );
428
+ $layout = $this->settings->has( 'message_layout' ) ?
429
+ $this->settings->get( 'message_layout' ) : 'text';
430
+ $logo_type = $this->settings->has( 'message_logo' ) ?
431
+ $this->settings->get( 'message_logo' ) : 'primary';
432
+ $logo_position = $this->settings->has( 'message_position' ) ?
433
+ $this->settings->get( 'message_position' ) : 'left';
434
+ $text_color = $this->settings->has( 'message_color' ) ?
435
+ $this->settings->get( 'message_color' ) : 'black';
436
+ $style_color = $this->settings->has( 'message_flex_color' ) ?
437
+ $this->settings->get( 'message_flex_color' ) : 'blue';
438
+ $ratio = $this->settings->has( 'message_flex_ratio' ) ?
439
+ $this->settings->get( 'message_flex_ratio' ) : '1x1';
440
+ $should_show = $this->settings->has( 'message_enabled' )
441
+ && $this->settings->get( 'message_enabled' );
442
+ }
443
+ if ( is_cart() ) {
444
+ $placement = 'cart';
445
+ $amount = WC()->cart->get_total( 'raw' );
446
+ $layout = $this->settings->has( 'message_cart_layout' ) ?
447
+ $this->settings->get( 'message_cart_layout' ) : 'text';
448
+ $logo_type = $this->settings->has( 'message_cart_logo' ) ?
449
+ $this->settings->get( 'message_cart_logo' ) : 'primary';
450
+ $logo_position = $this->settings->has( 'message_cart_position' ) ?
451
+ $this->settings->get( 'message_cart_position' ) : 'left';
452
+ $text_color = $this->settings->has( 'message_cart_color' ) ?
453
+ $this->settings->get( 'message_cart_color' ) : 'black';
454
+ $style_color = $this->settings->has( 'message_cart_flex_color' ) ?
455
+ $this->settings->get( 'message_cart_flex_color' ) : 'blue';
456
+ $ratio = $this->settings->has( 'message_cart_flex_ratio' ) ?
457
+ $this->settings->get( 'message_cart_flex_ratio' ) : '1x1';
458
+ $should_show = $this->settings->has( 'message_cart_enabled' )
459
+ && $this->settings->get( 'message_cart_enabled' );
460
+ }
461
+
462
+ if ( ! $should_show ) {
463
+ return array();
464
+ }
465
+
466
+ $values = array(
467
+ 'wrapper' => '#ppcp-messages',
468
+ 'amount' => $amount,
469
+ 'placement' => $placement,
470
+ 'style' => array(
471
+ 'layout' => $layout,
472
+ 'logo' => array(
473
+ 'type' => $logo_type,
474
+ 'position' => $logo_position,
475
+ ),
476
+ 'text' => array(
477
+ 'color' => $text_color,
478
+ ),
479
+ 'color' => $style_color,
480
+ 'ratio' => $ratio,
481
+ ),
482
+ );
483
+
484
+ return $values;
485
+ }
486
+
487
+ /**
488
+ * Whether DCC fields can be rendered.
489
+ *
490
+ * @return bool
491
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
492
+ */
493
+ private function can_render_dcc() : bool {
494
+
495
+ $can_render = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) && $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) && $this->dcc_applies->for_country_currency();
496
+ return $can_render;
497
+ }
498
+
499
+ /**
500
+ * Renders the HTML for the DCC fields.
501
+ */
502
+ public function dcc_renderer() {
503
+
504
+ $id = 'ppcp-hosted-fields';
505
+ if ( ! $this->can_render_dcc() ) {
506
+ return;
507
+ }
508
+
509
+ $save_card = $this->can_save_vault_token() ? sprintf(
510
+ '<div>
511
+
512
+ <label for="ppcp-vault-%1$s">%2$s</label>
513
+ <input
514
+ type="checkbox"
515
+ id="ppcp-vault-%1$s"
516
+ class="ppcp-credit-card-vault"
517
+ name="vault"
518
+ >
519
+ </div>',
520
+ esc_attr( $id ),
521
+ esc_html__( 'Save your card', 'woocommerce-paypal-payments' )
522
+ ) : '';
523
+
524
+ $label = 'checkout' === $this->context() ? __( 'Place order', 'woocommerce-paypal-payments' ) : __( 'Pay for order', 'woocommerce-paypal-payments' );
525
+
526
+ printf(
527
+ '<div id="%1$s" style="display:none;">
528
+ <button class="button alt">%6$s</button>
529
+ </div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
530
+ esc_attr( $id ),
531
+ esc_html__( 'Credit Card number', 'woocommerce-paypal-payments' ),
532
+ esc_html__( 'Expiration', 'woocommerce-paypal-payments' ),
533
+ esc_html__( 'CVV', 'woocommerce-paypal-payments' ),
534
+ //phpcs:ignore
535
+ $save_card,
536
+ esc_html( $label )
537
+ );
538
+ }
539
+
540
+ /**
541
+ * Whether we can store vault tokens or not.
542
+ *
543
+ * @return bool
544
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasnt been found.
545
+ */
546
+ public function can_save_vault_token(): bool {
547
+
548
+ if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
549
+ return false;
550
+ }
551
+ if ( ! $this->settings->has( 'vault_enabled' ) || ! $this->settings->get( 'vault_enabled' ) ) {
552
+ return false;
553
+ }
554
+ return is_user_logged_in();
555
+ }
556
+
557
+ /**
558
+ * Whether we need to initialize the script to enable tokenization for subscriptions or not.
559
+ *
560
+ * @return bool
561
+ */
562
+ private function has_subscriptions(): bool {
563
+ if ( ! $this->subscription_helper->accept_only_automatic_payment_gateways() ) {
564
+ return false;
565
+ }
566
+ if ( is_product() ) {
567
+ return $this->subscription_helper->current_product_is_subscription();
568
+ }
569
+ return $this->subscription_helper->cart_contains_subscription();
570
+ }
571
+
572
+ /**
573
+ * The localized data for the smart button.
574
+ *
575
+ * @return array
576
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasn't been found.
577
+ */
578
+ private function localize_script(): array {
579
+ global $wp;
580
+
581
+ $this->request_data->enqueue_nonce_fix();
582
+ $localize = array(
583
+ 'script_attributes' => $this->attributes(),
584
+ 'data_client_id' => array(
585
+ 'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() )
586
+ || $this->can_save_vault_token(),
587
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
588
+ 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
589
+ 'user' => get_current_user_id(),
590
+ ),
591
+ 'redirect' => wc_get_checkout_url(),
592
+ 'context' => $this->context(),
593
+ 'ajax' => array(
594
+ 'change_cart' => array(
595
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ) ),
596
+ 'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
597
+ ),
598
+ 'create_order' => array(
599
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ) ),
600
+ 'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
601
+ ),
602
+ 'approve_order' => array(
603
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ) ),
604
+ 'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
605
+ ),
606
+ ),
607
+ 'enforce_vault' => $this->has_subscriptions(),
608
+ 'bn_codes' => $this->bn_codes(),
609
+ 'payer' => $this->payerData(),
610
+ 'button' => array(
611
+ 'wrapper' => '#ppc-button',
612
+ 'mini_cart_wrapper' => '#ppc-button-minicart',
613
+ 'cancel_wrapper' => '#ppcp-cancel',
614
+ 'url' => $this->url(),
615
+ 'mini_cart_style' => array(
616
+ 'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
617
+ 'color' => $this->style_for_context( 'color', 'mini-cart' ),
618
+ 'shape' => $this->style_for_context( 'shape', 'mini-cart' ),
619
+ 'label' => $this->style_for_context( 'label', 'mini-cart' ),
620
+ 'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ),
621
+ ),
622
+ 'style' => array(
623
+ 'layout' => $this->style_for_context( 'layout', $this->context() ),
624
+ 'color' => $this->style_for_context( 'color', $this->context() ),
625
+ 'shape' => $this->style_for_context( 'shape', $this->context() ),
626
+ 'label' => $this->style_for_context( 'label', $this->context() ),
627
+ 'tagline' => $this->style_for_context( 'tagline', $this->context() ),
628
+ ),
629
+ ),
630
+ 'hosted_fields' => array(
631
+ 'wrapper' => '#ppcp-hosted-fields',
632
+ 'mini_cart_wrapper' => '#ppcp-hosted-fields-mini-cart',
633
+ 'labels' => array(
634
+ 'credit_card_number' => '',
635
+ 'cvv' => '',
636
+ 'mm_yyyy' => __( 'MM/YYYY', 'woocommerce-paypal-payments' ),
637
+ 'fields_not_valid' => __(
638
+ 'Unfortunatly, your credit card details are not valid.',
639
+ 'woocommerce-paypal-payments'
640
+ ),
641
+ 'card_not_supported' => __(
642
+ 'Unfortunatly, we do not support your credit card.',
643
+ 'woocommerce-paypal-payments'
644
+ ),
645
+ ),
646
+ 'valid_cards' => $this->dcc_applies->valid_cards(),
647
+ ),
648
+ 'messages' => $this->message_values(),
649
+ 'labels' => array(
650
+ 'error' => array(
651
+ 'generic' => __(
652
+ 'Something went wrong. Please try again or choose another payment source.',
653
+ 'woocommerce-paypal-payments'
654
+ ),
655
+ ),
656
+ ),
657
+ 'order_id' => 'pay-now' === $this->context() ? absint( $wp->query_vars['order-pay'] ) : 0,
658
+ );
659
+
660
+ if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) {
661
+ unset( $localize['button']['mini_cart_style']['tagline'] );
662
+ }
663
+ if ( $this->style_for_context( 'layout', $this->context() ) !== 'horizontal' ) {
664
+ unset( $localize['button']['style']['tagline'] );
665
+ }
666
+
667
+ $this->request_data->dequeue_nonce_fix();
668
+ return $localize;
669
+ }
670
+
671
+ /**
672
+ * If we can find the payer data for a current customer, we will return it.
673
+ *
674
+ * @return array|null
675
+ */
676
+ private function payerData() {
677
+
678
+ $customer = WC()->customer;
679
+ if ( ! is_user_logged_in() || ! is_a( $customer, \WC_Customer::class ) ) {
680
+ return null;
681
+ }
682
+ return $this->payer_factory->from_customer( $customer )->to_array();
683
+ }
684
+
685
+ /**
686
+ * The JavaScript SDK url to load.
687
+ *
688
+ * @return string
689
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
690
+ */
691
+ private function url(): string {
692
+ $params = array(
693
+ 'client-id' => $this->client_id,
694
+ 'currency' => get_woocommerce_currency(),
695
+ 'locale' => get_user_locale(),
696
+ 'integration-date' => PAYPAL_INTEGRATION_DATE,
697
+ 'components' => implode( ',', $this->components() ),
698
+ 'vault' => $this->can_save_vault_token() ?
699
+ 'true' : 'false',
700
+ 'commit' => is_checkout() ? 'true' : 'false',
701
+ 'intent' => ( $this->settings->has( 'intent' ) ) ?
702
+ $this->settings->get( 'intent' ) : 'capture',
703
+ );
704
+ if (
705
+ defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
706
+ && WC()->customer && WC()->customer->get_billing_country()
707
+ ) {
708
+ $params['buyer-country'] = WC()->customer->get_billing_country();
709
+ }
710
+ $payee = $this->payee_repository->payee();
711
+ if ( $payee->merchant_id() ) {
712
+ $params['merchant-id'] = $payee->merchant_id();
713
+ }
714
+ $disable_funding = $this->settings->has( 'disable_funding' ) ?
715
+ $this->settings->get( 'disable_funding' ) : array();
716
+ $disable_funding[] = 'venmo';
717
+ if ( ! is_checkout() ) {
718
+ $disable_funding[] = 'card';
719
+ }
720
+
721
+ /**
722
+ * Disable card for UK.
723
+ */
724
+ $region = wc_get_base_location();
725
+ $country = $region['country'];
726
+ if ( 'GB' === $country ) {
727
+ $disable_funding[] = 'card';
728
+ }
729
+ $params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
730
+
731
+ $smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
732
+ return $smart_button_url;
733
+ }
734
+
735
+ /**
736
+ * The attributes we need to load for the JS SDK.
737
+ *
738
+ * @return array
739
+ */
740
+ private function attributes(): array {
741
+ return array(
742
+ 'data-partner-attribution-id' => $this->bn_code_for_context( $this->context() ),
743
+ );
744
+ }
745
+
746
+ /**
747
+ * What BN Code to use in a given context.
748
+ *
749
+ * @param string $context The context.
750
+ * @return string
751
+ */
752
+ private function bn_code_for_context( string $context ): string {
753
+
754
+ $codes = $this->bn_codes();
755
+ return ( isset( $codes[ $context ] ) ) ? $codes[ $context ] : '';
756
+ }
757
+
758
+ /**
759
+ * BN Codes to use.
760
+ *
761
+ * @return array
762
+ */
763
+ private function bn_codes(): array {
764
+
765
+ return array(
766
+ 'checkout' => 'Woo_PPCP',
767
+ 'cart' => 'Woo_PPCP',
768
+ 'mini-cart' => 'Woo_PPCP',
769
+ 'product' => 'Woo_PPCP',
770
+ );
771
+ }
772
+
773
+ /**
774
+ * The JS SKD components we need to load.
775
+ *
776
+ * @return array
777
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
778
+ */
779
+ private function components(): array {
780
+ $components = array();
781
+
782
+ if ( $this->load_button_component() ) {
783
+ $components[] = 'buttons';
784
+ }
785
+ if ( $this->messages_apply->for_country() ) {
786
+ $components[] = 'messages';
787
+ }
788
+ if ( $this->dcc_is_enabled() ) {
789
+ $components[] = 'hosted-fields';
790
+ }
791
+ return $components;
792
+ }
793
+
794
+ /**
795
+ * Determines whether the button component should be loaded.
796
+ *
797
+ * @return bool
798
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting has not been found.
799
+ */
800
+ private function load_button_component() : bool {
801
+
802
+ $load_buttons = false;
803
+ if (
804
+ $this->context() === 'checkout'
805
+ && $this->settings->has( 'button_enabled' )
806
+ && $this->settings->get( 'button_enabled' )
807
+ ) {
808
+ $load_buttons = true;
809
+ }
810
+ if (
811
+ $this->context() === 'product'
812
+ && $this->settings->has( 'button_product_enabled' )
813
+ && $this->settings->get( 'button_product_enabled' )
814
+ ) {
815
+ $load_buttons = true;
816
+ }
817
+ if (
818
+ $this->settings->has( 'button_mini-cart_enabled' )
819
+ && $this->settings->get( 'button_mini-cart_enabled' )
820
+ ) {
821
+ $load_buttons = true;
822
+ }
823
+ if (
824
+ $this->context() === 'cart'
825
+ && $this->settings->has( 'button_cart_enabled' )
826
+ && $this->settings->get( 'button_cart_enabled' )
827
+ ) {
828
+ $load_buttons = true;
829
+ }
830
+ return $load_buttons;
831
+ }
832
+
833
+ /**
834
+ * The current context.
835
+ *
836
+ * @return string
837
+ */
838
+ private function context(): string {
839
+ $context = 'mini-cart';
840
+ if ( is_product() || wc_post_content_has_shortcode( 'product_page' ) ) {
841
+ $context = 'product';
842
+ }
843
+ if ( is_cart() ) {
844
+ $context = 'cart';
845
+ }
846
+ if ( is_checkout() && ! $this->session_handler->order() ) {
847
+ $context = 'checkout';
848
+ }
849
+ if ( is_checkout_pay_page() ) {
850
+ $context = 'pay-now';
851
+ }
852
+ return $context;
853
+ }
854
+
855
+ /**
856
+ * Whether DCC is enabled or not.
857
+ *
858
+ * @return bool
859
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting has not been found.
860
+ */
861
+ private function dcc_is_enabled(): bool {
862
+ if ( ! is_checkout() ) {
863
+ return false;
864
+ }
865
+ if ( ! $this->dcc_applies->for_country_currency() ) {
866
+ return false;
867
+ }
868
+ $keys = array(
869
+ 'client_id',
870
+ 'client_secret',
871
+ 'dcc_enabled',
872
+ );
873
+ foreach ( $keys as $key ) {
874
+ if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) {
875
+ return false;
876
+ }
877
+ }
878
+ return true;
879
+ }
880
+
881
+ /**
882
+ * Determines the style for a given indicator in a given context.
883
+ *
884
+ * @param string $style The style.
885
+ * @param string $context The context.
886
+ *
887
+ * @return string
888
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting hasn't been found.
889
+ */
890
+ private function style_for_context( string $style, string $context ): string {
891
+ $defaults = array(
892
+ 'layout' => 'vertical',
893
+ 'size' => 'responsive',
894
+ 'color' => 'gold',
895
+ 'shape' => 'pill',
896
+ 'label' => 'paypal',
897
+ 'tagline' => true,
898
+ );
899
+
900
+ $value = isset( $defaults[ $style ] ) ?
901
+ $defaults[ $style ] : '';
902
+ $value = $this->settings->has( 'button_' . $style ) ?
903
+ $this->settings->get( 'button_' . $style ) : $value;
904
+ $value = $this->settings->has( 'button_' . $context . '_' . $style ) ?
905
+ $this->settings->get( 'button_' . $context . '_' . $style ) : $value;
906
+
907
+ if ( is_bool( $value ) ) {
908
+ $value = $value ? 'true' : 'false';
909
+ }
910
+ return (string) $value;
911
+ }
912
+ }
modules/ppcp-button/src/Assets/class-smartbuttoninterface.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The interface for the smart button asset renderer.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Assets
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Assets;
11
+
12
+ /**
13
+ * Interface SmartButtonInterface
14
+ */
15
+ interface SmartButtonInterface {
16
+
17
+ /**
18
+ * Renders the necessary HTML.
19
+ *
20
+ * @return bool
21
+ */
22
+ public function render_wrapper(): bool;
23
+
24
+ /**
25
+ * Enqueues the necessary scripts.
26
+ *
27
+ * @return bool
28
+ */
29
+ public function enqueue(): bool;
30
+
31
+ /**
32
+ * Whether the running installation could save vault tokens or not.
33
+ *
34
+ * @return bool
35
+ */
36
+ public function can_save_vault_token(): bool;
37
+ }
modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Endpoint to verify if an order has been approved. An approved order
4
+ * will be stored in the current session.
5
+ *
6
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
7
+ */
8
+
9
+ declare(strict_types=1);
10
+
11
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
12
+
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
17
+ use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
18
+ use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
19
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
21
+
22
+ /**
23
+ * Class ApproveOrderEndpoint
24
+ */
25
+ class ApproveOrderEndpoint implements EndpointInterface {
26
+
27
+
28
+ const ENDPOINT = 'ppc-approve-order';
29
+
30
+ /**
31
+ * The request data helper.
32
+ *
33
+ * @var RequestData
34
+ */
35
+ private $request_data;
36
+
37
+ /**
38
+ * The session handler.
39
+ *
40
+ * @var SessionHandler
41
+ */
42
+ private $session_handler;
43
+
44
+ /**
45
+ * The order endpoint.
46
+ *
47
+ * @var OrderEndpoint
48
+ */
49
+ private $api_endpoint;
50
+
51
+ /**
52
+ * The 3d secure helper object.
53
+ *
54
+ * @var ThreeDSecure
55
+ */
56
+ private $threed_secure;
57
+
58
+ /**
59
+ * The settings.
60
+ *
61
+ * @var Settings
62
+ */
63
+ private $settings;
64
+
65
+ /**
66
+ * The DCC applies object.
67
+ *
68
+ * @var DccApplies
69
+ */
70
+ private $dcc_applies;
71
+
72
+ /**
73
+ * ApproveOrderEndpoint constructor.
74
+ *
75
+ * @param RequestData $request_data The request data helper.
76
+ * @param OrderEndpoint $order_endpoint The order endpoint.
77
+ * @param SessionHandler $session_handler The session handler.
78
+ * @param ThreeDSecure $three_d_secure The 3d secure helper object.
79
+ * @param Settings $settings The settings.
80
+ * @param DccApplies $dcc_applies The DCC applies object.
81
+ */
82
+ public function __construct(
83
+ RequestData $request_data,
84
+ OrderEndpoint $order_endpoint,
85
+ SessionHandler $session_handler,
86
+ ThreeDSecure $three_d_secure,
87
+ Settings $settings,
88
+ DccApplies $dcc_applies
89
+ ) {
90
+
91
+ $this->request_data = $request_data;
92
+ $this->api_endpoint = $order_endpoint;
93
+ $this->session_handler = $session_handler;
94
+ $this->threed_secure = $three_d_secure;
95
+ $this->settings = $settings;
96
+ $this->dcc_applies = $dcc_applies;
97
+ }
98
+
99
+ /**
100
+ * The nonce.
101
+ *
102
+ * @return string
103
+ */
104
+ public static function nonce(): string {
105
+ return self::ENDPOINT;
106
+ }
107
+
108
+ /**
109
+ * Handles the request.
110
+ *
111
+ * @return bool
112
+ * @throws RuntimeException When no order was found.
113
+ */
114
+ public function handle_request(): bool {
115
+ try {
116
+ $data = $this->request_data->read_request( $this->nonce() );
117
+ if ( ! isset( $data['order_id'] ) ) {
118
+ throw new RuntimeException(
119
+ __( 'No order id given', 'woocommerce-paypal-payments' )
120
+ );
121
+ }
122
+
123
+ $order = $this->api_endpoint->order( $data['order_id'] );
124
+ if ( ! $order ) {
125
+ throw new RuntimeException(
126
+ sprintf(
127
+ // translators: %s is the id of the order.
128
+ __( 'Order %s not found.', 'woocommerce-paypal-payments' ),
129
+ $data['order_id']
130
+ )
131
+ );
132
+ }
133
+
134
+ if ( $order->payment_source() && $order->payment_source()->card() ) {
135
+ if ( $this->settings->has( 'disable_cards' ) ) {
136
+ $disabled_cards = (array) $this->settings->get( 'disable_cards' );
137
+ $card = strtolower( $order->payment_source()->card()->brand() );
138
+ if ( 'master_card' === $card ) {
139
+ $card = 'mastercard';
140
+ }
141
+
142
+ if ( ! $this->dcc_applies->can_process_card( $card ) || in_array( $card, $disabled_cards, true ) ) {
143
+ throw new RuntimeException(
144
+ __(
145
+ 'Unfortunately, we do not accept this card.',
146
+ 'woocommerce-paypal-payments'
147
+ ),
148
+ 100
149
+ );
150
+ }
151
+ }
152
+ $proceed = $this->threed_secure->proceed_with_order( $order );
153
+ if ( ThreeDSecure::RETRY === $proceed ) {
154
+ throw new RuntimeException(
155
+ __(
156
+ 'Something went wrong. Please try again.',
157
+ 'woocommerce-paypal-payments'
158
+ )
159
+ );
160
+ }
161
+ if ( ThreeDSecure::REJECT === $proceed ) {
162
+ throw new RuntimeException(
163
+ __(
164
+ 'Unfortunatly, we can\'t accept your card. Please choose a different payment method.',
165
+ 'woocommerce-paypal-payments'
166
+ )
167
+ );
168
+ }
169
+ $this->session_handler->replace_order( $order );
170
+ wp_send_json_success( $order );
171
+ }
172
+
173
+ if ( ! $order->status()->is( OrderStatus::APPROVED ) ) {
174
+ throw new RuntimeException(
175
+ sprintf(
176
+ // translators: %s is the id of the order.
177
+ __( 'Order %s is not approved yet.', 'woocommerce-paypal-payments' ),
178
+ $data['order_id']
179
+ )
180
+ );
181
+ }
182
+
183
+ $this->session_handler->replace_order( $order );
184
+ wp_send_json_success( $order );
185
+ return true;
186
+ } catch ( \RuntimeException $error ) {
187
+ wp_send_json_error(
188
+ array(
189
+ 'name' => is_a( $error, PayPalApiException::class ) ? $error->name() : '',
190
+ 'message' => $error->getMessage(),
191
+ 'code' => $error->getCode(),
192
+ 'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(),
193
+ )
194
+ );
195
+ return false;
196
+ }
197
+ }
198
+ }
modules/ppcp-button/src/Endpoint/class-changecartendpoint.php ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Endpoint to update the cart.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
15
+ use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
16
+
17
+ /**
18
+ * Class ChangeCartEndpoint
19
+ */
20
+ class ChangeCartEndpoint implements EndpointInterface {
21
+
22
+
23
+ const ENDPOINT = 'ppc-change-cart';
24
+
25
+ /**
26
+ * The current cart object.
27
+ *
28
+ * @var \WC_Cart
29
+ */
30
+ private $cart;
31
+
32
+ /**
33
+ * The current shipping object.
34
+ *
35
+ * @var \WC_Shipping
36
+ */
37
+ private $shipping;
38
+
39
+ /**
40
+ * The request data helper.
41
+ *
42
+ * @var RequestData
43
+ */
44
+ private $request_data;
45
+
46
+ /**
47
+ * Contains purchase units based off the current WC cart.
48
+ *
49
+ * @var CartRepository
50
+ */
51
+ private $repository;
52
+
53
+ /**
54
+ * The product data store.
55
+ *
56
+ * @var \WC_Data_Store
57
+ */
58
+ private $product_data_store;
59
+
60
+ /**
61
+ * ChangeCartEndpoint constructor.
62
+ *
63
+ * @param \WC_Cart $cart The current WC cart object.
64
+ * @param \WC_Shipping $shipping The current WC shipping object.
65
+ * @param RequestData $request_data The request data helper.
66
+ * @param CartRepository $repository The repository for the current purchase items.
67
+ * @param \WC_Data_Store $product_data_store The data store for products.
68
+ */
69
+ public function __construct(
70
+ \WC_Cart $cart,
71
+ \WC_Shipping $shipping,
72
+ RequestData $request_data,
73
+ CartRepository $repository,
74
+ \WC_Data_Store $product_data_store
75
+ ) {
76
+
77
+ $this->cart = $cart;
78
+ $this->shipping = $shipping;
79
+ $this->request_data = $request_data;
80
+ $this->repository = $repository;
81
+ $this->product_data_store = $product_data_store;
82
+ }
83
+
84
+ /**
85
+ * The nonce.
86
+ *
87
+ * @return string
88
+ */
89
+ public static function nonce(): string {
90
+ return self::ENDPOINT;
91
+ }
92
+
93
+ /**
94
+ * Handles the request.
95
+ *
96
+ * @return bool
97
+ * @throws \Exception On error.
98
+ */
99
+ public function handle_request(): bool {
100
+ try {
101
+ return $this->handle_data();
102
+ } catch ( RuntimeException $error ) {
103
+ wp_send_json_error(
104
+ array(
105
+ 'name' => is_a( $error, PayPalApiException::class ) ? $error->name() : '',
106
+ 'message' => $error->getMessage(),
107
+ 'code' => $error->getCode(),
108
+ 'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(),
109
+ )
110
+ );
111
+ return false;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Handles the request data.
117
+ *
118
+ * @return bool
119
+ * @throws \Exception On error.
120
+ */
121
+ private function handle_data(): bool {
122
+ $data = $this->request_data->read_request( $this->nonce() );
123
+ $products = $this->products_from_data( $data );
124
+ if ( ! $products ) {
125
+ wp_send_json_error(
126
+ array(
127
+ 'name' => '',
128
+ 'message' => __(
129
+ 'Necessary fields not defined. Action aborted.',
130
+ 'woocommerce-paypal-payments'
131
+ ),
132
+ 'code' => 0,
133
+ 'details' => array(),
134
+ )
135
+ );
136
+ return false;
137
+ }
138
+
139
+ $this->shipping->reset_shipping();
140
+ $this->cart->empty_cart( false );
141
+ $success = true;
142
+ foreach ( $products as $product ) {
143
+ $success = $success && ( ! $product['product']->is_type( 'variable' ) ) ?
144
+ $this->add_product( $product['product'], $product['quantity'] )
145
+ : $this->add_variable_product(
146
+ $product['product'],
147
+ $product['quantity'],
148
+ $product['variations']
149
+ );
150
+ }
151
+ if ( ! $success ) {
152
+ $this->handle_error();
153
+ return $success;
154
+ }
155
+
156
+ wp_send_json_success( $this->generate_purchase_units() );
157
+ return $success;
158
+ }
159
+
160
+ /**
161
+ * Handles errors.
162
+ *
163
+ * @return bool
164
+ */
165
+ private function handle_error(): bool {
166
+
167
+ $message = __(
168
+ 'Something went wrong. Action aborted',
169
+ 'woocommerce-paypal-payments'
170
+ );
171
+ $errors = wc_get_notices( 'error' );
172
+ if ( count( $errors ) ) {
173
+ $message = array_reduce(
174
+ $errors,
175
+ static function ( string $add, array $error ): string {
176
+ return $add . $error['notice'] . ' ';
177
+ },
178
+ ''
179
+ );
180
+ wc_clear_notices();
181
+ }
182
+
183
+ wp_send_json_error(
184
+ array(
185
+ 'name' => '',
186
+ 'message' => $message,
187
+ 'code' => 0,
188
+ 'details' => array(),
189
+ )
190
+ );
191
+ return true;
192
+ }
193
+
194
+ /**
195
+ * Returns product information from an data array.
196
+ *
197
+ * @param array $data The data array.
198
+ *
199
+ * @return array|null
200
+ */
201
+ private function products_from_data( array $data ) {
202
+
203
+ $products = array();
204
+
205
+ if (
206
+ ! isset( $data['products'] )
207
+ || ! is_array( $data['products'] )
208
+ ) {
209
+ return null;
210
+ }
211
+ foreach ( $data['products'] as $product ) {
212
+ if ( ! isset( $product['quantity'] ) || ! isset( $product['id'] ) ) {
213
+ return null;
214
+ }
215
+
216
+ $wc_product = wc_get_product( (int) $product['id'] );
217
+
218
+ if ( ! $wc_product ) {
219
+ return null;
220
+ }
221
+ $products[] = array(
222
+ 'product' => $wc_product,
223
+ 'quantity' => (int) $product['quantity'],
224
+ 'variations' => isset( $product['variations'] ) ? $product['variations'] : null,
225
+ );
226
+ }
227
+ return $products;
228
+ }
229
+
230
+ /**
231
+ * Adds a product to the cart.
232
+ *
233
+ * @param \WC_Product $product The Product.
234
+ * @param int $quantity The Quantity.
235
+ *
236
+ * @return bool
237
+ * @throws \Exception When product could not be added.
238
+ */
239
+ private function add_product( \WC_Product $product, int $quantity ): bool {
240
+ return false !== $this->cart->add_to_cart( $product->get_id(), $quantity );
241
+ }
242
+
243
+
244
+ /**
245
+ * Adds variations to the cart.
246
+ *
247
+ * @param \WC_Product $product The Product.
248
+ * @param int $quantity The Quantity.
249
+ * @param array $post_variations The variations.
250
+ *
251
+ * @return bool
252
+ * @throws \Exception When product could not be added.
253
+ */
254
+ private function add_variable_product(
255
+ \WC_Product $product,
256
+ int $quantity,
257
+ array $post_variations
258
+ ): bool {
259
+
260
+ $variations = array();
261
+ foreach ( $post_variations as $key => $value ) {
262
+ $variations[ $value['name'] ] = $value['value'];
263
+ }
264
+
265
+ $variation_id = $this->product_data_store->find_matching_product_variation( $product, $variations );
266
+
267
+ // ToDo: Check stock status for variation.
268
+ return false !== $this->cart->add_to_cart(
269
+ $product->get_id(),
270
+ $quantity,
271
+ $variation_id,
272
+ $variations
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Based on the cart contents, the purchase units are created.
278
+ *
279
+ * @return array
280
+ */
281
+ private function generate_purchase_units(): array {
282
+ return array_map(
283
+ static function ( PurchaseUnit $line_item ): array {
284
+ return $line_item->to_array();
285
+ },
286
+ $this->repository->all()
287
+ );
288
+ }
289
+ }
modules/ppcp-button/src/Endpoint/class-createorderendpoint.php ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The endpoint to create an PayPal order.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
19
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
20
+ use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
21
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
23
+
24
+ /**
25
+ * Class CreateOrderEndpoint
26
+ */
27
+ class CreateOrderEndpoint implements EndpointInterface {
28
+
29
+
30
+ const ENDPOINT = 'ppc-create-order';
31
+
32
+ /**
33
+ * The request data helper.
34
+ *
35
+ * @var RequestData
36
+ */
37
+ private $request_data;
38
+
39
+ /**
40
+ * The cart repository.
41
+ *
42
+ * @var CartRepository
43
+ */
44
+ private $cart_repository;
45
+
46
+ /**
47
+ * The PurchaseUnit factory.
48
+ *
49
+ * @var PurchaseUnitFactory
50
+ */
51
+ private $purchase_unit_factory;
52
+
53
+ /**
54
+ * The order endpoint.
55
+ *
56
+ * @var OrderEndpoint
57
+ */
58
+ private $api_endpoint;
59
+
60
+ /**
61
+ * The payer factory.
62
+ *
63
+ * @var PayerFactory
64
+ */
65
+ private $payer_factory;
66
+
67
+ /**
68
+ * The session handler.
69
+ *
70
+ * @var SessionHandler
71
+ */
72
+ private $session_handler;
73
+
74
+ /**
75
+ * The settings.
76
+ *
77
+ * @var Settings
78
+ */
79
+ private $settings;
80
+
81
+ /**
82
+ * The early order handler.
83
+ *
84
+ * @var EarlyOrderHandler
85
+ */
86
+ private $early_order_handler;
87
+
88
+ /**
89
+ * The current PayPal order in a process.
90
+ *
91
+ * @var Order|null
92
+ */
93
+ private $order;
94
+
95
+ /**
96
+ * CreateOrderEndpoint constructor.
97
+ *
98
+ * @param RequestData $request_data The RequestData object.
99
+ * @param CartRepository $cart_repository The CartRepository object.
100
+ * @param PurchaseUnitFactory $purchase_unit_factory The Purchaseunit factory.
101
+ * @param OrderEndpoint $order_endpoint The OrderEndpoint object.
102
+ * @param PayerFactory $payer_factory The PayerFactory object.
103
+ * @param SessionHandler $session_handler The SessionHandler object.
104
+ * @param Settings $settings The Settings object.
105
+ * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
106
+ */
107
+ public function __construct(
108
+ RequestData $request_data,
109
+ CartRepository $cart_repository,
110
+ PurchaseUnitFactory $purchase_unit_factory,
111
+ OrderEndpoint $order_endpoint,
112
+ PayerFactory $payer_factory,
113
+ SessionHandler $session_handler,
114
+ Settings $settings,
115
+ EarlyOrderHandler $early_order_handler
116
+ ) {
117
+
118
+ $this->request_data = $request_data;
119
+ $this->cart_repository = $cart_repository;
120
+ $this->purchase_unit_factory = $purchase_unit_factory;
121
+ $this->api_endpoint = $order_endpoint;
122
+ $this->payer_factory = $payer_factory;
123
+ $this->session_handler = $session_handler;
124
+ $this->settings = $settings;
125
+ $this->early_order_handler = $early_order_handler;
126
+ }
127
+
128
+ /**
129
+ * Returns the nonce.
130
+ *
131
+ * @return string
132
+ */
133
+ public static function nonce(): string {
134
+ return self::ENDPOINT;
135
+ }
136
+
137
+ /**
138
+ * Handles the request.
139
+ *
140
+ * @return bool
141
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException In case a setting was not found.
142
+ */
143
+ public function handle_request(): bool {
144
+ try {
145
+ $data = $this->request_data->read_request( $this->nonce() );
146
+ $wc_order = null;
147
+ if ( 'pay-now' === $data['context'] ) {
148
+ $wc_order = wc_get_order( (int) $data['order_id'] );
149
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
150
+ wp_send_json_error(
151
+ array(
152
+ 'name' => 'order-not-found',
153
+ 'message' => __( 'Order not found', 'woocommerce-paypal-payments' ),
154
+ 'code' => 0,
155
+ 'details' => array(),
156
+ )
157
+ );
158
+ }
159
+ $purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) );
160
+ } else {
161
+ $purchase_units = $this->cart_repository->all();
162
+ }
163
+
164
+ $this->set_bn_code( $data );
165
+ $order = $this->api_endpoint->create(
166
+ $purchase_units,
167
+ $this->payer( $data, $wc_order ),
168
+ null,
169
+ $this->payment_method()
170
+ );
171
+ if ( 'checkout' === $data['context'] ) {
172
+ $this->validate_checkout_form( $data['form'], $order );
173
+ }
174
+ if ( 'pay-now' === $data['context'] ) {
175
+ $this->validate_paynow_form( $data['form'] );
176
+ }
177
+ wp_send_json_success( $order->to_array() );
178
+ return true;
179
+ } catch ( \RuntimeException $error ) {
180
+ wp_send_json_error(
181
+ array(
182
+ 'name' => is_a( $error, PayPalApiException::class ) ? $error->name() : '',
183
+ 'message' => $error->getMessage(),
184
+ 'code' => $error->getCode(),
185
+ 'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(),
186
+ )
187
+ );
188
+ return false;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Returns the Payer entity based on the request data.
194
+ *
195
+ * @param array $data The request data.
196
+ * @param \WC_Order $wc_order The order.
197
+ *
198
+ * @return Payer|null
199
+ */
200
+ private function payer( array $data, \WC_Order $wc_order = null ) {
201
+ if ( 'pay-now' === $data['context'] ) {
202
+ $payer = $this->payer_factory->from_wc_order( $wc_order );
203
+ return $payer;
204
+ }
205
+
206
+ $payer = null;
207
+ if ( isset( $data['payer'] ) && $data['payer'] ) {
208
+ if ( isset( $data['payer']['phone']['phone_number']['national_number'] ) ) {
209
+ // make sure the phone number contains only numbers and is max 14. chars long.
210
+ $number = $data['payer']['phone']['phone_number']['national_number'];
211
+ $number = preg_replace( '/[^0-9]/', '', $number );
212
+ $number = substr( $number, 0, 14 );
213
+ $data['payer']['phone']['phone_number']['national_number'] = $number;
214
+ }
215
+ $payer = $this->payer_factory->from_paypal_response( json_decode( wp_json_encode( $data['payer'] ) ) );
216
+ }
217
+ return $payer;
218
+ }
219
+
220
+
221
+ /**
222
+ * Sets the BN Code for the following request.
223
+ *
224
+ * @param array $data The request data.
225
+ */
226
+ private function set_bn_code( array $data ) {
227
+ $bn_code = isset( $data['bn_code'] ) ? (string) $data['bn_code'] : '';
228
+ if ( ! $bn_code ) {
229
+ return;
230
+ }
231
+
232
+ $this->session_handler->replace_bn_code( $bn_code );
233
+ $this->api_endpoint->with_bn_code( $bn_code );
234
+ }
235
+
236
+ /**
237
+ * Returns the PaymentMethod object for the order.
238
+ *
239
+ * @return PaymentMethod
240
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException In case a setting would not be found.
241
+ */
242
+ private function payment_method() : PaymentMethod {
243
+ $payee_preferred = $this->settings->has( 'payee_preferred' ) && $this->settings->get( 'payee_preferred' ) ?
244
+ PaymentMethod::PAYEE_PREFERRED_IMMEDIATE_PAYMENT_REQUIRED
245
+ : PaymentMethod::PAYEE_PREFERRED_UNRESTRICTED;
246
+ $payment_method = new PaymentMethod( $payee_preferred );
247
+ return $payment_method;
248
+ }
249
+
250
+ /**
251
+ * Prepare the Request parameter and process the checkout form and validate it.
252
+ *
253
+ * @param string $form_values The values of the form.
254
+ * @param Order $order The Order.
255
+ *
256
+ * @throws \Exception On Error.
257
+ */
258
+ private function validate_checkout_form( string $form_values, Order $order ) {
259
+ $this->order = $order;
260
+ $parsed_values = wp_parse_args( $form_values );
261
+ $_POST = $parsed_values;
262
+ $_REQUEST = $parsed_values;
263
+
264
+ add_filter(
265
+ 'woocommerce_after_checkout_validation',
266
+ array(
267
+ $this,
268
+ 'after_checkout_validation',
269
+ ),
270
+ 10,
271
+ 2
272
+ );
273
+ $checkout = \WC()->checkout();
274
+ $checkout->process_checkout();
275
+ }
276
+
277
+ /**
278
+ * Checks whether the terms input field is checked.
279
+ *
280
+ * @param string $form_values The form values.
281
+ * @throws \RuntimeException When field is not checked.
282
+ */
283
+ private function validate_paynow_form( string $form_values ) {
284
+ $parsed_values = wp_parse_args( $form_values );
285
+ if ( ! isset( $parsed_values['terms'] ) ) {
286
+ throw new \RuntimeException(
287
+ __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce-paypal-payments' )
288
+ );
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Once the checkout has been validated we execute this method.
294
+ *
295
+ * @param array $data The data.
296
+ * @param \WP_Error $errors The errors, which occurred.
297
+ *
298
+ * @return array
299
+ */
300
+ public function after_checkout_validation( array $data, \WP_Error $errors ): array {
301
+
302
+ $order = $this->order;
303
+ if ( ! $errors->errors ) {
304
+
305
+ /**
306
+ * In case we are onboarded and everything is fine with the \WC_Order
307
+ * we want this order to be created. We will intercept it and leave it
308
+ * in the "Pending payment" status though, which than later will change
309
+ * during the "onApprove"-JS callback or the webhook listener.
310
+ */
311
+ if ( ! $this->early_order_handler->should_create_early_order() ) {
312
+ wp_send_json_success( $order->to_array() );
313
+ }
314
+ $this->early_order_handler->register_for_order( $order );
315
+ return $data;
316
+ }
317
+
318
+ wp_send_json_error(
319
+ array(
320
+ 'name' => '',
321
+ 'message' => $errors->get_error_message(),
322
+ 'code' => (int) $errors->get_error_code(),
323
+ 'details' => array(),
324
+ )
325
+ );
326
+ return $data;
327
+ }
328
+ }
modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Data Client ID endpoint.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+
16
+ /**
17
+ * Class DataClientIdEndpoint
18
+ */
19
+ class DataClientIdEndpoint implements EndpointInterface {
20
+
21
+
22
+ const ENDPOINT = 'ppc-data-client-id';
23
+
24
+ /**
25
+ * The Request Data Helper.
26
+ *
27
+ * @var RequestData
28
+ */
29
+ private $request_data;
30
+
31
+ /**
32
+ * The Identity Token.
33
+ *
34
+ * @var IdentityToken
35
+ */
36
+ private $identity_token;
37
+
38
+ /**
39
+ * DataClientIdEndpoint constructor.
40
+ *
41
+ * @param RequestData $request_data The Request Data Helper.
42
+ * @param IdentityToken $identity_token The Identity Token.
43
+ */
44
+ public function __construct(
45
+ RequestData $request_data,
46
+ IdentityToken $identity_token
47
+ ) {
48
+
49
+ $this->request_data = $request_data;
50
+ $this->identity_token = $identity_token;
51
+ }
52
+
53
+ /**
54
+ * Returns the nonce.
55
+ *
56
+ * @return string
57
+ */
58
+ public static function nonce(): string {
59
+ return self::ENDPOINT;
60
+ }
61
+
62
+ /**
63
+ * Handles the request.
64
+ *
65
+ * @return bool
66
+ */
67
+ public function handle_request(): bool {
68
+ try {
69
+ $this->request_data->read_request( $this->nonce() );
70
+ $user_id = get_current_user_id();
71
+ $token = $this->identity_token->generate_for_customer( $user_id );
72
+ wp_send_json(
73
+ array(
74
+ 'token' => $token->token(),
75
+ 'expiration' => $token->expiration_timestamp(),
76
+ 'user' => get_current_user_id(),
77
+ )
78
+ );
79
+ return true;
80
+ } catch ( RuntimeException $error ) {
81
+ wp_send_json_error(
82
+ array(
83
+ 'name' => is_a( $error, PayPalApiException::class ) ? $error->name() : '',
84
+ 'message' => $error->getMessage(),
85
+ 'code' => $error->getCode(),
86
+ 'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(),
87
+ )
88
+ );
89
+ return false;
90
+ }
91
+ }
92
+ }
modules/ppcp-button/src/Endpoint/class-endpointinterface.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Endpoint interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
11
+
12
+ /**
13
+ * Interface EndpointInterface
14
+ */
15
+ interface EndpointInterface {
16
+
17
+ /**
18
+ * Returns the nonce for an endpoint.
19
+ *
20
+ * @return string
21
+ */
22
+ public static function nonce(): string;
23
+
24
+ /**
25
+ * Handles the request for an endpoint.
26
+ *
27
+ * @return bool
28
+ */
29
+ public function handle_request(): bool;
30
+ }
modules/ppcp-button/src/Endpoint/class-requestdata.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper to read request data for the endpoints.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
13
+
14
+ /**
15
+ * Class RequestData
16
+ */
17
+ class RequestData {
18
+
19
+ /**
20
+ * Enqueues the nonce fix hook.
21
+ */
22
+ public function enqueue_nonce_fix() {
23
+ add_filter( 'nonce_user_logged_out', array( $this, 'nonce_fix' ), 100 );
24
+ }
25
+
26
+ /**
27
+ * Dequeues the nonce fix hook.
28
+ */
29
+ public function dequeue_nonce_fix() {
30
+ remove_filter( 'nonce_user_logged_out', array( $this, 'nonce_fix' ), 100 );
31
+ }
32
+
33
+ /**
34
+ * Reads the current request.
35
+ *
36
+ * @param string $nonce The nonce.
37
+ *
38
+ * @return array
39
+ * @throws RuntimeException When nonce validation fails.
40
+ */
41
+ public function read_request( string $nonce ): array {
42
+ $stream = file_get_contents( 'php://input' );
43
+ $json = json_decode( $stream, true );
44
+ $this->enqueue_nonce_fix();
45
+ if (
46
+ ! isset( $json['nonce'] )
47
+ || ! wp_verify_nonce( $json['nonce'], $nonce )
48
+ ) {
49
+ remove_filter( 'nonce_user_logged_out', array( $this, 'nonce_fix' ), 100 );
50
+ throw new RuntimeException(
51
+ __( 'Could not validate nonce.', 'woocommerce-paypal-payments' )
52
+ );
53
+ }
54
+ $this->dequeue_nonce_fix();
55
+
56
+ $sanitized = $this->sanitize( $json );
57
+ return $sanitized;
58
+ }
59
+
60
+ /**
61
+ * WooCommerce will give you a customer object on your 2nd request. the first page
62
+ * load will not yet have this customer object, but the ajax request will. Therefore
63
+ * the nonce validation will fail. this fixes this problem:
64
+ *
65
+ * @wp-hook nonce_user_logged_out
66
+ * @see https://github.com/woocommerce/woocommerce/blob/69e3835041113bee80379c1037e97e26815a699b/includes/class-wc-session-handler.php#L288-L296
67
+ * @return int
68
+ */
69
+ public function nonce_fix(): int {
70
+ return 0;
71
+ }
72
+
73
+ /**
74
+ * Sanitizes the data.
75
+ *
76
+ * @param array $assoc_array The data array.
77
+ *
78
+ * @return array
79
+ */
80
+ private function sanitize( array $assoc_array ): array {
81
+ $data = array();
82
+ foreach ( (array) $assoc_array as $raw_key => $raw_value ) {
83
+ if ( ! is_array( $raw_value ) ) {
84
+ $data[ sanitize_text_field( urldecode( (string) $raw_key ) ) ] = sanitize_text_field( urldecode( (string) $raw_value ) );
85
+ continue;
86
+ }
87
+ $data[ sanitize_text_field( urldecode( (string) $raw_key ) ) ] = $this->sanitize( $raw_value );
88
+ }
89
+ return $data;
90
+ }
91
+ }
modules/ppcp-button/src/Exception/class-runtimeexception.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The modules Runtime Exception.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Exception
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Exception;
11
+
12
+ /**
13
+ * Class RuntimeException
14
+ */
15
+ class RuntimeException extends \RuntimeException {
16
+
17
+
18
+ }
modules/ppcp-button/src/Helper/class-earlyorderhandler.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Early Order logic, when we need to create the WC_Order by ourselfs.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Helper
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Helper;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
14
+ use WooCommerce\PayPalCommerce\Onboarding\State;
15
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
18
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\PrefixTrait;
19
+
20
+ /**
21
+ * Class EarlyOrderHandler
22
+ */
23
+ class EarlyOrderHandler {
24
+
25
+ use PrefixTrait;
26
+
27
+ /**
28
+ * The State.
29
+ *
30
+ * @var State
31
+ */
32
+ private $state;
33
+
34
+ /**
35
+ * The Order Processor.
36
+ *
37
+ * @var OrderProcessor
38
+ */
39
+ private $order_processor;
40
+
41
+ /**
42
+ * The Session Handler.
43
+ *
44
+ * @var SessionHandler
45
+ */
46
+ private $session_handler;
47
+
48
+ /**
49
+ * EarlyOrderHandler constructor.
50
+ *
51
+ * @param State $state The State.
52
+ * @param OrderProcessor $order_processor The Order Processor.
53
+ * @param SessionHandler $session_handler The Session Handler.
54
+ * @param string $prefix The Prefix.
55
+ */
56
+ public function __construct(
57
+ State $state,
58
+ OrderProcessor $order_processor,
59
+ SessionHandler $session_handler,
60
+ string $prefix
61
+ ) {
62
+
63
+ $this->state = $state;
64
+ $this->order_processor = $order_processor;
65
+ $this->session_handler = $session_handler;
66
+ $this->prefix = $prefix;
67
+ }
68
+
69
+ /**
70
+ * Whether early orders should be created at all.
71
+ *
72
+ * @return bool
73
+ */
74
+ public function should_create_early_order(): bool {
75
+ return $this->state->current_state() === State::STATE_ONBOARDED;
76
+ }
77
+
78
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
79
+
80
+ /**
81
+ * Tries to determine the current WC Order Id based on the PayPal order
82
+ * and the current order in session.
83
+ *
84
+ * @param int|null $value The initial value.
85
+ *
86
+ * @return int|null
87
+ */
88
+ public function determine_wc_order_id( int $value = null ) {
89
+
90
+ if ( ! isset( $_REQUEST['ppcp-resume-order'] ) ) {
91
+ return $value;
92
+ }
93
+
94
+ $resume_order_id = (int) WC()->session->get( 'order_awaiting_payment' );
95
+
96
+ $order = $this->session_handler->order();
97
+ if ( ! $order ) {
98
+ return $value;
99
+ }
100
+
101
+ $order_id = false;
102
+ foreach ( $order->purchase_units() as $purchase_unit ) {
103
+ if ( $purchase_unit->custom_id() === sanitize_text_field( wp_unslash( $_REQUEST['ppcp-resume-order'] ) ) ) {
104
+ $order_id = (int) $this->sanitize_custom_id( $purchase_unit->custom_id() );
105
+ }
106
+ }
107
+ if ( $order_id === $resume_order_id ) {
108
+ $value = $order_id;
109
+ }
110
+ return $value;
111
+ }
112
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
113
+
114
+ /**
115
+ * Registers the necessary checkout actions for a given order.
116
+ *
117
+ * @param Order $order The PayPal order.
118
+ *
119
+ * @return bool
120
+ */
121
+ public function register_for_order( Order $order ): bool {
122
+
123
+ $success = (bool) add_action(
124
+ 'woocommerce_checkout_order_processed',
125
+ function ( $order_id ) use ( $order ) {
126
+ try {
127
+ $order = $this->configure_session_and_order( (int) $order_id, $order );
128
+ wp_send_json_success( $order->to_array() );
129
+ } catch ( \RuntimeException $error ) {
130
+ wp_send_json_error(
131
+ array(
132
+ 'name' => is_a( $error, PayPalApiException::class ) ?
133
+ $error->name() : '',
134
+ 'message' => $error->getMessage(),
135
+ 'code' => $error->getCode(),
136
+ 'details' => is_a( $error, PayPalApiException::class ) ?
137
+ $error->details() : array(),
138
+
139
+ )
140
+ );
141
+ }
142
+ }
143
+ );
144
+
145
+ return $success;
146
+ }
147
+
148
+ /**
149
+ * Configures the session, so we can pick up the order, once we pass through the checkout.
150
+ *
151
+ * @param int $order_id The WooCommerce order id.
152
+ * @param Order $order The PayPal order.
153
+ *
154
+ * @return Order
155
+ */
156
+ public function configure_session_and_order( int $order_id, Order $order ): Order {
157
+
158
+ /**
159
+ * Set the order id in our session in order for
160
+ * us to resume this order in checkout.
161
+ */
162
+ WC()->session->set( 'order_awaiting_payment', $order_id );
163
+
164
+ $wc_order = wc_get_order( $order_id );
165
+ $wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
166
+ $wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
167
+ $wc_order->save_meta_data();
168
+
169
+ /**
170
+ * Patch Order so we have the \WC_Order id added.
171
+ */
172
+ return $this->order_processor->patch_order( $wc_order, $order );
173
+ }
174
+ }
modules/ppcp-button/src/Helper/class-messagesapply.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper class to determine if credit messaging should be displayed.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Helper
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Helper;
11
+
12
+ /**
13
+ * Class MessagesApply
14
+ */
15
+ class MessagesApply {
16
+
17
+
18
+ /**
19
+ * In which countries credit messaging is available.
20
+ *
21
+ * @var array
22
+ */
23
+ private $countries = array(
24
+ 'US',
25
+ );
26
+
27
+ /**
28
+ * Determines whether a credit messaging is enabled for the shops location country.
29
+ *
30
+ * @return bool
31
+ */
32
+ public function for_country(): bool {
33
+ $region = wc_get_base_location();
34
+ $country = $region['country'];
35
+ return in_array( $country, $this->countries, true );
36
+ }
37
+ }
modules/ppcp-button/src/Helper/class-threedsecure.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper class to determine how to proceed with an order depending on the 3d secure feedback.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button\Helper
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button\Helper;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult as AuthResult;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
14
+
15
+ /**
16
+ * Class ThreeDSecure
17
+ */
18
+ class ThreeDSecure {
19
+
20
+
21
+ const NO_DECISION = 0;
22
+ const PROCCEED = 1;
23
+ const REJECT = 2;
24
+ const RETRY = 3;
25
+
26
+ /**
27
+ * Determine, how we proceed with a given order.
28
+ *
29
+ * @link https://developer.paypal.com/docs/business/checkout/add-capabilities/3d-secure/#authenticationresult
30
+ *
31
+ * @param Order $order The order for which the decission is needed.
32
+ *
33
+ * @return int
34
+ */
35
+ public function proceed_with_order( Order $order ): int {
36
+ if ( ! $order->payment_source() ) {
37
+ return self::NO_DECISION;
38
+ }
39
+ if ( ! $order->payment_source()->card() ) {
40
+ return self::NO_DECISION;
41
+ }
42
+ if ( ! $order->payment_source()->card()->authentication_result() ) {
43
+ return self::NO_DECISION;
44
+ }
45
+ $result = $order->payment_source()->card()->authentication_result();
46
+ if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
47
+ return self::PROCCEED;
48
+ }
49
+
50
+ if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) {
51
+ return self::RETRY;
52
+ }
53
+ if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) {
54
+ return $this->no_liability_shift( $result );
55
+ }
56
+ return self::NO_DECISION;
57
+ }
58
+
59
+ /**
60
+ * Determines how to proceed depending on the Liability Shift.
61
+ *
62
+ * @param AuthResult $result The AuthResult object based on which we make the decision.
63
+ *
64
+ * @return int
65
+ */
66
+ private function no_liability_shift( AuthResult $result ): int {
67
+
68
+ if (
69
+ $result->enrollment_status() === AuthResult::ENROLLMENT_STATUS_BYPASS
70
+ && ! $result->authentication_result()
71
+ ) {
72
+ return self::PROCCEED;
73
+ }
74
+ if (
75
+ $result->enrollment_status() === AuthResult::ENROLLMENT_STATUS_UNAVAILABLE
76
+ && ! $result->authentication_result()
77
+ ) {
78
+ return self::PROCCEED;
79
+ }
80
+ if (
81
+ $result->enrollment_status() === AuthResult::ENROLLMENT_STATUS_NO
82
+ && ! $result->authentication_result()
83
+ ) {
84
+ return self::PROCCEED;
85
+ }
86
+
87
+ if ( $result->authentication_result() === AuthResult::AUTHENTICATION_RESULT_REJECTED ) {
88
+ return self::REJECT;
89
+ }
90
+
91
+ if ( $result->authentication_result() === AuthResult::AUTHENTICATION_RESULT_NO ) {
92
+ return self::REJECT;
93
+ }
94
+
95
+ if ( $result->authentication_result() === AuthResult::AUTHENTICATION_RESULT_UNABLE ) {
96
+ return self::RETRY;
97
+ }
98
+
99
+ if ( ! $result->authentication_result() ) {
100
+ return self::RETRY;
101
+ }
102
+ return self::NO_DECISION;
103
+ }
104
+ }
modules/ppcp-button/src/class-buttonmodule.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The button module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Button
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Button;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
15
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
16
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
17
+ use WooCommerce\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
18
+ use WooCommerce\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
19
+ use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
20
+ use Interop\Container\ServiceProviderInterface;
21
+ use Psr\Container\ContainerInterface;
22
+
23
+ /**
24
+ * Class ButtonModule
25
+ */
26
+ class ButtonModule implements ModuleInterface {
27
+
28
+
29
+ /**
30
+ * Sets up the module.
31
+ *
32
+ * @return ServiceProviderInterface
33
+ */
34
+ public function setup(): ServiceProviderInterface {
35
+ return new ServiceProvider(
36
+ require __DIR__ . '/../services.php',
37
+ require __DIR__ . '/../extensions.php'
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Runs the module.
43
+ *
44
+ * @param ContainerInterface|null $container The Container.
45
+ */
46
+ public function run( ContainerInterface $container = null ) {
47
+
48
+ add_action(
49
+ 'wp',
50
+ static function () use ( $container ) {
51
+ if ( is_admin() ) {
52
+ return;
53
+ }
54
+ $smart_button = $container->get( 'button.smart-button' );
55
+ /**
56
+ * The Smart Button.
57
+ *
58
+ * @var SmartButtonInterface $smart_button
59
+ */
60
+ $smart_button->render_wrapper();
61
+ }
62
+ );
63
+ add_action(
64
+ 'wp_enqueue_scripts',
65
+ static function () use ( $container ) {
66
+
67
+ $smart_button = $container->get( 'button.smart-button' );
68
+ /**
69
+ * The Smart Button.
70
+ *
71
+ * @var SmartButtonInterface $smart_button
72
+ */
73
+ $smart_button->enqueue();
74
+ }
75
+ );
76
+
77
+ add_filter(
78
+ 'woocommerce_create_order',
79
+ static function ( $value ) use ( $container ) {
80
+ $early_order_handler = $container->get( 'button.helper.early-order-handler' );
81
+ if ( ! is_null( $value ) ) {
82
+ $value = (int) $value;
83
+ }
84
+ /**
85
+ * The Early Order Handler
86
+ *
87
+ * @var EarlyOrderHandler $early_order_handler
88
+ */
89
+ return $early_order_handler->determine_wc_order_id( $value );
90
+ }
91
+ );
92
+
93
+ $this->register_ajax_endpoints( $container );
94
+ }
95
+
96
+ /**
97
+ * Registers the Ajax Endpoints.
98
+ *
99
+ * @param ContainerInterface $container The Container.
100
+ */
101
+ private function register_ajax_endpoints( ContainerInterface $container ) {
102
+ add_action(
103
+ 'wc_ajax_' . DataClientIdEndpoint::ENDPOINT,
104
+ static function () use ( $container ) {
105
+ $endpoint = $container->get( 'button.endpoint.data-client-id' );
106
+ /**
107
+ * The Data Client ID Endpoint.
108
+ *
109
+ * @var DataClientIdEndpoint $endpoint
110
+ */
111
+ $endpoint->handle_request();
112
+ }
113
+ );
114
+
115
+ add_action(
116
+ 'wc_ajax_' . ChangeCartEndpoint::ENDPOINT,
117
+ static function () use ( $container ) {
118
+ $endpoint = $container->get( 'button.endpoint.change-cart' );
119
+ /**
120
+ * The Change Cart Endpoint.
121
+ *
122
+ * @var ChangeCartEndpoint $endpoint
123
+ */
124
+ $endpoint->handle_request();
125
+ }
126
+ );
127
+
128
+ add_action(
129
+ 'wc_ajax_' . ApproveOrderEndpoint::ENDPOINT,
130
+ static function () use ( $container ) {
131
+ $endpoint = $container->get( 'button.endpoint.approve-order' );
132
+ /**
133
+ * The Approve Order Endpoint.
134
+ *
135
+ * @var ApproveOrderEndpoint $endpoint
136
+ */
137
+ $endpoint->handle_request();
138
+ }
139
+ );
140
+
141
+ add_action(
142
+ 'wc_ajax_' . CreateOrderEndpoint::ENDPOINT,
143
+ static function () use ( $container ) {
144
+ $endpoint = $container->get( 'button.endpoint.create-order' );
145
+ /**
146
+ * The Create Order Endpoint.
147
+ *
148
+ * @var CreateOrderEndpoint $endpoint
149
+ */
150
+ $endpoint->handle_request();
151
+ }
152
+ );
153
+ }
154
+
155
+ /**
156
+ * Returns the key for the module.
157
+ *
158
+ * @return string|void
159
+ */
160
+ public function getKey() {
161
+ }
162
+ }
modules/ppcp-onboarding/assets/css/onboarding.css ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .optional {
2
+ display: none;
3
+ }
4
+
5
+ #field-merchant_email_production,
6
+ #field-ppcp_disconnect_sandbox,
7
+ #field-ppcp_disconnect_production,
8
+ #field-merchant_id_production,
9
+ #field-client_id_production,
10
+ #field-client_secret_production,
11
+ #field-merchant_email_sandbox,
12
+ #field-merchant_id_sandbox,
13
+ #field-client_id_sandbox,
14
+ #field-client_secret_sandbox{
15
+ display: none;
16
+ }
17
+ #field-merchant_email_production.show,
18
+ #field-ppcp_disconnect_sandbox.show,
19
+ #field-ppcp_disconnect_production.show,
20
+ #field-merchant_id_production.show,
21
+ #field-client_id_production.show,
22
+ #field-client_secret_production.show,
23
+ #field-merchant_email_sandbox.show,
24
+ #field-merchant_id_sandbox.show,
25
+ #field-client_id_sandbox.show,
26
+ #field-client_secret_sandbox.show {
27
+ display: table-row;
28
+ }
29
+
30
+ #field-toggle_manual_input span.hide,
31
+ #field-toggle_manual_input.show span.show{
32
+ display: none;
33
+ }
34
+ #field-toggle_manual_input.show span.hide {
35
+ display: unset;
36
+ }
37
+
38
+ #field-production_toggle_manual_input button,
39
+ #field-sandbox_toggle_manual_input button {
40
+ color: #0073aa;
41
+ transition-property: border, background, color;
42
+ transition-duration: .05s;
43
+ transition-timing-function: ease-in-out;
44
+ background: none;
45
+ border: none;
46
+ text-decoration: underline;
47
+ cursor: pointer;
48
+ margin: 0;
49
+ padding: 0;
50
+ }
51
+
52
+ #field-sandbox_toggle_manual_input.onboarded,
53
+ #field-production_toggle_manual_input.onboarded {
54
+ display: none;
55
+ }
56
+
57
+
58
+ #field-ppcp_disconnect_sandbox.onboarded,
59
+ #field-ppcp_disconnect_production.onboarded,
60
+ #field-merchant_email_sandbox.onboarded,
61
+ #field-merchant_id_sandbox.onboarded,
62
+ #field-client_id_sandbox.onboarded,
63
+ #field-client_secret_sandbox.onboarded,
64
+ #field-merchant_email_production.onboarded,
65
+ #field-merchant_id_production.onboarded,
66
+ #field-client_id_production.onboarded,
67
+ #field-client_secret_production.onboarded {
68
+ display:table-row;
69
+ }
70
+ #field-ppcp_disconnect_sandbox.onboarded.hide,
71
+ #field-ppcp_disconnect_production.onboarded.hide,
72
+ #field-merchant_email_sandbox.onboarded.hide,
73
+ #field-merchant_id_sandbox.onboarded.hide,
74
+ #field-client_id_sandbox.onboarded.hide,
75
+ #field-client_secret_sandbox.onboarded.hide,
76
+ #field-merchant_email_production.onboarded.hide,
77
+ #field-merchant_id_production.onboarded.hide,
78
+ #field-client_id_production.onboarded.hide,
79
+ #field-client_secret_production.onboarded.hide {
80
+ display:none;
81
+ }
82
+
83
+ /* Probably not the best location for this but will do until there's a general purpose settings CSS file. */
84
+ .ppcp-settings-field-heading td, .ppcp-settings-field-heading th {
85
+ padding-left: 0;
86
+ }
87
+
88
+ .woocommerce_page_wc-settings h3.ppcp-subheading {
89
+ font-size: 1.1em;
90
+ }
modules/ppcp-onboarding/assets/js/onboarding.js ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function onboardingCallback(authCode, sharedId) {
2
+ const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on');
3
+ fetch(
4
+ PayPalCommerceGatewayOnboarding.endpoint,
5
+ {
6
+ method: 'POST',
7
+ headers: {
8
+ 'content-type': 'application/json'
9
+ },
10
+ body: JSON.stringify(
11
+ {
12
+ authCode: authCode,
13
+ sharedId: sharedId,
14
+ nonce: PayPalCommerceGatewayOnboarding.nonce,
15
+ env: sandboxSwitchElement && sandboxSwitchElement.checked ? 'sandbox' : 'production'
16
+ }
17
+ )
18
+ }
19
+ );
20
+ }
21
+
22
+ /**
23
+ * Since the PayPal modal will redirect the user a dirty form
24
+ * provokes an alert if the user wants to leave the page. Since the user
25
+ * needs to toggle the sandbox switch, we disable this dirty state with the
26
+ * following workaround for checkboxes.
27
+ *
28
+ * @param event
29
+ */
30
+ const checkBoxOnClick = (event) => {
31
+ const value = event.target.checked;
32
+ if (event.target.getAttribute('id') === 'ppcp-sandbox_on') {
33
+ toggleSandboxProduction(! value);
34
+ }
35
+ event.preventDefault();
36
+ event.stopPropagation();
37
+ setTimeout( () => {
38
+ event.target.checked = value;
39
+ },1
40
+ );
41
+ };
42
+
43
+ /**
44
+ * Toggles the credential input fields.
45
+ *
46
+ * @param forProduction
47
+ */
48
+ const credentialToggle = (forProduction) => {
49
+
50
+ const sandboxClassSelectors = [
51
+ '#field-ppcp_disconnect_sandbox',
52
+ '#field-merchant_email_sandbox',
53
+ '#field-merchant_id_sandbox',
54
+ '#field-client_id_sandbox',
55
+ '#field-client_secret_sandbox',
56
+ ];
57
+ const productionClassSelectors = [
58
+ '#field-ppcp_disconnect_production',
59
+ '#field-merchant_email_production',
60
+ '#field-merchant_id_production',
61
+ '#field-client_id_production',
62
+ '#field-client_secret_production',
63
+ ];
64
+
65
+ const selectors = forProduction ? productionClassSelectors : sandboxClassSelectors;
66
+ document.querySelectorAll(selectors.join()).forEach(
67
+ (element) => {element.classList.toggle('show')}
68
+ )
69
+ };
70
+
71
+ /**
72
+ * Toggles the visibility of the sandbox/production input fields.
73
+ *
74
+ * @param showProduction
75
+ */
76
+ const toggleSandboxProduction = (showProduction) => {
77
+ const productionDisplaySelectors = [
78
+ '#field-credentials_production_heading',
79
+ '#field-production_toggle_manual_input',
80
+ '#field-ppcp_onboarding_production',
81
+ ];
82
+ const productionClassSelectors = [
83
+
84
+ '#field-ppcp_disconnect_production',
85
+ '#field-merchant_email_production',
86
+ '#field-merchant_id_production',
87
+ '#field-client_id_production',
88
+ '#field-client_secret_production',
89
+ ];
90
+ const sandboxDisplaySelectors = [
91
+ '#field-credentials_sandbox_heading',
92
+ '#field-sandbox_toggle_manual_input',
93
+ '#field-ppcp_onboarding_sandbox',
94
+ ];
95
+ const sandboxClassSelectors = [
96
+ '#field-ppcp_disconnect_sandbox',
97
+ '#field-merchant_email_sandbox',
98
+ '#field-merchant_id_sandbox',
99
+ '#field-client_id_sandbox',
100
+ '#field-client_secret_sandbox',
101
+ ];
102
+
103
+ if (showProduction) {
104
+ document.querySelectorAll(productionDisplaySelectors.join()).forEach(
105
+ (element) => {element.style.display = ''}
106
+ );
107
+ document.querySelectorAll(sandboxDisplaySelectors.join()).forEach(
108
+ (element) => {element.style.display = 'none'}
109
+ );
110
+ document.querySelectorAll(productionClassSelectors.join()).forEach(
111
+ (element) => {element.classList.remove('hide')}
112
+ );
113
+ document.querySelectorAll(sandboxClassSelectors.join()).forEach(
114
+ (element) => {
115
+ element.classList.remove('show');
116
+ element.classList.add('hide');
117
+ }
118
+ );
119
+ return;
120
+ }
121
+ document.querySelectorAll(productionDisplaySelectors.join()).forEach(
122
+ (element) => {element.style.display = 'none'}
123
+ );
124
+ document.querySelectorAll(sandboxDisplaySelectors.join()).forEach(
125
+ (element) => {element.style.display = ''}
126
+ );
127
+
128
+ document.querySelectorAll(sandboxClassSelectors.join()).forEach(
129
+ (element) => {element.classList.remove('hide')}
130
+ );
131
+ document.querySelectorAll(productionClassSelectors.join()).forEach(
132
+ (element) => {
133
+ element.classList.remove('show');
134
+ element.classList.add('hide');
135
+ }
136
+ )
137
+ };
138
+
139
+ const disconnect = (event) => {
140
+ event.preventDefault();
141
+ const fields = event.target.classList.contains('production') ? [
142
+ '#field-merchant_email_production input',
143
+ '#field-merchant_id_production input',
144
+ '#field-client_id_production input',
145
+ '#field-client_secret_production input',
146
+ ] : [
147
+ '#field-merchant_email_sandbox input',
148
+ '#field-merchant_id_sandbox input',
149
+ '#field-client_id_sandbox input',
150
+ '#field-client_secret_sandbox input',
151
+ ];
152
+
153
+ document.querySelectorAll(fields.join()).forEach(
154
+ (element) => {
155
+ element.value = '';
156
+ }
157
+ );
158
+ document.querySelector('.woocommerce-save-button').click();
159
+ };
160
+
161
+ (() => {
162
+ const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on');
163
+ if (sandboxSwitchElement) {
164
+ toggleSandboxProduction(! sandboxSwitchElement.checked);
165
+ }
166
+
167
+ document.querySelectorAll('.ppcp-disconnect').forEach(
168
+ (button) => {
169
+ button.addEventListener(
170
+ 'click',
171
+ disconnect
172
+ );
173
+ }
174
+ );
175
+
176
+ // Prevent a possibly dirty form arising from this particular checkbox.
177
+ sandboxSwitchElement.addEventListener(
178
+ 'click',
179
+ (event) => {
180
+ const value = event.target.checked;
181
+
182
+ toggleSandboxProduction( ! value );
183
+
184
+ event.preventDefault();
185
+ event.stopPropagation();
186
+ setTimeout( () => {
187
+ event.target.checked = value;
188
+ }, 1
189
+ );
190
+ }
191
+ );
192
+
193
+ // document.querySelectorAll('#mainform input[type="checkbox"]').forEach(
194
+ // (checkbox) => {
195
+ // checkbox.addEventListener('click', checkBoxOnClick);
196
+ // }
197
+ // );
198
+
199
+ document.querySelectorAll('#field-sandbox_toggle_manual_input button, #field-production_toggle_manual_input button').forEach(
200
+ (button) => {
201
+ button.addEventListener(
202
+ 'click',
203
+ (event) => {
204
+ event.preventDefault();
205
+ const isProduction = event.target.classList.contains('production-toggle');
206
+ credentialToggle(isProduction);
207
+ }
208
+ )
209
+ }
210
+ )
211
+
212
+ })();
modules/ppcp-onboarding/assets/js/settings.js ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const groupToggle = (selector, group) => {
2
+ const toggleElement = document.querySelector(selector);
3
+ if (! toggleElement) {
4
+ return;
5
+ }
6
+ if (! toggleElement.checked) {
7
+ group.forEach( (elementToHide) => {
8
+ document.querySelector(elementToHide).style.display = 'none';
9
+ })
10
+ }
11
+ toggleElement.addEventListener(
12
+ 'change',
13
+ (event) => {
14
+
15
+ if (! event.target.checked) {
16
+ group.forEach( (elementToHide) => {
17
+ document.querySelector(elementToHide).style.display = 'none';
18
+ });
19
+ return;
20
+ }
21
+
22
+ group.forEach( (elementToShow) => {
23
+ document.querySelector(elementToShow).style.display = 'table-row';
24
+ })
25
+ }
26
+ );
27
+ };
28
+
29
+ const groupToggleSelect = (selector, group) => {
30
+ const toggleElement = document.querySelector(selector);
31
+ if (! toggleElement) {
32
+ return;
33
+ }
34
+ const value = toggleElement.value;
35
+ group.forEach( (elementToToggle) => {
36
+ const domElement = document.querySelector(elementToToggle.selector);
37
+ if (! domElement) {
38
+ return;
39
+ }
40
+ if (value === elementToToggle.value && domElement.style.display !== 'none') {
41
+ domElement.style.display = 'table-row';
42
+ return;
43
+ }
44
+ domElement.style.display = 'none';
45
+ });
46
+
47
+ // We need to use jQuery here as the select might be a select2 element, which doesn't use native events.
48
+ jQuery(toggleElement).on(
49
+ 'change',
50
+ (event) => {
51
+ const value = event.target.value;
52
+ group.forEach( (elementToToggle) => {
53
+ if (value === elementToToggle.value) {
54
+ document.querySelector(elementToToggle.selector).style.display = 'table-row';
55
+ return;
56
+ }
57
+ document.querySelector(elementToToggle.selector).style.display = 'none';
58
+ })
59
+ }
60
+ );
61
+ };
62
+
63
+ const disableOptions = (sourceSelector, targetSelector) => {
64
+
65
+ const source = jQuery(sourceSelector);
66
+ const target = document.querySelector(targetSelector);
67
+ if (! target) {
68
+ return;
69
+ }
70
+ const allOptions = Array.from(document.querySelectorAll('select[name="ppcp[disable_cards][]"] option'));
71
+ const replace = () => {
72
+ const validOptions = allOptions.filter(
73
+ (option) => {
74
+
75
+ return ! option.selected
76
+ }
77
+ );
78
+ const selectedValidOptions = validOptions.map(
79
+ (option) => {
80
+ option = option.cloneNode(true);
81
+ option.selected = target.querySelector('option[value="' + option.value + '"]') && target.querySelector('option[value="' + option.value + '"]').selected;
82
+ return option;
83
+ }
84
+ );
85
+ target.innerHTML = '';
86
+ selectedValidOptions.forEach(
87
+ (option) => {
88
+ target.append(option);
89
+ }
90
+ );
91
+ };
92
+
93
+ source.on('change',replace);
94
+ replace();
95
+ };
96
+
97
+ (() => {
98
+ disableOptions('select[name="ppcp[disable_cards][]"]', 'select[name="ppcp[card_icons][]"]');
99
+ groupToggle(
100
+ '#ppcp-button_enabled',
101
+ [
102
+ '#field-button_layout',
103
+ '#field-button_tagline',
104
+ '#field-button_label',
105
+ '#field-button_color',
106
+ '#field-button_shape',
107
+ ]
108
+ );
109
+
110
+ groupToggle(
111
+ '#ppcp-message_enabled',
112
+ [
113
+ '#field-message_layout',
114
+ '#field-message_logo',
115
+ '#field-message_position',
116
+ '#field-message_color',
117
+ '#field-message_flex_color',
118
+ '#field-message_flex_ratio',
119
+ ]
120
+ );
121
+
122
+ groupToggle(
123
+ '#ppcp-button_product_enabled',
124
+ [
125
+ '#field-button_product_layout',
126
+ '#field-button_product_tagline',
127
+ '#field-button_product_label',
128
+ '#field-button_product_color',
129
+ '#field-button_product_shape',
130
+ ]
131
+ );
132
+
133
+ groupToggle(
134
+ '#ppcp-message_product_enabled',
135
+ [
136
+ '#field-message_product_layout',
137
+ '#field-message_product_logo',
138
+ '#field-message_product_position',
139
+ '#field-message_product_color',
140
+ '#field-message_product_flex_color',
141
+ '#field-message_product_flex_ratio',
142
+ ]
143
+ );
144
+
145
+ groupToggle(
146
+ '#ppcp-button_mini-cart_enabled',
147
+ [
148
+ '#field-button_mini-cart_layout',
149
+ '#field-button_mini-cart_tagline',
150
+ '#field-button_mini-cart_label',
151
+ '#field-button_mini-cart_color',
152
+ '#field-button_mini-cart_shape',
153
+ ]
154
+ );
155
+
156
+ groupToggle(
157
+ '#ppcp-button_cart_enabled',
158
+ [
159
+ '#field-button_cart_layout',
160
+ '#field-button_cart_tagline',
161
+ '#field-button_cart_label',
162
+ '#field-button_cart_color',
163
+ '#field-button_cart_shape',
164
+ ]
165
+ );
166
+ groupToggle(
167
+ '#ppcp-message_cart_enabled',
168
+ [
169
+ '#field-message_cart_layout',
170
+ '#field-message_cart_logo',
171
+ '#field-message_cart_position',
172
+ '#field-message_cart_color',
173
+ '#field-message_cart_flex_color',
174
+ '#field-message_cart_flex_ratio',
175
+ ]
176
+ );
177
+
178
+ groupToggleSelect(
179
+ '#ppcp-message_product_layout',
180
+ [
181
+ {
182
+ value:'text',
183
+ selector:'#field-message_product_logo'
184
+ },
185
+ {
186
+ value:'text',
187
+ selector:'#field-message_product_position'
188
+ },
189
+ {
190
+ value:'text',
191
+ selector:'#field-message_product_color'
192
+ },
193
+ {
194
+ value:'flex',
195
+ selector:'#field-message_product_flex_ratio'
196
+ },
197
+ {
198
+ value:'flex',
199
+ selector:'#field-message_product_flex_color'
200
+ }
201
+ ]
202
+ );
203
+ groupToggleSelect(
204
+ '#ppcp-intent',
205
+ [
206
+ {
207
+ value:'authorize',
208
+ selector:'#field-capture_for_virtual_only'
209
+ }
210
+ ]
211
+ );
212
+ groupToggleSelect(
213
+ '#ppcp-message_cart_layout',
214
+ [
215
+ {
216
+ value:'text',
217
+ selector:'#field-message_cart_logo'
218
+ },
219
+ {
220
+ value:'text',
221
+ selector:'#field-message_cart_position'
222
+ },
223
+ {
224
+ value:'text',
225
+ selector:'#field-message_cart_color'
226
+ },
227
+ {
228
+ value:'flex',
229
+ selector:'#field-message_cart_flex_ratio'
230
+ },
231
+ {
232
+ value:'flex',
233
+ selector:'#field-message_cart_flex_color'
234
+ }
235
+ ]
236
+ );
237
+ groupToggleSelect(
238
+ '#ppcp-message_layout',
239
+ [
240
+ {
241
+ value:'text',
242
+ selector:'#field-message_logo'
243
+ },
244
+ {
245
+ value:'text',
246
+ selector:'#field-message_position'
247
+ },
248
+ {
249
+ value:'text',
250
+ selector:'#field-message_color'
251
+ },
252
+ {
253
+ value:'flex',
254
+ selector:'#field-message_flex_ratio'
255
+ },
256
+ {
257
+ value:'flex',
258
+ selector:'#field-message_flex_color'
259
+ }
260
+ ]
261
+ );
262
+ })();
modules/ppcp-onboarding/extensions.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The onboarding module extensions.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ return array();
modules/ppcp-onboarding/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The onboarding module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new OnboardingModule();
16
+ };
modules/ppcp-onboarding/services.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The onboarding module services.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
18
+ use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
19
+ use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
20
+ use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
21
+
22
+ return array(
23
+ 'api.sandbox-host' => static function ( $container ): string {
24
+
25
+ $state = $container->get( 'onboarding.state' );
26
+
27
+ /**
28
+ * The State object.
29
+ *
30
+ * @var State $state
31
+ */
32
+ if ( $state->current_state() >= State::STATE_ONBOARDED ) {
33
+ return PAYPAL_SANDBOX_API_URL;
34
+ }
35
+ return CONNECT_WOO_SANDBOX_URL;
36
+ },
37
+ 'api.production-host' => static function ( $container ): string {
38
+
39
+ $state = $container->get( 'onboarding.state' );
40
+
41
+ /**
42
+ * The Environment and State variables.
43
+ *
44
+ * @var Environment $environment
45
+ * @var State $state
46
+ */
47
+ if ( $state->current_state() >= State::STATE_ONBOARDED ) {
48
+ return PAYPAL_API_URL;
49
+ }
50
+ return CONNECT_WOO_URL;
51
+ },
52
+ 'api.host' => static function ( $container ): string {
53
+ $environment = $container->get( 'onboarding.environment' );
54
+
55
+ /**
56
+ * The Environment and State variables.
57
+ *
58
+ * @var Environment $environment
59
+ */
60
+ return $environment->current_environment_is( Environment::SANDBOX )
61
+ ? (string) $container->get( 'api.sandbox-host' ) : (string) $container->get( 'api.production-host' );
62
+
63
+ },
64
+ 'api.paypal-host-production' => static function( $container ) : string {
65
+ return PAYPAL_API_URL;
66
+ },
67
+ 'api.paypal-host-sandbox' => static function( $container ) : string {
68
+ return PAYPAL_SANDBOX_API_URL;
69
+ },
70
+ 'api.partner_merchant_id-production' => static function( $container ) : string {
71
+ return CONNECT_WOO_MERCHANT_ID;
72
+ },
73
+ 'api.partner_merchant_id-sandbox' => static function( $container ) : string {
74
+ return CONNECT_WOO_SANDBOX_MERCHANT_ID;
75
+ },
76
+ 'api.paypal-host' => function( $container ) : string {
77
+ $environment = $container->get( 'onboarding.environment' );
78
+ /**
79
+ * The current environment.
80
+ *
81
+ * @var Environment $environment
82
+ */
83
+ if ( $environment->current_environment_is( Environment::SANDBOX ) ) {
84
+ return $container->get( 'api.paypal-host-sandbox' );
85
+ }
86
+ return $container->get( 'api.paypal-host-production' );
87
+
88
+ },
89
+
90
+ 'api.bearer' => static function ( $container ): Bearer {
91
+
92
+ $state = $container->get( 'onboarding.state' );
93
+
94
+ /**
95
+ * The State.
96
+ *
97
+ * @var State $state
98
+ */
99
+ if ( $state->current_state() < State::STATE_ONBOARDED ) {
100
+ return new ConnectBearer();
101
+ }
102
+ $cache = new Cache( 'ppcp-paypal-bearer' );
103
+ $key = $container->get( 'api.key' );
104
+ $secret = $container->get( 'api.secret' );
105
+
106
+ $host = $container->get( 'api.host' );
107
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
108
+ return new PayPalBearer(
109
+ $cache,
110
+ $host,
111
+ $key,
112
+ $secret,
113
+ $logger
114
+ );
115
+ },
116
+ 'onboarding.state' => function( $container ) : State {
117
+ $environment = $container->get( 'onboarding.environment' );
118
+ $settings = $container->get( 'wcgateway.settings' );
119
+ return new State( $environment, $settings );
120
+ },
121
+ 'onboarding.environment' => function( $container ) : Environment {
122
+ $settings = $container->get( 'wcgateway.settings' );
123
+ return new Environment( $settings );
124
+ },
125
+
126
+ 'onboarding.assets' => function( $container ) : OnboardingAssets {
127
+ $state = $container->get( 'onboarding.state' );
128
+ $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' );
129
+ return new OnboardingAssets(
130
+ $container->get( 'onboarding.url' ),
131
+ $state,
132
+ $login_seller_endpoint
133
+ );
134
+ },
135
+
136
+ 'onboarding.url' => static function ( $container ): string {
137
+ return plugins_url(
138
+ '/modules/ppcp-onboarding/',
139
+ dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
140
+ );
141
+ },
142
+
143
+ 'api.endpoint.login-seller-production' => static function ( $container ) : LoginSeller {
144
+
145
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
146
+ return new LoginSeller(
147
+ $container->get( 'api.paypal-host-production' ),
148
+ $container->get( 'api.partner_merchant_id-production' ),
149
+ $logger
150
+ );
151
+ },
152
+
153
+ 'api.endpoint.login-seller-sandbox' => static function ( $container ) : LoginSeller {
154
+
155
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
156
+ return new LoginSeller(
157
+ $container->get( 'api.paypal-host-sandbox' ),
158
+ $container->get( 'api.partner_merchant_id-sandbox' ),
159
+ $logger
160
+ );
161
+ },
162
+
163
+ 'onboarding.endpoint.login-seller' => static function ( $container ) : LoginSellerEndpoint {
164
+
165
+ $request_data = $container->get( 'button.request-data' );
166
+ $login_seller_production = $container->get( 'api.endpoint.login-seller-production' );
167
+ $login_seller_sandbox = $container->get( 'api.endpoint.login-seller-sandbox' );
168
+ $partner_referrals_data = $container->get( 'api.repository.partner-referrals-data' );
169
+ $settings = $container->get( 'wcgateway.settings' );
170
+
171
+ $cache = new Cache( 'ppcp-paypal-bearer' );
172
+ return new LoginSellerEndpoint(
173
+ $request_data,
174
+ $login_seller_production,
175
+ $login_seller_sandbox,
176
+ $partner_referrals_data,
177
+ $settings,
178
+ $cache
179
+ );
180
+ },
181
+ 'api.endpoint.partner-referrals-sandbox' => static function ( $container ) : PartnerReferrals {
182
+
183
+ return new PartnerReferrals(
184
+ CONNECT_WOO_SANDBOX_URL,
185
+ new ConnectBearer(),
186
+ $container->get( 'api.repository.partner-referrals-data' ),
187
+ $container->get( 'woocommerce.logger.woocommerce' )
188
+ );
189
+ },
190
+ 'api.endpoint.partner-referrals-production' => static function ( $container ) : PartnerReferrals {
191
+
192
+ return new PartnerReferrals(
193
+ CONNECT_WOO_URL,
194
+ new ConnectBearer(),
195
+ $container->get( 'api.repository.partner-referrals-data' ),
196
+ $container->get( 'woocommerce.logger.woocommerce' )
197
+ );
198
+ },
199
+ 'onboarding.render' => static function ( $container ) : OnboardingRenderer {
200
+
201
+ $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
202
+ $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
203
+ $settings = $container->get( 'wcgateway.settings' );
204
+ return new OnboardingRenderer(
205
+ $settings,
206
+ $partner_referrals,
207
+ $partner_referrals_sandbox
208
+ );
209
+ },
210
+ );
modules/ppcp-onboarding/src/Assets/class-onboardingassets.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Registers and enqueues the assets for the Onboarding process.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding\Assets
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding\Assets;
11
+
12
+ use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
13
+ use WooCommerce\PayPalCommerce\Onboarding\State;
14
+
15
+ /**
16
+ * Class OnboardingAssets
17
+ */
18
+ class OnboardingAssets {
19
+
20
+ /**
21
+ * The URL to the module.
22
+ *
23
+ * @var string
24
+ */
25
+ private $module_url;
26
+
27
+ /**
28
+ * The State.
29
+ *
30
+ * @var State
31
+ */
32
+ private $state;
33
+
34
+ /**
35
+ * The LoginSeller Endpoint.
36
+ *
37
+ * @var LoginSellerEndpoint
38
+ */
39
+ private $login_seller_endpoint;
40
+
41
+ /**
42
+ * OnboardingAssets constructor.
43
+ *
44
+ * @param string $module_url The URL to the module.
45
+ * @param State $state The State object.
46
+ * @param LoginSellerEndpoint $login_seller_endpoint The LoginSeller endpoint.
47
+ */
48
+ public function __construct(
49
+ string $module_url,
50
+ State $state,
51
+ LoginSellerEndpoint $login_seller_endpoint
52
+ ) {
53
+
54
+ $this->module_url = $module_url;
55
+ $this->state = $state;
56
+ $this->login_seller_endpoint = $login_seller_endpoint;
57
+ }
58
+
59
+ /**
60
+ * Registers the scripts.
61
+ *
62
+ * @return bool
63
+ */
64
+ public function register(): bool {
65
+
66
+ $url = $this->module_url . '/assets/css/onboarding.css';
67
+ wp_register_style(
68
+ 'ppcp-onboarding',
69
+ $url,
70
+ array(),
71
+ 1
72
+ );
73
+ $url = $this->module_url . '/assets/js/settings.js';
74
+ wp_register_script(
75
+ 'ppcp-settings',
76
+ $url,
77
+ array(),
78
+ 1,
79
+ true
80
+ );
81
+ if ( ! $this->should_render_onboarding_script() ) {
82
+ return false;
83
+ }
84
+
85
+ $url = $this->module_url . '/assets/js/onboarding.js';
86
+ wp_register_script(
87
+ 'ppcp-onboarding',
88
+ $url,
89
+ array( 'jquery' ),
90
+ 1,
91
+ true
92
+ );
93
+ wp_localize_script(
94
+ 'ppcp-onboarding',
95
+ 'PayPalCommerceGatewayOnboarding',
96
+ array(
97
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ),
98
+ 'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ),
99
+ )
100
+ );
101
+
102
+ return true;
103
+ }
104
+
105
+ /**
106
+ * Enqueues the necessary scripts.
107
+ *
108
+ * @return bool
109
+ */
110
+ public function enqueue(): bool {
111
+ wp_enqueue_style( 'ppcp-onboarding' );
112
+ wp_enqueue_script( 'ppcp-settings' );
113
+ if ( ! $this->should_render_onboarding_script() ) {
114
+ return false;
115
+ }
116
+
117
+ wp_enqueue_script( 'ppcp-onboarding' );
118
+ return true;
119
+ }
120
+
121
+ /**
122
+ * Whether the onboarding script should be rendered or not.
123
+ *
124
+ * @return bool
125
+ */
126
+ private function should_render_onboarding_script(): bool {
127
+ global $current_section;
128
+ return 'ppcp-gateway' === $current_section;
129
+ }
130
+ }
modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the login seller incoming request to receive the credentials from Paypal.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
16
+ use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
17
+ use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
19
+ use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
20
+
21
+ /**
22
+ * Class LoginSellerEndpoint
23
+ */
24
+ class LoginSellerEndpoint implements EndpointInterface {
25
+
26
+ const ENDPOINT = 'ppc-login-seller';
27
+
28
+ /**
29
+ * The Request Data helper object.
30
+ *
31
+ * @var RequestData
32
+ */
33
+ private $request_data;
34
+
35
+ /**
36
+ * The Login Seller Endpoint for the production environment
37
+ *
38
+ * @var LoginSeller
39
+ */
40
+ private $login_seller_production;
41
+
42
+ /**
43
+ * The Login Seller Endpoint for the sandbox environment
44
+ *
45
+ * @var LoginSeller
46
+ */
47
+ private $login_seller_sandbox;
48
+
49
+ /**
50
+ * The Partner Referrals Data.
51
+ *
52
+ * @var PartnerReferralsData
53
+ */
54
+ private $partner_referrals_data;
55
+
56
+ /**
57
+ * The Settings.
58
+ *
59
+ * @var Settings
60
+ */
61
+ private $settings;
62
+
63
+ /**
64
+ * The Cache.
65
+ *
66
+ * @var Cache
67
+ */
68
+ private $cache;
69
+
70
+ /**
71
+ * LoginSellerEndpoint constructor.
72
+ *
73
+ * @param RequestData $request_data The Request Data.
74
+ * @param LoginSeller $login_seller_production The Login Seller for the production environment.
75
+ * @param LoginSeller $login_seller_sandbox The Login Seller for the sandbox environment.
76
+ * @param PartnerReferralsData $partner_referrals_data The Partner Referrals Data.
77
+ * @param Settings $settings The Settings.
78
+ * @param Cache $cache The Cache.
79
+ */
80
+ public function __construct(
81
+ RequestData $request_data,
82
+ LoginSeller $login_seller_production,
83
+ LoginSeller $login_seller_sandbox,
84
+ PartnerReferralsData $partner_referrals_data,
85
+ Settings $settings,
86
+ Cache $cache
87
+ ) {
88
+
89
+ $this->request_data = $request_data;
90
+ $this->login_seller_production = $login_seller_production;
91
+ $this->login_seller_sandbox = $login_seller_sandbox;
92
+ $this->partner_referrals_data = $partner_referrals_data;
93
+ $this->settings = $settings;
94
+ $this->cache = $cache;
95
+ }
96
+
97
+ /**
98
+ * Returns the nonce for the endpoint.
99
+ *
100
+ * @return string
101
+ */
102
+ public static function nonce(): string {
103
+ return self::ENDPOINT;
104
+ }
105
+
106
+ /**
107
+ * Handles the incoming request.
108
+ *
109
+ * @return bool
110
+ */
111
+ public function handle_request(): bool {
112
+
113
+ try {
114
+ $data = $this->request_data->read_request( $this->nonce() );
115
+ $is_sandbox = isset( $data['env'] ) && 'sandbox' === $data['env'];
116
+ $this->settings->set( 'sandbox_on', $is_sandbox );
117
+ $this->settings->set( 'products_dcc_enabled', null );
118
+ $this->settings->persist();
119
+ $endpoint = $is_sandbox ? $this->login_seller_sandbox : $this->login_seller_production;
120
+ $credentials = $endpoint->credentials_for(
121
+ $data['sharedId'],
122
+ $data['authCode'],
123
+ $this->partner_referrals_data->nonce()
124
+ );
125
+ if ( $is_sandbox ) {
126
+ $this->settings->set( 'client_secret_sandbox', $credentials->client_secret );
127
+ $this->settings->set( 'client_id_sandbox', $credentials->client_id );
128
+ } else {
129
+ $this->settings->set( 'client_secret_production', $credentials->client_secret );
130
+ $this->settings->set( 'client_id_production', $credentials->client_id );
131
+ }
132
+ $this->settings->set( 'client_secret', $credentials->client_secret );
133
+ $this->settings->set( 'client_id', $credentials->client_id );
134
+ $this->settings->persist();
135
+ if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
136
+ $this->cache->delete( PayPalBearer::CACHE_KEY );
137
+ }
138
+ wp_schedule_single_event(
139
+ time() - 1,
140
+ WebhookRegistrar::EVENT_HOOK
141
+ );
142
+ wp_send_json_success();
143
+ return true;
144
+ } catch ( \RuntimeException $error ) {
145
+ wp_send_json_error( $error->getMessage() );
146
+ return false;
147
+ }
148
+ }
149
+ }
modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the "Connect to PayPal" button.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding\Render
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding\Render;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
15
+
16
+ /**
17
+ * Class OnboardingRenderer
18
+ */
19
+ class OnboardingRenderer {
20
+
21
+ /**
22
+ * The settings.
23
+ *
24
+ * @var Settings
25
+ */
26
+ private $settings;
27
+
28
+ /**
29
+ * The partner referrals object for the production environment.
30
+ *
31
+ * @var PartnerReferrals
32
+ */
33
+ private $production_partner_referrals;
34
+
35
+ /**
36
+ * The partner referrals object for the sandbox environment.
37
+ *
38
+ * @var PartnerReferrals
39
+ */
40
+ private $sandbox_partner_referrals;
41
+
42
+ /**
43
+ * OnboardingRenderer constructor.
44
+ *
45
+ * @param Settings $settings The settings.
46
+ * @param PartnerReferrals $production_partner_referrals The PartnerReferrals for production.
47
+ * @param PartnerReferrals $sandbox_partner_referrals The PartnerReferrals for sandbox.
48
+ */
49
+ public function __construct( Settings $settings, PartnerReferrals $production_partner_referrals, PartnerReferrals $sandbox_partner_referrals ) {
50
+ $this->settings = $settings;
51
+ $this->production_partner_referrals = $production_partner_referrals;
52
+ $this->sandbox_partner_referrals = $sandbox_partner_referrals;
53
+ }
54
+
55
+ /**
56
+ * Renders the "Connect to PayPal" button.
57
+ *
58
+ * @param bool $is_production Whether the production or sandbox button should be rendered.
59
+ */
60
+ public function render( bool $is_production ) {
61
+ try {
62
+ $args = array(
63
+ 'displayMode' => 'minibrowser',
64
+ );
65
+
66
+ $url = $is_production ? $this->production_partner_referrals->signup_link() : $this->sandbox_partner_referrals->signup_link();
67
+ $url = add_query_arg( $args, $url );
68
+ $id = $is_production ? 'connect-to-production' : 'connect-to-sandbox';
69
+ $label = $is_production ? __( 'Connect to PayPal', 'woocommerce-paypal-payments' ) : __( 'Connect to PayPal Sandbox', 'woocommerce-paypal-payments' );
70
+ $this->render_button(
71
+ $url,
72
+ $id,
73
+ $label
74
+ );
75
+
76
+ $script_url = 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js'; ?>
77
+ <script>document.querySelectorAll('[data-paypal-onboard-complete=onboardingCallback]').forEach( (element) => { element.addEventListener('click', (e) => {if ('undefined' === typeof PAYPAL ) e.preventDefault(); }) });</script>
78
+ <script
79
+ id="paypal-js"
80
+ src="<?php echo esc_url( $script_url ); ?>"
81
+ ></script>
82
+ <?php
83
+ } catch ( RuntimeException $exception ) {
84
+ esc_html_e(
85
+ 'We could not properly connect to PayPal. Please reload the page to continue',
86
+ 'woocommerce-paypal-payments'
87
+ );
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Renders the button.
93
+ *
94
+ * @param string $url The url of the button.
95
+ * @param string $id The ID of the button.
96
+ * @param string $label The button text.
97
+ */
98
+ private function render_button( string $url, string $id, string $label ) {
99
+ ?>
100
+ <a
101
+ target="_blank"
102
+ class="button-primary"
103
+ id="<?php echo esc_attr( $id ); ?>"
104
+ data-paypal-onboard-complete="onboardingCallback"
105
+ href="<?php echo esc_url( $url ); ?>"
106
+ data-paypal-button="true"
107
+ >
108
+ <?php echo esc_html( $label ); ?>
109
+ </a>
110
+ <?php
111
+ }
112
+ }
modules/ppcp-onboarding/src/class-environment.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to detect the current environment.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ use Psr\Container\ContainerInterface;
13
+
14
+ /**
15
+ * Class Environment
16
+ */
17
+ class Environment {
18
+
19
+
20
+ const PRODUCTION = 'production';
21
+ const SANDBOX = 'sandbox';
22
+
23
+ /**
24
+ * The Settings.
25
+ *
26
+ * @var ContainerInterface
27
+ */
28
+ private $settings;
29
+
30
+ /**
31
+ * Environment constructor.
32
+ *
33
+ * @param ContainerInterface $settings The Settings.
34
+ */
35
+ public function __construct( ContainerInterface $settings ) {
36
+ $this->settings = $settings;
37
+ }
38
+
39
+ /**
40
+ * Returns the current environment.
41
+ *
42
+ * @return string
43
+ */
44
+ public function current_environment(): string {
45
+ return (
46
+ $this->settings->has( 'sandbox_on' ) && $this->settings->get( 'sandbox_on' )
47
+ ) ? self::SANDBOX : self::PRODUCTION;
48
+ }
49
+
50
+ /**
51
+ * Detect whether the current environment equals $environment
52
+ *
53
+ * @param string $environment The value to check against.
54
+ *
55
+ * @return bool
56
+ */
57
+ public function current_environment_is( string $environment ): bool {
58
+ return $this->current_environment() === $environment;
59
+ }
60
+ }
modules/ppcp-onboarding/src/class-onboardingmodule.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The onboarding module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
15
+ use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
16
+ use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
17
+ use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
18
+ use Interop\Container\ServiceProviderInterface;
19
+ use Psr\Container\ContainerInterface;
20
+
21
+ /**
22
+ * Class OnboardingModule
23
+ */
24
+ class OnboardingModule implements ModuleInterface {
25
+
26
+ /**
27
+ * Sets up the module.
28
+ *
29
+ * @return ServiceProviderInterface
30
+ */
31
+ public function setup(): ServiceProviderInterface {
32
+ return new ServiceProvider(
33
+ require __DIR__ . '/../services.php',
34
+ require __DIR__ . '/../extensions.php'
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Runs the module.
40
+ *
41
+ * @param ContainerInterface|null $container The container.
42
+ */
43
+ public function run( ContainerInterface $container = null ) {
44
+
45
+ $asset_loader = $container->get( 'onboarding.assets' );
46
+ /**
47
+ * The OnboardingAssets.
48
+ *
49
+ * @var OnboardingAssets $asset_loader
50
+ */
51
+ add_action(
52
+ 'admin_enqueue_scripts',
53
+ array(
54
+ $asset_loader,
55
+ 'register',
56
+ )
57
+ );
58
+ add_action(
59
+ 'woocommerce_settings_checkout',
60
+ array(
61
+ $asset_loader,
62
+ 'enqueue',
63
+ )
64
+ );
65
+
66
+ add_filter(
67
+ 'woocommerce_form_field',
68
+ static function ( $field, $key, $config ) use ( $container ) {
69
+ if ( 'ppcp_onboarding' !== $config['type'] ) {
70
+ return $field;
71
+ }
72
+ $renderer = $container->get( 'onboarding.render' );
73
+ $is_production = 'production' === $config['env'];
74
+
75
+ /**
76
+ * The OnboardingRenderer.
77
+ *
78
+ * @var OnboardingRenderer $renderer
79
+ */
80
+ ob_start();
81
+ $renderer->render( $is_production );
82
+ $content = ob_get_contents();
83
+ ob_end_clean();
84
+ return $content;
85
+ },
86
+ 10,
87
+ 3
88
+ );
89
+
90
+ add_action(
91
+ 'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,
92
+ static function () use ( $container ) {
93
+ $endpoint = $container->get( 'onboarding.endpoint.login-seller' );
94
+
95
+ /**
96
+ * The ChangeCartEndpoint.
97
+ *
98
+ * @var ChangeCartEndpoint $endpoint
99
+ */
100
+ $endpoint->handle_request();
101
+ }
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Returns the key for the module.
107
+ *
108
+ * @return string|void
109
+ */
110
+ public function getKey() {
111
+ }
112
+ }
modules/ppcp-onboarding/src/class-state.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to determine the current state of onboarding.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Onboarding
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Onboarding;
11
+
12
+ use Psr\Container\ContainerInterface;
13
+
14
+ /**
15
+ * Class State
16
+ */
17
+ class State {
18
+
19
+ const STATE_START = 0;
20
+ const STATE_PROGRESSIVE = 4;
21
+ const STATE_ONBOARDED = 8;
22
+
23
+ /**
24
+ * The Environment.
25
+ *
26
+ * @var Environment
27
+ */
28
+ private $environment;
29
+
30
+ /**
31
+ * The Settings.
32
+ *
33
+ * @var ContainerInterface
34
+ */
35
+ private $settings;
36
+
37
+ /**
38
+ * State constructor.
39
+ *
40
+ * @param Environment $environment The Environment.
41
+ * @param ContainerInterface $settings The Settings.
42
+ */
43
+ public function __construct(
44
+ Environment $environment,
45
+ ContainerInterface $settings
46
+ ) {
47
+
48
+ $this->environment = $environment;
49
+ $this->settings = $settings;
50
+ }
51
+
52
+ /**
53
+ * Returns the current active onboarding state.
54
+ *
55
+ * @return int
56
+ */
57
+ public function current_state(): int {
58
+
59
+ return $this->state_by_keys(
60
+ array(
61
+ 'merchant_email',
62
+ ),
63
+ array(
64
+ 'merchant_email',
65
+ 'merchant_id',
66
+ 'client_id',
67
+ 'client_secret',
68
+ )
69
+ );
70
+ }
71
+
72
+ /**
73
+ * Returns the onboarding state of the sandbox.
74
+ *
75
+ * @return int
76
+ */
77
+ public function sandbox_state() : int {
78
+
79
+ return $this->state_by_keys(
80
+ array(
81
+ 'merchant_email_sandbox',
82
+ ),
83
+ array(
84
+ 'merchant_email_sandbox',
85
+ 'merchant_id_sandbox',
86
+ 'client_id_sandbox',
87
+ 'client_secret_sandbox',
88
+ )
89
+ );
90
+ }
91
+
92
+ /**
93
+ * Returns the onboarding state of the production mode.
94
+ *
95
+ * @return int
96
+ */
97
+ public function production_state() : int {
98
+
99
+ return $this->state_by_keys(
100
+ array(
101
+ 'merchant_email_production',
102
+ ),
103
+ array(
104
+ 'merchant_email_production',
105
+ 'merchant_id_production',
106
+ 'client_id_production',
107
+ 'client_secret_production',
108
+ )
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Returns the state based on progressive and onboarded values being looked up in the settings.
114
+ *
115
+ * @param array $progressive_keys The keys which need to be present to be at least in progressive state.
116
+ * @param array $onboarded_keys The keys which need to be present to be in onboarded state.
117
+ *
118
+ * @return int
119
+ */
120
+ private function state_by_keys( array $progressive_keys, array $onboarded_keys ) : int {
121
+ $state = self::STATE_START;
122
+ $is_progressive = true;
123
+ foreach ( $progressive_keys as $key ) {
124
+ if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) {
125
+ $is_progressive = false;
126
+ }
127
+ }
128
+ if ( $is_progressive ) {
129
+ $state = self::STATE_PROGRESSIVE;
130
+ }
131
+
132
+ $is_onboarded = true;
133
+ foreach ( $onboarded_keys as $key ) {
134
+ if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) {
135
+ $is_onboarded = false;
136
+ }
137
+ }
138
+
139
+ if ( $is_onboarded ) {
140
+ $state = self::STATE_ONBOARDED;
141
+ }
142
+
143
+ return $state;
144
+ }
145
+ }
modules/ppcp-session/extensions.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The extensions of the session module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session;
11
+
12
+ return array();
modules/ppcp-session/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The session module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return function (): ModuleInterface {
15
+ return new SessionModule();
16
+ };
modules/ppcp-session/services.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The services of the session module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session;
11
+
12
+ use Dhii\Data\Container\ContainerInterface;
13
+ use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
14
+ use WooCommerce\PayPalCommerce\Session\Cancellation\CancelView;
15
+
16
+ return array(
17
+ 'session.handler' => function ( $container ) : SessionHandler {
18
+
19
+ if ( is_null( WC()->session ) ) {
20
+ return new SessionHandler();
21
+ }
22
+ $result = WC()->session->get( SessionHandler::ID );
23
+ if ( is_a( $result, SessionHandler::class ) ) {
24
+ return $result;
25
+ }
26
+ $session_handler = new SessionHandler();
27
+ WC()->session->set( SessionHandler::ID, $session_handler );
28
+ return $session_handler;
29
+ },
30
+ 'session.cancellation.view' => function ( $container ) : CancelView {
31
+ return new CancelView();
32
+ },
33
+ 'session.cancellation.controller' => function ( $container ) : CancelController {
34
+ return new CancelController(
35
+ $container->get( 'session.handler' ),
36
+ $container->get( 'session.cancellation.view' )
37
+ );
38
+ },
39
+ );
modules/ppcp-session/src/Cancellation/class-cancelcontroller.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controlls the cancel mechanism to step out of the PayPal order session.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session\Cancellation
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session\Cancellation;
11
+
12
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
13
+
14
+ /**
15
+ * Class CancelController
16
+ */
17
+ class CancelController {
18
+
19
+ /**
20
+ * The Session handler.
21
+ *
22
+ * @var SessionHandler
23
+ */
24
+ private $session_handler;
25
+
26
+ /**
27
+ * The view.
28
+ *
29
+ * @var CancelView
30
+ */
31
+ private $view;
32
+
33
+ /**
34
+ * CancelController constructor.
35
+ *
36
+ * @param SessionHandler $session_handler The session handler.
37
+ * @param CancelView $view The view object.
38
+ */
39
+ public function __construct(
40
+ SessionHandler $session_handler,
41
+ CancelView $view
42
+ ) {
43
+
44
+ $this->view = $view;
45
+ $this->session_handler = $session_handler;
46
+ }
47
+
48
+ /**
49
+ * Runs the controller.
50
+ */
51
+ public function run() {
52
+ $param_name = 'ppcp-cancel';
53
+ $nonce = 'ppcp-cancel-' . get_current_user_id();
54
+ if ( isset( $_GET[ $param_name ] ) && // Input var ok.
55
+ wp_verify_nonce(
56
+ sanitize_text_field( wp_unslash( $_GET[ $param_name ] ) ), // Input var ok.
57
+ $nonce
58
+ )
59
+ ) { // Input var ok.
60
+ $this->session_handler->destroy_session_data();
61
+ }
62
+ if ( ! $this->session_handler->order() ) {
63
+ return;
64
+ }
65
+
66
+ $url = add_query_arg( array( $param_name => wp_create_nonce( $nonce ) ), wc_get_checkout_url() );
67
+ add_action(
68
+ 'woocommerce_review_order_after_submit',
69
+ function () use ( $url ) {
70
+ $this->view->render_session_cancellation( $url );
71
+ }
72
+ );
73
+ }
74
+ }
modules/ppcp-session/src/Cancellation/class-cancelview.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the cancel view for the order on the checkout.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session\Cancellation
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session\Cancellation;
11
+
12
+ /**
13
+ * Class CancelView
14
+ */
15
+ class CancelView {
16
+
17
+ /**
18
+ * Renders the cancel link.
19
+ *
20
+ * @param string $url The URL.
21
+ */
22
+ public function render_session_cancellation( string $url ) {
23
+ ?>
24
+ <p id="ppcp-cancel"
25
+ class="has-text-align-center ppcp-cancel"
26
+ >
27
+ <?php
28
+ printf(
29
+ // translators: the placeholders are html tags for a link.
30
+ esc_html__(
31
+ 'You are currently paying with PayPal. If you want to cancel
32
+ this process, please click %1$shere%2$s.',
33
+ 'woocommerce-paypal-payments'
34
+ ),
35
+ '<a href="' . esc_url( $url ) . '">',
36
+ '</a>'
37
+ );
38
+ ?>
39
+ </p>
40
+ <?php
41
+ }
42
+ }
modules/ppcp-session/src/class-sessionhandler.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Session Handler.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
13
+
14
+ /**
15
+ * Class SessionHandler
16
+ */
17
+ class SessionHandler {
18
+
19
+ const ID = 'ppcp';
20
+
21
+ /**
22
+ * The Order.
23
+ *
24
+ * @var Order|null
25
+ */
26
+ private $order;
27
+
28
+ /**
29
+ * The BN Code.
30
+ *
31
+ * @var string
32
+ */
33
+ private $bn_code = '';
34
+
35
+ /**
36
+ * If PayPal respondes with INSTRUMENT_DECLINED, we only
37
+ * want to go max. three times through the process of trying again.
38
+ *
39
+ * @var int
40
+ */
41
+ private $insufficient_funding_tries = 0;
42
+
43
+ /**
44
+ * Returns the order.
45
+ *
46
+ * @return Order|null
47
+ */
48
+ public function order() {
49
+ return $this->order;
50
+ }
51
+
52
+ /**
53
+ * Replaces the current order.
54
+ *
55
+ * @param Order $order The new order.
56
+ *
57
+ * @return SessionHandler
58
+ */
59
+ public function replace_order( Order $order ) : SessionHandler {
60
+ $this->order = $order;
61
+ $this->store_session();
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Returns the BN Code.
67
+ *
68
+ * @return string
69
+ */
70
+ public function bn_code() : string {
71
+ return $this->bn_code;
72
+ }
73
+
74
+ /**
75
+ * Replaces the BN Code.
76
+ *
77
+ * @param string $bn_code The new BN Code.
78
+ *
79
+ * @return SessionHandler
80
+ */
81
+ public function replace_bn_code( string $bn_code ) : SessionHandler {
82
+ $this->bn_code = $bn_code;
83
+ $this->store_session();
84
+ return $this;
85
+ }
86
+
87
+ /**
88
+ * Returns how many times the customer tried to use the PayPal Gateway in this session.
89
+ *
90
+ * @return int
91
+ */
92
+ public function insufficient_funding_tries() : int {
93
+ return $this->insufficient_funding_tries;
94
+ }
95
+
96
+ /**
97
+ * Increments the number of tries, the customer has done in this session.
98
+ *
99
+ * @return SessionHandler
100
+ */
101
+ public function increment_insufficient_funding_tries() : SessionHandler {
102
+ $this->insufficient_funding_tries++;
103
+ $this->store_session();
104
+ return $this;
105
+ }
106
+
107
+ /**
108
+ * Destroys the session data.
109
+ *
110
+ * @return SessionHandler
111
+ */
112
+ public function destroy_session_data() : SessionHandler {
113
+ $this->order = null;
114
+ $this->bn_code = '';
115
+ $this->insufficient_funding_tries = 0;
116
+ $this->store_session();
117
+ return $this;
118
+ }
119
+
120
+ /**
121
+ * Stores the session.
122
+ */
123
+ private function store_session() {
124
+ WC()->session->set( self::ID, $this );
125
+ }
126
+ }
modules/ppcp-session/src/class-sessionmodule.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The session module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Session
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Session;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
15
+ use Interop\Container\ServiceProviderInterface;
16
+ use Psr\Container\ContainerInterface;
17
+
18
+ /**
19
+ * Class SessionModule
20
+ */
21
+ class SessionModule implements ModuleInterface {
22
+
23
+ /**
24
+ * Sets up the module.
25
+ *
26
+ * @return ServiceProviderInterface
27
+ */
28
+ public function setup(): ServiceProviderInterface {
29
+ return new ServiceProvider(
30
+ require __DIR__ . '/../services.php',
31
+ require __DIR__ . '/../extensions.php'
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Run the module.
37
+ *
38
+ * @param ContainerInterface|null $container The container.
39
+ */
40
+ public function run( ContainerInterface $container = null ) {
41
+ add_action(
42
+ 'woocommerce_init',
43
+ function () use ( $container ) {
44
+ $controller = $container->get( 'session.cancellation.controller' );
45
+ /**
46
+ * The Cancel controller.
47
+ *
48
+ * @var CancelController $controller
49
+ */
50
+ $controller->run();
51
+ }
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Returns the key for the module.
57
+ *
58
+ * @return string|void
59
+ */
60
+ public function getKey() {
61
+ }
62
+ }
modules/ppcp-subscription/extensions.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The extensions.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ return array();
modules/ppcp-subscription/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Subscription;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new SubscriptionModule();
16
+ };
modules/ppcp-subscription/services.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The services
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Subscription;
11
+
12
+ use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
13
+ use WooCommerce\PayPalCommerce\Subscription\Repository\PaymentTokenRepository;
14
+ use Psr\Container\ContainerInterface;
15
+
16
+ return array(
17
+ 'subscription.helper' => static function ( $container ): SubscriptionHelper {
18
+ return new SubscriptionHelper();
19
+ },
20
+ 'subscription.renewal-handler' => static function ( $container ): RenewalHandler {
21
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
22
+ $repository = $container->get( 'subscription.repository.payment-token' );
23
+ $endpoint = $container->get( 'api.endpoint.order' );
24
+ $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
25
+ $payer_factory = $container->get( 'api.factory.payer' );
26
+ return new RenewalHandler(
27
+ $logger,
28
+ $repository,
29
+ $endpoint,
30
+ $purchase_unit_factory,
31
+ $payer_factory
32
+ );
33
+ },
34
+ 'subscription.repository.payment-token' => static function ( $container ): PaymentTokenRepository {
35
+ $factory = $container->get( 'api.factory.payment-token' );
36
+ $endpoint = $container->get( 'api.endpoint.payment-token' );
37
+ return new PaymentTokenRepository( $factory, $endpoint );
38
+ },
39
+ );
modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper class for the subscriptions. Contains methods to determine
4
+ * whether the cart contains a subscription, the current product is
5
+ * a subscription or the subscription plugin is activated in the first place.
6
+ *
7
+ * @package WooCommerce\PayPalCommerce\Subscription\Helper
8
+ */
9
+
10
+ declare(strict_types=1);
11
+
12
+ namespace WooCommerce\PayPalCommerce\Subscription\Helper;
13
+
14
+ /**
15
+ * Class SubscriptionHelper
16
+ */
17
+ class SubscriptionHelper {
18
+
19
+ /**
20
+ * Whether the current product is a subscription.
21
+ *
22
+ * @return bool
23
+ */
24
+ public function current_product_is_subscription(): bool {
25
+ if ( ! $this->plugin_is_active() ) {
26
+ return false;
27
+ }
28
+ $product = wc_get_product();
29
+ return is_a( $product, \WC_Product::class ) && $product->is_type( 'subscription' );
30
+ }
31
+
32
+ /**
33
+ * Whether the current cart contains subscriptions.
34
+ *
35
+ * @return bool
36
+ */
37
+ public function cart_contains_subscription(): bool {
38
+ if ( ! $this->plugin_is_active() ) {
39
+ return false;
40
+ }
41
+ $cart = WC()->cart;
42
+ if ( ! $cart || $cart->is_empty() ) {
43
+ return false;
44
+ }
45
+
46
+ foreach ( $cart->get_cart() as $item ) {
47
+ if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
48
+ continue;
49
+ }
50
+ if ( $item['data']->is_type( 'subscription' ) ) {
51
+ return true;
52
+ }
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Whether only automatic payment gateways are accepted.
60
+ *
61
+ * @return bool
62
+ */
63
+ public function accept_only_automatic_payment_gateways(): bool {
64
+
65
+ if ( ! $this->plugin_is_active() ) {
66
+ return false;
67
+ }
68
+ $accept_manual_renewals = ( 'no' !== get_option(
69
+ //phpcs:disable Inpsyde.CodeQuality.VariablesName.SnakeCaseVar
70
+ \WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals',
71
+ //phpcs:enable Inpsyde.CodeQuality.VariablesName.SnakeCaseVar
72
+ 'no'
73
+ ) ) ? true : false;
74
+ return ! $accept_manual_renewals;
75
+ }
76
+
77
+ /**
78
+ * Whether the subscription plugin is active or not.
79
+ *
80
+ * @return bool
81
+ */
82
+ public function plugin_is_active(): bool {
83
+
84
+ return class_exists( \WC_Subscriptions::class );
85
+ }
86
+ }
modules/ppcp-subscription/src/Repository/class-paymenttokenrepository.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The payment token repository returns or deletes payment tokens for users.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Subscription\Repository;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
16
+
17
+ /**
18
+ * Class PaymentTokenRepository
19
+ */
20
+ class PaymentTokenRepository {
21
+
22
+
23
+ const USER_META = 'ppcp-vault-token';
24
+
25
+ /**
26
+ * The payment token factory.
27
+ *
28
+ * @var PaymentTokenFactory
29
+ */
30
+ private $factory;
31
+
32
+ /**
33
+ * The payment token endpoint.
34
+ *
35
+ * @var PaymentTokenEndpoint
36
+ */
37
+ private $endpoint;
38
+
39
+ /**
40
+ * PaymentTokenRepository constructor.
41
+ *
42
+ * @param PaymentTokenFactory $factory The payment token factory.
43
+ * @param PaymentTokenEndpoint $endpoint The payment token endpoint.
44
+ */
45
+ public function __construct(
46
+ PaymentTokenFactory $factory,
47
+ PaymentTokenEndpoint $endpoint
48
+ ) {
49
+
50
+ $this->factory = $factory;
51
+ $this->endpoint = $endpoint;
52
+ }
53
+
54
+ /**
55
+ * Return a token for a user.
56
+ *
57
+ * @param int $id The user id.
58
+ *
59
+ * @return PaymentToken|null
60
+ */
61
+ public function for_user_id( int $id ) {
62
+ try {
63
+ $token = (array) get_user_meta( $id, self::USER_META, true );
64
+ if ( ! $token || ! isset( $token['id'] ) ) {
65
+ return $this->fetch_for_user_id( $id );
66
+ }
67
+
68
+ $token = $this->factory->from_array( $token );
69
+ return $token;
70
+ } catch ( RuntimeException $error ) {
71
+ return null;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Delete a token for a user.
77
+ *
78
+ * @param int $user_id The user id.
79
+ * @param PaymentToken $token The token.
80
+ *
81
+ * @return bool
82
+ */
83
+ public function delete_token( int $user_id, PaymentToken $token ): bool {
84
+ delete_user_meta( $user_id, self::USER_META );
85
+ return $this->endpoint->delete_token( $token );
86
+ }
87
+
88
+ /**
89
+ * Fetch PaymentToken from PayPal for a user.
90
+ *
91
+ * @param int $id The user id.
92
+ * @return PaymentToken
93
+ */
94
+ private function fetch_for_user_id( int $id ): PaymentToken {
95
+
96
+ $tokens = $this->endpoint->for_user( $id );
97
+ $token = current( $tokens );
98
+ $token_array = $token->to_array();
99
+ update_user_meta( $id, self::USER_META, $token_array );
100
+ return $token;
101
+ }
102
+ }
modules/ppcp-subscription/src/class-renewalhandler.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles subscription renewals.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Subscription;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
18
+ use WooCommerce\PayPalCommerce\Subscription\Repository\PaymentTokenRepository;
19
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
+ use Psr\Log\LoggerInterface;
21
+
22
+ /**
23
+ * Class RenewalHandler
24
+ */
25
+ class RenewalHandler {
26
+
27
+ /**
28
+ * The logger.
29
+ *
30
+ * @var LoggerInterface
31
+ */
32
+ private $logger;
33
+
34
+ /**
35
+ * The payment token repository.
36
+ *
37
+ * @var PaymentTokenRepository
38
+ */
39
+ private $repository;
40
+
41
+ /**
42
+ * The order endpoint.
43
+ *
44
+ * @var OrderEndpoint
45
+ */
46
+ private $order_endpoint;
47
+
48
+ /**
49
+ * The purchase unit factory.
50
+ *
51
+ * @var PurchaseUnitFactory
52
+ */
53
+ private $purchase_unit_factory;
54
+
55
+ /**
56
+ * The payer factory.
57
+ *
58
+ * @var PayerFactory
59
+ */
60
+ private $payer_factory;
61
+
62
+ /**
63
+ * RenewalHandler constructor.
64
+ *
65
+ * @param LoggerInterface $logger The logger.
66
+ * @param PaymentTokenRepository $repository The payment token repository.
67
+ * @param OrderEndpoint $order_endpoint The order endpoint.
68
+ * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
69
+ * @param PayerFactory $payer_factory The payer factory.
70
+ */
71
+ public function __construct(
72
+ LoggerInterface $logger,
73
+ PaymentTokenRepository $repository,
74
+ OrderEndpoint $order_endpoint,
75
+ PurchaseUnitFactory $purchase_unit_factory,
76
+ PayerFactory $payer_factory
77
+ ) {
78
+
79
+ $this->logger = $logger;
80
+ $this->repository = $repository;
81
+ $this->order_endpoint = $order_endpoint;
82
+ $this->purchase_unit_factory = $purchase_unit_factory;
83
+ $this->payer_factory = $payer_factory;
84
+ }
85
+
86
+ /**
87
+ * Renew an order.
88
+ *
89
+ * @param \WC_Order $wc_order The WooCommerce order.
90
+ */
91
+ public function renew( \WC_Order $wc_order ) {
92
+
93
+ $this->logger->log(
94
+ 'info',
95
+ sprintf(
96
+ // translators: %d is the id of the order.
97
+ __( 'Start moneytransfer for order %d', 'woocommerce-paypal-payments' ),
98
+ (int) $wc_order->get_id()
99
+ ),
100
+ array(
101
+ 'order' => $wc_order,
102
+ )
103
+ );
104
+
105
+ try {
106
+ $this->process_order( $wc_order );
107
+ } catch ( \Exception $error ) {
108
+ $this->logger->log(
109
+ 'error',
110
+ sprintf(
111
+ // translators: %1$d is the order number, %2$s the error message.
112
+ __(
113
+ 'An error occured while trying to renew the subscription for order %1$d: %2$s',
114
+ 'woocommerce-paypal-payments'
115
+ ),
116
+ (int) $wc_order->get_id(),
117
+ $error->getMessage()
118
+ ),
119
+ array(
120
+ 'order' => $wc_order,
121
+ )
122
+ );
123
+ \WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $wc_order );
124
+ return;
125
+ }
126
+ $this->logger->log(
127
+ 'info',
128
+ sprintf(
129
+ // translators: %d is the order number.
130
+ __(
131
+ 'Moneytransfer for order %d is completed.',
132
+ 'woocommerce-paypal-payments'
133
+ ),
134
+ (int) $wc_order->get_id()
135
+ ),
136
+ array(
137
+ 'order' => $wc_order,
138
+ )
139
+ );
140
+ }
141
+
142
+ /**
143
+ * Process a WooCommerce order.
144
+ *
145
+ * @param \WC_Order $wc_order The WooCommerce order.
146
+ *
147
+ * @throws \Exception If customer cannot be read/found.
148
+ */
149
+ private function process_order( \WC_Order $wc_order ) {
150
+
151
+ $user_id = (int) $wc_order->get_customer_id();
152
+ $customer = new \WC_Customer( $user_id );
153
+ $token = $this->get_token_for_customer( $customer, $wc_order );
154
+ if ( ! $token ) {
155
+ return;
156
+ }
157
+ $purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
158
+ $payer = $this->payer_factory->from_customer( $customer );
159
+ $order = $this->order_endpoint->create(
160
+ array( $purchase_unit ),
161
+ $payer,
162
+ $token,
163
+ (string) $wc_order->get_id()
164
+ );
165
+ $this->capture_order( $order, $wc_order );
166
+ }
167
+
168
+ /**
169
+ * Returns a payment token for a customer.
170
+ *
171
+ * @param \WC_Customer $customer The customer.
172
+ * @param \WC_Order $wc_order The current WooCommerce order we want to process.
173
+ *
174
+ * @return PaymentToken|null
175
+ */
176
+ private function get_token_for_customer( \WC_Customer $customer, \WC_Order $wc_order ) {
177
+
178
+ $token = $this->repository->for_user_id( (int) $customer->get_id() );
179
+ if ( ! $token ) {
180
+ $this->logger->log(
181
+ 'error',
182
+ sprintf(
183
+ // translators: %d is the customer id.
184
+ __(
185
+ 'No payment token found for customer %d',
186
+ 'woocommerce-paypal-payments'
187
+ ),
188
+ (int) $customer->get_id()
189
+ ),
190
+ array(
191
+ 'customer' => $customer,
192
+ 'order' => $wc_order,
193
+ )
194
+ );
195
+ \WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $wc_order );
196
+ }
197
+ return $token;
198
+ }
199
+
200
+ /**
201
+ * If the PayPal order is captured/authorized the WooCommerce order gets updated accordingly.
202
+ *
203
+ * @param Order $order The PayPal order.
204
+ * @param \WC_Order $wc_order The related WooCommerce order.
205
+ */
206
+ private function capture_order( Order $order, \WC_Order $wc_order ) {
207
+
208
+ if ( $order->intent() === 'CAPTURE' && $order->status()->is( OrderStatus::COMPLETED ) ) {
209
+ $wc_order->update_status(
210
+ 'processing',
211
+ __( 'Payment received.', 'woocommerce-paypal-payments' )
212
+ );
213
+ \WC_Subscriptions_Manager::process_subscription_payments_on_order( $wc_order );
214
+ }
215
+
216
+ if ( $order->intent() === 'AUTHORIZE' ) {
217
+ $this->order_endpoint->authorize( $order );
218
+ $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
219
+ \WC_Subscriptions_Manager::process_subscription_payments_on_order( $wc_order );
220
+ }
221
+ }
222
+ }
modules/ppcp-subscription/src/class-subscriptionmodule.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The subscription module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Subscription
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Subscription;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
+ use Interop\Container\ServiceProviderInterface;
16
+ use Psr\Container\ContainerInterface;
17
+
18
+ /**
19
+ * Class SubscriptionModule
20
+ */
21
+ class SubscriptionModule implements ModuleInterface {
22
+
23
+ /**
24
+ * Setup the module.
25
+ *
26
+ * @return ServiceProviderInterface
27
+ */
28
+ public function setup(): ServiceProviderInterface {
29
+ return new ServiceProvider(
30
+ require __DIR__ . '/../services.php',
31
+ require __DIR__ . '/../extensions.php'
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Runs the module.
37
+ *
38
+ * @param ContainerInterface|null $container The container.
39
+ */
40
+ public function run( ContainerInterface $container = null ) {
41
+ add_action(
42
+ 'woocommerce_scheduled_subscription_payment_' . PayPalGateway::ID,
43
+ static function ( $amount, $order ) use ( $container ) {
44
+ if ( ! is_a( $order, \WC_Order::class ) ) {
45
+ return;
46
+ }
47
+ $handler = $container->get( 'subscription.renewal-handler' );
48
+ $handler->renew( $order );
49
+ },
50
+ 10,
51
+ 2
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Returns the key for the module.
57
+ *
58
+ * @return string|void
59
+ */
60
+ public function getKey() {
61
+ }
62
+ }
modules/ppcp-wc-gateway/assets/images/amex.svg ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Amex_acceptancemark_50x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Amex_acceptancemark_50x50">
6
+ <polygon id="Shape" fill="#FFFFFF" fill-rule="nonzero" points="50 0 0 0 0 50 50 50"></polygon>
7
+ <path d="M25.0930414,18.1130368 L21.2948396,18.1130368 L23.1939405,13.5354022 L25.0930414,18.1130368 Z M27.5916246,24.0501324 L31.8892892,24.0501324 L25.7128236,10.0571358 L20.7951652,10.0571358 L14.6182767,24.0501324 L18.8161334,24.0501324 L19.9755555,21.2514908 L26.412114,21.2514908 L27.5916246,24.0501324 Z M46.2218867,24.0501324 L50,24.0501324 L50,10.0571358 L44.1229584,10.0571358 L40.9845044,18.7725731 L37.8661389,10.0571358 L31.8892892,10.0571358 L31.8892892,24.0501324 L35.6671911,24.0501324 L35.6671911,14.255204 L39.2655654,24.0501324 L42.6237239,24.0501324 L46.2218867,14.234904 L46.2218867,24.0501324 Z M23.7946916,36.8350715 L23.7946916,34.6562122 L31.6905191,34.6562122 L31.6905191,31.4978812 L23.7946916,31.4978812 L23.7946916,29.3190219 L31.8903465,29.3190219 L31.8903465,26.0807599 L19.9766128,26.0807599 L19.9766128,40.0733335 L31.8903465,40.0733335 L31.8903465,36.8350715 L23.7946916,36.8350715 Z M46.1576036,33.0427906 L50,37.1306893 L50,28.989148 L46.1576036,33.0427906 Z M44.9840138,40.0733335 L50,40.0733335 L43.3646714,33.0370812 L50,26.0807599 L45.0637333,26.0807599 L40.9661076,30.558375 L36.9078129,26.0807599 L31.8907695,26.0807599 L38.4871899,33.0770467 L31.8907695,40.0733335 L36.7682509,40.0733335 L40.8861766,35.5557529 L44.9840138,40.0733335 Z M50,50 L50,42.0773174 L43.9679599,42.0773174 L40.8622819,38.6432456 L37.7411674,42.0773174 L17.8527325,42.0773174 L17.8527325,26.072513 L11.4335135,26.072513 L19.3957387,8.05336344 L27.0746107,8.05336344 L29.8157358,14.2264457 L29.8157358,8.05336344 L39.3205444,8.05336344 L40.9709711,12.7052196 L42.6319707,8.05336344 L50,8.05336344 L50,0 L0,0 L0,50 L50,50 L50,50 Z" id="Fill-18" fill="#216EA9"></path>
8
+ </g>
9
+ </g>
10
+ </svg>
modules/ppcp-wc-gateway/assets/images/blik.svg ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Blik_acceptancemark_80x50</title>
4
+ <defs>
5
+ <linearGradient x1="50%" y1="100%" x2="50%" y2="0%" id="linearGradient-1">
6
+ <stop stop-color="#4D4D4F" offset="0%"></stop>
7
+ <stop stop-color="#000000" offset="100%"></stop>
8
+ </linearGradient>
9
+ <linearGradient x1="0.838585795%" y1="0%" x2="99.1614142%" y2="100%" id="linearGradient-2">
10
+ <stop stop-color="#ED4706" offset="0%"></stop>
11
+ <stop stop-color="#F0689D" offset="100%"></stop>
12
+ </linearGradient>
13
+ </defs>
14
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
15
+ <g id="Blik_acceptancemark_80x50">
16
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
17
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
18
+ <g id="blik" transform="translate(16.000000, 12.000000)">
19
+ <path d="M4.07004248,0 C1.82228758,0 0,1.83776398 0,4.1046087 L0,4.1046087 L0,21.8953913 C0,24.162236 1.82228758,26 4.07004248,26 L4.07004248,26 L44.9299575,26 C47.1777124,26 49,24.162236 49,21.8953913 L49,21.8953913 L49,4.1046087 C49,1.83776398 47.1777124,0 44.9299575,0 L44.9299575,0 L4.07004248,0 Z" id="Fill-1" fill="url(#linearGradient-1)"></path>
20
+ <path d="M8.72712418,3.88922857 L8.72712418,10.8420484 C9.61520915,10.3603217 10.630598,10.0864335 11.7095588,10.0864335 C15.1917614,10.0864335 18.0147059,12.9333528 18.0147059,16.4451292 C18.0147059,19.9569056 15.1917614,22.8038248 11.7095588,22.8038248 C8.22735621,22.8038248 5.40441176,19.9569056 5.40441176,16.4451292 L5.40441176,16.4451292 L5.40441176,3.88922857 L8.72712418,3.88922857 Z M23.499183,3.88918012 L23.499183,22.662472 L20.1764706,22.662472 L20.1764706,3.88918012 L23.499183,3.88918012 Z M29.6642157,10.2276894 L29.6642157,22.662472 L26.3415033,22.662472 L26.3415033,10.2276894 L29.6642157,10.2276894 Z M35.8292484,3.88922857 L35.8292484,15.9070422 L40.2328431,10.2277379 L44.1560458,10.2277379 L39.5633366,16.0817752 L44.5563725,22.6625205 L40.2328431,22.6625205 L35.8292484,16.2783093 L35.8292484,22.6625205 L32.5065359,22.6625205 L32.5065359,3.88922857 L35.8292484,3.88922857 Z M11.7095588,13.4373652 C10.0624542,13.4373652 8.72712418,14.784036 8.72712418,16.4451292 C8.72712418,18.1062224 10.0624542,19.4528932 11.7095588,19.4528932 C13.3566634,19.4528932 14.6919935,18.1062224 14.6919935,16.4451292 C14.6919935,14.784036 13.3566634,13.4373652 11.7095588,13.4373652 Z" id="Combined-Shape" fill="#FFFFFF"></path>
21
+ <path d="M14.9722222,3.06832298 C13.3361667,3.06832298 12.0098039,4.40595031 12.0098039,6.05590062 L12.0098039,6.05590062 C12.0098039,7.70585093 13.3361667,9.04347826 14.9722222,9.04347826 L14.9722222,9.04347826 C16.6082778,9.04347826 17.9346405,7.70585093 17.9346405,6.05590062 L17.9346405,6.05590062 C17.9346405,4.40595031 16.6082778,3.06832298 14.9722222,3.06832298 Z" id="Clip-2" fill="url(#linearGradient-2)"></path>
22
+ </g>
23
+ </g>
24
+ </g>
25
+ </svg>
modules/ppcp-wc-gateway/assets/images/credit.svg ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>PP_Credit_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="PP_Credit_acceptancemark_80x50" fill-rule="nonzero">
6
+ <g id="Group">
7
+ <rect id="Rectangle" fill="#FFFFFF" x="0.4" y="0.4" width="79.2" height="49.2"></rect>
8
+ <path d="M79.2,0.8 L79.2,49.3 L0.8,49.3 L0.8,0.8 L79.2,0.8 M80,0 L0,0 L0,50 L80,50 L80,0 L80,0 Z" id="Shape" fill="#BFBFBF"></path>
9
+ </g>
10
+ <g id="Group" transform="translate(4.000000, 12.000000)">
11
+ <path d="M19.2,6.9 C19.5,5 19.2,3.8 18.2,2.6 C17.1,1.3 15.1,0.8 12.5,0.8 L5,0.8 C4.5,0.8 4,1.2 3.9,1.7 L0.9,21.4 C0.8,21.8 1.1,22.1 1.5,22.1 L6.1,22.1 L5.8,24.1 C5.7,24.4 6,24.7 6.4,24.7 L10.3,24.7 C10.8,24.7 11.2,24.4 11.2,23.9 L11.2,23.7 L11.9,19.1 L11.9,18.8 C12,18.3 12.4,18 12.8,18 L13.4,18 C17.2,18 20.1,16.5 21,12 C21.4,10.1 21.2,8.6 20.2,7.5 C20,7.4 19.6,7.1 19.2,6.9 L19.2,6.9" id="Path" fill="#009CDE"></path>
12
+ <path d="M19.2,6.9 C19.5,5 19.2,3.8 18.2,2.6 C17.1,1.3 15.1,0.8 12.5,0.8 L5,0.8 C4.5,0.8 4,1.2 3.9,1.7 L0.9,21.4 C0.8,21.8 1.1,22.1 1.5,22.1 L6.1,22.1 L7.3,14.7 L7.3,14.9 C7.4,14.4 7.8,14 8.4,14 L10.6,14 C14.9,14 18.3,12.2 19.3,7.2 C19.2,7.2 19.2,7 19.2,6.9" id="Path" fill="#012169"></path>
13
+ <path d="M8.5,6.9 C8.5,6.6 8.8,6.3 9,6.2 C9.1,6.1 9.3,6.1 9.4,6.1 L15.3,6.1 C16,6.1 16.6,6.1 17.2,6.2 C17.4,6.2 17.5,6.3 17.7,6.3 C17.9,6.3 18,6.4 18.2,6.4 C18.3,6.4 18.3,6.4 18.4,6.5 C18.7,6.6 19,6.7 19.2,6.8 C19.5,4.9 19.2,3.7 18.2,2.5 C17.1,1.2 15.1,0.7 12.5,0.7 L5,0.7 C4.5,0.7 4,1.1 3.9,1.6 L0.9,21.4 C0.8,21.8 1.1,22.1 1.5,22.1 L6.1,22.1 L7.3,14.7 L8.5,6.9 Z" id="Path" fill="#003087"></path>
14
+ </g>
15
+ <g id="Group" transform="translate(28.000000, 24.000000)" fill="#003087">
16
+ <path d="M27.3,1.1 C27.3,0.9 27.5,0.8 27.7,0.8 L31.3,0.8 C34.3,0.8 36.4,3.1 35.9,6.1 C35.4,9.1 32.6,11.4 29.6,11.4 L26,11.4 C25.9,11.4 25.8,11.3 25.8,11.1 L27.3,1.1 Z M28.8,9.1 L29.4,9.1 C31.1,9.1 32.6,8.2 33,6.1 C33.3,4.2 32.2,3.1 30.4,3.1 L30,3.1 C29.9,3.1 29.8,3.2 29.8,3.3 L28.8,9.1 Z" id="Shape"></path>
17
+ <path d="M22.7,3.5 L22.4,5 L25.3,5 C25.4,5 25.5,5.1 25.5,5.3 L25.2,7 C25.2,7.2 25,7.3 24.8,7.3 L22.3,7.3 C22.1,7.3 21.9,7.4 21.9,7.6 L21.7,9.1 L24.7,9.1 C24.8,9.1 24.9,9.2 24.9,9.4 L24.6,11.2 C24.6,11.4 24.4,11.5 24.2,11.5 L18.7,11.5 C18.6,11.5 18.5,11.4 18.5,11.2 L20.1,1.1 C20.1,0.9 20.3,0.8 20.5,0.8 L26,0.8 C26.1,0.8 26.2,0.9 26.2,1.1 L25.9,2.9 C25.9,3.1 25.7,3.2 25.5,3.2 L23,3.2 C22.8,3.2 22.7,3.3 22.7,3.5 Z" id="Path"></path>
18
+ <path d="M38.3,11.5 L36.1,11.5 C36,11.5 35.9,11.4 35.9,11.2 L37.5,1.1 C37.5,0.9 37.7,0.8 37.9,0.8 L40.1,0.8 C40.2,0.8 40.3,0.9 40.3,1.1 L38.7,11.2 C38.7,11.4 38.5,11.5 38.3,11.5 Z" id="Path"></path>
19
+ <path d="M17.9,11.5 L15,11.5 C14.9,11.5 14.8,11.4 14.7,11.3 L12.8,7.4 L12.8,7.4 L12.2,11.2 C12.2,11.4 12,11.5 11.9,11.5 L9.7,11.5 C9.6,11.5 9.5,11.4 9.5,11.2 L11.1,1 C11.1,0.8 11.3,0.7 11.4,0.7 L15.3,0.7 C17.4,0.7 18.9,1.7 18.5,4 C18.3,5.5 17.2,6.7 15.7,7 L18.2,11 C18.2,11.3 18.1,11.5 17.9,11.5 Z M13.1,5.6 L13.4,5.6 C14.3,5.6 15.4,5.4 15.5,4.3 C15.7,3.1 15.1,3 14.1,3 L13.7,3 C13.6,3 13.5,3.1 13.5,3.2 L13.1,5.6 Z" id="Shape"></path>
20
+ <path d="M44.2,11.5 L42,11.5 C41.9,11.5 41.8,11.4 41.8,11.2 L43.1,3.1 L41.1,3.1 C41,3.1 40.9,3 40.9,2.8 L41.2,1 C41.2,0.8 41.4,0.7 41.6,0.7 L48.4,0.7 C48.5,0.7 48.6,0.8 48.6,1 L48.3,2.8 C48.3,3 48.1,3.1 47.9,3.1 L45.9,3.1 L44.6,11.1 C44.6,11.4 44.4,11.5 44.2,11.5 Z" id="Path"></path>
21
+ <path d="M9.6,3.9 C9.6,4.1 9.3,4.2 9.2,4 C8.7,3.5 8,3.3 7.3,3.3 C5.6,3.3 4.3,4.6 4,6.3 C3.7,8 4.7,9.2 6.4,9.2 C7.1,9.2 7.9,8.9 8.5,8.5 C8.7,8.4 8.9,8.5 8.9,8.7 L8.5,11.1 C8.5,11.2 8.4,11.4 8.2,11.4 C7.4,11.6 6.7,11.8 5.9,11.8 C1.3,11.8 0.6,7.9 0.8,6.2 C1.5,1.5 5.3,0.4 7.6,0.6 C8.4,0.6 9,0.7 9.7,1 C9.9,1.1 10,1.3 10,1.5 L9.6,3.9 Z" id="Path"></path>
22
+ </g>
23
+ <g id="Group" transform="translate(30.000000, 14.000000)">
24
+ <path d="M21.4,0.1 L19,0.1 C18.8,0.1 18.7,0.2 18.7,0.4 L17.7,6.6 C17.7,6.7 17.8,6.8 17.9,6.8 L19.1,6.8 C19.2,6.8 19.3,6.7 19.3,6.6 L19.6,4.9 C19.6,4.7 19.8,4.6 19.9,4.6 L20.7,4.6 C22.3,4.6 23.2,3.8 23.4,2.3 C23.5,1.6 23.4,1.1 23.1,0.7 C22.8,0.3 22.2,0.1 21.4,0.1 Z M21.7,2.4 C21.6,3.3 20.9,3.3 20.3,3.3 L19.9,3.3 L20.2,1.7 C20.2,1.6 20.3,1.5 20.4,1.5 L20.6,1.5 C21,1.5 21.4,1.5 21.7,1.7 C21.7,1.9 21.8,2.1 21.7,2.4 Z" id="Shape" fill="#009CDE"></path>
25
+ <path d="M4.3,0.1 L1.9,0.1 C1.7,0.1 1.6,0.2 1.6,0.4 L0.6,6.6 C0.6,6.7 0.7,6.8 0.8,6.8 L1.9,6.8 C2.1,6.8 2.2,6.7 2.2,6.5 L2.5,4.8 C2.5,4.6 2.7,4.5 2.8,4.5 L3.6,4.5 C5.2,4.5 6.1,3.7 6.3,2.2 C6.4,1.5 6.3,1 6,0.6 C5.7,0.3 5.1,0.1 4.3,0.1 Z M4.6,2.4 C4.5,3.3 3.8,3.3 3.2,3.3 L2.8,3.3 L3.1,1.7 C3.1,1.6 3.2,1.5 3.3,1.5 L3.5,1.5 C3.9,1.5 4.3,1.5 4.6,1.7 C4.6,1.9 4.6,2.1 4.6,2.4 Z" id="Shape" fill="#003087"></path>
26
+ <path d="M11.5,2.3 L10.3,2.3 C10.2,2.3 10.1,2.4 10.1,2.5 L10,2.8 L10,2.7 C9.8,2.3 9.2,2.2 8.6,2.2 C7.3,2.2 6.2,3.2 6,4.5 C5.9,5.2 6,5.8 6.4,6.3 C6.8,6.7 7.3,6.9 7.9,6.9 C8.9,6.9 9.5,6.2 9.5,6.2 L9.4,6.5 C9.4,6.6 9.5,6.7 9.6,6.7 L10.6,6.7 C10.8,6.7 10.9,6.6 10.9,6.4 L11.5,2.5 C11.7,2.5 11.6,2.3 11.5,2.3 Z M9.9,4.6 C9.8,5.3 9.3,5.7 8.6,5.7 C8.3,5.7 8,5.6 7.8,5.4 C7.6,5.2 7.6,4.9 7.6,4.6 C7.7,3.9 8.2,3.5 8.9,3.5 C9.2,3.5 9.5,3.6 9.7,3.8 C9.8,4 9.9,4.3 9.9,4.6 Z" id="Shape" fill="#003087"></path>
27
+ <path d="M28.6,2.3 L27.4,2.3 C27.3,2.3 27.2,2.4 27.2,2.5 L27.1,2.8 L27,2.7 C26.8,2.3 26.2,2.2 25.6,2.2 C24.3,2.2 23.2,3.2 23,4.5 C22.9,5.2 23,5.8 23.4,6.3 C23.8,6.7 24.3,6.9 24.9,6.9 C25.9,6.9 26.5,6.2 26.5,6.2 L26.4,6.5 C26.4,6.6 26.5,6.7 26.6,6.7 L27.6,6.7 C27.8,6.7 27.9,6.6 27.9,6.4 L28.5,2.5 C28.8,2.5 28.7,2.3 28.6,2.3 Z M27,4.6 C26.9,5.3 26.4,5.7 25.7,5.7 C25.4,5.7 25.1,5.6 24.9,5.4 C24.7,5.2 24.7,4.9 24.7,4.6 C24.8,3.9 25.3,3.5 26,3.5 C26.3,3.5 26.6,3.6 26.8,3.8 C27,4 27.1,4.3 27,4.6 Z" id="Shape" fill="#009CDE"></path>
28
+ <path d="M17.6,2.3 L16.4,2.3 C16.3,2.3 16.2,2.4 16.1,2.4 L14.5,4.8 L13.8,2.5 C13.8,2.4 13.6,2.3 13.5,2.3 L12.4,2.3 C12.3,2.3 12.2,2.4 12.2,2.6 L13.5,6.3 L12.3,8 C12.2,8.1 12.3,8.3 12.5,8.3 L13.7,8.3 C13.8,8.3 13.9,8.2 14,8.2 L17.9,2.6 C17.9,2.5 17.8,2.3 17.6,2.3 Z" id="Path" fill="#003087"></path>
29
+ <path d="M30,0.3 L29,6.6 C29,6.7 29.1,6.8 29.2,6.8 L30.2,6.8 C30.4,6.8 30.5,6.7 30.5,6.5 L31.5,0.3 C31.5,0.2 31.4,0.1 31.3,0.1 L30.2,0.1 C30.1,0.1 30,0.2 30,0.3 Z" id="Path" fill="#009CDE"></path>
30
+ </g>
31
+ </g>
32
+ </g>
33
+ </svg>
modules/ppcp-wc-gateway/assets/images/discover.svg ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Discover_acceptancemark_80x50</title>
4
+ <defs>
5
+ <path d="M0.022193794,6.26609269 C0.022193794,6.26609269 0.022193794,6.26609269 0.022193794,6.26986689 C0.022193794,9.70807818 2.80197694,12.497295 6.22893278,12.497295 C9.6595249,12.497295 12.4393916,9.70807818 12.4393916,6.26986689 C12.4393916,6.26609269 12.4393916,6.26609269 12.4393916,6.26609269 C12.4393916,2.82771366 9.6595249,0.0386645705 6.22893278,0.0386645705 C2.80197694,0.0386645705 0.022193794,2.82771366 0.022193794,6.26609269" id="path-1"></path>
6
+ </defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Discover_acceptancemark_80x50">
9
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
10
+ <path d="M80,29 L80,50 L26,50 C39.4361216,46.4368995 49.3448942,43.4145169 55.7263176,40.9328523 C62.107741,38.4511876 70.1989685,34.4735702 80,29 Z" id="Rectangle" fill="#DD4703"></path>
11
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
12
+ <g id="Group" transform="translate(3.000000, 13.000000)">
13
+ <g id="g12" transform="translate(37.458774, 7.132839) scale(-1, 1) rotate(-180.000000) translate(-37.458774, -7.132839) translate(0.249471, 0.424506)">
14
+ <g id="g14" fill="#201D1C" fill-rule="nonzero">
15
+ <g id="g16" transform="translate(0.083592, 0.132807)">
16
+ <path d="M6.00214648,3.24149166 C5.28688773,2.59346171 4.35775771,2.31073228 2.8868776,2.31073228 L2.27593386,2.31073228 L2.27593386,10.0538787 L2.8868776,10.0538787 C4.35775771,10.0538787 5.25031604,9.78981055 6.00214648,9.10689024 C6.78942012,8.40350537 7.26305491,7.31364255 7.26305491,6.19186678 C7.26305491,5.06782649 6.78942012,3.94458297 6.00214648,3.24149166 L6.00214648,3.24149166 Z M3.34288275,12.0378073 L0.00130613194,12.0378073 L0.00130613194,0.328439172 L3.32524892,0.328439172 C5.09278608,0.328439172 6.36903372,0.746830083 7.48938145,1.68018946 C8.82063293,2.78561037 9.60790657,4.45170949 9.60790657,6.17500869 C9.60790657,9.63058129 7.03468035,12.0378073 3.34288275,12.0378073" id="path22"></path>
17
+ <polygon id="path24" points="10.6554453 0.328439172 12.9318682 0.328439172 12.9318682 12.0378073 10.6554453 12.0378073"></polygon>
18
+ <path d="M18.4980884,7.54445578 C17.1320625,8.05162423 16.7309023,8.38614406 16.7309023,9.01878366 C16.7309023,9.75622018 17.4455341,10.3166468 18.4267423,10.3166468 C19.1088566,10.3166468 19.6693857,10.0355528 20.2625159,9.36831641 L21.4535411,10.9332251 C20.4747571,11.7922327 19.3036688,12.2314237 18.0241192,12.2314237 C15.9593023,12.2314237 14.3842534,10.7926571 14.3842534,8.87624475 C14.3842534,7.26302635 15.1176518,6.43710583 17.2556539,5.66507249 C18.1467494,5.34971721 18.6002802,5.1395782 18.8291981,4.99821349 C19.2840664,4.70021952 19.511814,4.27838989 19.511814,3.78665372 C19.511814,2.83786206 18.7599835,2.13493849 17.7442935,2.13493849 C16.6585531,2.13493849 15.7839671,2.67976506 15.2598843,3.69670198 L13.7891588,2.27596772 C14.8379932,0.731271997 16.097606,0.0466742592 17.8296832,0.0466742592 C20.195433,0.0466742592 21.8548684,1.62483454 21.8548684,3.89166032 C21.8548684,5.7520468 21.0876569,6.59419638 18.4980884,7.54445578" id="path26"></path>
19
+ <path d="M22.5730529,6.17500869 C22.5730529,2.73319094 25.2666522,0.0643710583 28.7331055,0.0643710583 C29.7130179,0.0643710583 30.5522025,0.257693911 31.5871605,0.746830083 L31.5871605,3.43544354 C30.6771314,2.52154226 29.8710912,2.15297077 28.8388917,2.15297077 C26.5463271,2.15297077 24.919033,3.82070538 24.919033,6.19186678 C24.919033,8.44003123 26.5977365,10.2134434 28.7331055,10.2134434 C29.818846,10.2134434 30.6407269,9.82470092 31.5871605,8.89591252 L31.5871605,11.583226 C30.58798,12.0918622 29.7662663,12.3025044 28.7868136,12.3025044 C25.3379984,12.3025044 22.5730529,9.57967155 22.5730529,6.17500869" id="path28"></path>
20
+ <polyline id="path30" points="49.6367755 4.17258652 46.5246288 12.0378073 44.0377535 12.0378073 48.9901879 0.0280129426 50.2152352 0.0280129426 55.2571134 12.0378073 52.7894645 12.0378073 49.6367755 4.17258652"></polyline>
21
+ <polyline id="path32" points="56.2865544 0.328439172 62.7423989 0.328439172 62.7423989 2.31073228 58.5611048 2.31073228 58.5611048 5.47145609 62.5881708 5.47145609 62.5881708 7.45488146 58.5611048 7.45488146 58.5611048 10.0538787 62.7423989 10.0538787 62.7423989 12.0378073 56.2865544 12.0378073 56.2865544 0.328439172"></polyline>
22
+ <path d="M67.188681,6.64695129 L66.5237031,6.64695129 L66.5237031,10.1934402 L67.2246257,10.1934402 C68.6423536,10.1934402 69.4130759,9.59749415 69.4130759,8.45789577 C69.4130759,7.28072315 68.6423536,6.64695129 67.188681,6.64695129 L67.188681,6.64695129 Z M71.7557542,8.58089272 C71.7557542,10.7730313 70.2506722,12.0378073 67.6254515,12.0378073 L64.2499886,12.0378073 L64.2499886,0.328439172 L66.5237031,0.328439172 L66.5237031,5.03226515 L66.8204563,5.03226515 L69.9714735,0.328439172 L72.7709844,0.328439172 L69.0970965,5.26144289 C70.8115775,5.61118532 71.7557542,6.78798052 71.7557542,8.58089272" id="path34"></path>
23
+ <path d="M72.8355171,11.4572516 L72.7857183,11.4572516 L72.7857183,11.7262262 L72.8385352,11.7262262 C72.9844105,11.7262262 73.0598632,11.6824874 73.0598632,11.5938776 C73.0598632,11.5027936 72.9834045,11.4572516 72.8355171,11.4572516 Z M73.3546318,11.5976518 C73.3546318,11.8028844 73.1851147,11.9151039 72.887328,11.9151039 L72.4909497,11.9151039 L72.4909497,10.8858798 L72.7857183,10.8858798 L72.7857183,11.2850643 L73.1312918,10.8858798 L73.4909497,10.8858798 L73.0850141,11.3103095 C73.2585554,11.3493095 73.3546318,11.4547774 73.3546318,11.5976518" id="path36"></path>
24
+ <path d="M72.8662798,10.6655505 C72.4742312,10.6655505 72.1536542,10.9928574 72.1536542,11.4012257 C72.1536542,11.8110618 72.4700516,12.138201 72.8662798,12.138201 C73.2562386,12.138201 73.5743078,11.8035553 73.5743078,11.4012257 C73.5743078,10.9962961 73.2562386,10.6655505 72.8662798,10.6655505 Z M72.8696235,12.2997367 C72.3714125,12.2997367 71.9760203,11.9008458 71.9760203,11.4025257 C71.9760203,10.9045412 72.3760101,10.505189 72.8696235,10.505189 C73.3548776,10.505189 73.7523597,10.9088186 73.7523597,11.4025257 C73.7523597,11.8938006 73.3548776,12.2997367 72.8696235,12.2997367" id="path38"></path>
25
+ </g>
26
+ </g>
27
+ <g id="g66" transform="translate(31.976744, 0.000000)">
28
+ <g id="g74-Clipped" transform="translate(0.415328, 0.007000)">
29
+ <mask id="mask-2" fill="white">
30
+ <use xlink:href="#path-1"></use>
31
+ </mask>
32
+ <g id="path78"></g>
33
+ <g id="g74" mask="url(#mask-2)">
34
+ <g transform="translate(-0.167185, -0.125807)" id="g80">
35
+ <g transform="translate(0.037617, 0.037742)">
36
+ <image id="image82" transform="translate(6.357205, 6.357428) scale(-1, 1) rotate(-180.000000) translate(-6.357205, -6.357428) " x="0" y="0" width="12.7144108" height="12.7148566" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAAB+CAYAAADiI6WIAAAAAXNSR0IArs4c6QAAMEJJREFUeAHtnduPZdt11nd197n42IkwIjZxQrg8JEHihQf+A3hASCA/gYhCFCSIwJjIlo2FJWOHB4QQEs/8B/AP8IaEgpBQIOBATMIDxDeQkBNwjk+f013dXc33++b45hpr7bWrqrurb7anzlpzznGf45tjrrV3VZ86e6x2+GH7gcvAne+nFf+Dn/7E4UwLOuOu/255vF7hLUssNOR761VwcdBMApQG9C//9//VRV/r8dnrXPEADZBnBTJIZD7Gxs0AeTNoBNAB+6yjbCkBHKbmGbMBci5eQNcF7Uu//fpuhNcK+C/9jIBW1gHxdgEE0K5szVPNcx5gxTsTiqiwSfYAF2s0hKpFnSljV76UDb4IF5JlA1xo/Og12wivBfBf9hG+gH27wE51g9Vt0DGoA2DAv9VAzAZBLK2xrRs6PUCHzzjNQDMx2ADPBhD4GrARHmp3fPG3vx3xl9L/sT/yk1f6fWWBp7pvq0pTvR1sAM3xfotK1tzAa7nIA9miZ4IoA8bBHzTufXOEOiTHjOOeik4DaFA34KLD8lijR5qwCegfqX8oxsvaBFeB/8oBn+c2R3mqFLBuC13l8nBLE8CGBmgDyDXQgDzog+/jfUIvxdLtADPucwDtjTnXAJ7xeO4/KiFXvQQA/SGB0ov3UANOgS/81os9BV4b4AEccAFsW91Us8EUMowNOhTNAQt52tBVD6PmjHzp5o1DX3zoNN4baEUeE92LPF/yYPg5715VLwOcBuNZD285CdgID8Xj2c9meOANcDh8/re+hZnn3l554HOkU+ETcCFwW8liDhh3CiFOAG+CLqsUIjN5Nbcu43blWA+NjcKYFtDZYL1R2bRUuicAKjE4XOH5qBeFOdXORnDVq+dkGNU/NsHn/tvz3wCXgf/Sjvq8od9RxgMalRrAOdJHdS/H+J0ChS8fOtgB0I8D8Zj7PUCoDLkBMKAyB1o2GgBlMzAHxKuaQZbg6DXQY4fqRtfVrx6Q4VPtVP3cBIwl+0Ab4Vz8c/Wff44b4JUDnrf0Wc2CgTEgT5pAmM93jaEHzIxd+egIyfAk6mN7zAfI4YE249vc1NhYNOuM4ZhD2GuiC6elaTyf76ICOvwL3fyGL9o4AYYcRz3yDyTDM/8BG0BKbIBf/to3dX8+7RT4L7Tit8e6wRZwqWyO9D3A86I3NscAG3xMVyK9CdCtTWCQBWzoyHGhYx6Dmp8JAJPNLBkTTD66ITY0BmuAPWgX/ggwAKfSEaS/EMABnZ4j/xye+vu62AD31H/ma98aRm/w/tKBT5VToQAyj3XmyibHt0HXeFa1xnkMoDMeC+jqUuIMfNnyo0F0AGUDyeyo8BqfSQGa/lt6jWnQVy06jRgRsBVGbnQAzxw6Y89F4gTgeqQ3v0c69/2sF+qcBjwCHkieI/+eZDgB7tf1qedQ/Xvgv5CK/8pP/4RBAlAABPw7ylR/jg/wx7E9AB2yb0iWU5nLuoxFAyw2gEEWc4ItGjzmvMZztHvIlAFNvd8BamxyVX54lhuiGR71wmw2QPaG0Lo81A0aY4BnwCbgsz2PgPvaCQB+LufZADzz70npl772jWn3JgYvHPh+tPNi1oF/g+SLBqCA5CqvPgCnwjP3hhBirnhkpWyaxoDKmIvqxm6ANsgl4890Gk/gK7NnUlDepQNUxDZabNR0dkOqZDTJ3Me9yJ5D1+UNoA3BBmDMda6PBQ91AjwQjaP+vnSyAT54fHH4QIqf+s1vTn/PMnihwOdz+QAcQFTlih6wAdpHuHr4JBmQARiZ5XGguZI0wB2AA/YdXQBiusa3qrKxY6AKWMAF6NFrqCk3HhMczegxtw48NcuOYSloYsUQqx+qY4KdqnQQB1js0NOEo8Y6CdRDyvHPsc8J8EAnwbk2ARfPeo59gH9f19/8r9+wjWe9bcF/Lkd9f55PIJUIqvoNrSDg+wQQnTn0AA6gAO73AICFpxuAj4oe/S0hyGYhyX5Lp9dlsCXLkExDC9DZGBNs8TIehzT6KJ5ukz0Hi2wnGXfdhJ9A18c+CDUWxh4/ovJrA5w/PDvcE+O+ngX3ZOiuFD7Q7vjrNwD+cwc+oLuCFbx7ZT1Hu0FVZgETnjdGjeH5c7x6QAdoPwYa4Mw5yt1bjjngjco2iEoutG1Fw4O+bTcBODZl/srGJqA9FuAMLwT0Q+XHL4ACnv6env/va3wu4O9qXe+r//nf+Dpqz9Q6+Dda8YA+AAdQHd3KBC9x26M9pwC95dUP2VTy0LmtcvZmEFhHgBtYKfI8B1CGulzZonkDQIORS8PeXiTg+E1MicEnASeANgEvfH4H0MnwQKA/oPLV39XnwffFe1fPiZ/76tej+lT9cwH+MtD9HFfy3xACAXqCLjpVPjaMgAJkXT7a4QFwr3DmACkamwJQPVVlpJpd2RBp6cesSHJI2+ENxrhP9hx07pXqK+Et6CumJnMT8OYv0HkP4Og/V/W/p1f/9yTwPe2Ov/zV39mqXnt+48BvQe/PcUCnWv181+rzhg7Q0P3yJiQB840CHeCZB3A2w5hrjVvAe3VLbjbpb9uLrnD8XwV4YsynCc5/XgT9eV8nAW//nAB39dr/3oPD4XvaAJ/8z88O/jMf9VeBzufwvaN9VDyAil+Ap8pd8TyzRSdxHPl+htccTNkUSapf7GYGM1j61wJwwt1s1gteCHnxc+XrxU/f+rx773D4rsD/S7/+dOCn6p8JeD6yjcoF3PUbu+cb0NkEqXiPBSRVDnC8/OXNnZcyV7l5tQHIi2R+EADvG4A1Xwh4nv/nAv78wa3D739wOPw/zf/Cf/yfy+5+ghHgK7VP1/zljIEdoPO8zcc0nuXbSvdcMlT6m+oB3Ee7dsKbjNW/wTGu65bGd3Td0sOfzSBx029rPsAfm8WRw+RqjQp3le/wmpjVrHpC7gS5m5hj4uK6qnFyzWMd4a7THHZ7t/Q8fOvNi8M7b10cPvyhi8NHP/L48DE9T//Vn/kTV7k7yQeHp2o8s6lqv3UrYN7eAXSAD09gKXqe93me+7O6HtZ5eTP46AhQv/kL5FHpVeV63pEANgMJ4jk/E8V4016bI524e/xtvN08t/yhrz6tvPH48OadCz36lENdb9xTwp6yPdVR/5Wf0XfvcjiqGnAViILfHu9HoGtVeZ5T5fONHcCl7+qmyisRAD4+o48N4DW2JGXNrxXgBJ01pIfUxllXB900cC45jv/z81uHux+cHf7Uv3ny5/0TA99f5t4EcF08n3dBp7oVqyu9QH9LwafiOboBGXCh5flNEmaVs1haLXhMxv0HCvBNDrxRdBA+UNXf1fWz//rJwH8i4Hmu57N4qjzg949sjPOMD+hv8gwX3aD7Ga7jXIsZVS/Q6/kNvmwI2nxb34D+SgPO0byJd84bfa/CveZ2tM83sK6HUJszfaSXvu+9d/uJwH+iZ7zBlleqG0X/aFUr8DENTWMqeBf0qmqAvlOVvnqey95tXnzEn8/yzQJ/CDgwH7fbeun7Ub4QeYJ27YrnZ+rzzVwAswlczerfFFJ55vu5Dk2g8XKXN/Yc71vQXfEK+Kwq3lX+ugFOwnvMGacPu81RSeNZzlfNs8JhlKy7E3r+MWOXk9rH/+W30b6yXQt4Pq8D+qjkUfE+tk3jGT6qnU33ljZBjnfAfotjXf1epUOTifls52Ncb698hRNsByXj9GG3eV/flYBv7Ue5PuWs2M3Hx//F1eBf66incvmYxsVRDj7+iEYPXfxUPD3ygM1nc8trvFfpgD7f3CWT9loATrBJ9rZvrCmTxakP4I/bms2WnZhaBl2xjvMTcj41poGmtzPcuj4S4S0eIQMoo+Pz+ziVANjfwYvPaYCMP4+r5zO654CvYxwbeaan0v2FjBjzhys68gw6wXOdaJM9B2vBE+S1UM3YfFxXNeJabcg4iW71ITv+8JpxvrzZO9YdR+S2elR4VfmUm47GZ3xvItEg/5+f+4lYOtlfWfEGV97cK2LAdIWL5pc8zWf1awyfN3jAdcUrYJ8CuvFxzaCnl6w/p9eb7GVgZwVSObkpzIvgFT0JvE6bYCMcnfSN1klTrjmY39ZRAa2t4lgZkRBgVzsll1PDqtpUtK2ZMrHqNmGseIcv64ua8cYucGUzoM8XO3lg5wBsvsC5w4uerI5rfE5nvAe6P7cDOpFeEa1FTsidIK8XUzMSuErirtQgHoG+dYQtiXK5rSZFE3h7oK/i2OoBeIF+Sg7AuawK4HwikkvwQuc7f+3yqr+04l2pMsdxzr83Q5gL46Pq2QzisymQUyD+/l38OwqcjeKPZxz1BKm5N4HpBXjl51Qn0dHmIATZW4ZXjvB93XYEOIpdX+M+td0tAcC1RB9mWnvaKo4dnSnHIPz0IuU5PkkFuMUhxtcUgHPcInbEodoBFQEA5E09R7wrXHOOeoMuPpshz/VR7aJJ2c939QadDSA5PrrNRR15HgSJDZE5WAR3SAtzM8LvKtkbfp8C+BHoG2e2t1ZarwXAAQPQSR6X2iqOjU0LpMJL1otvcgDuClcP2Q4KdNsGFHyVDt3v/sLpqj9Z8bHjL2VkLRXutcgTAPYNkI9s/nUpActmmRtAQfD2PkHX/FQjYLc5CKEWvEwvHZGM67YV2Cihu9E/srfhczQbbACnNcAHQfetjuWGwmQxmJOqcEih2ckQMa38YAq9iHl+ya2rTbFUe694BOfLXI2h+ajXwNWuHoC9aXTL77cbdPFc6dPLekDADnoOFv4OaWFuRiRjJmnD206PKhwBFuVAhvSuvcZHalY4E/RZa48D+Y0Oot4sYcFvvl3hZcPrAfACfRRQyavDtv0xrvZYOHB95xc/EdKq3614P5slJj1Xej6/jyofz3pXuxzySxP8iHBUt0BX8FzQxwZQJZAIjO001us2ByFcSl4LaebkHFH3CUcVjhhJ37Qjm5sY50tb9Fhnl+njyNArF5PFYE6WCiddfmMvsK2G3CbOlT+xAXu2je1J12AXeOR9VJcAvvxFjXrGHPv0yLwB6Oon4PDlnDlgE5iDw2hrczoHjanhCfJaCLnrCtpmS0ossZBN27XZ/FwKuH4zxjt+Y3NOyUkmzbdf2kQHt/HG3mKVgkWb/DbGk4BPZ3E6+mZqEL7ys/ysnZc2wK1nOY51QWenBGie/1Qzz3fe4v0TOpX56g1evF7txOFY5mD4zf0EOexVv138itkmu0c6jjart29uvbWA+MZtC/oZjzRkAJyeY26vAXhAx2/5zpEO4Nh57BffAl1z8k4+I49MX3eOdLsUzzHQM6z5d/7G8XF/VPE+njEuxeGvNkDmsoaMfzKnwVsa5xluwFmclP0ZHTusSA17bnMQwqXktVDN+sJ3BSLnz1IbCfxvYvB0Q+sy8yvWZgrA3QCcRGU+qMs9YEPZ+Ab0Ss8APFrQM66BT/xJ3DnSYx830veGKhv+hyWxV/0R8MTmZ7qidJVXEPkcT7VD54c0vNDxg5XxTNdYq4Dvlx168dWNNgchXEpeC9XsmQHHTotjDudgzQdwGklMuzbgUsimPwU4YLrCp/ExML4F8gS8Yjg60lEp3i7gLfa4oS/zg8Qx7+NdAcHws1yKbGa+uRsbYlQ7CfDRDtgSzpGE8/m8J2oc7zg/QR6BbO7YvA7oJ4/0OKs4Ml3FNomsk58tjO/Uj0Cnwmkkpex53m4+0inl2GxyDGH5Oc6xniaGc85cA6cONsRqE/TYha6xcyO5xDp+S7n8IyPe7/2tH2c026riWYsBlDGPmcvaLRH9bNfcYItPn2e5hvNov+rzOrLXbdcBG1u7b+ndUY0naQ6sPMNJhUNIEhm7ygE8x3rXR6CayaBKY9LkMty+qUfG+BbIs8ptiE2y3iAmyyD5gZNYma/eQWKvyZTJ9Vs9igYersaAz+VqF4Mx/2tQvqRZVbscuMrFR28eccyriXzt9twAJ4IEkl6kk4BH5hkAB5Tgtgd6YUMQ+ZjuMaHuAs4SJPskgCO7zen062NeUfqoV3b6r1WxGQAd4fEGrzGBhq6VMeYLmvGCJ8FqIs9ch3aqtw0UrmiXHunoltOV7z4pHznSUQEgLtoqDhbNVTz4aZC8yUHWEwjhjiGseay7lIfMLLDK46xyfKntgQ7gxOI45cculfN54hXfIejW18Pu+7+f/sO2zW0e9TaiG7qu7BrnOQ/fL3YSYOwvbjQA7PHCV1/JslI1ZK7bSPR12lxgF97qElPnMw6h+l7hsFcJgkAjEbTojtlCqnVOfpPL8KjCpQ3gbuSRVHHFF9PYRahkyQ8xOrPqTQZwTiKIAKZmuvrVemIvTEs24NE1gOqzGzPn8zuxcfE275c5TVL1rhDN6efCJHtVe/GAE5HT59BWCUqwLDJtkyxP9xJZchE34NhIhWvY8+J1bwBHfAs6cnuA87/SNOgnAMfW/Ho8QUFsbal4efH/2lt9XuhYYzYBz3R/YUMvBuAT2F61N/u7Q/Su065V4TK0aw8f5WdgeQw4O3li86IAZ+Hdl6aXAs4y2loG4GMtPY1zE+skmK0J2ESbT+BJEnSApI0dmmc+sWqsHZZqR4znG5uOwPwRpnTR32u7AO0IvjDAyVEHYRO/p3sVTsysuWKfFW76AkrWazlu3dfULaCwp4vZBBEdLnfiMJYNb9air2RPxGosw7O1CuVX/uT4J1HEhT3AB1B2Bcc5Y1+i5xs5yyAsgznyNdtt3hjIXtEA/Ah09Da6u/Ycy5BlHVwjjSORTlAxnLhFyJLdh12SqCSr+9fY/rEuGxN0jOpyGE0GWSdvBDR8WXf89AyCX9ok5xjRDQ2mmj+iCYD4TazIm0aVE6sVhw53n9bhQRD/u5/9OKPxcueYoYsx3urphyKAjx0z7PqXLwAIgziW4Klq96Klf1U7AhsFFrFpu/aQa7Ijv4qt2gQcsZA7CE13Dk8BHqPqJ+DQCnAPZcR2uHU/MNX6sW7AocGIXtMZnxgqboRseGwQA544S5+OZh6DPX7Z91FvQRk16GUcL8gwhe5flxaBYKhwNgP/8oV+C8h2Tgx77eYBx8tA14AzJeY9wOHVWquTbAQXnsWmAMBBqbYBHKrX3mVKdAU49nTZm3qbjw5ExWERbswtoKF6YyXSjLV4kI54JnJTQ67JGvhR5fxenZhylF/AMOCaQ+doT2XbQdE9LoPWx8kV7ZkBx375TL4qjfP56F2LGImjLYJTt0wsSURuEjVs41OAW0VyU7b7EfMk4LjCfi7iBPBuC16a7Hq6szmtM+WyYBFiu9up8VLxkiNmH+sZoyvB8VzXCcBYl38IgzBG2PX012xHoO/o7tqLXPXr/NbvqhNDMXYBhy/9mJpVU3Q6mvlTCPAG3bxpWHKS0Ser4bLJIHcEOLSy6fUx5gInbMZOycwgu92AXjLudHMfnsyZUDLTDuTyg4iBZ0ALnerOEY7fnAAEbPBF9G/YMO+B2cr+7QhwxBJcqVwKeMmv3TXA4RdzYtOF5WvlbpsoqZvfhK4DOJ9yersUcAQ38mw+k+K3+hzrtr2JNXFGZW5gCCGmhxRgMVb+R8Vrw6WaO+AeW1HKUkAHcHxp4qMfY5e01xFwlhPQvYkq8aw7Fc5Lb5I45JcjNhvYFPKFADcPMi7Aw6s+gEe0gzppGnicDcFkMpfxCnDsF+gM51F/pIhxTiCtgoXMFzk5wwebwgP6nXYjgMuu/TT7j2c5F7EWMwBqgoprFVqSFJHwV0I7gCOnC8AB8qkBRzm+FKzDnnPZrnE2TQeckM3WzX3WwsQEJNRqvJKB3gDPhp5HPcJ8Lw/Q42Vvkedr2gBNzzGP/AwS49VeCuD4zuIUGLGtWhIFMfwjoQH63Fds8JIBdAOOfvxouD3WVxUe2QCOracFHFvS98e7GtPNhVac7vpaV7FaY+6nBvzQXmTHy5yfYWIBuN/s8YeoLrq06wCObJJpPZKyODRpW+HUWarBAtykswBU1E08pvYkiJC4S2N2qQLb3ADudW/i3APc+CYhrKkDjqcOuuSyppmPxFo2YupSwG1Xpsv+CpCW16wPF/mNHwM/ZSpYL5ZYdcGjH8aXSZ4fzwS4jcpmzLb5pYATJy3BabhSNS9C4sE8EpCHWvgEvOb+8bvG/tp7oxvQsYkHpyy209s/N7UTgJuF/CWAwzvjuOl2Mw6Z4EPDaK2BYdZnF5LjF0oi2ipeRCmFQc/FJuBioYCNH88ty7JbQ2HT5o6GjjiBNTmGKxkLSbTJoIPfYq1sdDFJiLfEZLtHApZyUmyT5BKTWgDHxOANOvcADu9C8nixaW7x0ceQZcSssp81OS4bKkV1NZKWmnacAa+xaU1grKvWGXr5sKxuE3RFOn9PMEz1C/AYYMEbA8jOBUjGn+mhwUhbTQZxBWay1GxHZZEbC0lypmkEa42m1cM2+pFzTzLVDNp8KJs0byQEvtdU8TwJ4BQgbSR/jGcyJm8fcOtxjMQIAJcJdwHcLxVt0dOupLw4+lJsOYWyAhxC50dHZAPPC10ao8jqVW9WPI78jFdP0twWtaiPhGSGWDdYU9iLy2WBHfSFj7TaMwJuG4ndfVW4GD7BEkYWLzpVnsKkymlecmQ8CXHkxUuGXrysyT/bANACNarYjKyrnI2RVkLualNHdoIUWfWAzi+ZDPnGiLP0Ys2KRyzraSoGCBAA3ZVHL8EJfgmvgPLqxUCWa+nG2LRlgUnOlCsdC18XcILfW0CM5jSQbSocFwYcPq3pBnAivBRw9GSI9xzWQA6Sh6wp80sBxw7xERStenfceqG1OC2rW6r8NgBt+dYvyWweTQ28wtawvEVGUz62regymud9xOfC0It4c9atDlmERktymFmuC7MAzTtpaOkeEDGF3HaxJYi/PJshGZwSn3FvdNnQmPVpHP9dJgGZdwz49IMccWJI/fSHQGwwRKbN55qhXQE4pgDdgDPZxtntVs4is6r440rgM738Y4DgMV5ttRAyRYuA+gxN9iRClpwvb1MuAztc6w8N3RO8hvaPTvSm0OABeDwCeJm1nuk9SbY3/kiweZK3WW4etL5kyYbtNhlvLM2jItHlV6A84TbaScBht3Xa2CZWRHKsm9X5LR7kpi3JOK4KrireIq7mMaq7hAJwyfsUoOrdktnMkS9Wuu0jgeTQplwGFXz8Dam6t0RMfvSaILwV4OLlOEfcvpOA0uOYzls6QdksNw+mkAfjNAjgWnyX6XYV74wTzZVcFVCjTdm2TutUTioKdyvAoUQGe82mhcvefGFvfAPf5pb3TcQVXRP+sYSJAM4Vga0srBxTNjZurojMo1uBz8WHT98SseJHt2ThOaSSZ7wFnIR1tRXgkrf9CGz6CTgW5MMhRyaJJxb8678Za2QIKG/wocUnetCSL8bdJvxq+dmITUQm9tIjW3nYAzxJWFU8R30qsnw5qFWFswiCLEdzkaUw5ggtLYDP2BhU4F5vFrGoLMFPJTH7mKnmeMpznPEKcHh6Oexq1wJceigRGxvGNboB3GvCv2T8xk6PozijJ6AArmF4FonsNQGf6slV9wMzTXFOwKFt5Wo+gb9wlKSltSiJaH/Mi3YdwG1J8jHjQQU+AZ/M8pvd2ul9TAiaE6djlTz9dQAHwLyl44ZNMVt8qHdsuj3GEYmctJJmDXYqHr2umWzsQKMFdGhq7rjVvBdQCsGCdXOO5cDiW8CRiR3GxBmZzovMpjfwrnSEqyVuL4AJSqWI7e7AwVlvankWeU/iVMpOlI0MsXkHCbXJDyO68DRGypKSp98DHNWosZVJ3QB8fC4H8OFtJThBpMox4KM1ghgU3RUOm3j1X8+FyKMFcGbYqX4MoKEIUQ1fmxbAIU/7kTexKVwFeOS7vmh2+8WvfXtYKuaUYdBpjKVhsm4DdDLDVc3MzRgd5BHbLpQEErw62wu/2RmJWLxwtEML6HjzI6qO9aE6YvKLm+Rxg86s8m5f+vj3sQ5oumwbE+jUhZ/xNj5sT1DMGLJeS83x59hZE/5oDoS+LmjVpryCwbZVuEW3jyHrHzXOGMJLj03G3bemH/ni78JZvsCh6vmj9zK1vOUiUQlj6DYNj8WHPHkMkKHhVO0k4J0XHStwk17R4gnAAzYs6AY8ftCpTbiqcPFdxeK7ld24HBXOytUk63g1sW2RDIjsznn567ZWgMPAWBwwB/C0ri9a1oljYrmVz9V7jyLk+VesafGRPvStj83cRz2yTqJ6vm/I2DaYQ4hhjWegFmi8yJQTJxCZ7rQSsMsr/djHLY2E958ROL7mi+EAa2xcbxAJuYK779i31cFH0WTJJSb0GHfA8TmrC/3pH86YOu7Q018T8GmDwSnAsZX1xH569Gjhj5nClECPoegTeF7uLiTklzxnGsC9XK/KmxAnW0edVk6TwG0QroqRp6MAsbsHOAikylFN1cW21yQZXsRcLfUQtlyPFfu1aOQm4NA0J+YV4LYpWulM0GPEerVpsB367KWZcfkoU4ssBBzTOSYPl1vp+/FSuZ02u20bwEhX1cTJKfszwCHTgFe1i4aYew1IxAB/CGN32BZzmQxmBeZ1JMjBcQCmjxjWoMtOYgp7gHYCcGzK/pMAjgrhGnDGlewJ+FiU4wgvG2wCHiP0cm6VFjvkkZPKjQm6tVxknWYFcCbIVAyD57s2Q2VkxcdpMlV6XdckEUq3/wBuWB33GdYXfvPbrnZAf0T1yzhjToHmZmjhqJw5mbJCLF7YtFiiYsw44YUvfZKaZOCDZHNxrPuHQtAwU74MlHRYE3I8xwEKGwF1yqKjiw49+ENWyhrbFjwLqJNRfwLQHNuODTkaMiVn0MMPjZ6gnAQUqpU+8WWdQ2ZsHG8qjvXYQQ1ZYsEe+pMPA77oNMbw6atxrNsmumor0CX7zhe+U5Lt5Q5KKt5j6RoIjk79Z392Mow6OZpD8qJaAOinchi7VRJQmEkQA2vYogF4mkexKV2GxIDsBW/dGnve7Fq3dOgcvwbeukWfgBc/vz+IrtcUexBoU29sME9DC59AOq1s9HUSrDefkmxwunzZmRXOfD7nJYj9lF/00ouzPMeR07w73q7HEhvg9fdrXfWPZMo/nRpmlBCeocM1J4D/aJDm3X7ZuzbgyMdHqjY2ehJdeVrPScBRIglc1V0HcGTHTx8XwMsErGlv7LBRXPEx+Qaky5pznJeSMwbcuiONTwKOufjweK27BdwiAeUE4MjQVuzP/ZdvHfRXq0cVqvexL8f6u/W+XPmauzJ68JKlqlZVjuVaJLEkHlFtH9CR99t6bNFnLF1XhkhUuGXZAKKvjvXSsZpu80h3sFKuOOBnQwA4F3MqK340G/6hc6TU53lMzLjCk75pzGnEq3Ffp0HDDzyMIBt5hqwrpxwV7iovIduXD1r0Snd7pFtEjmelO2Br+sY63/n8csxDnC93ETPIckr1648Z6g/aq/prjU6UBIkpbXWMhphFat4TgRo2DCKyGs/Wxh0IZONvAo4S8thSh01sI+sGsRbf+f5foCCrCx/wVg1CgNDYJrpQ40097HQZGBUH8WLD7Cbj7/ZjYFegrcP2hvClFY4ItloLXo00h0fAP1TQDxSq/ka9XvKWpFL9zi69HBhwxm1ByyqPFzsrHBXp1NJW+oAR+gRR8k8DeEJj8TcGeIzSk4O+dvMUvRwmXuPQZTSeFQ5z8mrQNy72aOhw86ZLdgZj5d/OrOGNPUZDf/EzqYZqmWn02d/4lp/zVLmrXjT+hjnnPm79MZk5sVa8tsIx5SDVNR6Aj2/cxsczZGb4yA01J5KxX7aSAM2TRPtKsrER3cjivxZvlm4+WcTHBvL9JMGXm47b+RyXjE3YgLj0vco9F1m+VkmvGOyHxwNqGG925rEepnncSggbbcqYo9sxJwZsimF6qS3OxhqTF9vCl+Q+/Nn1MY+Vo4qH+EDQnCuQt+1dR75iusCiUGf3KZVwxuoqAHc1hsUG8TNSHWtyUmDQmk7okE5WuRYAH5NZ2JT1c1GMarFjeWdfutVHxj2Ap0nYIijRbGTNR8D4RsZyLGwQ8g8VtnYcJyKJweLNSADHHk2sUxVudlRjT8TkBP6I3aNLb019kfuRX/6HBu6hUs3l577Y9DMdaDrI4csORfKnP+1Q/6ADYckArhtBlw6JgA6pV7k3QuTh19iLQ1c2ZzIb6N1OtxH9EcDwz4Z0kxLfCtoFBua18P3yJ7orPHF5BwwTAI4/WN0OR7qPdWxOvTgYujlpajYq2YbKvxlDB//zlCl75GSCjhh0+mpsoKkTYnj6Zq57mex//qd/6vAR/fupH5XmR3T9iP4ozUfefnz4kP6O6ZtvXxzuvNmSIy1bITgWLFaAmgbhIVdBM+4vhqFbHlldMzDmTDjyUCwbyDLlGjui/DJtMrCH3rTouUWmAWQavzbVbuJKLoBP+7I1NyXExLA1wjpa89v4hjYCHjZmWGVvgo0NL771HhLI8PHOZ46PedR2j3oY50LyAZeCfiSHvOz5BQ+mHv6PVf486ybg2vn4wt0RiEUboZAPjSrgI1nRbQM/iR/DSWJ6sT2Eh07Zs1qTsZ+eVMlNdgaVJHTzxYlJ4ZuhW8klZrPxq2s+ephH7yrAUfTpw4rTMKAmG3YXluZ9jV4XciU+hpqslKDut4R4xP30V791OBcEft4LXQMv5C/0tkYsBOGY1HNU0xxYD4QxAZcXAA/o0EIfiZNss4mqzZKYspOEYs4+6wRIQqjyWek2gOCITSPbcSg2YEo5GTwf67iLvxJxIFmjdKe6Bj7h4KHDKQGT1kGH3+LwEYysQbc0CuPCpoblzvb8iyOwaSU2xybVkT6VRJSdU9WO7smKh/lA8fJix5c6D3Q9VKU/1CZ4E6Yaye8bYFBH4Aa2CCPWkZwJNjwWqG7aGCQRNEhSkkiRaJ5WEgM49BXgFsRINTkZeiGo70kSCJ6i0v01mcRtNnE3IHNK2PoWcBZYDcC94K5rggTKb3O5/NII+s1OxsMeQbe1Jv4uj/6mRWxDHtNP/advHu7LKBuA/lw9le/jnR7juWpIEpIkWFQ4x6B3rbz5/8wohvOjPuBNMyRlB3QC9Xf5G9BnlU8DCMoGrfzwApfEDnrxAZyYmNqBuYNQCHgDixf2/FiGqKu2dOgCOrq+Bs8VDo91JbYkrgxHBQ3nCtu0vq6aD3vwah3QE2DJvPN395/tsGmXVjwC94TyhwTeQ0XwUEf9I6pe120d+Tniic3BoqDGnJaXN5IH4MikOjrgFiYhUWQRrdlP8aZel5l6SyLIczbXNJVEhRfxla0QFW/R6VbftuFvpVMBNPv4nBXOZAU4c4ijRc35mcQMIhR7xLfE2O3M/G1U96bN/R77cPjbv/5Nv+jdl6/7EjnX13mPeM4LSAcsMBMwyx/XUuW2ClFydDklIuuEnAAdwF3lEkbvCPRpRIYrsYA9/0+b8NMIVnNXeOisPhkwfyS0V7n/oWhOIPTYvNHBtncYtoeufejmN3XkicuxMSnHpT9dap4cWqTEMG978jE2cfmAjo3E0UzDuqrakYkq45PtF/7DN1z591X99/UF/qMC/2EhEb9UONdcBBYDuIaIR3YmJIS+EMmeqvLdZ7kS6/zLxkiQDGCXRnbDD23ja4ImcUCHPQEHtB4jNmk4QrADLtqVgKMTNY3JldMYH4M9ZGwvwsVAv2wMoaLTycZ1QEf0yqMeIRpH/n1FyLP+nir+LV1n2gBn/NFZtQDuZziEBjgBsS43736NJkHjtpBTgA/lrd4AfGU/dl1O5Sa05sf2ApomOdb9CyDbGLsegFuvqo/pKgAZs36cMrc336zKXOwJ+MIeMlsfUJuNIeT7uDVXjXrpcGvupPAv/to3Dh8I/HuSuK/X/Ie6+GjnKq8ko+yYWZTGXJ7DIBl7Ca0I+rGOuE8H8WaFQ8wCZccvWcx1mVxjxGaFM4aOj75Sx1vAiQXoAD5Bj62tHnMjp56hFjcrHILXaA630ZpfckEcrM0bjXlrZNPrbT6OYkc+evRt/M6nL3+ha65W6ej03fFf+fdfV7Wr+nVx5F+o4h/zvNdiArh/j514FJAXiqUOOIGSjCRE86Mq57QIH310rLcBXDT7gEdjQ3Ax5iY7R60l1XFLZgLOs3zaapo9XpENeH4DNGJeY5RFbDreZ8W6FPDkCZtNPy4cG3ZywejjKXj14NpHfUzd1Td2H9KWvffg7PBhvd2/IfDvyMr4PXaSEkn1fSHQN2Dmyxw0ZoUzSWu25lt10dyFr8xOv9Dwo83pFp8bwOd39Ajl5Y1x5BljtOlRkSu+5X2uIcxstLJhVcZisb4ugqDtmb6cPkf2EaRt9Zm39s7fuX61o9aX2cycHv5VVT3g36Xqz2/pyL/lX6FyjnowAR0aldc9iRbQnZBtheO+bPlIDzCiQTbIHlSFl+yscEBf+RuJTYVjxCrYjW18RgcHjDvooSGXZvk4F5F52XCMGrO+bZX7SLc9+Y+Pphvz7jEPL27oM7aAXuieEHTUKsyycM3uk//u64f3FPO7988OD/xrOi0SAA/oe4BroRztJCNVvnJbC/ORHVBEI0/2Yj4V3qocP9ADeFZFUsuX/89PZcP/3Du2cY48l50gJL1qBunoWBczPiJY85iAvAUc2nwniI/4hrltjqmIXvdW4OlAx8o2/GPLJyh//ld/5/AeVX9fVX9OVGodcMBIq6Cp8g746jmOLDmXDR/rZdK04vkZroSRXANNj5/LAK/kWZT4ADy2sWu+CEZsbBTIE/CeIcZ9jmDRvInLrte4kZtVDuBce7awR+s8bPZ4LfDstyd+xneX7+rIf+fe2eHtt28d7rzD79+qdcCZi9iP9SOwS2Z+951Fqs/QgJccnVsAZ5IkVxWReEiAwZ6Y/0MHZNOmTnkpXQCa9raymdOXPj4YYoXxErTGnopousCmxe+Yre+dh84V7WmO+JjsrkK7dv8Xf/Xrh+/q5e69D6rqO+gK3B/RNlV+ZJy8UIlOTnGhMaT6uRj7Vn3Gib4Bno2lDxsG/Ah0dLhyJqOra1ZkbErEcn0OjSYaIAd0j21zsLlPe8SKD/h7tobwwrM8xMvbs4CO5bNTv4hxuds199/+2T9++Kk/8Ojw4T+ob/TrKM2xbid7C9YCJ+AxB41xwLZyMc2AV3PzlFBlnd+CgUx1Y8CPZAMKoTWE/Jygly4dCtiOfYjdB/M00QGZhkjGXXfaQ6h8nLTX/Xb/6F7SnhV0TN8I8Bj6tT8n8D9xfnjrw/oHWC1xqUBk3LTAo2MdBnRfA5DIzqQ2m07oZYCXPdvghm4AZy5A1gBBVOs+BmXe8zU0IlcCjhagn7IXkOkzRuca7SZAx82NAY+x//HJP3r46MfP9cGeIxrKum0/i5trsBVIqgNiT0i3gwxZBzjRXeESz1/JsI2eSHRvCHCH1W3XeLWBLPR8AMf0TYE+wjzxO3cwn6b975//ycOHPsqvbixtAg4pyVPvCjetVXmATh/+VYB321vAcYvf+I5s9wGtN/FS2X3vxMYR4OjymNtr3e9lPvd0i3aToGPyRis+cf/eL/344dZbqkoWzIsbbbN4r79XeU9IH1uXo1kV3ui7VR5+Q+pZAOeoniFW/C8acJZ/06CPlN5wxWOU9t3PjL9o6ElAJ5EieJqMToIYAc5KCA7AoV96rEevA86PiHjLS2MYudB6XzxXucZLeHp5dBwy0MxZ9TlWeEJ7HqBj+7lUfIKm95+0JGG6nNslo+tEdlACuNRS5caQ3Hf96Nwg4MSMCyr7JOAIxDcKaX1j1JrDetL+eQGeOJ478Dh693NV/SOjTwU4dubLW096gS6YnqnCbb8AZ+zq7kBGoPu2YN0i+4yAY+15g46PFwI8jt79ex+jW0DfJlCbgpytKrzkZ5WvviAamTbggD+mS7+1jy1ao+cjWircfOzElgnMtSNoTXcQdI/stp8CTzZ4EaAT0QsDPst/9wvaAD2BBTip9VetmwQa9A64o/ZBrOglvJFf2Y5T+uYzgJtcr+6Y6d8/wPt+BNzr8tKe08tdHOz17/59gX8dwEGjAQbQs8IxDD/AM++yzGmNlhc3k68D+Eaf6fTX/faxhZ7s9qKqvEf1wiu+O3/3iz+mr3gbpRLob/YaYEj4Ue4bk7pg0DayW1oH3OIiYOJkhVvIVpZbBzfj9IvUE41eBuAJ8KUCTxDf+9KPzSqaX+U2IFeAo9B4TC+bV1FPmVsBHMA6aHmG79lbySGg1mmD8sT3lwm6l3ATP6R54lXvKLz3lT80AXJgBqdl+BkAx95tge6N0EzOZ3ji6T5WchFQ3+mNfN3hywY8cb70ik8g6e/+ijaAf/uxKB0MSNt5o20rHNYEnElA6xUOvduMTJffjpk/YXtVAE/YrxzwCYz+7j/SY6C3DhD0mk/AG41jfQG6jGwBb/JTFloHf28O7RrtVQO7h/xKA59A7/7jzQaAsQW95ivAkQPEHwJOJlbttQC+R3z3n4xNsK3yawOOMTZJr+o+jrM9Wng7/atc3TvhqhZewuf4vUCelvb+P/3Y8p06Rk5VOLwbBPx1A5rl9/baA98Xk/H7/2zzaLgO4CifqPLXHeTkpfffl8D3Bf5wvJ+B/w/viOYeB85Y6AAAAABJRU5ErkJggg=="></image>
37
+ </g>
38
+ </g>
39
+ </g>
40
+ </g>
41
+ </g>
42
+ </g>
43
+ </g>
44
+ </g>
45
+ </g>
46
+ </svg>
modules/ppcp-wc-gateway/assets/images/elo.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg width="780" height="500" enable-background="new 0 0 780 500" version="1.1" viewBox="0 0 780 500" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="780" height="500" fill="#000"/><path d="m167.25 181.4c6.8-2.3 14.1-3.5 21.7-3.5 33.2 0 60.9 23.601 67.2 54.9l47-9.6c-10.8-53.2-57.8-93.301-114.2-93.301-12.9 0-25.3 2.101-36.9 6l15.2 45.501z" fill="#FFF100"/><path d="m111.75 333.8l31.8-36c-14.2-12.6-23.1-30.9-23.1-51.4 0-20.399 8.9-38.8 23.1-51.3l-31.8-35.899c-24.1 21.399-39.3 52.5-39.3 87.3 0 34.699 15.2 65.898 39.3 87.299z" fill="#00A3DF"/><path d="m256.15 260.2c-6.4 31.3-34 54.8-67.2 54.8-7.6 0-14.9-1.2-21.8-3.5l-15.2 45.5c11.6 3.899 24.1 6 37 6 56.4 0 103.4-40 114.2-93.2l-47-9.6z" fill="#EE4023"/><path d="m459.75 292.4c-7.8 7.601-18.3 12.2-29.9 12-8-0.1-15.399-2.5-21.6-6.5l-15.601 24.801c10.7 6.699 23.2 10.699 36.801 10.899 19.699 0.3 37.699-7.5 50.8-20.2l-20.5-21zm-28.2-101.1c-39.2-0.6-71.6 30.8-72.2 70-0.2 14.7 4 28.5 11.5 39.9l128.8-55.101c-7.2-30.899-34.8-54.2-68.1-54.799m-42.7 75.599c-0.2-1.6-0.3-3.3-0.3-5 0.4-23.1 19.4-41.6 42.5-41.199 12.6 0.199 23.8 5.899 31.3 14.899l-73.5 31.3zm151.3-107.6v137.3l23.801 9.9-11.301 27.1-23.6-9.8c-5.3-2.3-8.9-5.8-11.6-9.8-2.601-4-4.601-9.601-4.601-17v-137.7h27.301zm85.901 63.5c4.2-1.4 8.6-2.1 13.3-2.1 20.3 0 37.101 14.399 41 33.5l28.7-5.9c-6.6-32.5-35.3-56.9-69.7-56.9-7.899 0-15.5 1.301-22.5 3.601l9.2 27.799zm-33.901 92.9l19.4-21.9c-8.7-7.7-14.1-18.9-14.1-31.4s5.5-23.699 14.1-31.3l-19.4-21.899c-14.699 13-24 32.1-24 53.3s9.301 40.199 24 53.199zm88.201-44.801c-3.899 19.101-20.8 33.5-41 33.5-4.6 0-9.1-0.8-13.3-2.199l-9.3 27.8c7.1 2.399 14.7 3.7 22.6 3.7 34.4 0 63.101-24.4 69.7-56.9l-28.7-5.901z" fill="#fff"/></svg>
modules/ppcp-wc-gateway/assets/images/giropay.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Giropay_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Giropay_acceptancemark_80x50">
6
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
8
+ <g id="Giropay" transform="translate(10.000000, 12.000000)">
9
+ <path d="M0.0485052988,4.66119138 C0.0485052988,2.09222708 2.12902174,0.00933576963 4.69412828,0.00933576963 L55.3234715,0.00933576963 C57.8896803,0.00933576963 59.9690706,2.09222708 59.9690706,4.66119138 L59.9690706,21.2852526 C59.9690706,23.8527219 57.8896803,25.9359985 55.3234715,25.9359985 L4.69412828,25.9359985 C2.12902174,25.9359985 0.0485052988,23.8527219 0.0485052988,21.2852526 L0.0485052988,4.66119138 L0.0485052988,4.66119138 Z" id="_92653320" fill="#000268"></path>
10
+ <path d="M1.95517995,4.82036195 L1.95517995,21.1276014 C1.95517995,22.7326433 3.25562557,24.034417 4.85974897,24.034417 L31.3849373,24.034417 L31.3849373,1.91354603 L4.85974897,1.91354603 C3.25562557,1.91354603 1.95517995,3.21529585 1.95517995,4.82036195 L1.95517995,4.82036195 Z M38.2385635,12.8925274 C38.2385635,13.9307775 37.7282077,14.6443441 36.8832548,14.6443441 C36.1367871,14.6443441 35.5145236,13.9307775 35.5145236,12.9799746 C35.5145236,12.0040421 36.0617905,11.2784658 36.8832548,11.2784658 C37.754333,11.2784658 38.2385635,12.0291961 38.2385635,12.8925274 Z M33.2773508,18.8472659 L35.5145236,18.8472659 L35.5145236,15.3064695 L35.5395227,15.3064695 C35.9633053,16.0823531 36.8093844,16.3698729 37.5924277,16.3698729 C39.5192354,16.3698729 40.5510927,14.7689549 40.5510927,12.8422195 C40.5510927,11.2664554 39.5692336,9.55141717 37.7782052,9.55141717 C36.7594106,9.55141717 35.8144627,9.96470555 35.3656809,10.8783204 L35.3406818,10.8783204 L35.3406818,9.7027011 L33.2773508,9.7027011 L33.2773508,18.8472659 Z M43.6067337,14.1556176 C43.6067337,13.5306321 44.2028719,13.2937816 44.9624023,13.2937816 C45.2977901,13.2937816 45.6216014,13.3174403 45.9073508,13.330946 C45.9073508,14.0936859 45.372763,14.8695463 44.5266832,14.8695463 C44.0044153,14.8695463 43.6067337,14.6071798 43.6067337,14.1556176 Z M48.1195488,16.2201082 C48.0206794,15.7077475 47.9956809,15.1938684 47.9956809,14.6815078 L47.9956809,12.2543983 C47.9956809,10.265369 46.5665256,9.55141717 44.9124284,9.55141717 C43.9555441,9.55141717 43.1225269,9.68917157 42.3264216,10.014989 L42.3644834,11.5419649 C42.9841103,11.1909942 43.7067051,11.0532391 44.4278144,11.0532391 C45.2347292,11.0532391 45.8939283,11.2916094 45.9073508,12.1800948 C45.6216014,12.1297868 45.2227935,12.0914892 44.8624309,12.0914892 C43.6697939,12.0914892 41.5184036,12.3298595 41.5184036,14.3185267 C41.5184036,15.7329015 42.6618095,16.3698729 43.9424814,16.3698729 C44.8624309,16.3698729 45.4846708,16.008411 45.9942595,15.1938684 L46.0192586,15.1938684 C46.0192586,15.5328288 46.0558099,15.8691368 46.0692561,16.2201082 L48.1195488,16.2201082 Z M49.1263833,18.8472659 C49.5867172,18.9478812 50.0463328,18.9985505 50.5186032,18.9985505 C52.5704056,18.9985505 53.0546124,17.409257 53.6888124,15.7700414 L56.0644018,9.7027011 L53.8257193,9.7027011 L52.495409,13.9559315 L52.4704099,13.9559315 L51.0778065,9.7027011 L48.6667921,9.7027011 L51.28971,16.3698729 C51.1278041,16.9456845 50.7055076,17.2715019 50.1578807,17.2715019 C49.8460059,17.2715019 49.5736789,17.2332043 49.2748667,17.1337468 L49.1263833,18.8472659 Z" id="_92186184" fill="#FFFFFF"></path>
11
+ <path d="M7.42075671,12.905671 C7.42075671,12.0171857 7.85647576,11.2784658 8.6894929,11.2784658 C9.69637475,11.2784658 10.1186719,12.0914892 10.1186719,12.8170662 C10.1186719,13.8181764 9.48447193,14.4934454 8.6894929,14.4934454 C8.01838174,14.4934454 7.42075671,13.9187672 7.42075671,12.905671 Z M12.2823578,9.7027011 L10.2555781,9.7027011 L10.2555781,10.8783204 L10.2320652,10.8783204 C9.75828501,10.0773066 8.98681894,9.55141717 8.03031747,9.55141717 C6.01657678,9.55141717 5.10858737,11.0040651 5.10858737,12.9428109 C5.10858737,14.8695463 6.21541759,16.2201082 7.99189651,16.2201082 C8.88833303,16.2201082 9.63444081,15.8691368 10.1686458,15.1064206 L10.1936442,15.1064206 L10.1936442,15.4573675 C10.1936442,16.732854 9.49753461,17.3458299 8.20528613,17.3458299 C7.27227396,17.3458299 6.69964803,17.1457572 6.01657678,16.808316 L5.904669,18.5852621 C6.42583495,18.7733245 7.30884893,18.9985505 8.37912785,18.9985505 C10.9901094,18.9985505 12.2823578,18.1348332 12.2823578,15.4573675 L12.2823578,9.7027011 Z M16.0647166,6.98807173 L13.8264169,6.98807173 L13.8264169,8.6392977 L16.0647166,8.6392977 L16.0647166,6.98807173 Z M13.8275432,16.2201082 L16.0647166,16.2201082 L16.0647166,9.7027011 L13.8275432,9.7027011 L13.8275432,16.2201082 Z M22.2961752,9.62687843 C22.0723353,9.59007618 21.7985222,9.55141717 21.538131,9.55141717 C20.5682077,9.55141717 20.0090043,10.0773066 19.6232591,10.9034743 L19.59826,10.9034743 L19.59826,9.7027011 L17.5595445,9.7027011 L17.5595445,16.2201082 L19.7971008,16.2201082 L19.7971008,13.4687004 C19.7971008,12.1921045 20.3824295,11.4293638 21.4262232,11.4293638 C21.6881006,11.4293638 21.9354284,11.4293638 22.1842674,11.5033059 L22.2961752,9.62687843 Z M26.1494557,14.7941089 C25.1175977,14.7941089 24.6953012,13.9307775 24.6953012,12.9679642 C24.6953012,11.9920317 25.1175977,11.1287004 26.1494557,11.1287004 C27.1824392,11.1287004 27.6050956,11.9920317 27.6050956,12.9679642 C27.6050956,13.9307775 27.1824392,14.7941089 26.1494557,14.7941089 Z M26.1494557,16.3698729 C28.2881425,16.3698729 29.9172649,15.1199263 29.9172649,12.9679642 C29.9172649,10.8028836 28.2881425,9.55141717 26.1494557,9.55141717 C24.0111274,9.55141717 22.3831319,10.8028836 22.3831319,12.9679642 C22.3831319,15.1199263 24.0111274,16.3698729 26.1494557,16.3698729 Z" id="_47303032" fill="#FF0007"></path>
12
+ </g>
13
+ </g>
14
+ </g>
15
+ </svg>
modules/ppcp-wc-gateway/assets/images/hiper.svg ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 780 500" style="enable-background:new 0 0 780 500;" xml:space="preserve">
4
+ <style type="text/css">
5
+ .st0{fill:#F37421;}
6
+ .st1{fill:#FFFFFF;}
7
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFE700;}
8
+ .st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
9
+ </style>
10
+ <rect y="0" class="st0" width="780" height="500"/>
11
+ <g>
12
+ <polygon class="st1" points="101,140.9 101,315.9 140.7,315.9 140.7,242.7 205.9,242.7 205.9,315.9 245.4,315.9 245.4,140.9 205.9,140.9 205.9,208.2 140.7,208.2 140.7,140.9 101,140.9 "/>
13
+ <path class="st1" d="M587.2,265c0.5-2.9,1.3-8.8,1.3-15.6c0-31.4-15.6-63.4-56.6-63.4c-44.1,0-64.1,35.6-64.1,67.8 c0,39.7,24.7,64.7,67.8,64.7c17.1,0,33-2.6,46-7.8l-5.2-26.7c-10.6,3.4-21.6,5.2-35.1,5.2c-18.4,0-34.5-7.8-35.8-24.1H587.2 L587.2,265z M505.1,238c1-10.6,7.8-25.7,24.4-25.7c18.2,0,22.3,16.1,22.3,25.7H505.1L505.1,238z"/>
14
+ <path class="st1" d="M601.1,315.9h39.5v-64.4c0-3.1,0.3-6.2,0.8-8.8c2.6-12.2,12.5-20,27-20c4.4,0,7.8,0.5,10.6,1v-37.1 c-2.9-0.5-4.7-0.5-8.3-0.5c-12.2,0-27.8,7.8-34.3,26.2h-1l-1.3-23.4h-34c0.5,10.9,1,23.1,1,41.8V315.9L601.1,315.9z"/>
15
+ <path class="st2" d="M285.5,133.9c11.2,0,20.3,9.1,20.3,20.3c0,11.2-9.1,20.3-20.3,20.3c-11.2,0-20.3-9.1-20.3-20.3 C265.2,143,274.3,133.9,285.5,133.9L285.5,133.9z"/>
16
+ <path class="st3" d="M368.9,286.3h19.8c19.9,0,28.9-12.7,28.9-26c0-13.3-1-43.3-25.5-43.3c-28.2,0-23.7,37.3-23.5,56.8 C368.5,278,368.8,282.2,368.9,286.3L368.9,286.3z M265.2,188.8h40.6v71.6c0,13.3,7.4,26,23.7,26c0.1-32.2,0-65.4-1.1-97.6h33.9 c0.7,6.2,1.4,12.4,2,18.6c16-32,66.5-25,83.5,2.1c17.5,27.9,23.5,107.9-59.1,107.9h-19.2c0.2,16.2,0.2,32.5,0.2,48.8h-40.6 c0-15.6,0.1-32,0.2-48.8c-43.9-0.2-64.1-28-64.1-57V188.8L265.2,188.8z"/>
17
+ </g>
18
+ </svg>
modules/ppcp-wc-gateway/assets/images/ideal.svg ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>iDEAL_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="iDEAL_acceptancemark_80x50">
6
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0" y="0" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
8
+ <g id="iDeal" transform="translate(20.000000, 7.000000)">
9
+ <g id="Group-10">
10
+ <path d="M0.0278615385,0.140182609 L0.0278615385,34.972487 L20.5587846,34.972487 C34.1023231,34.972487 39.9747846,27.4701609 39.9747846,17.5216391 C39.9747846,7.61268261 34.1023231,0.140182609 20.5587846,0.140182609 L0.0278615385,0.140182609 Z" id="Fill-6" fill="#FFFFFF"></path>
11
+ <path d="M20.5643385,2.69557826 C35.2091077,2.69557826 37.3957231,11.9844261 37.3957231,17.5203609 C37.3957231,27.1251217 31.4186462,32.4145348 20.5643385,32.4145348 L2.61387692,32.4145348 L2.61387692,2.69557826 L20.5643385,2.69557826 Z M4.02695385,4.0929913 L4.02695385,31.016513 L20.5643385,31.016513 C30.5506462,31.016513 35.9829538,26.4153826 35.9829538,17.5203609 C35.9829538,8.37927391 30.0944923,4.0929913 20.5643385,4.0929913 L4.02695385,4.0929913 Z" id="Fill-8" fill="#000000"></path>
12
+ </g>
13
+ <polygon id="Fill-11" fill="#000000" points="6.24569231 28.8217391 11.5396923 28.8217391 11.5396923 19.4998696 6.24569231 19.4998696"></polygon>
14
+ <g id="Group-16" transform="translate(5.538462, 6.239130)">
15
+ <path d="M6.64389231,8.56550435 C6.64389231,10.3629826 5.17127692,11.8203522 3.35389231,11.8203522 C1.53743077,11.8203522 0.0634307692,10.3629826 0.0634307692,8.56550435 C0.0634307692,6.76924348 1.53743077,5.31126522 3.35389231,5.31126522 C5.17127692,5.31126522 6.64389231,6.76924348 6.64389231,8.56550435" id="Fill-12" fill="#000000"></path>
16
+ <path d="M17.0311385,10.0886283 L17.0311385,11.5968239 L13.2585231,11.5968239 L13.2585231,5.54197609 L16.9094462,5.54197609 L16.9094462,7.04956304 L14.7837538,7.04956304 L14.7837538,7.7515413 L16.7940615,7.7515413 L16.7940615,9.25882391 L14.7837538,9.25882391 L14.7837538,10.0886283 L17.0311385,10.0886283 Z M17.7634462,11.5988022 L19.6102154,5.53938913 L21.7797538,5.53938913 L23.6259077,11.5988022 L22.0383692,11.5988022 L21.6923692,10.4266065 L19.6976,10.4266065 L19.3505231,11.5988022 L17.7634462,11.5988022 Z M20.1432923,8.91947609 L21.2465231,8.91947609 L20.7420615,7.20706304 L20.6505231,7.20706304 L20.1432923,8.91947609 Z M24.3920615,5.5395413 L25.9169846,5.5395413 L25.9169846,10.0886283 L28.1768308,10.0886283 C27.5571385,1.83441087 20.9922154,0.0510847826 15.0271385,0.0510847826 L8.66729231,0.0510847826 L8.66729231,5.54273696 L9.60867692,5.54273696 C11.3249846,5.54273696 12.3912923,6.69393261 12.3912923,8.54573696 C12.3912923,10.4564326 11.3506769,11.5968239 9.60867692,11.5968239 L8.66729231,11.5968239 L8.66729231,22.5853022 L15.0271385,22.5853022 C24.7259077,22.5853022 28.1009846,18.1304109 28.2200615,11.5968239 L24.3920615,11.5968239 L24.3920615,5.5395413 Z M8.66606154,7.05062826 L8.66606154,10.0886283 L9.60867692,10.0886283 C10.2619077,10.0886283 10.8651385,9.90191087 10.8651385,8.54573696 C10.8651385,7.22060652 10.1937538,7.05062826 9.60867692,7.05062826 L8.66606154,7.05062826 Z" id="Fill-14" fill="#CC0066"></path>
17
+ </g>
18
+ </g>
19
+ </g>
20
+ </g>
21
+ </svg>
modules/ppcp-wc-gateway/assets/images/jcb.svg ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" height="231.511" width="300" xml:space="preserve" viewBox="0 0 300.00001 231.511" y="0px" x="0px" id="レイヤー_1" version="1.1"><metadata id="metadata6424"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs6422"/><style id="style6319" type="text/css">
3
+ .st0{fill:#FFFFFF;}
4
+ .st1{fill:url(#SVGID_1_);}
5
+ .st2{fill:url(#SVGID_2_);}
6
+ .st3{fill:url(#SVGID_3_);}
7
+ .st4{fill:url(#SVGID_4_);}
8
+ .st5{fill:url(#SVGID_5_);}
9
+ </style><g transform="translate(-9.4000001,96.810998)" id="g6321"><g transform="matrix(1.8215159,0,0,1.8215159,-8.5437653,-109.83667)" id="g6323"><path style="fill:#ffffff" id="path6325" d="m 174,108.3 c 0,14 -11.4,25.4 -25.4,25.4 l -138.2,0 0,-100.6 c 0,-14 11.4,-25.4 25.4,-25.4 l 138.2,0 0,100.6 z" class="st0"/><g id="g6327"><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="81.398598" x2="157.3299" y1="81.398598" x1="117.3856" gradientUnits="userSpaceOnUse" id="SVGID_1_"><stop id="stop6330" style="stop-color:#007940" offset="0"/><stop id="stop6332" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6334" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6336" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_1_)" id="path6338" d="m 129,82.5 10.5,0 c 0.3,0 1,-0.1 1.3,-0.1 2,-0.4 3.7,-2.2 3.7,-4.7 0,-2.4 -1.7,-4.2 -3.7,-4.7 -0.3,-0.1 -0.9,-0.1 -1.3,-0.1 l -10.5,0 0,9.6 z" class="st1"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="157.3318" y1="75.171402" x1="117.3844" gradientUnits="userSpaceOnUse" id="SVGID_2_"><stop id="stop6341" style="stop-color:#007940" offset="0"/><stop id="stop6343" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6345" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6347" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_2_)" id="path6349" d="m 138.3,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,18.9 25.7,0 c 0.6,0 1.3,0 1.8,0.1 5.8,0.3 10.1,3.3 10.1,8.5 0,4.1 -2.9,7.6 -8.3,8.3 l 0,0.2 c 5.9,0.4 10.4,3.7 10.4,8.8 0,5.5 -5,9.1 -11.6,9.1 l -28.2,0 0,37 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.9 -26.6,0 z" class="st2"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="68.399101" x2="157.33051" y1="68.399101" x1="117.3846" gradientUnits="userSpaceOnUse" id="SVGID_3_"><stop id="stop6352" style="stop-color:#007940" offset="0"/><stop id="stop6354" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6356" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6358" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_3_)" id="path6360" d="m 143.2,63.1 c 0,-2.4 -1.7,-4 -3.7,-4.3 -0.2,0 -0.7,-0.1 -1,-0.1 l -9.5,0 0,8.8 9.5,0 c 0.3,0 0.9,0 1,-0.1 2,-0.3 3.7,-1.9 3.7,-4.3 z" class="st3"/></g><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="68.522102" y1="75.171402" x1="27.9594" gradientUnits="userSpaceOnUse" id="SVGID_4_"><stop id="stop6363" style="stop-color:#1F286F" offset="0"/><stop id="stop6365" style="stop-color:#004E94" offset="0.4751"/><stop id="stop6367" style="stop-color:#0066B1" offset="0.8261"/><stop id="stop6369" style="stop-color:#006FBC" offset="1"/></linearGradient><path style="fill:url(#SVGID_4_)" id="path6371" d="m 37.7,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,44.9 c 5.1,2.5 10.4,4.1 15.7,4.1 6.3,0 9.7,-3.8 9.7,-9 l 0,-21.2 15.6,0 0,21.1 c 0,8.2 -5.1,14.9 -22.4,14.9 -10.5,0 -18.7,-2.3 -18.7,-2.3 l 0,38.3 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.8 -26.6,0 z" class="st4"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="111.8553" y1="75.171402" x1="72.459503" gradientUnits="userSpaceOnUse" id="SVGID_5_"><stop id="stop6374" style="stop-color:#6C2C2F" offset="0"/><stop id="stop6376" style="stop-color:#882730" offset="0.1735"/><stop id="stop6378" style="stop-color:#BE1833" offset="0.5731"/><stop id="stop6380" style="stop-color:#DC0436" offset="0.8585"/><stop id="stop6382" style="stop-color:#E60039" offset="1"/></linearGradient><path style="fill:url(#SVGID_5_)" id="path6384" d="m 88,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,23.8 c 4.6,-3.9 12.6,-6.4 25.5,-5.8 6.9,0.3 14.3,2.2 14.3,2.2 l 0,7.7 c -3.7,-1.9 -8.1,-3.6 -13.8,-4 -9.8,-0.7 -15.7,4.1 -15.7,12.5 0,8.5 5.9,13.3 15.7,12.5 5.7,-0.4 10.1,-2.2 13.8,-4 l 0,7.7 c 0,0 -7.3,1.9 -14.3,2.2 -12.9,0.6 -20.9,-1.9 -25.5,-5.8 l 0,42 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-91 -26.7,0 z" class="st5"/></g><g id="g6386"/></g></svg>
modules/ppcp-wc-gateway/assets/images/mastercard.svg ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Mastercard_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Mastercard_acceptancemark_80x50" fill-rule="nonzero">
6
+ <rect id="Rectangle" fill="#FFFFFF" x="0" y="0" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF"></path>
8
+ <g id="mc_symbol" transform="translate(10.000000, 6.000000)">
9
+ <rect id="Rectangle" fill="#FF5F00" x="20.8617949" y="4.12575342" width="17.4781197" height="28.6927397"></rect>
10
+ <path d="M22.6620513,18.4746575 C22.6576628,12.8765076 25.2144865,7.58721934 29.595812,4.13082192 C22.1526293,-1.74860389 11.4639205,-0.892214679 5.04142287,6.09814223 C-1.38107479,13.0884991 -1.38107479,23.8658844 5.04142287,30.8562413 C11.4639205,37.8465982 22.1526293,38.7029875 29.595812,32.8235616 C25.2130922,29.3660666 22.6561123,24.0745861 22.6620513,18.4746575 Z" id="Path" fill="#EB001B"></path>
11
+ <path d="M57.2350427,30.0728767 L57.2350427,29.2443053 L57.4871795,29.2443053 L57.4871795,29.0728767 L56.887094,29.0728767 L56.887094,29.2443053 L57.1241026,29.2443053 L57.1241026,30.0728767 L57.2350427,30.0728767 Z M58.3999145,30.0728767 L58.3999145,29.0728767 L58.2183761,29.0728767 L58.0065812,29.7871624 L57.7947863,29.0728767 L57.6132479,29.0728767 L57.6132479,30.0728767 L57.744359,30.0728767 L57.744359,29.3157339 L57.9410256,29.9657339 L58.0771795,29.9657339 L58.2738462,29.3157339 L58.2738462,30.0728767 L58.3999145,30.0728767 Z" id="Shape" fill="#F79E1B"></path>
12
+ <path d="M58.9697436,18.4746575 C58.9697436,25.4607544 55.0008191,31.8335077 48.7490048,34.8863846 C42.4971905,37.9392614 35.0599128,37.1362892 29.595812,32.8184932 C33.9752258,29.3591613 36.5322419,24.0705763 36.5322419,18.4721233 C36.5322419,12.8736703 33.9752258,7.58508524 29.595812,4.12575342 C35.0599128,-0.192042583 42.4971905,-0.995014858 48.7490048,2.057862 C55.0008191,5.11073887 58.9697436,11.4834921 58.9697436,18.469589 L58.9697436,18.4746575 Z" id="Path" fill="#F79E1B"></path>
13
+ </g>
14
+ </g>
15
+ </g>
16
+ </svg>
modules/ppcp-wc-gateway/assets/images/mybank.svg ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>MyBank_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="MyBank_acceptancemark_80x50" fill-rule="nonzero">
6
+ <rect id="Rectangle" fill="#FFFFFF" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF"></path>
8
+ <g id="mybank-logo-color-" transform="translate(12.000000, 9.000000)">
9
+ <path d="M39.2777778,12.9544828 C37.0888889,12.9324138 36.0555556,14.1903448 36.0555556,14.1903448 C35.3888889,14.8965517 35.8222222,15.8455172 36.4666667,15.9117241 C37.4,16.0110345 37.4,15.2275862 38.8333333,14.8855172 C40.1,14.5765517 40.1555556,15.7462069 40.1555556,15.7462069 C34.7666667,15.6137931 35.0222222,20.1048276 36.8555556,21.0537931 C38.6111111,21.9696552 40.2555556,20.8110345 40.2555556,20.8110345 C40.2555556,20.8110345 40.3222222,21.4289655 41.1888889,21.4289655 C42.1888889,21.4289655 42.1888889,20.4468966 42.1888889,20.4468966 L42.1888889,16.0772414 C42.1222222,12.8662069 39.2777778,12.9544828 39.2777778,12.9544828 Z M38.8555556,19.2772414 C38.8555556,19.2772414 37.4444444,19.5641379 37.4555556,18.56 C37.4666667,17.5558621 40.0222222,17.622069 40.2888889,17.6993103 C40.2888889,17.6993103 40.3666667,18.8358621 38.8555556,19.2772414 L38.8555556,19.2772414 Z" id="Shape" fill="#334B66"></path>
10
+ <path d="M56.6777778,19.6634483 L54.4777778,16.3751724 L56.0888889,14.8634483 C56.0888889,14.8634483 56.8333333,14.1793103 56.2222222,13.4951724 C55.5444444,12.7448276 54.7333333,13.4841379 54.7333333,13.4841379 L52.7,15.36 L52.7,11.6082759 C52.7,11.0675862 52.2555556,10.6372414 51.7222222,10.6372414 C51.1777778,10.6372414 50.7444444,11.0786207 50.7444444,11.6082759 L50.7444444,20.4468966 C50.7444444,20.9875862 51.1888889,21.417931 51.7222222,21.417931 C52.2666667,21.417931 52.7,20.9765517 52.7,20.4468966 L52.7,18.0855172 L53.0666667,17.7213793 L55.0555556,20.8110345 C55.0555556,20.8110345 55.7,21.8813793 56.6555556,21.1972414 C57.3888889,20.6896552 56.6777778,19.6634483 56.6777778,19.6634483 Z" id="Path" fill="#334B66"></path>
11
+ <path d="M49.6666667,16.0662069 C49.6666667,12.8772414 46.9888889,12.4248276 45.1666667,13.44 C45.1666667,13.44 45.1666667,13.44 45.1666667,13.4510345 C44.9888889,12.9324138 44.4222222,12.6565517 43.9,12.8331034 C43.4888889,12.9765517 43.2222222,13.3517241 43.2222222,13.782069 L43.2222222,20.4358621 C43.2222222,20.9875862 43.6666667,21.4289655 44.2222222,21.4289655 C44.7777778,21.4289655 45.2222222,20.9875862 45.2222222,20.4358621 L45.2111111,15.9448276 C45.4,15.7351724 45.6111111,15.5475862 45.8444444,15.382069 C46.7888889,14.72 47.6777778,14.9517241 47.6777778,16.0772414 L47.7,20.457931 C47.7222222,20.9986207 48.1777778,21.4289655 48.7222222,21.4068966 C49.2444444,21.3848276 49.6555556,20.9765517 49.6777778,20.457931 L49.6666667,16.0662069 Z" id="Path" fill="#334B66"></path>
12
+ <path d="M20.8222222,21.5503448 C20.9555556,21.3517241 21.0444444,21.1310345 21.0888889,20.8993103 L18.8222222,15.017931 C18.8222222,15.017931 18.4111111,13.8813793 19.3222222,13.5393103 C20.2777778,13.1862069 20.6333333,14.0910345 20.7,14.2786207 L22.1333333,18.0634483 L23.4444444,14.2896552 C23.4444444,14.2896552 23.8222222,13.12 24.8666667,13.5282759 C25.7333333,13.8703448 25.2888889,15.0289655 25.2888889,15.0289655 C25.2888889,15.0289655 23.9444444,18.9682759 22.8222222,21.8151724 C22.1555556,23.5255172 21.5777778,23.6910345 20.9222222,23.8455172 C20.0444444,24.0551724 18.3888889,23.9558621 18.3888889,22.8744828 C18.3888889,22.0248276 19.2666667,21.9696552 19.6666667,21.9806897 C19.6888889,22.0027586 20.5111111,22.0689655 20.8222222,21.5503448 Z" id="Path" fill="#2ABAEA"></path>
13
+ <path d="M15.5555556,11.6634483 L13.4888889,17.3351724 L11.2333333,11.6965517 C11.2333333,11.6965517 10.9,10.626123 9.95555556,10.626123 C8.86666667,10.626123 8.9,11.4868966 8.87777778,11.6965517 C8.85555556,11.9062069 8.87777778,20.5131034 8.87777778,20.5131034 C8.87777778,20.5131034 8.86666667,21.417931 9.86666667,21.417931 C10.8888889,21.417931 10.8444444,20.502069 10.8444444,20.502069 C10.8444444,20.502069 10.8444444,15.9558621 10.8444444,15.9558621 L12.5111111,20.502069 C12.5111111,20.502069 12.7555556,21.3958621 13.5222222,21.3848276 C14.2888889,21.3737931 14.5111111,20.502069 14.5111111,20.502069 L15.9,15.9668966 L15.9,20.502069 C15.9,20.502069 15.9,21.417931 16.9111111,21.417931 C17.8888889,21.417931 17.8888889,20.502069 17.8888889,20.502069 L17.8888889,11.6965517 C17.8888889,11.6965517 17.8888889,10.6151724 16.8333333,10.626123 C15.9555556,10.6372414 15.6222222,11.4758621 15.5555556,11.6634483 C15.5555556,11.6855172 15.5555556,11.6965517 15.5555556,11.6965517" id="Path" fill="#2ABAEA"></path>
14
+ <path d="M57,24.8937931 L39.5222222,24.8937931 L26.6888889,24.8937931 L26.7,24.9048276 C21.7444444,30.6758621 13.0111111,31.36 7.2,26.4386207 C1.38888889,21.5172414 0.688888889,12.8551724 5.64444444,7.08413793 C10.6,1.31310345 19.3333333,0.617931034 25.1444444,5.55034483 C25.7111111,6.03586207 26.2444444,6.55448276 26.7222222,7.12827586 L29.5,7.12827586 C24.5777778,-0.19862069 14.5888889,-2.1737931 7.21111111,2.72551724 C-0.166666667,7.62482759 -2.14444444,17.5448276 2.78888889,24.8717241 C7.72222222,32.1986207 17.7,34.1627586 25.0777778,29.2634483 C26.1222222,28.5682759 27.0777778,27.7627586 27.9333333,26.8468966 L55.6777778,26.8248276 L57,24.8937931 Z" id="Path" fill="#2ABAEA"></path>
15
+ <path d="M33.7444444,15.6358621 C33.8,15.5586207 34.4666667,15.0289655 34.4111111,13.5944828 C34.3,10.7034483 31.7777778,10.7365517 31.2111111,10.7144828 C30.3111111,10.6924138 29.7666667,10.7034483 28.1111111,10.7144828 C26.7111111,10.7255172 26.7222208,11.9944828 26.7222208,11.9944828 L26.7222208,21.417931 L31.4333333,21.417931 C33.9555556,21.417931 34.8888889,20.0386207 34.8888889,18.1075862 C34.8888889,16.1765517 33.7444444,15.6358621 33.7444444,15.6358621 Z M28.7555556,12.7117241 L31.3555556,12.7117241 C31.8777778,12.7227586 32.4222222,12.9986207 32.4222222,13.7710345 C32.4222222,14.5765517 31.9444444,14.8303448 31.3555556,14.8303448 L28.7555556,14.8303448 L28.7555556,12.7117241 Z M31.5444444,19.497931 L28.7555556,19.497931 L28.7555556,16.8496552 L31.5444444,16.8496552 C32.2222222,16.8827586 32.8777778,17.2248276 32.8777778,18.1737931 C32.8777778,19.1448276 32.2777778,19.497931 31.5444444,19.497931 Z" id="Shape" fill="#334B66"></path>
16
+ </g>
17
+ </g>
18
+ </g>
19
+ </svg>
modules/ppcp-wc-gateway/assets/images/przelewy.svg ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Przelewy_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Przelewy_acceptancemark_80x50">
6
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
8
+ <g id="logo-przelewy-24" transform="translate(6.000000, 14.000000)">
9
+ <polygon id="Path" fill="#D13239" points="14.2599156 13.2573438 19.8691983 13.2501563 19.6647679 14.5295313 14.9736287 19.018125 18.9116034 19.0109375 18.6820675 20.3909375 12.8827004 20.3945312 13.1265823 18.9678125 17.6240506 14.6517188 14.0339662 14.6517188"></polygon>
10
+ <path d="M8.12341772,11.06875 C8.00147679,10.939375 7.8257384,10.83875 7.63206751,10.7596875 C7.42763713,10.680625 7.20168776,10.623125 6.97932489,10.5835938 C6.69957806,10.5332812 6.42700422,10.5117188 6.23333333,10.5045312 C6.05400844,10.4973438 5.93924051,10.4973438 5.93924051,10.4973438 L3.48607595,10.4973438 L1.66054852,10.4973438 L0.0251054852,20.3945312 L1.55295359,20.3945312 L2.15548523,16.7289063 L5.11793249,16.7432812 C5.11793249,16.7432812 6.27278481,16.79 7.09050633,16.3551563 C7.90822785,15.9203125 8.12700422,14.9320312 8.12700422,14.9320312 C8.12700422,14.9320312 8.21666667,14.5654687 8.29198312,14.1198437 C8.37447257,13.6275 8.45696203,13.038125 8.5,12.7254687 C8.51793249,12.5889062 8.52869198,12.5026562 8.52869198,12.5026562 C8.52869198,12.5026562 8.55021097,12.4020312 8.55021097,12.2439062 C8.55379747,12.0246875 8.52151899,11.6940625 8.34936709,11.3778125 C8.28839662,11.2664062 8.21666667,11.1657813 8.12341772,11.06875 Z M6.94704641,12.8153125 C6.94704641,12.8332813 6.81075949,13.6275 6.6314346,14.5690625 C6.56329114,14.9284375 6.2871308,15.1225 5.97151899,15.1907813 C5.4478903,15.3021875 4.88481013,15.280625 4.88481013,15.280625 L2.41012658,15.2734375 L2.95527426,11.9851563 L5.19683544,11.9923438 C5.19683544,11.9923438 5.34746835,11.98875 5.55907173,11.9923438 C5.79936709,11.9959375 6.1185654,12.0067188 6.38037975,12.0426563 C6.60632911,12.0714063 6.78565401,12.118125 6.84303797,12.19 C6.91835443,12.2834375 6.94704641,12.405625 6.95780591,12.5134375 C6.9721519,12.6715625 6.94704641,12.8045313 6.94704641,12.8153125 Z" id="Shape" fill="#D13239"></path>
11
+ <polygon id="Path" fill="#D13239" points="27.4761603 10.4973438 28.9466245 10.4973438 27.3004219 20.3945312 25.8263713 20.3909375"></polygon>
12
+ <polygon id="Path" fill="#D13239" points="35.3234177 13.2573438 36.7329114 13.25375 37.2314346 18.2778125 39.4012658 13.2465625 41.1407173 13.2501563 41.6535865 18.2957813 43.8198312 13.25375 45.2831224 13.25375 42.1772152 20.3873437 40.4413502 20.3873437 39.9392405 15.3920313 37.7478903 20.3873437 36.0407173 20.3945312"></polygon>
13
+ <g id="Group" transform="translate(19.259494, 13.153125)" fill="#D13239" fill-rule="nonzero">
14
+ <path d="M5.50168776,0.16171875 C5.08924051,0.02875 4.37552743,-1.91686944e-16 3.76940928,0.0071875 C3.18481013,0.014375 2.91582278,0.043125 2.69704641,0.08984375 C2.69704641,0.08984375 1.65696203,0.24078125 1.06518987,0.97390625 C0.473417722,1.70703125 0.297679325,3.30984375 0.297679325,3.30984375 C0.297679325,3.30984375 -0.0537974684,5.0815625 0.0502109705,5.67453125 C0.154219409,6.26390625 0.337130802,6.81375 1.00421941,7.06890625 C1.67130802,7.32765625 2.23797468,7.31328125 2.23797468,7.31328125 C2.23797468,7.31328125 3.42869198,7.40671875 4.32531646,7.1946875 C5.22194093,6.98265625 5.69535865,6.35015625 5.69535865,6.35015625 C5.69535865,6.35015625 5.90696203,6.07703125 6.05759494,5.75359375 C6.20822785,5.43015625 6.25485232,5.20375 6.26202532,5.175 L6.35527426,4.79046875 L4.83101266,4.7940625 C4.83101266,4.7940625 4.74852321,5.80390625 3.92362869,5.89734375 C3.10232068,5.99078125 2.66118143,5.95484375 2.49978903,5.94765625 C2.34198312,5.94046875 1.45970464,5.98 1.5314346,5.2396875 C1.5314346,5.22890625 1.5314346,5.21453125 1.5350211,5.19296875 C1.57447257,4.35203125 1.66772152,4.1328125 1.66772152,4.1328125 L6.4556962,4.1184375 L6.66012658,2.9325 C6.89683544,1.5884375 6.72827004,0.56421875 5.50168776,0.16171875 Z M5.18248945,2.76359375 L1.90084388,2.76 L2.02995781,2.23890625 C2.02995781,2.23890625 2.14472574,1.82921875 2.37067511,1.65671875 C2.60021097,1.48421875 2.8907173,1.451875 3.16329114,1.42671875 C3.43586498,1.4015625 4.16392405,1.34765625 4.7556962,1.46984375 C4.95295359,1.509375 5.13945148,1.62078125 5.18966245,1.78609375 C5.30443038,2.17421875 5.18248945,2.76359375 5.18248945,2.76359375 Z" id="Shape"></path>
15
+ <path d="M1.57836624,5.20744047 C1.57836624,5.22849976 1.56836624,5.24955904 1.56836624,5.27061832 C1.55836624,5.38293448 1.57836624,5.20042071 1.57836624,5.20744047 Z" id="Path"></path>
16
+ </g>
17
+ <g id="Group" transform="translate(28.297468, 13.153125)" fill="#D13239" fill-rule="nonzero">
18
+ <path d="M1.57029536,5.21103422 C1.57029536,5.23209351 1.56029536,5.25315279 1.56029536,5.27421207 C1.56029536,5.38652823 1.57029536,5.20401446 1.57029536,5.21103422 Z" id="Path"></path>
19
+ <path d="M5.49810127,0.1653125 C5.08565401,0.03234375 4.37194093,0.00359375 3.76582278,0.01078125 C3.18122363,0.01796875 2.91223629,0.04671875 2.69345992,0.0934375 C2.69345992,0.0934375 1.65337553,0.244375 1.06160338,0.9775 C0.469831224,1.710625 0.294092827,3.3134375 0.294092827,3.3134375 C0.294092827,3.3134375 -0.0573839662,5.08515625 0.0466244726,5.678125 C0.150632911,6.2675 0.333544304,6.81734375 1.00063291,7.0725 C1.66772152,7.33125 2.23438819,7.316875 2.23438819,7.316875 C2.23438819,7.316875 3.42510549,7.4103125 4.32172996,7.19828125 C5.21835443,6.98625 5.69177215,6.35375 5.69177215,6.35375 C5.69177215,6.35375 5.90337553,6.080625 6.05400844,5.7571875 C6.20464135,5.43375 6.25126582,5.20734375 6.25843882,5.17859375 L6.35168776,4.7940625 L4.82742616,4.79765625 C4.82742616,4.79765625 4.74493671,5.8075 3.92004219,5.9009375 C3.09873418,5.994375 2.65759494,5.9584375 2.49620253,5.95484375 C2.33839662,5.94765625 1.45611814,5.98359375 1.5278481,5.246875 C1.5278481,5.23609375 1.5278481,5.22171875 1.5314346,5.20015625 C1.57088608,4.35921875 1.66413502,4.14 1.66413502,4.14 L6.4521097,4.125625 L6.65654008,2.9396875 C6.89324895,1.59203125 6.72468354,0.56421875 5.49810127,0.1653125 Z M5.16455696,2.76359375 L1.88291139,2.76 L2.01202532,2.23890625 C2.01202532,2.23890625 2.12679325,1.82921875 2.35274262,1.65671875 C2.57869198,1.48421875 2.87278481,1.451875 3.14535865,1.42671875 C3.41793249,1.4015625 4.14599156,1.34765625 4.73776371,1.46984375 C4.9350211,1.509375 5.12151899,1.62078125 5.17172996,1.78609375 C5.28649789,2.170625 5.16455696,2.76359375 5.16455696,2.76359375 Z" id="Shape"></path>
20
+ </g>
21
+ <path d="M46.9759494,13.2573438 L47.9191983,18.4754687 L50.5839662,13.25375 L52.0831224,13.268125 L48.2419831,20.7251562 C48.2419831,20.7251562 47.5462025,22.0764062 47.1158228,22.4178125 C46.685443,22.7592187 46.4200422,22.91375 46.0685654,22.9496875 C45.7170886,22.985625 45.5736287,23.0107812 45.2364979,22.9496875 L44.8778481,22.885 L45.100211,21.5517187 C45.100211,21.5517187 45.6955696,21.663125 46.0470464,21.5229687 C46.4021097,21.3828125 46.685443,20.7790625 46.685443,20.7790625 L46.8647679,20.4771875 L45.4767932,13.25375 L46.9759494,13.2573438 L46.9759494,13.2573438 Z" id="Path" fill="#D13239"></path>
22
+ <path d="M52.62827,13.9653125 L54.1740506,13.9689062 L54.2672996,13.36875 C54.2672996,13.36875 54.4322785,12.2834375 54.8016878,12.075 C54.9200422,12.0067188 55.1101266,11.945625 55.328903,11.9060938 C55.7341772,11.8342187 56.2470464,11.8270313 56.6666667,11.8414063 C57.3086498,11.8629688 57.5525316,11.8701563 58.2052743,11.945625 C58.8580169,12.0210938 58.693038,12.6535937 58.693038,12.6535937 L58.5639241,13.59875 C58.5639241,13.59875 58.5065401,14.0228125 58.3559072,14.2851562 C58.2232068,14.51875 57.857384,14.676875 57.6457806,14.7451562 C57.1364979,14.9104687 55.3934599,15.3560937 55.3934599,15.3560937 L54.0234177,15.7514062 C54.0234177,15.7514062 53.1805907,15.9957813 52.7107595,16.516875 C52.2373418,17.0415625 52.0508439,17.6345313 51.9862869,17.9435937 C51.92173,18.2526563 51.5594937,20.3909375 51.5594937,20.3909375 L58.9548523,20.3945312 L59.2023207,18.9139062 L53.3527426,18.9210938 L53.4567511,18.3173438 C53.4567511,18.3173438 53.5248945,17.695625 53.7759494,17.4907813 C53.8548523,17.4260937 53.8943038,17.3398438 54.3605485,17.1745313 C54.6402954,17.0739063 55.5943038,16.81875 55.5943038,16.81875 L57.8,16.215 C57.8,16.215 59.0050633,15.9059375 59.478481,15.2446875 C59.9518987,14.5870313 60.1348101,13.325625 60.1348101,13.325625 C60.1348101,13.325625 60.2639241,12.1001563 60.1635021,11.715625 C60.0666667,11.3310938 59.7044304,10.8710938 59.2632911,10.6734375 C58.8221519,10.4757813 58.3630802,10.3607813 57.0324895,10.37875 C55.7018987,10.3967188 55.0419831,10.4578125 54.3677215,10.709375 C53.6934599,10.9573438 53.3025316,11.4101563 53.0550633,12.0498438 C52.7860759,12.6571875 52.62827,13.9653125 52.62827,13.9653125 L52.62827,13.9653125 Z" id="Path" fill="#B3B2B1"></path>
23
+ <path d="M66.5510549,16.718125 L67.5875527,10.49375 L65.7512658,10.49375 L60.0343882,16.64625 L59.7761603,18.2059375 L64.7757384,18.2059375 L64.4099156,20.3909375 L65.9449367,20.3945312 L66.307173,18.2059375 L67.7238397,18.2095312 L67.978481,16.718125 L66.5510549,16.718125 Z M65.0232068,16.7217188 L61.7917722,16.718125 L65.7261603,12.5170312 L65.0232068,16.7217188 Z" id="Shape" fill="#B3B2B1"></path>
24
+ <path d="M11.3656118,11.313125 L16.0746835,11.313125 C16.0746835,11.313125 17.1291139,10.4578125 17.878692,9.90796875 C18.62827,9.358125 19.9911392,8.49203125 19.9911392,8.49203125 L17.3299578,7.245 C17.3299578,7.245 15.0812236,8.639375 14.1272152,9.29703125 C13.2018987,9.904375 11.3656118,11.313125 11.3656118,11.313125 L11.3656118,11.313125 Z" id="Path" fill="#B3B2B1"></path>
25
+ <path d="M21.4867089,7.6115625 L19.3025316,6.138125 C19.3025316,6.138125 21.278692,5.01328125 23.9075949,3.96390625 C26.5329114,2.91453125 27.9352321,2.47609375 27.9352321,2.47609375 L28.3799578,4.5640625 C28.3799578,4.5640625 25.8514768,5.4121875 24.4025316,6.09859375 C22.9033755,6.73828125 21.4867089,7.6115625 21.4867089,7.6115625 L21.4867089,7.6115625 Z" id="Path" fill="#B3B2B1"></path>
26
+ <path d="M29.9938819,4.10765625 L29.6137131,1.969375 C29.6137131,1.969375 32.3107595,1.250625 34.77827,0.790625 C37.2493671,0.330625 40.5238397,0.11140625 40.5238397,0.11140625 L39.4407173,3.4140625 C39.4407173,3.4140625 36.5607595,3.01875 33.8565401,3.38890625 C31.7512658,3.64046875 29.9938819,4.10765625 29.9938819,4.10765625 L29.9938819,4.10765625 Z" id="Path" fill="#B3B2B1"></path>
27
+ <path d="M41.1550633,3.694375 L42.9770042,0.02515625 C42.9770042,0.02515625 46.9687764,-0.05390625 50.4118143,0.4815625 C53.8548523,1.0134375 57.0037975,1.8328125 56.935654,1.86875 L48.2061181,6.44359375 C48.2061181,6.44359375 46.1654008,5.14984375 43.6333333,4.355625 C42.1987342,3.9315625 41.1550633,3.694375 41.1550633,3.694375 L41.1550633,3.694375 Z" id="Path" fill="#B3B2B1"></path>
28
+ <path d="M49.7698312,7.4390625 L51.6886076,8.898125 L67.4584388,8.898125 C67.4584388,8.898125 67.4261603,8.3878125 67.0065401,7.661875 C66.7447257,7.2090625 66.2677215,6.7275 65.7691983,6.22796875 C65.5862869,6.04828125 64.8618143,5.48046875 64.3166667,5.1246875 C62.9251055,4.2190625 62.1468354,3.87046875 60.7014768,3.2128125 L49.7698312,7.4390625 L49.7698312,7.4390625 Z" id="Path" fill="#B3B2B1"></path>
29
+ <path d="M12.3877637,13.2501562 C11.7959916,13.2501562 11.2364979,13.48375 10.7594937,13.7460937 L10.8419831,13.2501562 L9.27468354,13.2501562 L8.01940928,20.355 L9.59029536,20.355 L10.2860759,16.4198437 C10.4295359,15.6220312 11.0248945,14.63375 12.1869198,14.63375 L12.9974684,14.6301562 L13.2413502,13.2501562 L12.3877637,13.2501562 Z" id="Path" fill="#D13239" fill-rule="nonzero"></path>
30
+ </g>
31
+ </g>
32
+ </g>
33
+ </svg>
modules/ppcp-wc-gateway/assets/images/sofort.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Sofort_acceptancemark_80x50</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Sofort_acceptancemark_80x50" fill-rule="nonzero">
6
+ <rect id="Rectangle" fill="#FFFFFF" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
7
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF"></path>
8
+ <g id="Sofort" transform="translate(7.000000, 19.000000)" fill="#EE7F00">
9
+ <path d="M21.8227633,-1.0658141e-14 C23.2022135,0.00138415272 24.193416,0.424150532 24.7729533,1.25538038 C25.7317243,2.63159729 25.2067815,4.6702697 24.8093341,5.76375035 C23.3037824,9.89318544 20.9254633,11.9868087 17.7407264,11.9868087 L17.7407264,11.9868087 C15.985713,11.9854707 15.1266523,11.2774304 14.712478,10.685336 C13.9828177,9.63711719 13.9744078,8.04640274 14.6882242,6.08607338 C15.067458,5.04745131 15.5504909,4.11960761 16.1146488,3.31822932 C16.9839315,2.08402648 18.0486854,1.15382971 19.2226747,0.596569823 C20.0442395,0.2078536 20.9199806,-1.0658141e-14 21.8227633,-1.0658141e-14 Z M41.0403735,-1.0658141e-14 C42.420753,0.00138415272 43.4112585,0.424150532 43.9915392,1.25538038 C44.9502638,2.63159729 44.4260179,4.6702697 44.0271301,5.76375035 C42.5230652,9.89318544 40.1446997,11.9868087 36.9585689,11.9868087 L36.9585689,11.9868087 C35.2042989,11.9854707 34.34482,11.2774304 33.9317609,10.685336 C33.2013571,9.63711719 33.1928543,8.04640274 33.9067636,6.08607338 C34.2857186,5.04745131 34.768194,4.11960761 35.3331882,3.31822932 C36.2031214,2.08402648 37.2672249,1.15382971 38.4419111,0.596569823 C39.262779,0.2078536 40.1385665,-1.0658141e-14 41.0403735,-1.0658141e-14 Z M65.9836614,0.172603844 L64.9816329,2.93357328 L60.8509489,2.93357328 L57.631318,11.8031778 L54.4155436,11.8031778 L57.6343846,2.93357328 L55.4994405,2.93357328 C55.5941792,2.11249388 55.4342524,1.3957796 55.0178479,0.79311951 C54.8546687,0.557951962 54.6589651,0.352682113 54.432224,0.172603844 L54.432224,0.172603844 L65.9836614,0.172603844 Z M50.9806945,0.172788398 C52.666524,0.174403243 53.7428473,0.549462492 54.2715072,1.31319183 C54.7073799,1.94293518 54.7302863,2.79972571 54.3374852,3.86109402 C53.6988466,5.58796295 52.1561707,6.43958598 51.0915561,6.83656098 C51.2718803,7.11657508 51.4069493,7.45260122 51.5367214,7.75167049 C51.6987921,8.12616289 51.8795942,8.67829206 52.0503414,9.25517174 L52.1623673,9.64174717 C52.4737636,10.737926 52.7264617,11.8011938 52.7264617,11.8011938 L52.7264617,11.8011938 L48.957216,11.8011938 C48.957216,11.8011938 48.0515525,7.87582899 47.9766536,7.70793126 L47.9766536,7.70793126 L46.4422482,11.8011938 L42.8562539,11.8011938 L47.0777738,0.172788398 Z M18.241183,0.16600605 C17.2104402,0.796395338 16.2693717,1.68894315 15.4916683,2.79202059 C15.4613742,2.83575982 15.4341931,2.88226735 15.4045495,2.92623727 L15.4045495,2.92623727 L11.1482286,2.92623727 C10.8530934,2.92623727 10.5999611,2.98506376 10.4071847,3.09182807 C10.215384,3.19882308 10.0825918,3.35472481 10.0279974,3.5488753 C9.97493623,3.73652027 10.0030001,3.92019734 10.0957409,4.07093157 C10.188807,4.2222656 10.3458996,4.34130273 10.550617,4.40008309 C10.6251907,4.42164819 10.7421501,4.45525541 10.8691991,4.49170625 L11.1271807,4.56567389 C11.2776223,4.60917583 11.4119441,4.64820517 11.4764184,4.66695648 L11.5168223,4.67871303 C12.3162241,4.90917446 12.8661642,5.26822367 13.1694769,5.76481153 C13.472836,6.26103028 13.5298001,6.89211165 13.3446437,7.66779083 C12.8532938,9.73068591 11.6922214,10.7617413 10.4817119,11.277615 C9.27124891,11.7934887 8.01139537,11.7934887 7.32280864,11.7934887 L0,11.7934887 L1.08166661,8.81414612 L7.92260393,8.81414612 C8.47040673,8.80962455 8.83207739,8.77723538 9.0770786,8.67849915 C9.32263736,8.57833263 9.45166607,8.41652518 9.53655459,8.16350206 C9.57075161,8.06545791 9.58524817,7.97211988 9.58287854,7.88561033 C9.58099792,7.80217528 9.56079612,7.72015385 9.52368425,7.64527528 C9.4669525,7.53380485 9.37746411,7.4538931 9.27742853,7.39437453 C9.17725356,7.33421003 9.06643849,7.29416187 8.96626353,7.26338755 C8.74187751,7.19600132 8.51716263,7.12969962 8.29212689,7.0644848 C8.05985664,6.99841458 7.86814889,6.9433253 7.85383818,6.93958809 C7.48882216,6.82816379 7.14982561,6.65320689 6.86686386,6.43944757 C6.58413442,6.22504231 6.35799733,5.97031207 6.21851437,5.70067912 C6.10556199,5.47912241 6.05384829,5.22471514 6.06309449,4.92421558 C6.07206192,4.6258384 6.14333669,4.28183031 6.27770867,3.88185631 C6.89785491,2.02381583 7.70273939,1.09454183 8.61509358,0.629927904 C9.52758717,0.16600605 10.5451808,0.16600605 11.5934868,0.16600605 Z M37.5001921,0.16600605 C36.4694028,0.796395338 35.3688256,1.68894315 34.5916797,2.79197445 C34.5613392,2.83571368 34.5340187,2.88319012 34.5037246,2.92692935 L34.5037246,2.92692935 L32.5959613,2.92604571 C32.5289878,2.92602067 32.462549,2.92599624 32.3969068,2.92597249 L30.8304722,2.92549905 C30.4656885,2.92549905 30.2169702,3.12726238 30.1121489,3.38023936 L30.1121489,3.38023936 L29.6123892,4.79392067 L32.7175808,4.79604304 L31.8316178,7.23718092 L28.7160648,7.23464331 L27.0626668,11.7934426 L23.537493,11.7934426 L26.7554047,2.92623727 C27.4215032,1.12702328 28.8312475,0.16600605 30.7252327,0.16600605 L30.7252327,0.16600605 Z M20.977084,2.63062839 C19.8190317,2.63062839 18.861701,3.92697969 18.1231197,5.95360996 C17.1333576,8.66779504 17.5040421,9.33864772 18.5615942,9.34026257 L18.5615942,9.34026257 C19.6490223,9.34026257 20.3704122,8.65349212 21.363752,5.92629602 C22.3307935,3.27213703 22.0784046,2.63228937 20.977084,2.63062839 L20.977084,2.63062839 Z M40.196274,2.63062839 C39.0374317,2.63062839 38.079497,3.92697969 37.3416591,5.95360996 C36.352594,8.66779504 36.7218846,9.33864772 37.7799478,9.34026257 L37.7799478,9.34026257 C38.8675153,9.34026257 39.5889516,8.65349212 40.5815945,5.92629602 C41.549333,3.27213703 41.2968976,2.63228937 40.196274,2.63062839 L40.196274,2.63062839 Z M50.0317737,2.57309377 L49.440156,2.57309377 L48.4003993,5.38527686 L49.0087438,5.38624576 C50.1889127,5.38624576 50.8069681,4.811361 51.1512615,3.882087 C51.5184148,2.89098751 51.1141837,2.57383199 50.0317737,2.57309377 L50.0317737,2.57309377 Z" id="Combined-Shape"></path>
10
+ </g>
11
+ </g>
12
+ </g>
13
+ </svg>
modules/ppcp-wc-gateway/assets/images/visa.svg ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="80px" height="50px" viewBox="0 0 80 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Visa_acceptancemark_80x50</title>
4
+ <defs>
5
+ <linearGradient x1="0%" y1="50.0001434%" x2="100%" y2="50.0001434%" id="linearGradient-1">
6
+ <stop stop-color="#1D1C45" offset="0%"></stop>
7
+ <stop stop-color="#174489" offset="100%"></stop>
8
+ </linearGradient>
9
+ </defs>
10
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
11
+ <g id="Visa_acceptancemark_80x50">
12
+ <rect id="Rectangle" fill="#FFFFFF" fill-rule="nonzero" x="0.38" y="0.38" width="79.25" height="49.25"></rect>
13
+ <path d="M79.25,0.75 L79.25,49.25 L0.75,49.25 L0.75,0.75 L79.25,0.75 M80,0 L0,0 L0,50 L80,50 L80,0 Z" id="Shape" fill="#BFBFBF" fill-rule="nonzero"></path>
14
+ <g id="Visa" transform="translate(9.000000, 15.000000)" fill="url(#linearGradient-1)">
15
+ <path d="M30.6983241,0.352571429 L26.5555185,19.6294286 L21.545,19.6294286 L25.6895278,0.352571429 L30.6983241,0.352571429 Z M51.7760278,12.7991429 L54.4133241,5.56114286 L55.931463,12.7991429 L51.7760278,12.7991429 Z M57.3663611,19.6294286 L62,19.6294286 L57.9553611,0.352571429 L53.6793704,0.352571429 C52.7175093,0.352571429 51.9066296,0.908857143 51.5466852,1.76628571 L44.0294722,19.6294286 L49.2888519,19.6294286 L50.3339537,16.7494286 L56.761,16.7494286 L57.3663611,19.6294286 Z M44.2898148,13.3351429 C44.3122037,8.248 37.2223889,7.96714286 37.2711852,5.694 C37.2866852,5.00285714 37.9480185,4.268 39.3961204,4.07971429 C40.1128519,3.98657143 42.0925463,3.91428571 44.3351667,4.942 L45.2155093,0.854571429 C44.0090926,0.418857143 42.4588056,0 40.5281944,0 C35.5768056,0 32.0910278,2.62057143 32.0631852,6.37171429 C32.0301759,9.14828571 34.5506481,10.6954286 36.4496852,11.6185714 C38.4006759,12.5631429 39.0551204,13.1691429 39.0479444,14.014 C39.0333056,15.308 37.4910556,15.8782857 36.0492685,15.9005714 C33.5305185,15.9397143 32.0686389,15.2228571 30.9038426,14.6825714 L29.9968056,18.9068571 C31.1661944,19.4417143 33.3270093,19.908 35.5679074,19.9308571 C40.8313056,19.9308571 44.2734537,17.344 44.2898148,13.3351429 L44.2898148,13.3351429 Z M23.5396204,0.352571429 L15.4225,19.6294286 L10.1269537,19.6294286 L6.1325463,4.24514286 C5.89,3.298 5.67960185,2.95028571 4.9422037,2.552 C3.73808333,1.90085714 1.74949074,1.29057143 0,0.911428571 L0.117972222,0.352571429 L8.64325926,0.352571429 C9.72912037,0.352571429 10.7067685,1.07171429 10.9533333,2.31771429 L13.0630556,13.4728571 L18.2773704,0.352571429 L23.5396204,0.352571429 L23.5396204,0.352571429 Z" id="Fill-1"></path>
16
+ </g>
17
+ </g>
18
+ </g>
19
+ </svg>
modules/ppcp-wc-gateway/extensions.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The extensions of the gateway module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\Onboarding\Environment;
14
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
15
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
16
+ use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
17
+ use WooCommerce\WooCommerce\Logging\Logger\WooCommerceLogger;
18
+ use Psr\Container\ContainerInterface;
19
+ use Psr\Log\LoggerInterface;
20
+
21
+ return array(
22
+
23
+ 'api.merchant_email' => static function ( $container ): string {
24
+ $settings = $container->get( 'wcgateway.settings' );
25
+ return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
26
+ },
27
+ 'api.merchant_id' => static function ( $container ): string {
28
+ $settings = $container->get( 'wcgateway.settings' );
29
+ return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
30
+ },
31
+ 'api.partner_merchant_id' => static function ( $container ): string {
32
+ $environment = $container->get( 'onboarding.environment' );
33
+
34
+ /**
35
+ * The environment.
36
+ *
37
+ * @var Environment $environment
38
+ */
39
+ return $environment->current_environment_is( Environment::SANDBOX ) ?
40
+ (string) $container->get( 'api.partner_merchant_id-sandbox' ) : (string) $container->get( 'api.partner_merchant_id-production' );
41
+ },
42
+ 'api.key' => static function ( $container ): string {
43
+ $settings = $container->get( 'wcgateway.settings' );
44
+ $key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
45
+ return $key;
46
+ },
47
+ 'api.secret' => static function ( $container ): string {
48
+ $settings = $container->get( 'wcgateway.settings' );
49
+ return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
50
+ },
51
+ 'api.prefix' => static function ( $container ): string {
52
+ $settings = $container->get( 'wcgateway.settings' );
53
+ return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
54
+ },
55
+ 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
56
+ $order_factory = $container->get( 'api.factory.order' );
57
+ $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
58
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
59
+ /**
60
+ * The session handler.
61
+ *
62
+ * @var SessionHandler $session_handler
63
+ */
64
+ $session_handler = $container->get( 'session.handler' );
65
+ $bn_code = $session_handler->bn_code();
66
+
67
+ /**
68
+ * The settings.
69
+ *
70
+ * @var Settings $settings
71
+ */
72
+ $settings = $container->get( 'wcgateway.settings' );
73
+ $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
74
+ $application_context_repository = $container->get( 'api.repository.application-context' );
75
+ $pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
76
+ return new OrderEndpoint(
77
+ $container->get( 'api.host' ),
78
+ $container->get( 'api.bearer' ),
79
+ $order_factory,
80
+ $patch_collection_factory,
81
+ $intent,
82
+ $logger,
83
+ $application_context_repository,
84
+ $pay_pal_request_id_repository,
85
+ $bn_code
86
+ );
87
+ },
88
+ 'woocommerce.logger.woocommerce' => function ( $container ): LoggerInterface {
89
+ $settings = $container->get( 'wcgateway.settings' );
90
+ if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
91
+ return new NullLogger();
92
+ }
93
+
94
+ $source = $container->get( 'woocommerce.logger.source' );
95
+ return new WooCommerceLogger(
96
+ wc_get_logger(),
97
+ $source
98
+ );
99
+ },
100
+ );
modules/ppcp-wc-gateway/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new WcGatewayModule();
16
+ };
modules/ppcp-wc-gateway/services.php ADDED
@@ -0,0 +1,1837 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The services of the Gateway module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway;
11
+
12
+ use Dhii\Data\Container\ContainerInterface;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
16
+ use WooCommerce\PayPalCommerce\Onboarding\State;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
19
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderAuthorizeAction;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
21
+ use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
23
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
24
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
25
+ use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
26
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
27
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
28
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
29
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
30
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
31
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
32
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
33
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
34
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
35
+ use WpOop\TransientCache\CachePoolFactory;
36
+
37
+ return array(
38
+ 'wcgateway.paypal-gateway' => static function ( $container ): PayPalGateway {
39
+ $order_processor = $container->get( 'wcgateway.order-processor' );
40
+ $settings_renderer = $container->get( 'wcgateway.settings.render' );
41
+ $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
42
+ $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
43
+ $settings = $container->get( 'wcgateway.settings' );
44
+ $session_handler = $container->get( 'session.handler' );
45
+ $refund_processor = $container->get( 'wcgateway.processor.refunds' );
46
+ $state = $container->get( 'onboarding.state' );
47
+
48
+ return new PayPalGateway(
49
+ $settings_renderer,
50
+ $order_processor,
51
+ $authorized_payments,
52
+ $notice,
53
+ $settings,
54
+ $session_handler,
55
+ $refund_processor,
56
+ $state
57
+ );
58
+ },
59
+ 'wcgateway.credit-card-gateway' => static function ( $container ): CreditCardGateway {
60
+ $order_processor = $container->get( 'wcgateway.order-processor' );
61
+ $settings_renderer = $container->get( 'wcgateway.settings.render' );
62
+ $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
63
+ $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
64
+ $settings = $container->get( 'wcgateway.settings' );
65
+ $module_url = $container->get( 'wcgateway.url' );
66
+ $session_handler = $container->get( 'session.handler' );
67
+ $refund_processor = $container->get( 'wcgateway.processor.refunds' );
68
+ $state = $container->get( 'onboarding.state' );
69
+ return new CreditCardGateway(
70
+ $settings_renderer,
71
+ $order_processor,
72
+ $authorized_payments,
73
+ $notice,
74
+ $settings,
75
+ $module_url,
76
+ $session_handler,
77
+ $refund_processor,
78
+ $state
79
+ );
80
+ },
81
+ 'wcgateway.disabler' => static function ( $container ): DisableGateways {
82
+ $session_handler = $container->get( 'session.handler' );
83
+ $settings = $container->get( 'wcgateway.settings' );
84
+ return new DisableGateways( $session_handler, $settings );
85
+ },
86
+ 'wcgateway.settings' => static function ( $container ): Settings {
87
+ return new Settings();
88
+ },
89
+ 'wcgateway.notice.connect' => static function ( $container ): ConnectAdminNotice {
90
+ $state = $container->get( 'onboarding.state' );
91
+ $settings = $container->get( 'wcgateway.settings' );
92
+ return new ConnectAdminNotice( $state, $settings );
93
+ },
94
+ 'wcgateway.notice.authorize-order-action' =>
95
+ static function ( $container ): AuthorizeOrderActionNotice {
96
+ return new AuthorizeOrderActionNotice();
97
+ },
98
+ 'wcgateway.settings.sections-renderer' => static function ( $container ): SectionsRenderer {
99
+ return new SectionsRenderer();
100
+ },
101
+ 'wcgateway.settings.render' => static function ( $container ): SettingsRenderer {
102
+ $settings = $container->get( 'wcgateway.settings' );
103
+ $state = $container->get( 'onboarding.state' );
104
+ $fields = $container->get( 'wcgateway.settings.fields' );
105
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
106
+ $messages_apply = $container->get( 'button.helper.messages-apply' );
107
+ $dcc_product_status = $container->get( 'wcgateway.helper.dcc-product-status' );
108
+ return new SettingsRenderer(
109
+ $settings,
110
+ $state,
111
+ $fields,
112
+ $dcc_applies,
113
+ $messages_apply,
114
+ $dcc_product_status
115
+ );
116
+ },
117
+ 'wcgateway.settings.listener' => static function ( $container ): SettingsListener {
118
+ $settings = $container->get( 'wcgateway.settings' );
119
+ $fields = $container->get( 'wcgateway.settings.fields' );
120
+ $webhook_registrar = $container->get( 'webhook.registrar' );
121
+ $state = $container->get( 'onboarding.state' );
122
+ $cache = new Cache( 'ppcp-paypal-bearer' );
123
+ return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state );
124
+ },
125
+ 'wcgateway.order-processor' => static function ( $container ): OrderProcessor {
126
+
127
+ $session_handler = $container->get( 'session.handler' );
128
+ $cart_repository = $container->get( 'api.repository.cart' );
129
+ $order_endpoint = $container->get( 'api.endpoint.order' );
130
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
131
+ $order_factory = $container->get( 'api.factory.order' );
132
+ $threed_secure = $container->get( 'button.helper.three-d-secure' );
133
+ $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
134
+ $settings = $container->get( 'wcgateway.settings' );
135
+ return new OrderProcessor(
136
+ $session_handler,
137
+ $cart_repository,
138
+ $order_endpoint,
139
+ $payments_endpoint,
140
+ $order_factory,
141
+ $threed_secure,
142
+ $authorized_payments_processor,
143
+ $settings
144
+ );
145
+ },
146
+ 'wcgateway.processor.refunds' => static function ( $container ): RefundProcessor {
147
+ $order_endpoint = $container->get( 'api.endpoint.order' );
148
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
149
+ return new RefundProcessor( $order_endpoint, $payments_endpoint );
150
+ },
151
+ 'wcgateway.processor.authorized-payments' => static function ( $container ): AuthorizedPaymentsProcessor {
152
+ $order_endpoint = $container->get( 'api.endpoint.order' );
153
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
154
+ return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint );
155
+ },
156
+ 'wcgateway.admin.render-authorize-action' => static function ( $container ): RenderAuthorizeAction {
157
+
158
+ return new RenderAuthorizeAction();
159
+ },
160
+ 'wcgateway.admin.order-payment-status' => static function ( $container ): PaymentStatusOrderDetail {
161
+ return new PaymentStatusOrderDetail();
162
+ },
163
+ 'wcgateway.admin.orders-payment-status-column' => static function ( $container ): OrderTablePaymentStatusColumn {
164
+ $settings = $container->get( 'wcgateway.settings' );
165
+ return new OrderTablePaymentStatusColumn( $settings );
166
+ },
167
+
168
+ 'wcgateway.settings.fields' => static function ( $container ): array {
169
+
170
+ $state = $container->get( 'onboarding.state' );
171
+ /**
172
+ * The state.
173
+ *
174
+ * @var State $state
175
+ */
176
+
177
+ $settings = $container->get( 'wcgateway.settings' );
178
+
179
+ $fields = array(
180
+ 'sandbox_on' => array(
181
+ 'title' => __( 'Sandbox', 'woocommerce-paypal-payments' ),
182
+ 'type' => 'checkbox',
183
+ 'label' => __( 'To test your WooCommerce installation, you can use the sandbox mode.', 'woocommerce-paypal-payments' ),
184
+ 'default' => 0,
185
+ 'screens' => array(
186
+ State::STATE_START,
187
+ State::STATE_PROGRESSIVE,
188
+ State::STATE_ONBOARDED,
189
+ ),
190
+ 'requirements' => array(),
191
+ 'gateway' => 'paypal',
192
+ ),
193
+
194
+ // Production credentials.
195
+ 'credentials_production_heading' => array(
196
+ 'heading' => __( 'API Credentials', 'woocommerce-paypal-payments' ),
197
+ 'type' => 'ppcp-heading',
198
+ 'screens' => array(
199
+ State::STATE_PROGRESSIVE,
200
+ State::STATE_ONBOARDED,
201
+ ),
202
+ 'requirements' => array(),
203
+ 'gateway' => 'paypal',
204
+ ),
205
+ 'ppcp_onboarding_production' => array(
206
+ 'title' => __( 'Connect to PayPal', 'woocommerce-paypal-payments' ),
207
+ 'type' => 'ppcp_onboarding',
208
+ 'screens' => array(
209
+ State::STATE_START,
210
+ State::STATE_PROGRESSIVE,
211
+ State::STATE_ONBOARDED,
212
+ ),
213
+ 'env' => 'production',
214
+ 'requirements' => array(),
215
+ 'gateway' => 'paypal',
216
+ 'description' => __( 'Setup or link an existing PayPal account.', 'woocommerce-paypal-payments' ),
217
+ ),
218
+ 'ppcp_disconnect_production' => array(
219
+ 'title' => __( 'Disconnect from PayPal', 'woocommerce-paypal-payments' ),
220
+ 'type' => 'ppcp-text',
221
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
222
+ 'text' => '<button type="button" class="button ppcp-disconnect production">' . esc_html__( 'Disconnect', 'woocommerce-paypal-payments' ) . '</button>',
223
+ 'screens' => array(
224
+ State::STATE_START,
225
+ State::STATE_PROGRESSIVE,
226
+ State::STATE_ONBOARDED,
227
+ ),
228
+ 'env' => 'production',
229
+ 'requirements' => array(),
230
+ 'gateway' => 'paypal',
231
+ 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ),
232
+ ),
233
+ 'production_toggle_manual_input' => array(
234
+ 'type' => 'ppcp-text',
235
+ 'title' => __( 'Manual mode', 'woocommerce-paypal-payments' ),
236
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
237
+ 'text' => '<button type="button" id="ppcp[production_toggle_manual_input]" class="production-toggle">' . __( 'Toggle to manual credential input', 'woocommerce-paypal-payments' ) . '</button>',
238
+ 'screens' => array(
239
+ State::STATE_START,
240
+ State::STATE_PROGRESSIVE,
241
+ State::STATE_ONBOARDED,
242
+ ),
243
+ 'requirements' => array(),
244
+ 'gateway' => 'paypal',
245
+ ),
246
+ 'merchant_email_production' => array(
247
+ 'title' => __( 'Live Email address', 'woocommerce-paypal-payments' ),
248
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
249
+ 'type' => 'text',
250
+ 'required' => true,
251
+ 'desc_tip' => true,
252
+ 'description' => __( 'The email address of your PayPal account.', 'woocommerce-paypal-payments' ),
253
+ 'default' => '',
254
+ 'screens' => array(
255
+ State::STATE_START,
256
+ State::STATE_PROGRESSIVE,
257
+ State::STATE_ONBOARDED,
258
+ ),
259
+ 'requirements' => array(),
260
+ 'gateway' => 'paypal',
261
+ ),
262
+ 'merchant_id_production' => array(
263
+ 'title' => __( 'Live Merchant Id', 'woocommerce-paypal-payments' ),
264
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
265
+ 'type' => 'ppcp-text-input',
266
+ 'desc_tip' => true,
267
+ 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ),
268
+ 'default' => false,
269
+ 'screens' => array(
270
+ State::STATE_START,
271
+ State::STATE_PROGRESSIVE,
272
+ State::STATE_ONBOARDED,
273
+ ),
274
+ 'requirements' => array(),
275
+ 'gateway' => 'paypal',
276
+ ),
277
+ 'client_id_production' => array(
278
+ 'title' => __( 'Live Client Id', 'woocommerce-paypal-payments' ),
279
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
280
+ 'type' => 'ppcp-text-input',
281
+ 'desc_tip' => true,
282
+ 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
283
+ 'default' => false,
284
+ 'screens' => array(
285
+ State::STATE_START,
286
+ State::STATE_PROGRESSIVE,
287
+ State::STATE_ONBOARDED,
288
+ ),
289
+ 'requirements' => array(),
290
+ 'gateway' => 'paypal',
291
+ ),
292
+ 'client_secret_production' => array(
293
+ 'title' => __( 'Live Secret Key', 'woocommerce-paypal-payments' ),
294
+ 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ),
295
+ 'type' => 'ppcp-password',
296
+ 'desc_tip' => true,
297
+ 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ),
298
+ 'default' => false,
299
+ 'screens' => array(
300
+ State::STATE_START,
301
+ State::STATE_PROGRESSIVE,
302
+ State::STATE_ONBOARDED,
303
+ ),
304
+ 'requirements' => array(),
305
+ 'gateway' => 'paypal',
306
+ ),
307
+
308
+ // Sandbox credentials.
309
+ 'credentials_sandbox_heading' => array(
310
+ 'heading' => __( 'Sandbox API Credentials', 'woocommerce-paypal-payments' ),
311
+ 'type' => 'ppcp-heading',
312
+ 'screens' => array(
313
+ State::STATE_PROGRESSIVE,
314
+ State::STATE_ONBOARDED,
315
+ ),
316
+ 'requirements' => array(),
317
+ 'gateway' => 'paypal',
318
+ 'description' => __( 'Your account setting is set to sandbox, no real charging takes place. To accept live payments, switch your environment to live and connect your PayPal account.', 'woocommerce-paypal-payments' ),
319
+ ),
320
+
321
+ 'ppcp_onboarding_sandbox' => array(
322
+ 'title' => __( 'Connect to PayPal', 'woocommerce-paypal-payments' ),
323
+ 'type' => 'ppcp_onboarding',
324
+ 'screens' => array(
325
+ State::STATE_START,
326
+ State::STATE_PROGRESSIVE,
327
+ State::STATE_ONBOARDED,
328
+ ),
329
+ 'env' => 'sandbox',
330
+ 'requirements' => array(),
331
+ 'gateway' => 'paypal',
332
+ 'description' => __( 'Setup or link an existing PayPal Sandbox account.', 'woocommerce-paypal-payments' ),
333
+ ),
334
+ 'ppcp_disconnect_sandbox' => array(
335
+ 'title' => __( 'Disconnect from PayPal Sandbox', 'woocommerce-paypal-payments' ),
336
+ 'type' => 'ppcp-text',
337
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
338
+ 'text' => '<button type="button" class="button ppcp-disconnect sandbox">' . esc_html__( 'Disconnect', 'woocommerce-paypal-payments' ) . '</button>',
339
+ 'screens' => array(
340
+ State::STATE_START,
341
+ State::STATE_PROGRESSIVE,
342
+ State::STATE_ONBOARDED,
343
+ ),
344
+ 'env' => 'production',
345
+ 'requirements' => array(),
346
+ 'gateway' => 'paypal',
347
+ 'description' => __( 'Click to reset current credentials and use another account.', 'woocommerce-paypal-payments' ),
348
+ ),
349
+ 'sandbox_toggle_manual_input' => array(
350
+ 'type' => 'ppcp-text',
351
+ 'title' => __( 'Manual mode', 'woocommerce-paypal-payments' ),
352
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
353
+ 'text' => '<button type="button" id="ppcp[sandbox_toggle_manual_input]" class="sandbox-toggle">' . __( 'Toggle to manual credential input', 'woocommerce-paypal-payments' ) . '</button>',
354
+ 'screens' => array(
355
+ State::STATE_START,
356
+ State::STATE_PROGRESSIVE,
357
+ State::STATE_ONBOARDED,
358
+ ),
359
+ 'requirements' => array(),
360
+ 'gateway' => 'paypal',
361
+ ),
362
+ 'merchant_email_sandbox' => array(
363
+ 'title' => __( 'Sandbox Email address', 'woocommerce-paypal-payments' ),
364
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
365
+ 'type' => 'text',
366
+ 'required' => true,
367
+ 'desc_tip' => true,
368
+ 'description' => __( 'The email address of your PayPal account.', 'woocommerce-paypal-payments' ),
369
+ 'default' => '',
370
+ 'screens' => array(
371
+ State::STATE_START,
372
+ State::STATE_PROGRESSIVE,
373
+ State::STATE_ONBOARDED,
374
+ ),
375
+ 'requirements' => array(),
376
+ 'gateway' => 'paypal',
377
+ ),
378
+ 'merchant_id_sandbox' => array(
379
+ 'title' => __( 'Sandbox Merchant Id', 'woocommerce-paypal-payments' ),
380
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
381
+ 'type' => 'ppcp-text-input',
382
+ 'desc_tip' => true,
383
+ 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ),
384
+ 'default' => false,
385
+ 'screens' => array(
386
+ State::STATE_START,
387
+ State::STATE_PROGRESSIVE,
388
+ State::STATE_ONBOARDED,
389
+ ),
390
+ 'requirements' => array(),
391
+ 'gateway' => 'paypal',
392
+ ),
393
+ 'client_id_sandbox' => array(
394
+ 'title' => __( 'Sandbox Client Id', 'woocommerce-paypal-payments' ),
395
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
396
+ 'type' => 'ppcp-text-input',
397
+ 'desc_tip' => true,
398
+ 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
399
+ 'default' => false,
400
+ 'screens' => array(
401
+ State::STATE_START,
402
+ State::STATE_PROGRESSIVE,
403
+ State::STATE_ONBOARDED,
404
+ ),
405
+ 'requirements' => array(),
406
+ 'gateway' => 'paypal',
407
+ ),
408
+ 'client_secret_sandbox' => array(
409
+ 'title' => __( 'Sandbox Secret Key', 'woocommerce-paypal-payments' ),
410
+ 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ),
411
+ 'type' => 'ppcp-password',
412
+ 'desc_tip' => true,
413
+ 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ),
414
+ 'default' => false,
415
+ 'screens' => array(
416
+ State::STATE_START,
417
+ State::STATE_PROGRESSIVE,
418
+ State::STATE_ONBOARDED,
419
+ ),
420
+ 'requirements' => array(),
421
+ 'gateway' => 'paypal',
422
+ ),
423
+
424
+ 'checkout_settings_heading' => array(
425
+ 'heading' => __( 'PayPal Checkout Settings', 'woocommerce-paypal-payments' ),
426
+ 'type' => 'ppcp-heading',
427
+ 'screens' => array(
428
+ State::STATE_PROGRESSIVE,
429
+ State::STATE_ONBOARDED,
430
+ ),
431
+ 'requirements' => array(),
432
+ 'gateway' => 'paypal',
433
+ ),
434
+ 'title' => array(
435
+ 'title' => __( 'Title', 'woocommerce-paypal-payments' ),
436
+ 'type' => 'text',
437
+ 'description' => __(
438
+ 'This controls the title which the user sees during checkout.',
439
+ 'woocommerce-paypal-payments'
440
+ ),
441
+ 'default' => __( 'PayPal', 'woocommerce-paypal-payments' ),
442
+ 'desc_tip' => true,
443
+ 'screens' => array(
444
+ State::STATE_PROGRESSIVE,
445
+ State::STATE_ONBOARDED,
446
+ ),
447
+ 'requirements' => array(),
448
+ 'gateway' => 'paypal',
449
+ ),
450
+ 'dcc_enabled' => array(
451
+ 'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
452
+ 'desc_tip' => true,
453
+ 'description' => __( 'Once enabled, the Credit Card option will show up in the checkout.', 'woocommerce-paypal-payments' ),
454
+ 'label' => __( 'Enable PayPal Card Processing', 'woocommerce-paypal-payments' ),
455
+ 'type' => 'checkbox',
456
+ 'default' => false,
457
+ 'gateway' => 'dcc',
458
+ 'requirements' => array(
459
+ 'dcc',
460
+ ),
461
+ 'screens' => array(
462
+ State::STATE_ONBOARDED,
463
+ ),
464
+ ),
465
+ 'dcc_gateway_title' => array(
466
+ 'title' => __( 'Title', 'woocommerce-paypal-payments' ),
467
+ 'type' => 'text',
468
+ 'description' => __(
469
+ 'This controls the title which the user sees during checkout.',
470
+ 'woocommerce-paypal-payments'
471
+ ),
472
+ 'default' => __( 'Credit Cards', 'woocommerce-paypal-payments' ),
473
+ 'desc_tip' => true,
474
+ 'screens' => array(
475
+ State::STATE_ONBOARDED,
476
+ ),
477
+ 'requirements' => array(
478
+ 'dcc',
479
+ ),
480
+ 'gateway' => 'dcc',
481
+ ),
482
+ 'description' => array(
483
+ 'title' => __( 'Description', 'woocommerce-paypal-payments' ),
484
+ 'type' => 'text',
485
+ 'desc_tip' => true,
486
+ 'description' => __(
487
+ 'This controls the description which the user sees during checkout.',
488
+ 'woocommerce-paypal-payments'
489
+ ),
490
+ 'default' => __(
491
+ 'Pay via PayPal; you can pay with your credit card if you don\'t have a PayPal account.',
492
+ 'woocommerce-paypal-payments'
493
+ ),
494
+ 'screens' => array(
495
+ State::STATE_PROGRESSIVE,
496
+ State::STATE_ONBOARDED,
497
+ ),
498
+ 'requirements' => array(),
499
+ 'gateway' => 'paypal',
500
+ ),
501
+ 'intent' => array(
502
+ 'title' => __( 'Intent', 'woocommerce-paypal-payments' ),
503
+ 'type' => 'select',
504
+ 'class' => array(),
505
+ 'input_class' => array( 'wc-enhanced-select' ),
506
+ 'default' => 'capture',
507
+ 'desc_tip' => true,
508
+ 'description' => __(
509
+ 'The intent to either capture payment immediately or authorize a payment for an order after order creation.',
510
+ 'woocommerce-paypal-payments'
511
+ ),
512
+ 'options' => array(
513
+ 'capture' => __( 'Capture', 'woocommerce-paypal-payments' ),
514
+ 'authorize' => __( 'Authorize', 'woocommerce-paypal-payments' ),
515
+ ),
516
+ 'screens' => array(
517
+ State::STATE_ONBOARDED,
518
+ ),
519
+ 'requirements' => array(),
520
+ 'gateway' => 'paypal',
521
+ ),
522
+ 'capture_for_virtual_only' => array(
523
+ 'title' => __( 'Capture Virtual-Only Orders ', 'woocommerce-paypal-payments' ),
524
+ 'type' => 'checkbox',
525
+ 'default' => false,
526
+ 'desc_tip' => true,
527
+ 'description' => __(
528
+ 'If the order contains exclusively virtual items, enable this to immediately capture, rather than authorize, the transaction.',
529
+ 'woocommerce-paypal-payments'
530
+ ),
531
+ 'label' => __( 'Capture Virtual-Only Orders', 'woocommerce-paypal-payments' ),
532
+ 'screens' => array(
533
+ State::STATE_ONBOARDED,
534
+ ),
535
+ 'requirements' => array(),
536
+ 'gateway' => 'paypal',
537
+ ),
538
+ 'payee_preferred' => array(
539
+ 'title' => __( 'Instant Payments ', 'woocommerce-paypal-payments' ),
540
+ 'type' => 'checkbox',
541
+ 'default' => false,
542
+ 'desc_tip' => true,
543
+ 'description' => __(
544
+ 'If you enable this setting, PayPal will be instructed not to allow the buyer to use funding sources that take additional time to complete (for example, eChecks). Instead, the buyer will be required to use an instant funding source, such as an instant transfer, a credit/debit card, or PayPal Credit.',
545
+ 'woocommerce-paypal-payments'
546
+ ),
547
+ 'label' => __( 'Require Instant Payment', 'woocommerce-paypal-payments' ),
548
+ 'screens' => array(
549
+ State::STATE_PROGRESSIVE,
550
+ State::STATE_ONBOARDED,
551
+ ),
552
+ 'requirements' => array(),
553
+ 'gateway' => 'paypal',
554
+ ),
555
+ 'brand_name' => array(
556
+ 'title' => __( 'Brand Name', 'woocommerce-paypal-payments' ),
557
+ 'type' => 'text',
558
+ 'default' => get_bloginfo( 'name' ),
559
+ 'desc_tip' => true,
560
+ 'description' => __(
561
+ 'Control the name of your shop, customers will see in the PayPal process.',
562
+ 'woocommerce-paypal-payments'
563
+ ),
564
+ 'screens' => array(
565
+ State::STATE_PROGRESSIVE,
566
+ State::STATE_ONBOARDED,
567
+ ),
568
+ 'requirements' => array(),
569
+ 'gateway' => 'paypal',
570
+ ),
571
+ 'landing_page' => array(
572
+ 'title' => __( 'Landing Page', 'woocommerce-paypal-payments' ),
573
+ 'type' => 'select',
574
+ 'class' => array(),
575
+ 'input_class' => array( 'wc-enhanced-select' ),
576
+ 'default' => 'gold',
577
+ 'desc_tip' => true,
578
+ 'description' => __(
579
+ 'Type of PayPal page to display.',
580
+ 'woocommerce-paypal-payments'
581
+ ),
582
+ 'options' => array(
583
+ ApplicationContext::LANDING_PAGE_LOGIN => __( 'Login (PayPal account login)', 'woocommerce-paypal-payments' ),
584
+ ApplicationContext::LANDING_PAGE_BILLING => __( 'Billing (Non-PayPal account)', 'woocommerce-paypal-payments' ),
585
+ ),
586
+ 'screens' => array(
587
+ State::STATE_PROGRESSIVE,
588
+ State::STATE_ONBOARDED,
589
+ ),
590
+ 'requirements' => array(),
591
+ 'gateway' => 'paypal',
592
+ ),
593
+ 'disable_funding' => array(
594
+ 'title' => __( 'Disable funding sources', 'woocommerce-paypal-payments' ),
595
+ 'type' => 'ppcp-multiselect',
596
+ 'class' => array(),
597
+ 'input_class' => array( 'wc-enhanced-select' ),
598
+ 'default' => array(),
599
+ 'desc_tip' => true,
600
+ 'description' => __(
601
+ 'By default all possible funding sources will be shown. You can disable some sources, if you wish.',
602
+ 'woocommerce-paypal-payments'
603
+ ),
604
+ 'options' => array(
605
+ 'card' => _x( 'Credit or debit cards', 'Name of payment method', 'woocommerce-paypal-payments' ),
606
+ 'credit' => _x( 'PayPal Credit', 'Name of payment method', 'woocommerce-paypal-payments' ),
607
+ 'sepa' => _x( 'SEPA-Lastschrift', 'Name of payment method', 'woocommerce-paypal-payments' ),
608
+ 'bancontact' => _x( 'Bancontact', 'Name of payment method', 'woocommerce-paypal-payments' ),
609
+ 'eps' => _x( 'eps', 'Name of payment method', 'woocommerce-paypal-payments' ),
610
+ 'giropay' => _x( 'giropay', 'Name of payment method', 'woocommerce-paypal-payments' ),
611
+ 'ideal' => _x( 'iDEAL', 'Name of payment method', 'woocommerce-paypal-payments' ),
612
+ 'mybank' => _x( 'MyBank', 'Name of payment method', 'woocommerce-paypal-payments' ),
613
+ 'p24' => _x( 'Przelewy24', 'Name of payment method', 'woocommerce-paypal-payments' ),
614
+ 'sofort' => _x( 'Sofort', 'Name of payment method', 'woocommerce-paypal-payments' ),
615
+ ),
616
+ 'screens' => array(
617
+ State::STATE_PROGRESSIVE,
618
+ State::STATE_ONBOARDED,
619
+ ),
620
+ 'requirements' => array(),
621
+ 'gateway' => 'paypal',
622
+ ),
623
+ 'vault_enabled' => array(
624
+ 'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
625
+ 'type' => 'checkbox',
626
+ 'desc_tip' => true,
627
+ 'label' => __( 'Enable vaulting', 'woocommerce-paypal-payments' ),
628
+ 'description' => __( 'Enables you to store payment tokens for subscriptions.', 'woocommerce-paypal-payments' ),
629
+ 'default' => true,
630
+ 'screens' => array(
631
+ State::STATE_ONBOARDED,
632
+ ),
633
+ 'requirements' => array(),
634
+ 'gateway' => 'paypal',
635
+ ),
636
+
637
+ 'logging_enabled' => array(
638
+ 'title' => __( 'Logging', 'woocommerce-paypal-payments' ),
639
+ 'type' => 'checkbox',
640
+ 'desc_tip' => true,
641
+ 'label' => __( 'Enable logging', 'woocommerce-paypal-payments' ),
642
+ 'description' => __( 'Enable logging of unexpected behavior. This can also log private data and should only be enabled in a development or stage environment.', 'woocommerce-paypal-payments' ),
643
+ 'default' => false,
644
+ 'screens' => array(
645
+ State::STATE_PROGRESSIVE,
646
+ State::STATE_ONBOARDED,
647
+ ),
648
+ 'requirements' => array(),
649
+ 'gateway' => 'paypal',
650
+ ),
651
+ 'prefix' => array(
652
+ 'title' => __( 'Invoice prefix', 'woocommerce-paypal-payments' ),
653
+ 'type' => 'text',
654
+ 'desc_tip' => true,
655
+ 'description' => __( 'If you use your PayPal account with more than one installation, please use a distinct prefix to seperate those installations. Please do not use numbers in your prefix.', 'woocommerce-paypal-payments' ),
656
+ 'default' => 'WC-',
657
+ 'screens' => array(
658
+ State::STATE_PROGRESSIVE,
659
+ State::STATE_ONBOARDED,
660
+ ),
661
+ 'requirements' => array(),
662
+ 'gateway' => 'paypal',
663
+ ),
664
+
665
+ // General button styles.
666
+ 'button_style_heading' => array(
667
+ 'heading' => __( 'Checkout', 'woocommerce-paypal-payments' ),
668
+ 'type' => 'ppcp-heading',
669
+ 'screens' => array(
670
+ State::STATE_PROGRESSIVE,
671
+ State::STATE_ONBOARDED,
672
+ ),
673
+ 'requirements' => array(),
674
+ 'gateway' => 'paypal',
675
+ 'description' => __( 'Customize the appearance of PayPal Checkout on the checkout page.', 'woocommerce-paypal-payments' ),
676
+ ),
677
+ 'button_enabled' => array(
678
+ 'title' => __( 'Enable buttons on Checkout', 'woocommerce-paypal-payments' ),
679
+ 'type' => 'checkbox',
680
+ 'label' => __( 'Enable on Checkout', 'woocommerce-paypal-payments' ),
681
+ 'default' => true,
682
+ 'screens' => array(
683
+ State::STATE_PROGRESSIVE,
684
+ State::STATE_ONBOARDED,
685
+ ),
686
+ 'requirements' => array(),
687
+ 'gateway' => 'paypal',
688
+ ),
689
+ 'button_layout' => array(
690
+ 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ),
691
+ 'type' => 'select',
692
+ 'class' => array(),
693
+ 'input_class' => array( 'wc-enhanced-select' ),
694
+ 'default' => 'vertical',
695
+ 'desc_tip' => true,
696
+ 'description' => __(
697
+ 'If additional funding sources are available to the buyer through PayPal, then multiple buttons are displayed in the space provided. Choose "vertical" for a dynamic list of alternative and local payment options, or "horizontal" when space is limited.',
698
+ 'woocommerce-paypal-payments'
699
+ ),
700
+ 'options' => array(
701
+ 'vertical' => __( 'Vertical', 'woocommerce-paypal-payments' ),
702
+ 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ),
703
+ ),
704
+ 'screens' => array(
705
+ State::STATE_PROGRESSIVE,
706
+ State::STATE_ONBOARDED,
707
+ ),
708
+ 'requirements' => array(),
709
+ 'gateway' => 'paypal',
710
+ ),
711
+ 'button_tagline' => array(
712
+ 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ),
713
+ 'type' => 'checkbox',
714
+ 'default' => true,
715
+ 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ),
716
+ 'desc_tip' => true,
717
+ 'description' => __(
718
+ 'Add the tagline. This line will only show up, if you select a horizontal layout.',
719
+ 'woocommerce-paypal-payments'
720
+ ),
721
+ 'screens' => array(
722
+ State::STATE_PROGRESSIVE,
723
+ State::STATE_ONBOARDED,
724
+ ),
725
+ 'requirements' => array(),
726
+ 'gateway' => 'paypal',
727
+ ),
728
+ 'button_label' => array(
729
+ 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ),
730
+ 'type' => 'select',
731
+ 'class' => array(),
732
+ 'input_class' => array( 'wc-enhanced-select' ),
733
+ 'default' => 'paypal',
734
+ 'desc_tip' => true,
735
+ 'description' => __(
736
+ 'This controls the label on the primary button.',
737
+ 'woocommerce-paypal-payments'
738
+ ),
739
+ 'options' => array(
740
+ 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ),
741
+ 'checkout' => __( 'PayPal Checkout', 'woocommerce-paypal-payments' ),
742
+ 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ),
743
+ 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ),
744
+ ),
745
+ 'screens' => array(
746
+ State::STATE_PROGRESSIVE,
747
+ State::STATE_ONBOARDED,
748
+ ),
749
+ 'requirements' => array(),
750
+ 'gateway' => 'paypal',
751
+ ),
752
+ 'button_color' => array(
753
+ 'title' => __( 'Color', 'woocommerce-paypal-payments' ),
754
+ 'type' => 'select',
755
+ 'class' => array(),
756
+ 'input_class' => array( 'wc-enhanced-select' ),
757
+ 'default' => 'gold',
758
+ 'desc_tip' => true,
759
+ 'description' => __(
760
+ 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
761
+ 'woocommerce-paypal-payments'
762
+ ),
763
+ 'options' => array(
764
+ 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ),
765
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
766
+ 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
767
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
768
+ ),
769
+ 'screens' => array(
770
+ State::STATE_PROGRESSIVE,
771
+ State::STATE_ONBOARDED,
772
+ ),
773
+ 'requirements' => array(),
774
+ 'gateway' => 'paypal',
775
+ ),
776
+ 'button_shape' => array(
777
+ 'title' => __( 'Shape', 'woocommerce-paypal-payments' ),
778
+ 'type' => 'select',
779
+ 'class' => array(),
780
+ 'input_class' => array( 'wc-enhanced-select' ),
781
+ 'default' => 'rect',
782
+ 'desc_tip' => true,
783
+ 'description' => __(
784
+ 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
785
+ 'woocommerce-paypal-payments'
786
+ ),
787
+ 'options' => array(
788
+ 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ),
789
+ 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ),
790
+ ),
791
+ 'screens' => array(
792
+ State::STATE_PROGRESSIVE,
793
+ State::STATE_ONBOARDED,
794
+ ),
795
+ 'requirements' => array(),
796
+ 'gateway' => 'paypal',
797
+ ),
798
+ 'message_heading' => array(
799
+ 'heading' => __( 'Credit Messaging on Checkout', 'woocommerce-paypal-payments' ),
800
+ 'type' => 'ppcp-heading',
801
+ 'screens' => array(
802
+ State::STATE_PROGRESSIVE,
803
+ State::STATE_ONBOARDED,
804
+ ),
805
+ 'requirements' => array( 'messages' ),
806
+ 'gateway' => 'paypal',
807
+ 'description' => str_replace( '<a>', '<a href="https://www.paypal.com/us/business/buy-now-pay-later">', __( 'Customize the appearance of <a>PayPal Credit messages</a> on checkout to promote special financing offers, which help increase sales.', 'woocommerce-paypal-payments' ) ),
808
+ 'class' => array( 'ppcp-subheading' ),
809
+ ),
810
+ 'message_enabled' => array(
811
+ 'title' => __( 'Enable message on Checkout', 'woocommerce-paypal-payments' ),
812
+ 'type' => 'checkbox',
813
+ 'label' => __( 'Enable on Checkout', 'woocommerce-paypal-payments' ),
814
+ 'default' => true,
815
+ 'screens' => array(
816
+ State::STATE_PROGRESSIVE,
817
+ State::STATE_ONBOARDED,
818
+ ),
819
+ 'requirements' => array( 'messages' ),
820
+ 'gateway' => 'paypal',
821
+ ),
822
+ 'message_layout' => array(
823
+ 'title' => __( 'Credit Messaging layout', 'woocommerce-paypal-payments' ),
824
+ 'type' => 'select',
825
+ 'class' => array(),
826
+ 'input_class' => array( 'wc-enhanced-select' ),
827
+ 'default' => 'text',
828
+ 'desc_tip' => true,
829
+ 'description' => __(
830
+ 'The layout of the message.',
831
+ 'woocommerce-paypal-payments'
832
+ ),
833
+ 'options' => array(
834
+ 'text' => __( 'Text', 'woocommerce-paypal-payments' ),
835
+ 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ),
836
+ ),
837
+ 'screens' => array(
838
+ State::STATE_PROGRESSIVE,
839
+ State::STATE_ONBOARDED,
840
+ ),
841
+ 'requirements' => array( 'messages' ),
842
+ 'gateway' => 'paypal',
843
+ ),
844
+ 'message_logo' => array(
845
+ 'title' => __( 'Credit Messaging logo', 'woocommerce-paypal-payments' ),
846
+ 'type' => 'select',
847
+ 'class' => array(),
848
+ 'input_class' => array( 'wc-enhanced-select' ),
849
+ 'default' => 'primary',
850
+ 'desc_tip' => true,
851
+ 'description' => __(
852
+ 'What logo the text message contains. Only applicable, when the layout style Text is used.',
853
+ 'woocommerce-paypal-payments'
854
+ ),
855
+ 'options' => array(
856
+ 'primary' => __( 'Primary', 'woocommerce-paypal-payments' ),
857
+ 'alternative' => __( 'Alternative', 'woocommerce-paypal-payments' ),
858
+ 'inline' => __( 'Inline', 'woocommerce-paypal-payments' ),
859
+ 'none' => __( 'None', 'woocommerce-paypal-payments' ),
860
+ ),
861
+ 'screens' => array(
862
+ State::STATE_PROGRESSIVE,
863
+ State::STATE_ONBOARDED,
864
+ ),
865
+ 'requirements' => array( 'messages' ),
866
+ 'gateway' => 'paypal',
867
+ ),
868
+ 'message_position' => array(
869
+ 'title' => __( 'Credit Messaging logo position', 'woocommerce-paypal-payments' ),
870
+ 'type' => 'select',
871
+ 'class' => array(),
872
+ 'input_class' => array( 'wc-enhanced-select' ),
873
+ 'default' => 'left',
874
+ 'desc_tip' => true,
875
+ 'description' => __(
876
+ 'The position of the logo. Only applicable, when the layout style Text is used.',
877
+ 'woocommerce-paypal-payments'
878
+ ),
879
+ 'options' => array(
880
+ 'left' => __( 'Left', 'woocommerce-paypal-payments' ),
881
+ 'right' => __( 'Right', 'woocommerce-paypal-payments' ),
882
+ 'top' => __( 'Top', 'woocommerce-paypal-payments' ),
883
+ ),
884
+ 'screens' => array(
885
+ State::STATE_PROGRESSIVE,
886
+ State::STATE_ONBOARDED,
887
+ ),
888
+ 'requirements' => array( 'messages' ),
889
+ 'gateway' => 'paypal',
890
+ ),
891
+ 'message_color' => array(
892
+ 'title' => __( 'Credit Messaging text color', 'woocommerce-paypal-payments' ),
893
+ 'type' => 'select',
894
+ 'class' => array(),
895
+ 'input_class' => array( 'wc-enhanced-select' ),
896
+ 'default' => 'black',
897
+ 'desc_tip' => true,
898
+ 'description' => __(
899
+ 'The color of the text. Only applicable, when the layout style Text is used.',
900
+ 'woocommerce-paypal-payments'
901
+ ),
902
+ 'options' => array(
903
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
904
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
905
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
906
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
907
+ ),
908
+ 'screens' => array(
909
+ State::STATE_PROGRESSIVE,
910
+ State::STATE_ONBOARDED,
911
+ ),
912
+ 'requirements' => array( 'messages' ),
913
+ 'gateway' => 'paypal',
914
+ ),
915
+ 'message_flex_color' => array(
916
+ 'title' => __( 'Credit Messaging color', 'woocommerce-paypal-payments' ),
917
+ 'type' => 'select',
918
+ 'class' => array(),
919
+ 'input_class' => array( 'wc-enhanced-select' ),
920
+ 'default' => 'blue',
921
+ 'desc_tip' => true,
922
+ 'description' => __(
923
+ 'The color of the text. Only applicable, when the layout style Flex is used.',
924
+ 'woocommerce-paypal-payments'
925
+ ),
926
+ 'options' => array(
927
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
928
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
929
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
930
+ 'white-no-border' => __( 'White no border', 'woocommerce-paypal-payments' ),
931
+ 'gray' => __( 'Gray', 'woocommerce-paypal-payments' ),
932
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
933
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
934
+ ),
935
+ 'screens' => array(
936
+ State::STATE_PROGRESSIVE,
937
+ State::STATE_ONBOARDED,
938
+ ),
939
+ 'requirements' => array( 'messages' ),
940
+ 'gateway' => 'paypal',
941
+ ),
942
+ 'message_flex_ratio' => array(
943
+ 'title' => __( 'Credit Messaging ratio', 'woocommerce-paypal-payments' ),
944
+ 'type' => 'select',
945
+ 'class' => array(),
946
+ 'input_class' => array( 'wc-enhanced-select' ),
947
+ 'default' => '1x1',
948
+ 'desc_tip' => true,
949
+ 'description' => __(
950
+ 'The width/height ratio of the banner. Only applicable, when the layout style Flex is used.',
951
+ 'woocommerce-paypal-payments'
952
+ ),
953
+ 'options' => array(
954
+ '1x1' => __( '1x1', 'woocommerce-paypal-payments' ),
955
+ '1x4' => __( '1x4', 'woocommerce-paypal-payments' ),
956
+ '8x1' => __( '8x1', 'woocommerce-paypal-payments' ),
957
+ '20x1' => __( '20x1', 'woocommerce-paypal-payments' ),
958
+ ),
959
+ 'screens' => array(
960
+ State::STATE_PROGRESSIVE,
961
+ State::STATE_ONBOARDED,
962
+ ),
963
+ 'requirements' => array( 'messages' ),
964
+ 'gateway' => 'paypal',
965
+ ),
966
+
967
+ // Single product page.
968
+ 'button_product_heading' => array(
969
+ 'heading' => __( 'Single Product Page', 'woocommerce-paypal-payments' ),
970
+ 'type' => 'ppcp-heading',
971
+ 'screens' => array(
972
+ State::STATE_PROGRESSIVE,
973
+ State::STATE_ONBOARDED,
974
+ ),
975
+ 'requirements' => array(),
976
+ 'gateway' => 'paypal',
977
+ 'description' => __( 'Customize the appearance of PayPal Checkout on the single product page.', 'woocommerce-paypal-payments' ),
978
+ ),
979
+ 'button_product_enabled' => array(
980
+ 'title' => __( 'Enable buttons on Single Product', 'woocommerce-paypal-payments' ),
981
+ 'type' => 'checkbox',
982
+ 'label' => __( 'Enable on Single Product', 'woocommerce-paypal-payments' ),
983
+ 'default' => true,
984
+ 'screens' => array(
985
+ State::STATE_PROGRESSIVE,
986
+ State::STATE_ONBOARDED,
987
+ ),
988
+ 'requirements' => array(),
989
+ 'gateway' => 'paypal',
990
+ ),
991
+ 'button_product_layout' => array(
992
+ 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ),
993
+ 'type' => 'select',
994
+ 'class' => array(),
995
+ 'input_class' => array( 'wc-enhanced-select' ),
996
+ 'default' => 'horizontal',
997
+ 'desc_tip' => true,
998
+ 'description' => __(
999
+ 'If additional funding sources are available to the buyer through PayPal, such as Venmo, then multiple buttons are displayed in the space provided. Choose "vertical" for a dynamic list of alternative and local payment options, or "horizontal" when space is limited.',
1000
+ 'woocommerce-paypal-payments'
1001
+ ),
1002
+ 'options' => array(
1003
+ 'vertical' => __( 'Vertical', 'woocommerce-paypal-payments' ),
1004
+ 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ),
1005
+ ),
1006
+ 'screens' => array(
1007
+ State::STATE_PROGRESSIVE,
1008
+ State::STATE_ONBOARDED,
1009
+ ),
1010
+ 'requirements' => array(),
1011
+ 'gateway' => 'paypal',
1012
+ ),
1013
+ 'button_product_tagline' => array(
1014
+ 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ),
1015
+ 'type' => 'checkbox',
1016
+ 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ),
1017
+ 'default' => true,
1018
+ 'desc_tip' => true,
1019
+ 'description' => __(
1020
+ 'Add the tagline. This line will only show up, if you select a horizontal layout.',
1021
+ 'woocommerce-paypal-payments'
1022
+ ),
1023
+ 'screens' => array(
1024
+ State::STATE_PROGRESSIVE,
1025
+ State::STATE_ONBOARDED,
1026
+ ),
1027
+ 'requirements' => array(),
1028
+ 'gateway' => 'paypal',
1029
+ ),
1030
+ 'button_product_label' => array(
1031
+ 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ),
1032
+ 'type' => 'select',
1033
+ 'class' => array(),
1034
+ 'input_class' => array( 'wc-enhanced-select' ),
1035
+ 'default' => 'paypal',
1036
+ 'desc_tip' => true,
1037
+ 'description' => __(
1038
+ 'This controls the label on the primary button.',
1039
+ 'woocommerce-paypal-payments'
1040
+ ),
1041
+ 'options' => array(
1042
+ 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ),
1043
+ 'checkout' => __( 'PayPal Checkout', 'woocommerce-paypal-payments' ),
1044
+ 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ),
1045
+ 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ),
1046
+ ),
1047
+ 'screens' => array(
1048
+ State::STATE_PROGRESSIVE,
1049
+ State::STATE_ONBOARDED,
1050
+ ),
1051
+ 'requirements' => array(),
1052
+ 'gateway' => 'paypal',
1053
+ ),
1054
+ 'button_product_color' => array(
1055
+ 'title' => __( 'Color', 'woocommerce-paypal-payments' ),
1056
+ 'type' => 'select',
1057
+ 'class' => array(),
1058
+ 'input_class' => array( 'wc-enhanced-select' ),
1059
+ 'default' => 'gold',
1060
+ 'desc_tip' => true,
1061
+ 'description' => __(
1062
+ 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
1063
+ 'woocommerce-paypal-payments'
1064
+ ),
1065
+ 'options' => array(
1066
+ 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ),
1067
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
1068
+ 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
1069
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1070
+ ),
1071
+ 'screens' => array(
1072
+ State::STATE_PROGRESSIVE,
1073
+ State::STATE_ONBOARDED,
1074
+ ),
1075
+ 'requirements' => array(),
1076
+ 'gateway' => 'paypal',
1077
+ ),
1078
+ 'button_product_shape' => array(
1079
+ 'title' => __( 'Shape', 'woocommerce-paypal-payments' ),
1080
+ 'type' => 'select',
1081
+ 'class' => array(),
1082
+ 'input_class' => array( 'wc-enhanced-select' ),
1083
+ 'default' => 'rect',
1084
+ 'desc_tip' => true,
1085
+ 'description' => __(
1086
+ 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
1087
+ 'woocommerce-paypal-payments'
1088
+ ),
1089
+ 'options' => array(
1090
+ 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ),
1091
+ 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ),
1092
+ ),
1093
+ 'screens' => array(
1094
+ State::STATE_PROGRESSIVE,
1095
+ State::STATE_ONBOARDED,
1096
+ ),
1097
+ 'requirements' => array(),
1098
+ 'gateway' => 'paypal',
1099
+ ),
1100
+
1101
+ 'message_product_heading' => array(
1102
+ 'heading' => __( 'Credit Messaging on Single Product Page', 'woocommerce-paypal-payments' ),
1103
+ 'type' => 'ppcp-heading',
1104
+ 'screens' => array(
1105
+ State::STATE_PROGRESSIVE,
1106
+ State::STATE_ONBOARDED,
1107
+ ),
1108
+ 'requirements' => array( 'messages' ),
1109
+ 'gateway' => 'paypal',
1110
+ 'description' => str_replace( '<a>', '<a href="https://www.paypal.com/us/business/buy-now-pay-later">', __( 'Customize the appearance of <a>PayPal Credit messages</a> on product pages to promote special financing offers, which help increase sales.', 'woocommerce-paypal-payments' ) ),
1111
+ 'class' => array( 'ppcp-subheading' ),
1112
+ ),
1113
+ 'message_product_enabled' => array(
1114
+ 'title' => __( 'Enable message on Single Product', 'woocommerce-paypal-payments' ),
1115
+ 'type' => 'checkbox',
1116
+ 'label' => __( 'Enable on Single Product', 'woocommerce-paypal-payments' ),
1117
+ 'default' => true,
1118
+ 'screens' => array(
1119
+ State::STATE_PROGRESSIVE,
1120
+ State::STATE_ONBOARDED,
1121
+ ),
1122
+ 'requirements' => array( 'messages' ),
1123
+ 'gateway' => 'paypal',
1124
+ ),
1125
+ 'message_product_layout' => array(
1126
+ 'title' => __( 'Credit Messaging layout', 'woocommerce-paypal-payments' ),
1127
+ 'type' => 'select',
1128
+ 'class' => array(),
1129
+ 'input_class' => array( 'wc-enhanced-select' ),
1130
+ 'default' => 'text',
1131
+ 'desc_tip' => true,
1132
+ 'description' => __(
1133
+ 'The layout of the message.',
1134
+ 'woocommerce-paypal-payments'
1135
+ ),
1136
+ 'options' => array(
1137
+ 'text' => __( 'Text', 'woocommerce-paypal-payments' ),
1138
+ 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ),
1139
+ ),
1140
+ 'screens' => array(
1141
+ State::STATE_PROGRESSIVE,
1142
+ State::STATE_ONBOARDED,
1143
+ ),
1144
+ 'requirements' => array( 'messages' ),
1145
+ 'gateway' => 'paypal',
1146
+ ),
1147
+ 'message_product_logo' => array(
1148
+ 'title' => __( 'Credit Messaging logo', 'woocommerce-paypal-payments' ),
1149
+ 'type' => 'select',
1150
+ 'class' => array(),
1151
+ 'input_class' => array( 'wc-enhanced-select' ),
1152
+ 'default' => 'primary',
1153
+ 'desc_tip' => true,
1154
+ 'description' => __(
1155
+ 'What logo the text message contains. Only applicable, when the layout style Text is used.',
1156
+ 'woocommerce-paypal-payments'
1157
+ ),
1158
+ 'options' => array(
1159
+ 'primary' => __( 'Primary', 'woocommerce-paypal-payments' ),
1160
+ 'alternative' => __( 'Alternative', 'woocommerce-paypal-payments' ),
1161
+ 'inline' => __( 'Inline', 'woocommerce-paypal-payments' ),
1162
+ 'none' => __( 'None', 'woocommerce-paypal-payments' ),
1163
+ ),
1164
+ 'screens' => array(
1165
+ State::STATE_PROGRESSIVE,
1166
+ State::STATE_ONBOARDED,
1167
+ ),
1168
+ 'requirements' => array( 'messages' ),
1169
+ 'gateway' => 'paypal',
1170
+ ),
1171
+ 'message_product_position' => array(
1172
+ 'title' => __( 'Credit Messaging logo position', 'woocommerce-paypal-payments' ),
1173
+ 'type' => 'select',
1174
+ 'class' => array(),
1175
+ 'input_class' => array( 'wc-enhanced-select' ),
1176
+ 'default' => 'left',
1177
+ 'desc_tip' => true,
1178
+ 'description' => __(
1179
+ 'The position of the logo. Only applicable, when the layout style Text is used.',
1180
+ 'woocommerce-paypal-payments'
1181
+ ),
1182
+ 'options' => array(
1183
+ 'left' => __( 'Left', 'woocommerce-paypal-payments' ),
1184
+ 'right' => __( 'Right', 'woocommerce-paypal-payments' ),
1185
+ 'top' => __( 'Top', 'woocommerce-paypal-payments' ),
1186
+ ),
1187
+ 'screens' => array(
1188
+ State::STATE_PROGRESSIVE,
1189
+ State::STATE_ONBOARDED,
1190
+ ),
1191
+ 'requirements' => array( 'messages' ),
1192
+ 'gateway' => 'paypal',
1193
+ ),
1194
+ 'message_product_color' => array(
1195
+ 'title' => __( 'Credit Messaging text color', 'woocommerce-paypal-payments' ),
1196
+ 'type' => 'select',
1197
+ 'class' => array(),
1198
+ 'input_class' => array( 'wc-enhanced-select' ),
1199
+ 'default' => 'black',
1200
+ 'desc_tip' => true,
1201
+ 'description' => __(
1202
+ 'The color of the text. Only applicable, when the layout style Text is used.',
1203
+ 'woocommerce-paypal-payments'
1204
+ ),
1205
+ 'options' => array(
1206
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1207
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
1208
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
1209
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
1210
+ ),
1211
+ 'screens' => array(
1212
+ State::STATE_PROGRESSIVE,
1213
+ State::STATE_ONBOARDED,
1214
+ ),
1215
+ 'requirements' => array( 'messages' ),
1216
+ 'gateway' => 'paypal',
1217
+ ),
1218
+ 'message_product_flex_color' => array(
1219
+ 'title' => __( 'Credit Messaging color', 'woocommerce-paypal-payments' ),
1220
+ 'type' => 'select',
1221
+ 'class' => array(),
1222
+ 'input_class' => array( 'wc-enhanced-select' ),
1223
+ 'default' => 'blue',
1224
+ 'desc_tip' => true,
1225
+ 'description' => __(
1226
+ 'The color of the text. Only applicable, when the layout style Flex is used.',
1227
+ 'woocommerce-paypal-payments'
1228
+ ),
1229
+ 'options' => array(
1230
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
1231
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1232
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
1233
+ 'white-no-border' => __( 'White no border', 'woocommerce-paypal-payments' ),
1234
+ 'gray' => __( 'Gray', 'woocommerce-paypal-payments' ),
1235
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
1236
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
1237
+ ),
1238
+ 'screens' => array(
1239
+ State::STATE_PROGRESSIVE,
1240
+ State::STATE_ONBOARDED,
1241
+ ),
1242
+ 'requirements' => array( 'messages' ),
1243
+ 'gateway' => 'paypal',
1244
+ ),
1245
+ 'message_product_flex_ratio' => array(
1246
+ 'title' => __( 'Credit Messaging ratio', 'woocommerce-paypal-payments' ),
1247
+ 'type' => 'select',
1248
+ 'class' => array(),
1249
+ 'input_class' => array( 'wc-enhanced-select' ),
1250
+ 'default' => '1x1',
1251
+ 'desc_tip' => true,
1252
+ 'description' => __(
1253
+ 'The width/height ratio of the banner. Only applicable, when the layout style Flex is used.',
1254
+ 'woocommerce-paypal-payments'
1255
+ ),
1256
+ 'options' => array(
1257
+ '1x1' => __( '1x1', 'woocommerce-paypal-payments' ),
1258
+ '1x4' => __( '1x4', 'woocommerce-paypal-payments' ),
1259
+ '8x1' => __( '8x1', 'woocommerce-paypal-payments' ),
1260
+ '20x1' => __( '20x1', 'woocommerce-paypal-payments' ),
1261
+ ),
1262
+ 'screens' => array(
1263
+ State::STATE_PROGRESSIVE,
1264
+ State::STATE_ONBOARDED,
1265
+ ),
1266
+ 'requirements' => array( 'messages' ),
1267
+ 'gateway' => 'paypal',
1268
+ ),
1269
+
1270
+ // Cart settings.
1271
+ 'button_cart_heading' => array(
1272
+ 'heading' => __( 'Cart', 'woocommerce-paypal-payments' ),
1273
+ 'type' => 'ppcp-heading',
1274
+ 'screens' => array(
1275
+ State::STATE_PROGRESSIVE,
1276
+ State::STATE_ONBOARDED,
1277
+ ),
1278
+ 'requirements' => array(),
1279
+ 'gateway' => 'paypal',
1280
+ 'description' => __( 'Customize the appearance of PayPal Checkout on the cart page.', 'woocommerce-paypal-payments' ),
1281
+ ),
1282
+ 'button_cart_enabled' => array(
1283
+ 'title' => __( 'Buttons on Cart', 'woocommerce-paypal-payments' ),
1284
+ 'type' => 'checkbox',
1285
+ 'label' => __( 'Enable on Cart', 'woocommerce-paypal-payments' ),
1286
+ 'default' => true,
1287
+ 'screens' => array(
1288
+ State::STATE_PROGRESSIVE,
1289
+ State::STATE_ONBOARDED,
1290
+ ),
1291
+ 'requirements' => array(),
1292
+ 'gateway' => 'paypal',
1293
+ ),
1294
+ 'button_cart_layout' => array(
1295
+ 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ),
1296
+ 'type' => 'select',
1297
+ 'class' => array(),
1298
+ 'input_class' => array( 'wc-enhanced-select' ),
1299
+ 'default' => 'horizontal',
1300
+ 'desc_tip' => true,
1301
+ 'description' => __(
1302
+ 'If additional funding sources are available to the buyer through PayPal, such as Venmo, then multiple buttons are displayed in the space provided. Choose "vertical" for a dynamic list of alternative and local payment options, or "horizontal" when space is limited.',
1303
+ 'woocommerce-paypal-payments'
1304
+ ),
1305
+ 'options' => array(
1306
+ 'vertical' => __( 'Vertical', 'woocommerce-paypal-payments' ),
1307
+ 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ),
1308
+ ),
1309
+ 'screens' => array(
1310
+ State::STATE_PROGRESSIVE,
1311
+ State::STATE_ONBOARDED,
1312
+ ),
1313
+ 'requirements' => array(),
1314
+ 'gateway' => 'paypal',
1315
+ ),
1316
+ 'button_cart_tagline' => array(
1317
+ 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ),
1318
+ 'type' => 'checkbox',
1319
+ 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ),
1320
+ 'default' => true,
1321
+ 'desc_tip' => true,
1322
+ 'description' => __(
1323
+ 'Add the tagline. This line will only show up, if you select a horizontal layout.',
1324
+ 'woocommerce-paypal-payments'
1325
+ ),
1326
+ 'screens' => array(
1327
+ State::STATE_PROGRESSIVE,
1328
+ State::STATE_ONBOARDED,
1329
+ ),
1330
+ 'requirements' => array(),
1331
+ 'gateway' => 'paypal',
1332
+ ),
1333
+ 'button_cart_label' => array(
1334
+ 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ),
1335
+ 'type' => 'select',
1336
+ 'class' => array(),
1337
+ 'input_class' => array( 'wc-enhanced-select' ),
1338
+ 'default' => 'paypal',
1339
+ 'desc_tip' => true,
1340
+ 'description' => __(
1341
+ 'This controls the label on the primary button.',
1342
+ 'woocommerce-paypal-payments'
1343
+ ),
1344
+ 'options' => array(
1345
+ 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ),
1346
+ 'checkout' => __( 'PayPal Checkout', 'woocommerce-paypal-payments' ),
1347
+ 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ),
1348
+ 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ),
1349
+ ),
1350
+ 'screens' => array(
1351
+ State::STATE_PROGRESSIVE,
1352
+ State::STATE_ONBOARDED,
1353
+ ),
1354
+ 'requirements' => array(),
1355
+ 'gateway' => 'paypal',
1356
+ ),
1357
+ 'button_cart_color' => array(
1358
+ 'title' => __( 'Color', 'woocommerce-paypal-payments' ),
1359
+ 'type' => 'select',
1360
+ 'class' => array(),
1361
+ 'input_class' => array( 'wc-enhanced-select' ),
1362
+ 'default' => 'gold',
1363
+ 'desc_tip' => true,
1364
+ 'description' => __(
1365
+ 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
1366
+ 'woocommerce-paypal-payments'
1367
+ ),
1368
+ 'options' => array(
1369
+ 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ),
1370
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
1371
+ 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
1372
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1373
+ ),
1374
+ 'screens' => array(
1375
+ State::STATE_PROGRESSIVE,
1376
+ State::STATE_ONBOARDED,
1377
+ ),
1378
+ 'requirements' => array(),
1379
+ 'gateway' => 'paypal',
1380
+ ),
1381
+ 'button_cart_shape' => array(
1382
+ 'title' => __( 'Shape', 'woocommerce-paypal-payments' ),
1383
+ 'type' => 'select',
1384
+ 'class' => array(),
1385
+ 'input_class' => array( 'wc-enhanced-select' ),
1386
+ 'default' => 'rect',
1387
+ 'desc_tip' => true,
1388
+ 'description' => __(
1389
+ 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
1390
+ 'woocommerce-paypal-payments'
1391
+ ),
1392
+ 'options' => array(
1393
+ 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ),
1394
+ 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ),
1395
+ ),
1396
+ 'screens' => array(
1397
+ State::STATE_PROGRESSIVE,
1398
+ State::STATE_ONBOARDED,
1399
+ ),
1400
+ 'requirements' => array(),
1401
+ 'gateway' => 'paypal',
1402
+ ),
1403
+
1404
+ 'message_cart_heading' => array(
1405
+ 'heading' => __( 'Credit Messaging on Cart', 'woocommerce-paypal-payments' ),
1406
+ 'type' => 'ppcp-heading',
1407
+ 'screens' => array(
1408
+ State::STATE_PROGRESSIVE,
1409
+ State::STATE_ONBOARDED,
1410
+ ),
1411
+ 'requirements' => array( 'messages' ),
1412
+ 'gateway' => 'paypal',
1413
+ 'description' => str_replace( '<a>', '<a href="https://www.paypal.com/us/business/buy-now-pay-later">', __( 'Customize the appearance of <a>PayPal Credit messages</a> on your cart page to promote special financing offers, which help increase sales.', 'woocommerce-paypal-payments' ) ),
1414
+ 'class' => array( 'ppcp-subheading' ),
1415
+ ),
1416
+ 'message_cart_enabled' => array(
1417
+ 'title' => __( 'Enable message on Cart', 'woocommerce-paypal-payments' ),
1418
+ 'type' => 'checkbox',
1419
+ 'label' => __( 'Enable on Cart', 'woocommerce-paypal-payments' ),
1420
+ 'default' => true,
1421
+ 'screens' => array(
1422
+ State::STATE_PROGRESSIVE,
1423
+ State::STATE_ONBOARDED,
1424
+ ),
1425
+ 'requirements' => array( 'messages' ),
1426
+ 'gateway' => 'paypal',
1427
+ ),
1428
+ 'message_cart_layout' => array(
1429
+ 'title' => __( 'Credit Messaging layout', 'woocommerce-paypal-payments' ),
1430
+ 'type' => 'select',
1431
+ 'class' => array(),
1432
+ 'input_class' => array( 'wc-enhanced-select' ),
1433
+ 'default' => 'text',
1434
+ 'desc_tip' => true,
1435
+ 'description' => __(
1436
+ 'The layout of the message.',
1437
+ 'woocommerce-paypal-payments'
1438
+ ),
1439
+ 'options' => array(
1440
+ 'text' => __( 'Text', 'woocommerce-paypal-payments' ),
1441
+ 'flex' => __( 'Flex', 'woocommerce-paypal-payments' ),
1442
+ ),
1443
+ 'screens' => array(
1444
+ State::STATE_PROGRESSIVE,
1445
+ State::STATE_ONBOARDED,
1446
+ ),
1447
+ 'requirements' => array( 'messages' ),
1448
+ 'gateway' => 'paypal',
1449
+ ),
1450
+ 'message_cart_logo' => array(
1451
+ 'title' => __( 'Credit Messaging logo', 'woocommerce-paypal-payments' ),
1452
+ 'type' => 'select',
1453
+ 'class' => array(),
1454
+ 'input_class' => array( 'wc-enhanced-select' ),
1455
+ 'default' => 'primary',
1456
+ 'desc_tip' => true,
1457
+ 'description' => __(
1458
+ 'What logo the text message contains. Only applicable, when the layout style Text is used.',
1459
+ 'woocommerce-paypal-payments'
1460
+ ),
1461
+ 'options' => array(
1462
+ 'primary' => __( 'Primary', 'woocommerce-paypal-payments' ),
1463
+ 'alternative' => __( 'Alternative', 'woocommerce-paypal-payments' ),
1464
+ 'inline' => __( 'Inline', 'woocommerce-paypal-payments' ),
1465
+ 'none' => __( 'None', 'woocommerce-paypal-payments' ),
1466
+ ),
1467
+ 'screens' => array(
1468
+ State::STATE_PROGRESSIVE,
1469
+ State::STATE_ONBOARDED,
1470
+ ),
1471
+ 'requirements' => array( 'messages' ),
1472
+ 'gateway' => 'paypal',
1473
+ ),
1474
+ 'message_cart_position' => array(
1475
+ 'title' => __( 'Credit Messaging logo position', 'woocommerce-paypal-payments' ),
1476
+ 'type' => 'select',
1477
+ 'class' => array(),
1478
+ 'input_class' => array( 'wc-enhanced-select' ),
1479
+ 'default' => 'left',
1480
+ 'desc_tip' => true,
1481
+ 'description' => __(
1482
+ 'The position of the logo. Only applicable, when the layout style Text is used.',
1483
+ 'woocommerce-paypal-payments'
1484
+ ),
1485
+ 'options' => array(
1486
+ 'left' => __( 'Left', 'woocommerce-paypal-payments' ),
1487
+ 'right' => __( 'Right', 'woocommerce-paypal-payments' ),
1488
+ 'top' => __( 'Top', 'woocommerce-paypal-payments' ),
1489
+ ),
1490
+ 'screens' => array(
1491
+ State::STATE_PROGRESSIVE,
1492
+ State::STATE_ONBOARDED,
1493
+ ),
1494
+ 'requirements' => array( 'messages' ),
1495
+ 'gateway' => 'paypal',
1496
+ ),
1497
+ 'message_cart_color' => array(
1498
+ 'title' => __( 'Credit Messaging text color', 'woocommerce-paypal-payments' ),
1499
+ 'type' => 'select',
1500
+ 'class' => array(),
1501
+ 'input_class' => array( 'wc-enhanced-select' ),
1502
+ 'default' => 'black',
1503
+ 'desc_tip' => true,
1504
+ 'description' => __(
1505
+ 'The color of the text. Only applicable, when the layout style Text is used.',
1506
+ 'woocommerce-paypal-payments'
1507
+ ),
1508
+ 'options' => array(
1509
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1510
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
1511
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
1512
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
1513
+ ),
1514
+ 'screens' => array(
1515
+ State::STATE_PROGRESSIVE,
1516
+ State::STATE_ONBOARDED,
1517
+ ),
1518
+ 'requirements' => array( 'messages' ),
1519
+ 'gateway' => 'paypal',
1520
+ ),
1521
+ 'message_cart_flex_color' => array(
1522
+ 'title' => __( 'Credit Messaging color', 'woocommerce-paypal-payments' ),
1523
+ 'type' => 'select',
1524
+ 'class' => array(),
1525
+ 'input_class' => array( 'wc-enhanced-select' ),
1526
+ 'default' => 'blue',
1527
+ 'desc_tip' => true,
1528
+ 'description' => __(
1529
+ 'The color of the text. Only applicable, when the layout style Flex is used.',
1530
+ 'woocommerce-paypal-payments'
1531
+ ),
1532
+ 'options' => array(
1533
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
1534
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1535
+ 'white' => __( 'White', 'woocommerce-paypal-payments' ),
1536
+ 'white-no-border' => __( 'White no border', 'woocommerce-paypal-payments' ),
1537
+ 'gray' => __( 'Gray', 'woocommerce-paypal-payments' ),
1538
+ 'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
1539
+ 'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
1540
+ ),
1541
+ 'screens' => array(
1542
+ State::STATE_PROGRESSIVE,
1543
+ State::STATE_ONBOARDED,
1544
+ ),
1545
+ 'requirements' => array( 'messages' ),
1546
+ 'gateway' => 'paypal',
1547
+ ),
1548
+ 'message_cart_flex_ratio' => array(
1549
+ 'title' => __( 'Credit Messaging ratio', 'woocommerce-paypal-payments' ),
1550
+ 'type' => 'select',
1551
+ 'class' => array(),
1552
+ 'input_class' => array( 'wc-enhanced-select' ),
1553
+ 'default' => '1x1',
1554
+ 'desc_tip' => true,
1555
+ 'description' => __(
1556
+ 'The width/height ratio of the banner. Only applicable, when the layout style Flex is used.',
1557
+ 'woocommerce-paypal-payments'
1558
+ ),
1559
+ 'options' => array(
1560
+ '1x1' => __( '1x1', 'woocommerce-paypal-payments' ),
1561
+ '1x4' => __( '1x4', 'woocommerce-paypal-payments' ),
1562
+ '8x1' => __( '8x1', 'woocommerce-paypal-payments' ),
1563
+ '20x1' => __( '20x1', 'woocommerce-paypal-payments' ),
1564
+ ),
1565
+ 'screens' => array(
1566
+ State::STATE_PROGRESSIVE,
1567
+ State::STATE_ONBOARDED,
1568
+ ),
1569
+ 'requirements' => array( 'messages' ),
1570
+ 'gateway' => 'paypal',
1571
+ ),
1572
+
1573
+ // Mini cart settings.
1574
+ 'button_mini-cart_heading' => array(
1575
+ 'heading' => __( 'Mini Cart', 'woocommerce-paypal-payments' ),
1576
+ 'type' => 'ppcp-heading',
1577
+ 'screens' => array(
1578
+ State::STATE_PROGRESSIVE,
1579
+ State::STATE_ONBOARDED,
1580
+ ),
1581
+ 'requirements' => array(),
1582
+ 'gateway' => 'paypal',
1583
+ 'description' => __( 'Customize the appearance of PayPal Checkout on the Mini Cart.', 'woocommerce-paypal-payments' ),
1584
+ ),
1585
+ 'button_mini-cart_enabled' => array(
1586
+ 'title' => __( 'Buttons on Mini Cart', 'woocommerce-paypal-payments' ),
1587
+ 'type' => 'checkbox',
1588
+ 'label' => __( 'Enable on Mini Cart', 'woocommerce-paypal-payments' ),
1589
+ 'default' => true,
1590
+ 'screens' => array(
1591
+ State::STATE_PROGRESSIVE,
1592
+ State::STATE_ONBOARDED,
1593
+ ),
1594
+ 'requirements' => array(),
1595
+ 'gateway' => 'paypal',
1596
+ ),
1597
+ 'button_mini-cart_layout' => array(
1598
+ 'title' => __( 'Button Layout', 'woocommerce-paypal-payments' ),
1599
+ 'type' => 'select',
1600
+ 'class' => array(),
1601
+ 'input_class' => array( 'wc-enhanced-select' ),
1602
+ 'default' => 'horizontal',
1603
+ 'desc_tip' => true,
1604
+ 'description' => __(
1605
+ 'If additional funding sources are available to the buyer through PayPal, such as Venmo, then multiple buttons are displayed in the space provided. Choose "vertical" for a dynamic list of alternative and local payment options, or "horizontal" when space is limited.',
1606
+ 'woocommerce-paypal-payments'
1607
+ ),
1608
+ 'options' => array(
1609
+ 'vertical' => __( 'Vertical', 'woocommerce-paypal-payments' ),
1610
+ 'horizontal' => __( 'Horizontal', 'woocommerce-paypal-payments' ),
1611
+ ),
1612
+ 'screens' => array(
1613
+ State::STATE_PROGRESSIVE,
1614
+ State::STATE_ONBOARDED,
1615
+ ),
1616
+ 'requirements' => array(),
1617
+ 'gateway' => 'paypal',
1618
+ ),
1619
+ 'button_mini-cart_tagline' => array(
1620
+ 'title' => __( 'Tagline', 'woocommerce-paypal-payments' ),
1621
+ 'type' => 'checkbox',
1622
+ 'label' => __( 'Enable tagline', 'woocommerce-paypal-payments' ),
1623
+ 'default' => false,
1624
+ 'desc_tip' => true,
1625
+ 'description' => __(
1626
+ 'Add the tagline. This line will only show up, if you select a horizontal layout.',
1627
+ 'woocommerce-paypal-payments'
1628
+ ),
1629
+ 'screens' => array(
1630
+ State::STATE_PROGRESSIVE,
1631
+ State::STATE_ONBOARDED,
1632
+ ),
1633
+ 'requirements' => array(),
1634
+ 'gateway' => 'paypal',
1635
+ ),
1636
+ 'button_mini-cart_label' => array(
1637
+ 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ),
1638
+ 'type' => 'select',
1639
+ 'class' => array(),
1640
+ 'input_class' => array( 'wc-enhanced-select' ),
1641
+ 'default' => 'paypal',
1642
+ 'desc_tip' => true,
1643
+ 'description' => __(
1644
+ 'This controls the label on the primary button.',
1645
+ 'woocommerce-paypal-payments'
1646
+ ),
1647
+ 'options' => array(
1648
+ 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ),
1649
+ 'checkout' => __( 'PayPal Checkout', 'woocommerce-paypal-payments' ),
1650
+ 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ),
1651
+ 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ),
1652
+ ),
1653
+ 'screens' => array(
1654
+ State::STATE_PROGRESSIVE,
1655
+ State::STATE_ONBOARDED,
1656
+ ),
1657
+ 'requirements' => array(),
1658
+ 'gateway' => 'paypal',
1659
+ ),
1660
+ 'button_mini-cart_color' => array(
1661
+ 'title' => __( 'Color', 'woocommerce-paypal-payments' ),
1662
+ 'type' => 'select',
1663
+ 'class' => array(),
1664
+ 'input_class' => array( 'wc-enhanced-select' ),
1665
+ 'default' => 'gold',
1666
+ 'desc_tip' => true,
1667
+ 'description' => __(
1668
+ 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
1669
+ 'woocommerce-paypal-payments'
1670
+ ),
1671
+ 'options' => array(
1672
+ 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ),
1673
+ 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
1674
+ 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
1675
+ 'black' => __( 'Black', 'woocommerce-paypal-payments' ),
1676
+ ),
1677
+ 'screens' => array(
1678
+ State::STATE_PROGRESSIVE,
1679
+ State::STATE_ONBOARDED,
1680
+ ),
1681
+ 'requirements' => array(),
1682
+ 'gateway' => 'paypal',
1683
+ ),
1684
+ 'button_mini-cart_shape' => array(
1685
+ 'title' => __( 'Shape', 'woocommerce-paypal-payments' ),
1686
+ 'type' => 'select',
1687
+ 'class' => array(),
1688
+ 'input_class' => array( 'wc-enhanced-select' ),
1689
+ 'default' => 'rect',
1690
+ 'desc_tip' => true,
1691
+ 'description' => __(
1692
+ 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
1693
+ 'woocommerce-paypal-payments'
1694
+ ),
1695
+ 'options' => array(
1696
+ 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ),
1697
+ 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ),
1698
+ ),
1699
+ 'screens' => array(
1700
+ State::STATE_PROGRESSIVE,
1701
+ State::STATE_ONBOARDED,
1702
+ ),
1703
+ 'requirements' => array(),
1704
+ 'gateway' => 'paypal',
1705
+ ),
1706
+
1707
+ 'disable_cards' => array(
1708
+ 'title' => __( 'Disable specific credit cards', 'woocommerce-paypal-payments' ),
1709
+ 'type' => 'ppcp-multiselect',
1710
+ 'class' => array(),
1711
+ 'input_class' => array( 'wc-enhanced-select' ),
1712
+ 'default' => array(),
1713
+ 'desc_tip' => true,
1714
+ 'description' => __(
1715
+ 'By default all possible credit cards will be accepted. You can disable some cards, if you wish.',
1716
+ 'woocommerce-paypal-payments'
1717
+ ),
1718
+ 'options' => array(
1719
+ 'visa' => _x( 'Visa', 'Name of credit card', 'woocommerce-paypal-payments' ),
1720
+ 'mastercard' => _x( 'Mastercard', 'Name of credit card', 'woocommerce-paypal-payments' ),
1721
+ 'amex' => _x( 'American Express', 'Name of credit card', 'woocommerce-paypal-payments' ),
1722
+ 'discover' => _x( 'Discover', 'Name of credit card', 'woocommerce-paypal-payments' ),
1723
+ 'jcb' => _x( 'JCB', 'Name of credit card', 'woocommerce-paypal-payments' ),
1724
+ 'elo' => _x( 'Elo', 'Name of credit card', 'woocommerce-paypal-payments' ),
1725
+ 'hiper' => _x( 'Hiper', 'Name of credit card', 'woocommerce-paypal-payments' ),
1726
+ ),
1727
+ 'screens' => array(
1728
+ State::STATE_ONBOARDED,
1729
+ ),
1730
+ 'requirements' => array(
1731
+ 'dcc',
1732
+ ),
1733
+ 'gateway' => 'dcc',
1734
+ ),
1735
+ 'card_icons' => array(
1736
+ 'title' => __( 'Show logo of the following credit cards', 'woocommerce-paypal-payments' ),
1737
+ 'type' => 'ppcp-multiselect',
1738
+ 'class' => array(),
1739
+ 'input_class' => array( 'wc-enhanced-select' ),
1740
+ 'default' => array(),
1741
+ 'desc_tip' => true,
1742
+ 'description' => __(
1743
+ 'Define which cards you want to display in your checkout.',
1744
+ 'woocommerce-paypal-payments'
1745
+ ),
1746
+ 'options' => array(
1747
+ 'visa' => _x( 'Visa', 'Name of credit card', 'woocommerce-paypal-payments' ),
1748
+ 'mastercard' => _x( 'Mastercard', 'Name of credit card', 'woocommerce-paypal-payments' ),
1749
+ 'amex' => _x( 'American Express', 'Name of credit card', 'woocommerce-paypal-payments' ),
1750
+ 'discover' => _x( 'Discover', 'Name of credit card', 'woocommerce-paypal-payments' ),
1751
+ 'jcb' => _x( 'JCB', 'Name of credit card', 'woocommerce-paypal-payments' ),
1752
+ 'elo' => _x( 'Elo', 'Name of credit card', 'woocommerce-paypal-payments' ),
1753
+ 'hiper' => _x( 'Hiper', 'Name of credit card', 'woocommerce-paypal-payments' ),
1754
+ ),
1755
+ 'screens' => array(
1756
+ State::STATE_ONBOARDED,
1757
+ ),
1758
+ 'requirements' => array(
1759
+ 'dcc',
1760
+ ),
1761
+ 'gateway' => 'dcc',
1762
+ ),
1763
+ );
1764
+ if ( ! defined( 'PPCP_FLAG_SUBSCRIPTION' ) || ! PPCP_FLAG_SUBSCRIPTION ) {
1765
+ unset( $fields['vault_enabled'] );
1766
+ }
1767
+
1768
+ if ( State::STATE_ONBOARDED === $state->production_state() ) {
1769
+ unset( $fields['ppcp_onboarding_production'] );
1770
+ } else {
1771
+ unset( $fields['ppcp_disconnect_production'] );
1772
+ }
1773
+ if ( State::STATE_ONBOARDED === $state->sandbox_state() ) {
1774
+ unset( $fields['ppcp_onboarding_sandbox'] );
1775
+ } else {
1776
+ unset( $fields['ppcp_disconnect_sandbox'] );
1777
+ }
1778
+
1779
+ /**
1780
+ * Disable card for UK.
1781
+ */
1782
+ $region = wc_get_base_location();
1783
+ $country = $region['country'];
1784
+ if ( 'GB' === $country ) {
1785
+ unset( $fields['disable_funding']['options']['card'] );
1786
+ }
1787
+
1788
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
1789
+ /**
1790
+ * Depending on your store location, some credit cards can't be used.
1791
+ * Here, we filter them out.
1792
+ *
1793
+ * The DCC Applies object.
1794
+ *
1795
+ * @var DccApplies $dcc_applies
1796
+ */
1797
+ $card_options = $fields['disable_cards']['options'];
1798
+ foreach ( $card_options as $card => $label ) {
1799
+ if ( $dcc_applies->can_process_card( $card ) ) {
1800
+ continue;
1801
+ }
1802
+ unset( $card_options[ $card ] );
1803
+ }
1804
+ $fields['disable_cards']['options'] = $card_options;
1805
+ $fields['card_icons']['options'] = $card_options;
1806
+ return $fields;
1807
+ },
1808
+
1809
+ 'wcgateway.checkout.address-preset' => static function( $container ): CheckoutPayPalAddressPreset {
1810
+
1811
+ return new CheckoutPayPalAddressPreset(
1812
+ $container->get( 'session.handler' )
1813
+ );
1814
+ },
1815
+ 'wcgateway.url' => static function ( $container ): string {
1816
+ return plugins_url(
1817
+ '/modules/ppcp-wc-gateway/',
1818
+ dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1819
+ );
1820
+ },
1821
+ 'wcgateway.endpoint.return-url' => static function ( $container ) : ReturnUrlEndpoint {
1822
+ $gateway = $container->get( 'wcgateway.paypal-gateway' );
1823
+ $endpoint = $container->get( 'api.endpoint.order' );
1824
+ $prefix = $container->get( 'api.prefix' );
1825
+ return new ReturnUrlEndpoint(
1826
+ $gateway,
1827
+ $endpoint,
1828
+ $prefix
1829
+ );
1830
+ },
1831
+ 'wcgateway.helper.dcc-product-status' => static function ( $container ) : DccProductStatus {
1832
+
1833
+ $settings = $container->get( 'wcgateway.settings' );
1834
+ $partner_endpoint = $container->get( 'api.endpoint.partners' );
1835
+ return new DccProductStatus( $settings, $partner_endpoint );
1836
+ },
1837
+ );
modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the columns to display to the merchant, which orders have been authorized and
4
+ * which have not been authorized yet.
5
+ *
6
+ * @package WooCommerce\PayPalCommerce\WcGateway\Admin
7
+ */
8
+
9
+ declare(strict_types=1);
10
+
11
+ namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
12
+
13
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
15
+
16
+ /**
17
+ * Class OrderTablePaymentStatusColumn
18
+ */
19
+ class OrderTablePaymentStatusColumn {
20
+
21
+ const COLUMN_KEY = 'ppcp_payment_status';
22
+ const INTENT = 'authorize';
23
+ const AFTER_COLUMN_KEY = 'order_status';
24
+
25
+ /**
26
+ * The settings.
27
+ *
28
+ * @var Settings
29
+ */
30
+ private $settings;
31
+
32
+ /**
33
+ * OrderTablePaymentStatusColumn constructor.
34
+ *
35
+ * @param Settings $settings The Settings.
36
+ */
37
+ public function __construct( Settings $settings ) {
38
+ $this->settings = $settings;
39
+ }
40
+
41
+ /**
42
+ * Register the columns.
43
+ *
44
+ * @param array $columns The existing columns.
45
+ *
46
+ * @return array
47
+ */
48
+ public function register( array $columns ): array {
49
+ if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
50
+ return $columns;
51
+ }
52
+
53
+ $status_column_position = array_search( self::AFTER_COLUMN_KEY, array_keys( $columns ), true );
54
+ $to_insert_position = false === $status_column_position ? count( $columns ) : $status_column_position + 1;
55
+
56
+ $columns = array_merge(
57
+ array_slice( $columns, 0, $to_insert_position ),
58
+ array(
59
+ self::COLUMN_KEY => __( 'Payment Captured', 'woocommerce-paypal-payments' ),
60
+ ),
61
+ array_slice( $columns, $to_insert_position )
62
+ );
63
+
64
+ return $columns;
65
+ }
66
+
67
+ /**
68
+ * Render the column.
69
+ *
70
+ * @param string $column The column.
71
+ * @param int $wc_order_id The id or the WooCommerce order.
72
+ */
73
+ public function render( string $column, int $wc_order_id ) {
74
+ if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
75
+ return;
76
+ }
77
+
78
+ if ( self::COLUMN_KEY !== $column ) {
79
+ return;
80
+ }
81
+
82
+ $wc_order = wc_get_order( $wc_order_id );
83
+
84
+ if ( ! is_a( $wc_order, \WC_Order::class ) || ! $this->render_for_order( $wc_order ) ) {
85
+ return;
86
+ }
87
+
88
+ if ( $this->is_captured( $wc_order ) ) {
89
+ $this->render_completed_status();
90
+ return;
91
+ }
92
+
93
+ $this->render_incomplete_status();
94
+ }
95
+
96
+ /**
97
+ * Whether to render the authorization status of an order or not.
98
+ *
99
+ * @param \WC_Order $order The WooCommerce order.
100
+ *
101
+ * @return bool
102
+ */
103
+ private function render_for_order( \WC_Order $order ): bool {
104
+ return ! empty( $order->get_meta( PayPalGateway::CAPTURED_META_KEY ) );
105
+ }
106
+
107
+ /**
108
+ * Whether the order has been captured or not.
109
+ *
110
+ * @param \WC_Order $wc_order The WooCommerce order.
111
+ *
112
+ * @return bool
113
+ */
114
+ private function is_captured( \WC_Order $wc_order ): bool {
115
+ $captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
116
+ return wc_string_to_bool( $captured );
117
+ }
118
+
119
+ /**
120
+ * Renders the captured status.
121
+ */
122
+ private function render_completed_status() {
123
+ printf(
124
+ '<span class="dashicons dashicons-yes">
125
+ <span class="screen-reader-text">%s</span>
126
+ </span>',
127
+ esc_html__( 'Payment captured', 'woocommerce-paypal-payments' )
128
+ );
129
+ }
130
+
131
+ /**
132
+ * Renders the "not captured" status.
133
+ */
134
+ private function render_incomplete_status() {
135
+ printf(
136
+ '<mark class="onbackorder">%s</mark>',
137
+ esc_html__( 'Not captured', 'woocommerce-paypal-payments' )
138
+ );
139
+ }
140
+ }
modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the not captured information.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Admin
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
+
12
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
+
14
+ /**
15
+ * Class PaymentStatusOrderDetail
16
+ */
17
+ class PaymentStatusOrderDetail {
18
+
19
+ /**
20
+ * Renders the not captured information.
21
+ *
22
+ * @param int $wc_order_id The WooCommerce order id.
23
+ */
24
+ public function render( int $wc_order_id ) {
25
+ $wc_order = new \WC_Order( $wc_order_id );
26
+ $intent = $wc_order->get_meta( PayPalGateway::INTENT_META_KEY );
27
+ $captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
28
+
29
+ if ( strcasecmp( $intent, 'AUTHORIZE' ) !== 0 ) {
30
+ return;
31
+ }
32
+
33
+ if ( ! empty( $captured ) && wc_string_to_bool( $captured ) ) {
34
+ return;
35
+ }
36
+
37
+ printf(
38
+ // @phpcs:ignore Inpsyde.CodeQuality.LineLength.TooLong
39
+ '<li class="wide"><p><mark class="order-status status-on-hold"><span>%1$s</span></mark></p><p>%2$s</p></li>',
40
+ esc_html__(
41
+ 'Not captured',
42
+ 'woocommerce-paypal-payments'
43
+ ),
44
+ esc_html__(
45
+ 'To capture the payment select capture action from the list below.',
46
+ 'woocommerce-paypal-payments'
47
+ )
48
+ );
49
+ }
50
+ }
modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the order action "Capture authorized PayPal payment"
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Admin
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
+
12
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
+
14
+ /**
15
+ * Class RenderAuthorizeAction
16
+ */
17
+ class RenderAuthorizeAction {
18
+
19
+ /**
20
+ * Renders the action into the $order_actions array based on the WooCommerce order.
21
+ *
22
+ * @param array $order_actions The actions to render into.
23
+ * @param \WC_Order $wc_order The order for which to render the action.
24
+ *
25
+ * @return array
26
+ */
27
+ public function render( array $order_actions, \WC_Order $wc_order ) : array {
28
+
29
+ if ( ! $this->should_render_for_order( $wc_order ) ) {
30
+ return $order_actions;
31
+ }
32
+
33
+ $order_actions['ppcp_authorize_order'] = esc_html__(
34
+ 'Capture authorized PayPal payment',
35
+ 'woocommerce-paypal-payments'
36
+ );
37
+ return $order_actions;
38
+ }
39
+
40
+ /**
41
+ * Whether the action should be rendered for a certain WooCommerce order.
42
+ *
43
+ * @param \WC_Order $order The Woocommerce order.
44
+ *
45
+ * @return bool
46
+ */
47
+ private function should_render_for_order( \WC_Order $order ) : bool {
48
+ $data = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
49
+ return in_array( $data, array( 'true', 'false' ), true );
50
+ }
51
+ }
modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Service that fills checkout address fields
4
+ * with address selected via PayPal
5
+ *
6
+ * @package WooCommerce\PayPalCommerce\WcGateway\Checkout
7
+ */
8
+
9
+ declare(strict_types=1);
10
+
11
+ namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
12
+
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping;
14
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
15
+
16
+ /**
17
+ * Class CheckoutPayPalAddressPreset
18
+ */
19
+ class CheckoutPayPalAddressPreset {
20
+
21
+ /**
22
+ * Caches Shipping objects for orders.
23
+ *
24
+ * @var array
25
+ */
26
+ private $shipping_cache = array();
27
+
28
+ /**
29
+ * The Session Handler.
30
+ *
31
+ * @var SessionHandler
32
+ */
33
+ private $session_handler;
34
+
35
+ /**
36
+ * CheckoutPayPalAddressPreset constructor.
37
+ *
38
+ * @param SessionHandler $session_handler The session handler.
39
+ */
40
+ public function __construct( SessionHandler $session_handler ) {
41
+ $this->session_handler = $session_handler;
42
+ }
43
+
44
+ /**
45
+ * Filters the checkout fields to replace values if necessary.
46
+ *
47
+ * @wp-hook woocommerce_checkout_get_value
48
+ *
49
+ * @param string|null $default_value The default value.
50
+ * @param string $field_id The field ID.
51
+ *
52
+ * @return string|null
53
+ */
54
+ public function filter_checkout_field( $default_value, $field_id ) {
55
+ if ( ! is_string( $default_value ) ) {
56
+ $default_value = null;
57
+ }
58
+
59
+ if ( ! is_string( $field_id ) ) {
60
+ return $default_value;
61
+ }
62
+
63
+ return $this->read_preset_for_field( $field_id ) ?? $default_value;
64
+ }
65
+
66
+ /**
67
+ * Returns the value for a checkout field from an PayPal order if given.
68
+ *
69
+ * @param string $field_id The ID of the field.
70
+ *
71
+ * @return string|null
72
+ */
73
+ private function read_preset_for_field( string $field_id ) {
74
+ $order = $this->session_handler->order();
75
+ if ( ! $order ) {
76
+ return null;
77
+ }
78
+
79
+ $shipping = $this->read_shipping_from_order();
80
+ $payer = $order->payer();
81
+
82
+ $address_map = array(
83
+ 'billing_address_1' => 'address_line_1',
84
+ 'billing_address_2' => 'address_line_2',
85
+ 'billing_postcode' => 'postal_code',
86
+ 'billing_country' => 'country_code',
87
+ 'billing_city' => 'admin_area_2',
88
+ 'billing_state' => 'admin_area_1',
89
+ );
90
+ $payer_name_map = array(
91
+ 'billing_last_name' => 'surname',
92
+ 'billing_first_name' => 'given_name',
93
+ );
94
+ $payer_map = array(
95
+ 'billing_email' => 'email_address',
96
+ );
97
+ $payer_phone_map = array(
98
+ 'billing_phone' => 'national_number',
99
+ );
100
+
101
+ if ( array_key_exists( $field_id, $address_map ) && $shipping ) {
102
+ return $shipping->address()->{$address_map[ $field_id ]}() ? $shipping->address()->{$address_map[ $field_id ]}() : null;
103
+ }
104
+
105
+ if ( array_key_exists( $field_id, $payer_name_map ) && $payer ) {
106
+ return $payer->name()->{$payer_name_map[ $field_id ]}() ? $payer->name()->{$payer_name_map[ $field_id ]}() : null;
107
+ }
108
+
109
+ if ( array_key_exists( $field_id, $payer_map ) && $payer ) {
110
+ return $payer->{$payer_map[ $field_id ]}() ? $payer->{$payer_map[ $field_id ]}() : null;
111
+ }
112
+
113
+ if (
114
+ array_key_exists( $field_id, $payer_phone_map )
115
+ && $payer
116
+ && $payer->phone()
117
+ && $payer->phone()->phone()
118
+ ) {
119
+ return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
120
+ }
121
+
122
+ return null;
123
+ }
124
+
125
+ /**
126
+ * Returns the Shipping object for an order, if given.
127
+ *
128
+ * @return Shipping|null
129
+ */
130
+ private function read_shipping_from_order() {
131
+ $order = $this->session_handler->order();
132
+ if ( ! $order ) {
133
+ return null;
134
+ }
135
+
136
+ if ( array_key_exists( $order->id(), $this->shipping_cache ) ) {
137
+ return $this->shipping_cache[ $order->id() ];
138
+ }
139
+
140
+ $shipping = null;
141
+ foreach ( $this->session_handler->order()->purchase_units() as $unit ) {
142
+ $shipping = $unit->shipping();
143
+ if ( $shipping ) {
144
+ break;
145
+ }
146
+ }
147
+
148
+ $this->shipping_cache[ $order->id() ] = $shipping;
149
+
150
+ return $shipping;
151
+ }
152
+ }
modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Determines whether specific gateways need to be disabled.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Checkout
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
11
+
12
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class DisableGateways
19
+ */
20
+ class DisableGateways {
21
+
22
+
23
+ /**
24
+ * The Session Handler.
25
+ *
26
+ * @var SessionHandler
27
+ */
28
+ private $session_handler;
29
+
30
+ /**
31
+ * The Settings.
32
+ *
33
+ * @var ContainerInterface
34
+ */
35
+ private $settings;
36
+
37
+ /**
38
+ * DisableGateways constructor.
39
+ *
40
+ * @param SessionHandler $session_handler The Session Handler.
41
+ * @param ContainerInterface $settings The Settings.
42
+ */
43
+ public function __construct(
44
+ SessionHandler $session_handler,
45
+ ContainerInterface $settings
46
+ ) {
47
+
48
+ $this->session_handler = $session_handler;
49
+ $this->settings = $settings;
50
+ }
51
+
52
+ /**
53
+ * Controls the logic for enabling/disabling gateways.
54
+ *
55
+ * @param array $methods The Gateways.
56
+ *
57
+ * @return array
58
+ */
59
+ public function handler( array $methods ): array {
60
+ if ( ! isset( $methods[ PayPalGateway::ID ] ) && ! isset( $methods[ CreditCardGateway::ID ] ) ) {
61
+ return $methods;
62
+ }
63
+ if ( $this->disable_both_gateways() ) {
64
+ unset( $methods[ PayPalGateway::ID ] );
65
+ unset( $methods[ CreditCardGateway::ID ] );
66
+ return $methods;
67
+ }
68
+
69
+ if ( ! $this->settings->has( 'client_id' ) || empty( $this->settings->get( 'client_id' ) ) ) {
70
+ unset( $methods[ CreditCardGateway::ID ] );
71
+ }
72
+
73
+ if ( $this->settings->has( 'button_enabled' ) && ! $this->settings->get( 'button_enabled' ) && ! $this->session_handler->order() ) {
74
+ unset( $methods[ PayPalGateway::ID ] );
75
+ }
76
+
77
+ if ( ! $this->needs_to_disable_gateways() ) {
78
+ return $methods;
79
+ }
80
+
81
+ if ( $this->is_credit_card() ) {
82
+ return array( CreditCardGateway::ID => $methods[ CreditCardGateway::ID ] );
83
+ }
84
+ return array( PayPalGateway::ID => $methods[ PayPalGateway::ID ] );
85
+ }
86
+
87
+ /**
88
+ * Whether both gateways should be disabled or not.
89
+ *
90
+ * @return bool
91
+ */
92
+ private function disable_both_gateways() : bool {
93
+ if ( ! $this->settings->has( 'enabled' ) || ! $this->settings->get( 'enabled' ) ) {
94
+ return true;
95
+ }
96
+ if ( ! $this->settings->has( 'merchant_email' ) || ! is_email( $this->settings->get( 'merchant_email' ) ) ) {
97
+ return true;
98
+ }
99
+
100
+ return false;
101
+ }
102
+
103
+ /**
104
+ * Whether the Gateways need to be disabled. When we come to the checkout with a running PayPal
105
+ * session, we need to disable the other Gateways, so the customer can smoothly sail through the
106
+ * process.
107
+ *
108
+ * @return bool
109
+ */
110
+ private function needs_to_disable_gateways(): bool {
111
+ return $this->session_handler->order() !== null;
112
+ }
113
+
114
+ /**
115
+ * Whether the current PayPal session is done via DCC payment.
116
+ *
117
+ * @return bool
118
+ */
119
+ private function is_credit_card(): bool {
120
+ $order = $this->session_handler->order();
121
+ if ( ! $order ) {
122
+ return false;
123
+ }
124
+ if ( ! $order->payment_source() || ! $order->payment_source()->card() ) {
125
+ return false;
126
+ }
127
+ return true;
128
+ }
129
+ }
modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the endpoint for customers returning from PayPal.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Endpoint
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Endpoint;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
14
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\PrefixTrait;
15
+
16
+ /**
17
+ * Class ReturnUrlEndpoint
18
+ */
19
+ class ReturnUrlEndpoint {
20
+
21
+ use PrefixTrait;
22
+ const ENDPOINT = 'ppc-return-url';
23
+
24
+ /**
25
+ * The PayPal Gateway.
26
+ *
27
+ * @var PayPalGateway
28
+ */
29
+ private $gateway;
30
+
31
+ /**
32
+ * The Order Endpoint.
33
+ *
34
+ * @var OrderEndpoint
35
+ */
36
+ private $order_endpoint;
37
+
38
+ /**
39
+ * ReturnUrlEndpoint constructor.
40
+ *
41
+ * @param PayPalGateway $gateway The PayPal Gateway.
42
+ * @param OrderEndpoint $order_endpoint The Order Endpoint.
43
+ * @param string $prefix The prefix.
44
+ */
45
+ public function __construct( PayPalGateway $gateway, OrderEndpoint $order_endpoint, string $prefix ) {
46
+ $this->gateway = $gateway;
47
+ $this->order_endpoint = $order_endpoint;
48
+ $this->prefix = $prefix;
49
+ }
50
+
51
+ /**
52
+ * Handles the incoming request.
53
+ */
54
+ public function handle_request() {
55
+
56
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
57
+ if ( ! isset( $_GET['token'] ) ) {
58
+ exit();
59
+ }
60
+
61
+ $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
62
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
63
+ $order = $this->order_endpoint->order( $token );
64
+ if ( ! $order ) {
65
+ exit();
66
+ }
67
+
68
+ $wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
69
+ if ( ! $wc_order_id ) {
70
+ exit();
71
+ }
72
+
73
+ $wc_order = wc_get_order( $wc_order_id );
74
+ if ( ! $wc_order ) {
75
+ exit();
76
+ }
77
+
78
+ $success = $this->gateway->process_payment( $wc_order_id );
79
+ if ( isset( $success['result'] ) && 'success' === $success['result'] ) {
80
+ add_filter(
81
+ 'allowed_redirect_hosts',
82
+ function( $allowed_hosts ) : array {
83
+ $allowed_hosts[] = 'www.paypal.com';
84
+ $allowed_hosts[] = 'www.sandbox.paypal.com';
85
+ return (array) $allowed_hosts;
86
+ }
87
+ );
88
+ wp_safe_redirect( $success['redirect'] );
89
+ exit();
90
+ }
91
+ wp_safe_redirect( wc_get_checkout_url() );
92
+ exit();
93
+ }
94
+ }
modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Not Found Exception for the Settings Container.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Exception
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Exception;
11
+
12
+ use Exception;
13
+ use Psr\Container\NotFoundExceptionInterface;
14
+
15
+ /**
16
+ * Class NotFoundException
17
+ */
18
+ class NotFoundException extends Exception implements NotFoundExceptionInterface {
19
+
20
+
21
+ }
modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Credit card gateway.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Gateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
+
12
+ use WooCommerce\PayPalCommerce\Onboarding\State;
13
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
15
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
19
+ use Psr\Container\ContainerInterface;
20
+
21
+ /**
22
+ * Class CreditCardGateway
23
+ */
24
+ class CreditCardGateway extends \WC_Payment_Gateway_CC {
25
+
26
+ use ProcessPaymentTrait;
27
+
28
+ const ID = 'ppcp-credit-card-gateway';
29
+
30
+ /**
31
+ * The URL to the module.
32
+ *
33
+ * @var string
34
+ */
35
+ private $module_url;
36
+
37
+ /**
38
+ * The refund processor.
39
+ *
40
+ * @var RefundProcessor
41
+ */
42
+ private $refund_processor;
43
+
44
+ /**
45
+ * CreditCardGateway constructor.
46
+ *
47
+ * @param SettingsRenderer $settings_renderer The Settings Renderer.
48
+ * @param OrderProcessor $order_processor The Order processor.
49
+ * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
50
+ * @param AuthorizeOrderActionNotice $notice The Notices.
51
+ * @param ContainerInterface $config The settings.
52
+ * @param string $module_url The URL to the module.
53
+ * @param SessionHandler $session_handler The Session Handler.
54
+ * @param RefundProcessor $refund_processor The refund processor.
55
+ * @param State $state The state.
56
+ */
57
+ public function __construct(
58
+ SettingsRenderer $settings_renderer,
59
+ OrderProcessor $order_processor,
60
+ AuthorizedPaymentsProcessor $authorized_payments_processor,
61
+ AuthorizeOrderActionNotice $notice,
62
+ ContainerInterface $config,
63
+ string $module_url,
64
+ SessionHandler $session_handler,
65
+ RefundProcessor $refund_processor,
66
+ State $state
67
+ ) {
68
+
69
+ $this->id = self::ID;
70
+ $this->order_processor = $order_processor;
71
+ $this->authorized_payments = $authorized_payments_processor;
72
+ $this->notice = $notice;
73
+ $this->settings_renderer = $settings_renderer;
74
+ $this->config = $config;
75
+ $this->session_handler = $session_handler;
76
+ $this->refund_processor = $refund_processor;
77
+
78
+ if ( $state->current_state() === State::STATE_ONBOARDED ) {
79
+ $this->supports = array( 'refunds' );
80
+ }
81
+ if (
82
+ defined( 'PPCP_FLAG_SUBSCRIPTION' )
83
+ && PPCP_FLAG_SUBSCRIPTION
84
+ && $this->config->has( 'vault_enabled' )
85
+ && $this->config->get( 'vault_enabled' )
86
+ ) {
87
+ $this->supports = array(
88
+ 'refunds',
89
+ 'products',
90
+ 'subscriptions',
91
+ 'subscription_cancellation',
92
+ 'subscription_suspension',
93
+ 'subscription_reactivation',
94
+ 'subscription_amount_changes',
95
+ 'subscription_date_changes',
96
+ 'subscription_payment_method_change',
97
+ 'subscription_payment_method_change_customer',
98
+ 'subscription_payment_method_change_admin',
99
+ 'multiple_subscriptions',
100
+ 'credit_card_form_cvc_on_saved_method',
101
+ );
102
+ }
103
+
104
+ $this->method_title = __(
105
+ 'PayPal Card Processing',
106
+ 'woocommerce-paypal-payments'
107
+ );
108
+ $this->method_description = __(
109
+ 'Accept debit and credit cards, and local payment methods with PayPal’s latest solution.',
110
+ 'woocommerce-paypal-payments'
111
+ );
112
+ $this->title = $this->config->has( 'dcc_gateway_title' ) ?
113
+ $this->config->get( 'dcc_gateway_title' ) : $this->method_title;
114
+ $this->description = $this->config->has( 'dcc_gateway_description' ) ?
115
+ $this->config->get( 'dcc_gateway_description' ) : $this->method_description;
116
+
117
+ $this->init_form_fields();
118
+ $this->init_settings();
119
+
120
+ add_action(
121
+ 'woocommerce_update_options_payment_gateways_' . $this->id,
122
+ array(
123
+ $this,
124
+ 'process_admin_options',
125
+ )
126
+ );
127
+
128
+ $this->module_url = $module_url;
129
+ }
130
+
131
+ /**
132
+ * Initialize the form fields.
133
+ */
134
+ public function init_form_fields() {
135
+ $this->form_fields = array(
136
+ 'enabled' => array(
137
+ 'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
138
+ 'type' => 'checkbox',
139
+ 'label' => __( 'Enable Credit Card Payments', 'woocommerce-paypal-payments' ),
140
+ 'default' => 'no',
141
+ ),
142
+ 'ppcp' => array(
143
+ 'type' => 'ppcp',
144
+ ),
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Returns the title of the gateway.
150
+ *
151
+ * @return string
152
+ */
153
+ public function get_title() {
154
+
155
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
156
+ if ( ! is_checkout() || ( is_ajax() && isset( $_GET['wc-ajax'] ) && 'update_order_review' !== $_GET['wc-ajax'] ) ) {
157
+ return parent::get_title();
158
+ }
159
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
160
+ $title = parent::get_title();
161
+ $icons = $this->config->has( 'card_icons' ) ? (array) $this->config->get( 'card_icons' ) : array();
162
+ if ( empty( $icons ) ) {
163
+ return $title;
164
+ }
165
+
166
+ $title_options = $this->card_labels();
167
+ $images = array_map(
168
+ function ( string $type ) use ( $title_options ): string {
169
+ return '<img
170
+ title="' . esc_attr( $title_options[ $type ] ) . '"
171
+ src="' . esc_url( $this->module_url ) . '/assets/images/' . esc_attr( $type ) . '.svg"
172
+ class="ppcp-card-icon"
173
+ > ';
174
+ },
175
+ $icons
176
+ );
177
+ return $title . implode( '', $images );
178
+ }
179
+
180
+ /**
181
+ * Returns an array of credit card names.
182
+ *
183
+ * @return array
184
+ */
185
+ private function card_labels(): array {
186
+ return array(
187
+ 'visa' => _x(
188
+ 'Visa',
189
+ 'Name of credit card',
190
+ 'woocommerce-paypal-payments'
191
+ ),
192
+ 'mastercard' => _x(
193
+ 'Mastercard',
194
+ 'Name of credit card',
195
+ 'woocommerce-paypal-payments'
196
+ ),
197
+ 'amex' => _x(
198
+ 'American Express',
199
+ 'Name of credit card',
200
+ 'woocommerce-paypal-payments'
201
+ ),
202
+ 'discover' => _x(
203
+ 'Discover',
204
+ 'Name of credit card',
205
+ 'woocommerce-paypal-payments'
206
+ ),
207
+ 'jcb' => _x(
208
+ 'JCB',
209
+ 'Name of credit card',
210
+ 'woocommerce-paypal-payments'
211
+ ),
212
+ 'elo' => _x(
213
+ 'Elo',
214
+ 'Name of credit card',
215
+ 'woocommerce-paypal-payments'
216
+ ),
217
+ 'hiper' => _x(
218
+ 'Hiper',
219
+ 'Name of credit card',
220
+ 'woocommerce-paypal-payments'
221
+ ),
222
+ );
223
+ }
224
+
225
+ /**
226
+ * Whether the gateway is available or not.
227
+ *
228
+ * @return bool
229
+ */
230
+ public function is_available() : bool {
231
+ return $this->config->has( 'dcc_enabled' ) && $this->config->get( 'dcc_enabled' );
232
+ }
233
+
234
+
235
+ /**
236
+ * Process refund.
237
+ *
238
+ * If the gateway declares 'refunds' support, this will allow it to refund.
239
+ * a passed in amount.
240
+ *
241
+ * @param int $order_id Order ID.
242
+ * @param float $amount Refund amount.
243
+ * @param string $reason Refund reason.
244
+ * @return boolean True or false based on success, or a WP_Error object.
245
+ */
246
+ public function process_refund( $order_id, $amount = null, $reason = '' ) {
247
+ $order = wc_get_order( $order_id );
248
+ if ( ! is_a( $order, \WC_Order::class ) ) {
249
+ return false;
250
+ }
251
+ return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
252
+ }
253
+ }
modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The PayPal Payment Gateway
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Gateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
13
+ use WooCommerce\PayPalCommerce\Onboarding\State;
14
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
15
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
19
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
21
+ use Psr\Container\ContainerInterface;
22
+
23
+ /**
24
+ * Class PayPalGateway
25
+ */
26
+ class PayPalGateway extends \WC_Payment_Gateway {
27
+
28
+ use ProcessPaymentTrait;
29
+
30
+ const ID = 'ppcp-gateway';
31
+ const CAPTURED_META_KEY = '_ppcp_paypal_captured';
32
+ const INTENT_META_KEY = '_ppcp_paypal_intent';
33
+ const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
34
+
35
+ /**
36
+ * The Settings Renderer.
37
+ *
38
+ * @var SettingsRenderer
39
+ */
40
+ protected $settings_renderer;
41
+
42
+ /**
43
+ * The processor for authorized payments.
44
+ *
45
+ * @var AuthorizedPaymentsProcessor
46
+ */
47
+ protected $authorized_payments;
48
+
49
+ /**
50
+ * The Authorized Order Action Notice.
51
+ *
52
+ * @var AuthorizeOrderActionNotice
53
+ */
54
+ protected $notice;
55
+
56
+ /**
57
+ * The processor for orders.
58
+ *
59
+ * @var OrderProcessor
60
+ */
61
+ protected $order_processor;
62
+
63
+ /**
64
+ * The settings.
65
+ *
66
+ * @var ContainerInterface
67
+ */
68
+ protected $config;
69
+
70
+ /**
71
+ * The Session Handler.
72
+ *
73
+ * @var SessionHandler
74
+ */
75
+ protected $session_handler;
76
+
77
+ /**
78
+ * The Refund Processor.
79
+ *
80
+ * @var RefundProcessor
81
+ */
82
+ private $refund_processor;
83
+
84
+ /**
85
+ * PayPalGateway constructor.
86
+ *
87
+ * @param SettingsRenderer $settings_renderer The Settings Renderer.
88
+ * @param OrderProcessor $order_processor The Order Processor.
89
+ * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
90
+ * @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
91
+ * @param ContainerInterface $config The settings.
92
+ * @param SessionHandler $session_handler The Session Handler.
93
+ * @param RefundProcessor $refund_processor The Refund Processor.
94
+ * @param State $state The state.
95
+ */
96
+ public function __construct(
97
+ SettingsRenderer $settings_renderer,
98
+ OrderProcessor $order_processor,
99
+ AuthorizedPaymentsProcessor $authorized_payments_processor,
100
+ AuthorizeOrderActionNotice $notice,
101
+ ContainerInterface $config,
102
+ SessionHandler $session_handler,
103
+ RefundProcessor $refund_processor,
104
+ State $state
105
+ ) {
106
+
107
+ $this->id = self::ID;
108
+ $this->order_processor = $order_processor;
109
+ $this->authorized_payments = $authorized_payments_processor;
110
+ $this->notice = $notice;
111
+ $this->settings_renderer = $settings_renderer;
112
+ $this->config = $config;
113
+ $this->session_handler = $session_handler;
114
+ $this->refund_processor = $refund_processor;
115
+
116
+ if ( $state->current_state() === State::STATE_ONBOARDED ) {
117
+ $this->supports = array( 'refunds' );
118
+ }
119
+ if (
120
+ defined( 'PPCP_FLAG_SUBSCRIPTION' )
121
+ && PPCP_FLAG_SUBSCRIPTION
122
+ && $this->config->has( 'vault_enabled' )
123
+ && $this->config->get( 'vault_enabled' )
124
+ ) {
125
+ $this->supports = array(
126
+ 'refunds',
127
+ 'products',
128
+ 'subscriptions',
129
+ 'subscription_cancellation',
130
+ 'subscription_suspension',
131
+ 'subscription_reactivation',
132
+ 'subscription_amount_changes',
133
+ 'subscription_date_changes',
134
+ 'subscription_payment_method_change',
135
+ 'subscription_payment_method_change_customer',
136
+ 'subscription_payment_method_change_admin',
137
+ 'multiple_subscriptions',
138
+ );
139
+ }
140
+
141
+ $this->method_title = $this->define_method_title();
142
+ $this->method_description = $this->define_method_description();
143
+ $this->title = $this->config->has( 'title' ) ?
144
+ $this->config->get( 'title' ) : $this->method_title;
145
+ $this->description = $this->config->has( 'description' ) ?
146
+ $this->config->get( 'description' ) : $this->method_description;
147
+
148
+ $this->init_form_fields();
149
+ $this->init_settings();
150
+
151
+ add_action(
152
+ 'woocommerce_update_options_payment_gateways_' . $this->id,
153
+ array(
154
+ $this,
155
+ 'process_admin_options',
156
+ )
157
+ );
158
+ }
159
+
160
+ /**
161
+ * Whether the Gateway needs to be setup.
162
+ *
163
+ * @return bool
164
+ */
165
+ public function needs_setup(): bool {
166
+
167
+ return true;
168
+ }
169
+
170
+ /**
171
+ * Initializes the form fields.
172
+ */
173
+ public function init_form_fields() {
174
+ $this->form_fields = array(
175
+ 'enabled' => array(
176
+ 'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
177
+ 'type' => 'checkbox',
178
+ 'desc_tip' => true,
179
+ 'description' => __( 'In order to use PayPal or PayPal Card Processing, you need to enable the Gateway.', 'woocommerce-paypal-payments' ),
180
+ 'label' => __( 'Enable the PayPal Gateway', 'woocommerce-paypal-payments' ),
181
+ 'default' => 'no',
182
+ ),
183
+ 'ppcp' => array(
184
+ 'type' => 'ppcp',
185
+ ),
186
+ );
187
+
188
+ $should_show_enabled_checkbox = ! $this->is_credit_card_tab() && ( $this->config->has( 'merchant_email' ) && $this->config->get( 'merchant_email' ) );
189
+ if ( ! $should_show_enabled_checkbox ) {
190
+ unset( $this->form_fields['enabled'] );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Captures an authorized payment for an WooCommerce order.
196
+ *
197
+ * @param \WC_Order $wc_order The WooCommerce order.
198
+ *
199
+ * @return bool
200
+ */
201
+ public function capture_authorized_payment( \WC_Order $wc_order ): bool {
202
+ $is_processed = $this->authorized_payments->process( $wc_order );
203
+ $this->render_authorization_message_for_status( $this->authorized_payments->last_status() );
204
+
205
+ if ( $is_processed ) {
206
+ $wc_order->add_order_note(
207
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
208
+ );
209
+
210
+ $wc_order->set_status( 'processing' );
211
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
212
+ $wc_order->save();
213
+ return true;
214
+ }
215
+
216
+ if ( $this->authorized_payments->last_status() === AuthorizedPaymentsProcessor::ALREADY_CAPTURED ) {
217
+ if ( $wc_order->get_status() === 'on-hold' ) {
218
+ $wc_order->add_order_note(
219
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
220
+ );
221
+ $wc_order->set_status( 'processing' );
222
+ }
223
+
224
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
225
+ $wc_order->save();
226
+ return true;
227
+ }
228
+ return false;
229
+ }
230
+
231
+ /**
232
+ * Displays the notice for a status.
233
+ *
234
+ * @param string $status The status.
235
+ */
236
+ private function render_authorization_message_for_status( string $status ) {
237
+
238
+ $message_mapping = array(
239
+ AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
240
+ AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
241
+ AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
242
+ AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
243
+ );
244
+ $display_message = ( isset( $message_mapping[ $status ] ) ) ?
245
+ $message_mapping[ $status ]
246
+ : AuthorizeOrderActionNotice::FAILED;
247
+ $this->notice->display_message( $display_message );
248
+ }
249
+
250
+ /**
251
+ * Renders the settings.
252
+ *
253
+ * @return string
254
+ */
255
+ public function generate_ppcp_html(): string {
256
+
257
+ ob_start();
258
+ $this->settings_renderer->render( false );
259
+ $content = ob_get_contents();
260
+ ob_end_clean();
261
+ return $content;
262
+ }
263
+
264
+ /**
265
+ * Defines the method title. If we are on the credit card tab in the settings, we want to change this.
266
+ *
267
+ * @return string
268
+ */
269
+ private function define_method_title(): string {
270
+ if ( $this->is_credit_card_tab() ) {
271
+ return __( 'PayPal Card Processing', 'woocommerce-paypal-payments' );
272
+ }
273
+ if ( $this->is_paypal_tab() ) {
274
+ return __( 'PayPal Checkout', 'woocommerce-paypal-payments' );
275
+ }
276
+ return __( 'PayPal', 'woocommerce-paypal-payments' );
277
+ }
278
+
279
+ /**
280
+ * Defines the method description. If we are on the credit card tab in the settings, we want to change this.
281
+ *
282
+ * @return string
283
+ */
284
+ private function define_method_description(): string {
285
+ if ( $this->is_credit_card_tab() ) {
286
+ return __(
287
+ 'Accept debit and credit cards, and local payment methods.',
288
+ 'woocommerce-paypal-payments'
289
+ );
290
+ }
291
+
292
+ return __(
293
+ 'Accept PayPal, PayPal Credit and alternative payment types.',
294
+ 'woocommerce-paypal-payments'
295
+ );
296
+ }
297
+
298
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
299
+
300
+ /**
301
+ * Determines, whether the current session is on the credit card tab in the admin settings.
302
+ *
303
+ * @return bool
304
+ */
305
+ private function is_credit_card_tab() : bool {
306
+ return is_admin()
307
+ && isset( $_GET[ SectionsRenderer::KEY ] )
308
+ && CreditCardGateway::ID === sanitize_text_field( wp_unslash( $_GET[ SectionsRenderer::KEY ] ) );
309
+
310
+ }
311
+
312
+ /**
313
+ * Whether we are on the PayPal settings tab.
314
+ *
315
+ * @return bool
316
+ */
317
+ private function is_paypal_tab() : bool {
318
+ return ! $this->is_credit_card_tab()
319
+ && is_admin()
320
+ && isset( $_GET['section'] )
321
+ && self::ID === sanitize_text_field( wp_unslash( $_GET['section'] ) );
322
+ }
323
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
324
+
325
+ /**
326
+ * Process refund.
327
+ *
328
+ * If the gateway declares 'refunds' support, this will allow it to refund.
329
+ * a passed in amount.
330
+ *
331
+ * @param int $order_id Order ID.
332
+ * @param float $amount Refund amount.
333
+ * @param string $reason Refund reason.
334
+ * @return boolean True or false based on success, or a WP_Error object.
335
+ */
336
+ public function process_refund( $order_id, $amount = null, $reason = '' ) {
337
+ $order = wc_get_order( $order_id );
338
+ if ( ! is_a( $order, \WC_Order::class ) ) {
339
+ return false;
340
+ }
341
+ return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
342
+ }
343
+ }
modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The process_payment functionality for the both gateways.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Gateway
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
13
+
14
+ /**
15
+ * Trait ProcessPaymentTrait
16
+ */
17
+ trait ProcessPaymentTrait {
18
+ /**
19
+ * Process a payment for an WooCommerce order.
20
+ *
21
+ * @param int $order_id The WooCommerce order id.
22
+ *
23
+ * @return array|null
24
+ */
25
+ public function process_payment( $order_id ) {
26
+ global $woocommerce;
27
+ $wc_order = wc_get_order( $order_id );
28
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
29
+ return null;
30
+ }
31
+
32
+ /**
33
+ * If the WC_Order is payed through the approved webhook.
34
+ */
35
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
36
+ if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
37
+ $this->session_handler->destroy_session_data();
38
+ return array(
39
+ 'result' => 'success',
40
+ 'redirect' => $this->get_return_url( $wc_order ),
41
+ );
42
+ }
43
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
44
+
45
+ try {
46
+ if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
47
+ $this->session_handler->destroy_session_data();
48
+ return array(
49
+ 'result' => 'success',
50
+ 'redirect' => $this->get_return_url( $wc_order ),
51
+ );
52
+ }
53
+ } catch ( PayPalApiException $error ) {
54
+ if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
55
+ $this->session_handler->increment_insufficient_funding_tries();
56
+ $host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
57
+ 'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
58
+ $url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
59
+ if ( $this->session_handler->insufficient_funding_tries() >= 3 ) {
60
+ $this->session_handler->destroy_session_data();
61
+ wc_add_notice(
62
+ __( 'Please use a different payment method.', 'woocommerce-paypal-payments' ),
63
+ 'error'
64
+ );
65
+ return null;
66
+ }
67
+ return array(
68
+ 'result' => 'success',
69
+ 'redirect' => $url,
70
+ );
71
+ }
72
+
73
+ $this->session_handler->destroy_session_data();
74
+ }
75
+ wc_add_notice(
76
+ $this->order_processor->last_error(),
77
+ 'error'
78
+ );
79
+
80
+ return null;
81
+ }
82
+ }
modules/ppcp-wc-gateway/src/Gateway/class-wcgatewayinterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The WcGateway interface.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Gateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
+
12
+ /**
13
+ * Interface WcGatewayInterface
14
+ */
15
+ interface WcGatewayInterface {
16
+
17
+
18
+ }
modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manage the Seller status.
4
+ *
5
+ * @package Woocommerce\PayPalCommerce\WcGateway\Helper
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace Woocommerce\PayPalCommerce\WcGateway\Helper;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
16
+
17
+ /**
18
+ * Class DccProductStatus
19
+ */
20
+ class DccProductStatus {
21
+
22
+ /**
23
+ * Caches the status for the current load.
24
+ *
25
+ * @var string|null
26
+ */
27
+ private $current_status_cache;
28
+ /**
29
+ * The settings.
30
+ *
31
+ * @var Settings
32
+ */
33
+ private $settings;
34
+
35
+ /**
36
+ * The partners endpoint.
37
+ *
38
+ * @var PartnersEndpoint
39
+ */
40
+ private $partners_endpoint;
41
+
42
+ /**
43
+ * DccProductStatus constructor.
44
+ *
45
+ * @param Settings $settings The Settings.
46
+ * @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
47
+ */
48
+ public function __construct(
49
+ Settings $settings,
50
+ PartnersEndpoint $partners_endpoint
51
+ ) {
52
+ $this->settings = $settings;
53
+ $this->partners_endpoint = $partners_endpoint;
54
+ }
55
+
56
+ /**
57
+ * Whether the active/subscribed products support DCC.
58
+ *
59
+ * @return bool
60
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException Should a setting not be found.
61
+ */
62
+ public function dcc_is_active() : bool {
63
+ if ( is_bool( $this->current_status_cache ) ) {
64
+ return $this->current_status_cache;
65
+ }
66
+ if ( $this->settings->has( 'products_dcc_enabled' ) && $this->settings->get( 'products_dcc_enabled' ) ) {
67
+ $this->current_status_cache = true;
68
+ return true;
69
+ }
70
+
71
+ try {
72
+ $seller_status = $this->partners_endpoint->seller_status();
73
+ } catch ( RuntimeException $error ) {
74
+ $this->current_status_cache = false;
75
+ return false;
76
+ }
77
+
78
+ foreach ( $seller_status->products() as $product ) {
79
+ if ( ! in_array(
80
+ $product->vetting_status(),
81
+ array(
82
+ SellerStatusProduct::VETTING_STATUS_APPROVED,
83
+ SellerStatusProduct::VETTING_STATUS_SUBSCRIBED,
84
+ ),
85
+ true
86
+ )
87
+ ) {
88
+ continue;
89
+ }
90
+
91
+ if ( in_array( 'CUSTOM_CARD_PROCESSING', $product->capabilities(), true ) ) {
92
+ $this->settings->set( 'products_dcc_enabled', true );
93
+ $this->settings->persist();
94
+ $this->current_status_cache = true;
95
+ return true;
96
+ }
97
+ }
98
+
99
+ $this->current_status_cache = false;
100
+ return false;
101
+ }
102
+ }
modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains the messages to display, when capturing an authorization manually.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Notice
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Notice;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
+
14
+ /**
15
+ * Class AuthorizeOrderActionNotice
16
+ */
17
+ class AuthorizeOrderActionNotice {
18
+
19
+ const QUERY_PARAM = 'ppcp-authorized-message';
20
+
21
+ const NO_INFO = 81;
22
+ const ALREADY_CAPTURED = 82;
23
+ const FAILED = 83;
24
+ const SUCCESS = 84;
25
+ const NOT_FOUND = 85;
26
+
27
+ /**
28
+ * Returns the current message if there is one.
29
+ *
30
+ * @return Message|null
31
+ */
32
+ public function message() {
33
+
34
+ $message = $this->current_message();
35
+ if ( ! $message ) {
36
+ return null;
37
+ }
38
+
39
+ return new Message( $message['message'], $message['type'] );
40
+ }
41
+
42
+ /**
43
+ * Returns the current message.
44
+ *
45
+ * @return array
46
+ */
47
+ private function current_message(): array {
48
+ $messages[ self::NO_INFO ] = array(
49
+ 'message' => __(
50
+ 'Could not retrieve information. Try again later.',
51
+ 'woocommerce-paypal-payments'
52
+ ),
53
+ 'type' => 'error',
54
+ );
55
+ $messages[ self::ALREADY_CAPTURED ] = array(
56
+ 'message' => __(
57
+ 'Payment already captured.',
58
+ 'woocommerce-paypal-payments'
59
+ ),
60
+ 'type' => 'error',
61
+ );
62
+ $messages[ self::FAILED ] = array(
63
+ 'message' => __(
64
+ 'Failed to capture. Try again later.',
65
+ 'woocommerce-paypal-payments'
66
+ ),
67
+ 'type' => 'error',
68
+ );
69
+ $messages[ self::NOT_FOUND ] = array(
70
+ 'message' => __(
71
+ 'Could not find payment to process.',
72
+ 'woocommerce-paypal-payments'
73
+ ),
74
+ 'type' => 'error',
75
+ );
76
+ $messages[ self::SUCCESS ] = array(
77
+ 'message' => __(
78
+ 'Payment successfully captured.',
79
+ 'woocommerce-paypal-payments'
80
+ ),
81
+ 'type' => 'success',
82
+ );
83
+
84
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
85
+ if ( ! isset( $_GET[ self::QUERY_PARAM ] ) ) { // Input ok.
86
+ return array();
87
+ }
88
+ $message_id = absint( $_GET[ self::QUERY_PARAM ] ); // Input ok.
89
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
90
+ return ( isset( $messages[ $message_id ] ) ) ? $messages[ $message_id ] : array();
91
+ }
92
+
93
+ /**
94
+ * Adds the query parameter for the message to 'redirect_post_location'.
95
+ *
96
+ * @param int $message_code The message code.
97
+ */
98
+ public function display_message( int $message_code ) {
99
+ add_filter(
100
+ 'redirect_post_location',
101
+ static function ( $location ) use ( $message_code ) {
102
+ return add_query_arg(
103
+ self::QUERY_PARAM,
104
+ $message_code,
105
+ $location
106
+ );
107
+ }
108
+ );
109
+ }
110
+ }
modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Registers the admin message to "connect your account" if necessary.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Notice
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Notice;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
+ use WooCommerce\PayPalCommerce\Onboarding\State;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class ConnectAdminNotice
19
+ */
20
+ class ConnectAdminNotice {
21
+
22
+ /**
23
+ * The state.
24
+ *
25
+ * @var State
26
+ */
27
+ private $state;
28
+
29
+ /**
30
+ * The settings.
31
+ *
32
+ * @var ContainerInterface
33
+ */
34
+ private $settings;
35
+
36
+ /**
37
+ * ConnectAdminNotice constructor.
38
+ *
39
+ * @param State $state The state.
40
+ * @param ContainerInterface $settings The settings.
41
+ */
42
+ public function __construct( State $state, ContainerInterface $settings ) {
43
+ $this->state = $state;
44
+ $this->settings = $settings;
45
+ }
46
+
47
+ /**
48
+ * Returns the message.
49
+ *
50
+ * @return Message|null
51
+ */
52
+ public function connect_message() {
53
+ if ( ! $this->should_display() ) {
54
+ return null;
55
+ }
56
+
57
+ $message = sprintf(
58
+ /* translators: %1$s the gateway name. */
59
+ __(
60
+ 'PayPal Checkout is almost ready. To get started, <a href="%1$s">connect your account</a>.',
61
+ 'woocommerce-paypal-payments'
62
+ ),
63
+ admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway' )
64
+ );
65
+ return new Message( $message, 'warning' );
66
+ }
67
+
68
+ /**
69
+ * Whether the message should display.
70
+ *
71
+ * @return bool
72
+ */
73
+ protected function should_display(): bool {
74
+ return $this->state->current_state() < State::STATE_PROGRESSIVE;
75
+ }
76
+ }
modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Authorizes payments for a given WooCommerce order.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Processor
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
11
+
12
+ use Exception;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
+
20
+ /**
21
+ * Class AuthorizedPaymentsProcessor
22
+ */
23
+ class AuthorizedPaymentsProcessor {
24
+
25
+ const SUCCESSFUL = 'SUCCESSFUL';
26
+ const ALREADY_CAPTURED = 'ALREADY_CAPTURED';
27
+ const FAILED = 'FAILED';
28
+ const INACCESSIBLE = 'INACCESSIBLE';
29
+ const NOT_FOUND = 'NOT_FOUND';
30
+
31
+ /**
32
+ * The Order endpoint.
33
+ *
34
+ * @var OrderEndpoint
35
+ */
36
+ private $order_endpoint;
37
+
38
+ /**
39
+ * The Payments endpoint.
40
+ *
41
+ * @var PaymentsEndpoint
42
+ */
43
+ private $payments_endpoint;
44
+
45
+ /**
46
+ * The last status.
47
+ *
48
+ * @var string
49
+ */
50
+ private $last_status = '';
51
+
52
+ /**
53
+ * AuthorizedPaymentsProcessor constructor.
54
+ *
55
+ * @param OrderEndpoint $order_endpoint The Order endpoint.
56
+ * @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
57
+ */
58
+ public function __construct(
59
+ OrderEndpoint $order_endpoint,
60
+ PaymentsEndpoint $payments_endpoint
61
+ ) {
62
+
63
+ $this->order_endpoint = $order_endpoint;
64
+ $this->payments_endpoint = $payments_endpoint;
65
+ }
66
+
67
+ /**
68
+ * Process a WooCommerce order.
69
+ *
70
+ * @param \WC_Order $wc_order The WooCommerce order.
71
+ *
72
+ * @return bool
73
+ */
74
+ public function process( \WC_Order $wc_order ): bool {
75
+ try {
76
+ $order = $this->paypal_order_from_wc_order( $wc_order );
77
+ } catch ( Exception $exception ) {
78
+ if ( $exception->getCode() === 404 ) {
79
+ $this->last_status = self::NOT_FOUND;
80
+ return false;
81
+ }
82
+ $this->last_status = self::INACCESSIBLE;
83
+ return false;
84
+ }
85
+
86
+ $authorizations = $this->all_authorizations( $order );
87
+
88
+ if ( ! $this->are_authorzations_to_capture( ...$authorizations ) ) {
89
+ $this->last_status = self::ALREADY_CAPTURED;
90
+ return false;
91
+ }
92
+
93
+ try {
94
+ $this->capture_authorizations( ...$authorizations );
95
+ } catch ( Exception $exception ) {
96
+ $this->last_status = self::FAILED;
97
+ return false;
98
+ }
99
+
100
+ $this->last_status = self::SUCCESSFUL;
101
+ return true;
102
+ }
103
+
104
+ /**
105
+ * Returns the last status.
106
+ *
107
+ * @return string
108
+ */
109
+ public function last_status(): string {
110
+
111
+ return $this->last_status;
112
+ }
113
+
114
+ /**
115
+ * Returns the PayPal order from a given WooCommerce order.
116
+ *
117
+ * @param \WC_Order $wc_order The WooCommerce order.
118
+ *
119
+ * @return Order
120
+ */
121
+ private function paypal_order_from_wc_order( \WC_Order $wc_order ): Order {
122
+ $order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
123
+ return $this->order_endpoint->order( $order_id );
124
+ }
125
+
126
+ /**
127
+ * Returns all Authorizations from an order.
128
+ *
129
+ * @param Order $order The order.
130
+ *
131
+ * @return array
132
+ */
133
+ private function all_authorizations( Order $order ): array {
134
+ $authorizations = array();
135
+ foreach ( $order->purchase_units() as $purchase_unit ) {
136
+ foreach ( $purchase_unit->payments()->authorizations() as $authorization ) {
137
+ $authorizations[] = $authorization;
138
+ }
139
+ }
140
+
141
+ return $authorizations;
142
+ }
143
+
144
+ /**
145
+ * Whether Authorizations need to be captured.
146
+ *
147
+ * @param Authorization ...$authorizations All Authorizations.
148
+ *
149
+ * @return bool
150
+ */
151
+ private function are_authorzations_to_capture( Authorization ...$authorizations ): bool {
152
+ return (bool) count( $this->authorizations_to_capture( ...$authorizations ) );
153
+ }
154
+
155
+ /**
156
+ * Captures the authorizations.
157
+ *
158
+ * @param Authorization ...$authorizations All authorizations.
159
+ */
160
+ private function capture_authorizations( Authorization ...$authorizations ) {
161
+ $uncaptured_authorizations = $this->authorizations_to_capture( ...$authorizations );
162
+ foreach ( $uncaptured_authorizations as $authorization ) {
163
+ $this->payments_endpoint->capture( $authorization->id() );
164
+ }
165
+ }
166
+
167
+ /**
168
+ * The authorizations which need to be captured.
169
+ *
170
+ * @param Authorization ...$authorizations All Authorizations.
171
+ * @return Authorization[]
172
+ */
173
+ private function authorizations_to_capture( Authorization ...$authorizations ): array {
174
+ return array_filter(
175
+ $authorizations,
176
+ static function ( Authorization $authorization ): bool {
177
+ return $authorization->status()->is( AuthorizationStatus::CREATED )
178
+ || $authorization->status()->is( AuthorizationStatus::PENDING );
179
+ }
180
+ );
181
+ }
182
+ }
modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Processes orders for the gateways.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Processor
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
18
+ use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
19
+ use WooCommerce\PayPalCommerce\Session\SessionHandler;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
21
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
22
+
23
+ /**
24
+ * Class OrderProcessor
25
+ */
26
+ class OrderProcessor {
27
+
28
+ /**
29
+ * The Session Handler.
30
+ *
31
+ * @var SessionHandler
32
+ */
33
+ private $session_handler;
34
+
35
+ /**
36
+ * The Cart Repository.
37
+ *
38
+ * @var CartRepository
39
+ */
40
+ private $cart_repository;
41
+
42
+ /**
43
+ * The Order Endpoint.
44
+ *
45
+ * @var OrderEndpoint
46
+ */
47
+ private $order_endpoint;
48
+
49
+ /**
50
+ * The Payments Endpoint.
51
+ *
52
+ * @var PaymentsEndpoint
53
+ */
54
+ private $payments_endpoint;
55
+
56
+ /**
57
+ * The Order Factory.
58
+ *
59
+ * @var OrderFactory
60
+ */
61
+ private $order_factory;
62
+
63
+ /**
64
+ * The helper for 3d secure.
65
+ *
66
+ * @var ThreeDSecure
67
+ */
68
+ private $threed_secure;
69
+
70
+ /**
71
+ * The processor for authorized payments.
72
+ *
73
+ * @var AuthorizedPaymentsProcessor
74
+ */
75
+ private $authorized_payments_processor;
76
+
77
+ /**
78
+ * The settings.
79
+ *
80
+ * @var Settings
81
+ */
82
+ private $settings;
83
+
84
+ /**
85
+ * The last error.
86
+ *
87
+ * @var string
88
+ */
89
+ private $last_error = '';
90
+
91
+ /**
92
+ * OrderProcessor constructor.
93
+ *
94
+ * @param SessionHandler $session_handler The Session Handler.
95
+ * @param CartRepository $cart_repository The Cart Repository.
96
+ * @param OrderEndpoint $order_endpoint The Order Endpoint.
97
+ * @param PaymentsEndpoint $payments_endpoint The Payments Endpoint.
98
+ * @param OrderFactory $order_factory The Order Factory.
99
+ * @param ThreeDSecure $three_d_secure The ThreeDSecure Helper.
100
+ * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
101
+ * @param Settings $settings The Settings.
102
+ */
103
+ public function __construct(
104
+ SessionHandler $session_handler,
105
+ CartRepository $cart_repository,
106
+ OrderEndpoint $order_endpoint,
107
+ PaymentsEndpoint $payments_endpoint,
108
+ OrderFactory $order_factory,
109
+ ThreeDSecure $three_d_secure,
110
+ AuthorizedPaymentsProcessor $authorized_payments_processor,
111
+ Settings $settings
112
+ ) {
113
+
114
+ $this->session_handler = $session_handler;
115
+ $this->cart_repository = $cart_repository;
116
+ $this->order_endpoint = $order_endpoint;
117
+ $this->payments_endpoint = $payments_endpoint;
118
+ $this->order_factory = $order_factory;
119
+ $this->threed_secure = $three_d_secure;
120
+ $this->authorized_payments_processor = $authorized_payments_processor;
121
+ $this->settings = $settings;
122
+ }
123
+
124
+ /**
125
+ * Processes a given WooCommerce order and captured/authorizes the connected PayPal orders.
126
+ *
127
+ * @param \WC_Order $wc_order The WooCommerce order.
128
+ * @param \WooCommerce $woocommerce The WooCommerce object.
129
+ *
130
+ * @return bool
131
+ */
132
+ public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
133
+ $order = $this->session_handler->order();
134
+ if ( ! $order ) {
135
+ return false;
136
+ }
137
+ $wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
138
+ $wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
139
+
140
+ $error_message = null;
141
+ if ( ! $order || ! $this->order_is_approved( $order ) ) {
142
+ $error_message = __(
143
+ 'The payment has not been approved yet.',
144
+ 'woocommerce-paypal-payments'
145
+ );
146
+ }
147
+ if ( $error_message ) {
148
+ $this->last_error = sprintf(
149
+ // translators: %s is the message of the error.
150
+ __( 'Payment error: %s', 'woocommerce-paypal-payments' ),
151
+ $error_message
152
+ );
153
+ return false;
154
+ }
155
+
156
+ $order = $this->patch_order( $wc_order, $order );
157
+ if ( $order->intent() === 'CAPTURE' ) {
158
+ $order = $this->order_endpoint->capture( $order );
159
+ }
160
+
161
+ if ( $order->intent() === 'AUTHORIZE' ) {
162
+ $order = $this->order_endpoint->authorize( $order );
163
+ $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
164
+ }
165
+
166
+ $wc_order->update_status(
167
+ 'on-hold',
168
+ __( 'Awaiting payment.', 'woocommerce-paypal-payments' )
169
+ );
170
+ if ( $order->status()->is( OrderStatus::COMPLETED ) && $order->intent() === 'CAPTURE' ) {
171
+ $wc_order->update_status(
172
+ 'processing',
173
+ __( 'Payment received.', 'woocommerce-paypal-payments' )
174
+ );
175
+ }
176
+
177
+ if ( $this->capture_authorized_downloads( $order ) && $this->authorized_payments_processor->process( $wc_order ) ) {
178
+ $wc_order->add_order_note(
179
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
180
+ );
181
+ $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
182
+ $wc_order->update_status( 'processing' );
183
+ }
184
+ $woocommerce->cart->empty_cart();
185
+ $this->session_handler->destroy_session_data();
186
+ $this->last_error = '';
187
+ return true;
188
+ }
189
+
190
+ /**
191
+ * Returns if an order should be captured immediately.
192
+ *
193
+ * @param Order $order The PayPal order.
194
+ *
195
+ * @return bool
196
+ */
197
+ private function capture_authorized_downloads( Order $order ): bool {
198
+ if (
199
+ ! $this->settings->has( 'capture_for_virtual_only' )
200
+ || ! $this->settings->get( 'capture_for_virtual_only' )
201
+ ) {
202
+ return false;
203
+ }
204
+
205
+ if ( $order->intent() === 'CAPTURE' ) {
206
+ return false;
207
+ }
208
+
209
+ /**
210
+ * We fetch the order again as the authorize endpoint (from which the Order derives)
211
+ * drops the item's category, making it impossible to check, if purchase units contain
212
+ * physical goods.
213
+ */
214
+ $order = $this->order_endpoint->order( $order->id() );
215
+
216
+ foreach ( $order->purchase_units() as $unit ) {
217
+ if ( $unit->contains_physical_goods() ) {
218
+ return false;
219
+ }
220
+ }
221
+ return true;
222
+ }
223
+
224
+ /**
225
+ * Returns the last error.
226
+ *
227
+ * @return string
228
+ */
229
+ public function last_error(): string {
230
+
231
+ return $this->last_error;
232
+ }
233
+
234
+ /**
235
+ * Patches a given PayPal order with a WooCommerce order.
236
+ *
237
+ * @param \WC_Order $wc_order The WooCommerce order.
238
+ * @param Order $order The PayPal order.
239
+ *
240
+ * @return Order
241
+ */
242
+ public function patch_order( \WC_Order $wc_order, Order $order ): Order {
243
+ $updated_order = $this->order_factory->from_wc_order( $wc_order, $order );
244
+ $order = $this->order_endpoint->patch_order_with( $order, $updated_order );
245
+ return $order;
246
+ }
247
+
248
+ /**
249
+ * Whether a given order is approved.
250
+ *
251
+ * @param Order $order The order.
252
+ *
253
+ * @return bool
254
+ */
255
+ private function order_is_approved( Order $order ): bool {
256
+
257
+ if ( $order->status()->is( OrderStatus::APPROVED ) ) {
258
+ return true;
259
+ }
260
+
261
+ if ( ! $order->payment_source() || ! $order->payment_source()->card() ) {
262
+ return false;
263
+ }
264
+
265
+ $is_approved = in_array(
266
+ $this->threed_secure->proceed_with_order( $order ),
267
+ array(
268
+ ThreeDSecure::NO_DECISION,
269
+ ThreeDSecure::PROCCEED,
270
+ ),
271
+ true
272
+ );
273
+ return $is_approved;
274
+ }
275
+ }
modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Processes refunds started in the WooCommerce environment.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Processor
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
+
20
+ /**
21
+ * Class RefundProcessor
22
+ */
23
+ class RefundProcessor {
24
+
25
+ /**
26
+ * The order endpoint.
27
+ *
28
+ * @var OrderEndpoint
29
+ */
30
+ private $order_endpoint;
31
+
32
+ /**
33
+ * The payments endpoint.
34
+ *
35
+ * @var PaymentsEndpoint
36
+ */
37
+ private $payments_endpoint;
38
+
39
+ /**
40
+ * RefundProcessor constructor.
41
+ *
42
+ * @param OrderEndpoint $order_endpoint The order endpoint.
43
+ * @param PaymentsEndpoint $payments_endpoint The payments endpoint.
44
+ */
45
+ public function __construct( OrderEndpoint $order_endpoint, PaymentsEndpoint $payments_endpoint ) {
46
+
47
+ $this->order_endpoint = $order_endpoint;
48
+ $this->payments_endpoint = $payments_endpoint;
49
+ }
50
+
51
+ /**
52
+ * Processes a refund.
53
+ *
54
+ * @param \WC_Order $wc_order The WooCommerce order.
55
+ * @param float|null $amount The refund amount.
56
+ * @param string $reason The reason for the refund.
57
+ *
58
+ * @return bool
59
+ */
60
+ public function process( \WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
61
+ $order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
62
+ if ( ! $order_id ) {
63
+ return false;
64
+ }
65
+ try {
66
+ $order = $this->order_endpoint->order( $order_id );
67
+ if ( ! $order ) {
68
+ return false;
69
+ }
70
+
71
+ $purchase_units = $order->purchase_units();
72
+ if ( ! $purchase_units ) {
73
+ return false;
74
+ }
75
+
76
+ $payments = $purchase_units[0]->payments();
77
+ if ( ! $payments ) {
78
+ return false;
79
+ }
80
+ $captures = $payments->captures();
81
+ if ( ! $captures ) {
82
+ return false;
83
+ }
84
+
85
+ $capture = $captures[0];
86
+ $refund = new Refund(
87
+ $capture,
88
+ $capture->invoice_id(),
89
+ $reason,
90
+ new Amount(
91
+ new Money( $amount, get_woocommerce_currency() )
92
+ )
93
+ );
94
+ return $this->payments_endpoint->refund( $refund );
95
+ } catch ( RuntimeException $error ) {
96
+ return false;
97
+ }
98
+ }
99
+ }
modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the Sections Tab.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Settings
6
+ */
7
+
8
+ declare( strict_types=1 );
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
+
12
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
14
+
15
+ /**
16
+ * Class SectionsRenderer
17
+ */
18
+ class SectionsRenderer {
19
+
20
+ const KEY = 'ppcp-tab';
21
+
22
+ /**
23
+ * Whether the sections tab should be rendered.
24
+ *
25
+ * @return bool
26
+ */
27
+ public function should_render() : bool {
28
+
29
+ global $current_section;
30
+ return PayPalGateway::ID === $current_section;
31
+ }
32
+
33
+ /**
34
+ * Renders the Sections tab.
35
+ */
36
+ public function render() {
37
+ if ( ! $this->should_render() ) {
38
+ return;
39
+ }
40
+
41
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended
42
+ $current = ! isset( $_GET[ self::KEY ] ) ? PayPalGateway::ID : sanitize_text_field( wp_unslash( $_GET[ self::KEY ] ) );
43
+ $sections = array(
44
+ PayPalGateway::ID => __( 'PayPal Checkout', 'woocommerce-paypal-payments' ),
45
+ CreditCardGateway::ID => __( 'PayPal Card Processing', 'woocommerce-paypal-payments' ),
46
+ );
47
+
48
+ echo '<ul class="subsubsub">';
49
+
50
+ $array_keys = array_keys( $sections );
51
+
52
+ foreach ( $sections as $id => $label ) {
53
+ $url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&' . self::KEY . '=' . $id );
54
+ echo '<li><a href="' . esc_url( $url ) . '" class="' . ( $current === $id ? 'current' : '' ) . '">' . esc_html( $label ) . '</a> ' . ( end( $array_keys ) === $id ? '' : '|' ) . ' </li>';
55
+ }
56
+
57
+ echo '</ul><br class="clear" />';
58
+ }
59
+ }
modules/ppcp-wc-gateway/src/Settings/class-settings.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The settings object.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Settings
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
+
12
+ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
13
+ use Psr\Container\ContainerInterface;
14
+
15
+ /**
16
+ * Class Settings
17
+ */
18
+ class Settings implements ContainerInterface {
19
+
20
+ const KEY = 'woocommerce-ppcp-settings';
21
+
22
+ /**
23
+ * The settings.
24
+ *
25
+ * @var array
26
+ */
27
+ private $settings = array();
28
+
29
+ /**
30
+ * Returns the value for an id.
31
+ *
32
+ * @param string $id The value identificator.
33
+ *
34
+ * @return mixed
35
+ * @throws NotFoundException When nothing was found.
36
+ */
37
+ public function get( $id ) {
38
+ if ( ! $this->has( $id ) ) {
39
+ throw new NotFoundException();
40
+ }
41
+ return $this->settings[ $id ];
42
+ }
43
+
44
+ /**
45
+ * Whether a value exists.
46
+ *
47
+ * @param string $id The value identificator.
48
+ *
49
+ * @return bool
50
+ */
51
+ public function has( $id ) {
52
+ $this->load();
53
+ return array_key_exists( $id, $this->settings );
54
+ }
55
+
56
+ /**
57
+ * Sets a value.
58
+ *
59
+ * @param string $id The value identificator.
60
+ * @param mixed $value The value.
61
+ */
62
+ public function set( $id, $value ) {
63
+ $this->load();
64
+ $this->settings[ $id ] = $value;
65
+ }
66
+
67
+ /**
68
+ * Stores the settings to the database.
69
+ */
70
+ public function persist() {
71
+
72
+ update_option( self::KEY, $this->settings );
73
+ }
74
+
75
+
76
+ /**
77
+ * Loads the settings.
78
+ *
79
+ * @return bool
80
+ */
81
+ private function load(): bool {
82
+
83
+ if ( $this->settings ) {
84
+ return false;
85
+ }
86
+ $this->settings = get_option( self::KEY, array() );
87
+
88
+ $defaults = array(
89
+ 'title' => __( 'PayPal', 'woocommerce-paypal-payments' ),
90
+ 'description' => __(
91
+ 'Pay via PayPal.',
92
+ 'woocommerce-paypal-payments'
93
+ ),
94
+ 'button_single_product_enabled' => true,
95
+ 'button_mini-cart_enabled' => true,
96
+ 'button_cart_enabled' => true,
97
+ 'brand_name' => get_bloginfo( 'name' ),
98
+ 'dcc_gateway_title' => __( 'Credit Cards', 'woocommerce-paypal-payments' ),
99
+ 'dcc_gateway_description' => __(
100
+ 'Pay with your credit card.',
101
+ 'woocommerce-paypal-payments'
102
+ ),
103
+ );
104
+ foreach ( $defaults as $key => $value ) {
105
+ if ( isset( $this->settings[ $key ] ) ) {
106
+ continue;
107
+ }
108
+ $this->settings[ $key ] = $value;
109
+ }
110
+ return true;
111
+ }
112
+ }
modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Listens to requests and updates the settings if necessary.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Settings
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
14
+ use WooCommerce\PayPalCommerce\Onboarding\State;
15
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
17
+ use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
18
+
19
+ /**
20
+ * Class SettingsListener
21
+ */
22
+ class SettingsListener {
23
+
24
+
25
+ const NONCE = 'ppcp-settings';
26
+
27
+ /**
28
+ * The Settings.
29
+ *
30
+ * @var Settings
31
+ */
32
+ private $settings;
33
+
34
+ /**
35
+ * Array contains the setting fields.
36
+ *
37
+ * @var array
38
+ */
39
+ private $setting_fields;
40
+
41
+ /**
42
+ * The Webhook Registrar.
43
+ *
44
+ * @var WebhookRegistrar
45
+ */
46
+ private $webhook_registrar;
47
+
48
+ /**
49
+ * The Cache.
50
+ *
51
+ * @var Cache
52
+ */
53
+ private $cache;
54
+
55
+ /**
56
+ * The State.
57
+ *
58
+ * @var State
59
+ */
60
+ private $state;
61
+
62
+ /**
63
+ * SettingsListener constructor.
64
+ *
65
+ * @param Settings $settings The settings.
66
+ * @param array $setting_fields The setting fields.
67
+ * @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
68
+ * @param Cache $cache The Cache.
69
+ * @param State $state The state.
70
+ */
71
+ public function __construct(
72
+ Settings $settings,
73
+ array $setting_fields,
74
+ WebhookRegistrar $webhook_registrar,
75
+ Cache $cache,
76
+ State $state
77
+ ) {
78
+
79
+ $this->settings = $settings;
80
+ $this->setting_fields = $setting_fields;
81
+ $this->webhook_registrar = $webhook_registrar;
82
+ $this->cache = $cache;
83
+ $this->state = $state;
84
+ }
85
+
86
+ /**
87
+ * Listens if the merchant ID should be updated.
88
+ */
89
+ public function listen_for_merchant_id() {
90
+
91
+ if ( ! $this->is_valid_site_request() ) {
92
+ return;
93
+ }
94
+
95
+ /**
96
+ * No nonce provided.
97
+ * phpcs:disable WordPress.Security.NonceVerification.Missing
98
+ * phpcs:disable WordPress.Security.NonceVerification.Recommended
99
+ */
100
+ if ( ! isset( $_GET['merchantIdInPayPal'] ) || ! isset( $_GET['merchantId'] ) ) {
101
+ return;
102
+ }
103
+ $merchant_id = sanitize_text_field( wp_unslash( $_GET['merchantIdInPayPal'] ) );
104
+ $merchant_email = sanitize_text_field( wp_unslash( $_GET['merchantId'] ) );
105
+ // phpcs:enable WordPress.Security.NonceVerification.Missing
106
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
107
+
108
+ $this->settings->set( 'merchant_id', $merchant_id );
109
+ $this->settings->set( 'merchant_email', $merchant_email );
110
+
111
+ $is_sandbox = $this->settings->has( 'sandbox_on' ) && $this->settings->get( 'sandbox_on' );
112
+ if ( $is_sandbox ) {
113
+ $this->settings->set( 'merchant_id_sandbox', $merchant_id );
114
+ $this->settings->set( 'merchant_email_sandbox', $merchant_email );
115
+ } else {
116
+ $this->settings->set( 'merchant_id_production', $merchant_id );
117
+ $this->settings->set( 'merchant_email_production', $merchant_email );
118
+ }
119
+ $this->settings->persist();
120
+ $redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway' );
121
+ if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
122
+ $redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&ppcp-onboarding-error=1' );
123
+ }
124
+ wp_safe_redirect( $redirect_url, 302 );
125
+ exit;
126
+ }
127
+
128
+ /**
129
+ * Listens to the request.
130
+ *
131
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
132
+ */
133
+ public function listen() {
134
+
135
+ if ( ! $this->is_valid_update_request() ) {
136
+ return;
137
+ }
138
+
139
+ /**
140
+ * Sanitization is done in retrieve_settings_from_raw_data().
141
+ *
142
+ * phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
143
+ *
144
+ * Nonce verification is done in is_valid_update_request().
145
+ *
146
+ * phpcs:disable WordPress.Security.NonceVerification.Missing
147
+ * phpcs:disable WordPress.Security.NonceVerification.Recommended
148
+ */
149
+ $raw_data = ( isset( $_POST['ppcp'] ) ) ? (array) wp_unslash( $_POST['ppcp'] ) : array();
150
+ // phpcs:enable phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
151
+ $settings = $this->retrieve_settings_from_raw_data( $raw_data );
152
+
153
+ $settings = $this->read_active_credentials_from_settings( $settings );
154
+
155
+ if ( ! isset( $_GET[ SectionsRenderer::KEY ] ) || PayPalGateway::ID === $_GET[ SectionsRenderer::KEY ] ) {
156
+ $settings['enabled'] = isset( $_POST['woocommerce_ppcp-gateway_enabled'] )
157
+ && 1 === absint( $_POST['woocommerce_ppcp-gateway_enabled'] );
158
+ $this->maybe_register_webhooks( $settings );
159
+ }
160
+ // phpcs:enable phpcs:disable WordPress.Security.NonceVerification.Missing
161
+ // phpcs:enable phpcs:disable WordPress.Security.NonceVerification.Missing
162
+
163
+ foreach ( $settings as $id => $value ) {
164
+ $this->settings->set( $id, $value );
165
+ }
166
+ $this->settings->persist();
167
+ if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
168
+ $this->cache->delete( PayPalBearer::CACHE_KEY );
169
+ }
170
+
171
+ if ( isset( $_GET['ppcp-onboarding-error'] ) ) {
172
+ $url = remove_query_arg( 'ppcp-onboarding-error' );
173
+ wp_safe_redirect( $url, 302 );
174
+ exit;
175
+ }
176
+
177
+ // phpcs:enable WordPress.Security.NonceVerification.Missing
178
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
179
+ }
180
+
181
+ /**
182
+ * The actual used client credentials are stored in 'client_secret', 'client_id', 'merchant_id' and 'merchant_email'.
183
+ * This method populates those fields depending on the sandbox status.
184
+ *
185
+ * @param array $settings The settings array.
186
+ *
187
+ * @return array
188
+ */
189
+ private function read_active_credentials_from_settings( array $settings ) : array {
190
+ if ( ! isset( $settings['client_id_sandbox'] ) && ! isset( $settings['client_id_production'] ) ) {
191
+ return $settings;
192
+ }
193
+ $is_sandbox = isset( $settings['sandbox_on'] ) && $settings['sandbox_on'];
194
+ $settings['client_id'] = $is_sandbox ? $settings['client_id_sandbox'] : $settings['client_id_production'];
195
+ $settings['client_secret'] = $is_sandbox ? $settings['client_secret_sandbox'] : $settings['client_secret_production'];
196
+ $settings['merchant_id'] = $is_sandbox ? $settings['merchant_id_sandbox'] : $settings['merchant_id_production'];
197
+ $settings['merchant_email'] = $is_sandbox ? $settings['merchant_email_sandbox'] : $settings['merchant_email_production'];
198
+ return $settings;
199
+ }
200
+
201
+ /**
202
+ * Depending on the settings change, we might need to register or unregister the Webhooks at PayPal.
203
+ *
204
+ * @param array $settings The settings.
205
+ *
206
+ * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasn't been found.
207
+ */
208
+ private function maybe_register_webhooks( array $settings ) {
209
+
210
+ if ( ! $this->settings->has( 'client_id' ) && $settings['client_id'] ) {
211
+ $this->settings->set( 'products_dcc_enabled', null );
212
+ $this->webhook_registrar->register();
213
+ }
214
+ if ( $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) ) {
215
+ $current_secret = $this->settings->has( 'client_secret' ) ?
216
+ $this->settings->get( 'client_secret' ) : '';
217
+ if (
218
+ $settings['client_id'] !== $this->settings->get( 'client_id' )
219
+ || $settings['client_secret'] !== $current_secret
220
+ ) {
221
+ $this->settings->set( 'products_dcc_enabled', null );
222
+ $this->webhook_registrar->unregister();
223
+ $this->webhook_registrar->register();
224
+ }
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Sanitizes the settings input data and returns a valid settings array.
230
+ *
231
+ * @param array $raw_data The Raw data.
232
+ *
233
+ * @return array
234
+ */
235
+ private function retrieve_settings_from_raw_data( array $raw_data ): array {
236
+ /**
237
+ * Nonce verification has already been done.
238
+ * phpcs:disable WordPress.Security.NonceVerification.Recommended
239
+ */
240
+ if ( ! isset( $_GET['section'] ) ) {
241
+ return array();
242
+ }
243
+ $settings = array();
244
+ foreach ( $this->setting_fields as $key => $config ) {
245
+ if ( ! in_array( $this->state->current_state(), $config['screens'], true ) ) {
246
+ continue;
247
+ }
248
+ if (
249
+ 'dcc' === $config['gateway']
250
+ && (
251
+ ! isset( $_GET[ SectionsRenderer::KEY ] )
252
+ || sanitize_text_field( wp_unslash( $_GET[ SectionsRenderer::KEY ] ) ) !== CreditCardGateway::ID
253
+ )
254
+ ) {
255
+ continue;
256
+ }
257
+ if (
258
+ 'paypal' === $config['gateway']
259
+ && isset( $_GET[ SectionsRenderer::KEY ] )
260
+ && sanitize_text_field( wp_unslash( $_GET[ SectionsRenderer::KEY ] ) ) !== PayPalGateway::ID
261
+ ) {
262
+ continue;
263
+ }
264
+ switch ( $config['type'] ) {
265
+ case 'checkbox':
266
+ $settings[ $key ] = isset( $raw_data[ $key ] );
267
+ break;
268
+ case 'text':
269
+ case 'ppcp-text-input':
270
+ case 'ppcp-password':
271
+ $settings[ $key ] = isset( $raw_data[ $key ] ) ? sanitize_text_field( $raw_data[ $key ] ) : '';
272
+ break;
273
+ case 'password':
274
+ if ( empty( $raw_data[ $key ] ) ) {
275
+ break;
276
+ }
277
+ $settings[ $key ] = sanitize_text_field( $raw_data[ $key ] );
278
+ break;
279
+ case 'ppcp-multiselect':
280
+ $values = isset( $raw_data[ $key ] ) ? (array) $raw_data[ $key ] : array();
281
+ $values_to_save = array();
282
+ foreach ( $values as $index => $raw_value ) {
283
+ $value = sanitize_text_field( $raw_value );
284
+ if ( ! in_array( $value, array_keys( $config['options'] ), true ) ) {
285
+ continue;
286
+ }
287
+ $values_to_save[] = $value;
288
+ }
289
+ $settings[ $key ] = $values_to_save;
290
+ break;
291
+ case 'select':
292
+ $options = array_keys( $config['options'] );
293
+ $settings[ $key ] = isset( $raw_data[ $key ] ) && in_array(
294
+ sanitize_text_field( $raw_data[ $key ] ),
295
+ $options,
296
+ true
297
+ ) ? sanitize_text_field( $raw_data[ $key ] ) : null;
298
+ break;
299
+ }
300
+ }
301
+
302
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
303
+ return $settings;
304
+ }
305
+
306
+ /**
307
+ * Evaluates whether the current request is supposed to update the settings.
308
+ *
309
+ * @return bool
310
+ */
311
+ private function is_valid_update_request(): bool {
312
+
313
+ if ( ! $this->is_valid_site_request() ) {
314
+ return false;
315
+ }
316
+
317
+ if (
318
+ ! isset( $_POST['ppcp-nonce'] )
319
+ || ! wp_verify_nonce(
320
+ sanitize_text_field( wp_unslash( $_POST['ppcp-nonce'] ) ),
321
+ self::NONCE
322
+ )
323
+ ) {
324
+ return false;
325
+ }
326
+ return true;
327
+ }
328
+
329
+ /**
330
+ * Whether we are on the settings page and are allowed to be here.
331
+ *
332
+ * @return bool
333
+ */
334
+ private function is_valid_site_request() : bool {
335
+
336
+ /**
337
+ * No nonce needed at this point.
338
+ *
339
+ * phpcs:disable WordPress.Security.NonceVerification.Missing
340
+ * phpcs:disable WordPress.Security.NonceVerification.Recommended
341
+ */
342
+ if (
343
+ ! isset( $_REQUEST['section'] )
344
+ || ! in_array(
345
+ sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ),
346
+ array( 'ppcp-gateway', 'ppcp-credit-card-gateway' ),
347
+ true
348
+ )
349
+ ) {
350
+ return false;
351
+ }
352
+
353
+ // phpcs:enable WordPress.Security.NonceVerification.Missing
354
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
355
+
356
+ if ( ! current_user_can( 'manage_options' ) ) {
357
+ return false;
358
+ }
359
+ return true;
360
+ }
361
+ }
modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Renders the settings of the Gateways.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Settings
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
+
12
+ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
+ use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
15
+ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
16
+ use WooCommerce\PayPalCommerce\Onboarding\State;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
18
+ use Psr\Container\ContainerInterface;
19
+ use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
20
+
21
+ /**
22
+ * Class SettingsRenderer
23
+ */
24
+ class SettingsRenderer {
25
+
26
+ /**
27
+ * The settings.
28
+ *
29
+ * @var ContainerInterface
30
+ */
31
+ private $settings;
32
+
33
+ /**
34
+ * The current onboarding state.
35
+ *
36
+ * @var State
37
+ */
38
+ private $state;
39
+
40
+ /**
41
+ * The setting fields.
42
+ *
43
+ * @var array
44
+ */
45
+ private $fields;
46
+
47
+ /**
48
+ * Helper to see if DCC gateway can be shown.
49
+ *
50
+ * @var DccApplies
51
+ */
52
+ private $dcc_applies;
53
+
54
+ /**
55
+ * Helper to see if messages are supposed to show up.
56
+ *
57
+ * @var MessagesApply
58
+ */
59
+ private $messages_apply;
60
+
61
+ /**
62
+ * The DCC Product Status.
63
+ *
64
+ * @var DccProductStatus
65
+ */
66
+ private $dcc_product_status;
67
+
68
+ /**
69
+ * SettingsRenderer constructor.
70
+ *
71
+ * @param ContainerInterface $settings The Settings.
72
+ * @param State $state The current state.
73
+ * @param array $fields The setting fields.
74
+ * @param DccApplies $dcc_applies Whether DCC gateway can be shown.
75
+ * @param MessagesApply $messages_apply Whether messages can be shown.
76
+ * @param DccProductStatus $dcc_product_status The product status.
77
+ */
78
+ public function __construct(
79
+ ContainerInterface $settings,
80
+ State $state,
81
+ array $fields,
82
+ DccApplies $dcc_applies,
83
+ MessagesApply $messages_apply,
84
+ DccProductStatus $dcc_product_status
85
+ ) {
86
+
87
+ $this->settings = $settings;
88
+ $this->state = $state;
89
+ $this->fields = $fields;
90
+ $this->dcc_applies = $dcc_applies;
91
+ $this->messages_apply = $messages_apply;
92
+ $this->dcc_product_status = $dcc_product_status;
93
+ }
94
+
95
+ /**
96
+ * Returns the notice, when onboarding failed.
97
+ *
98
+ * @return array
99
+ */
100
+ public function messages() : array {
101
+
102
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
103
+ //phpcs:disable WordPress.Security.NonceVerification.Missing
104
+ if ( ! isset( $_GET['ppcp-onboarding-error'] ) || ! empty( $_POST ) ) {
105
+ return array();
106
+ }
107
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
108
+ //phpcs:enable WordPress.Security.NonceVerification.Missing
109
+
110
+ $messages = array(
111
+ new Message(
112
+ __(
113
+ 'We could not complete the onboarding process. Some features, such as card processing, will not be available. To fix this, please try again.',
114
+ 'woocommerce-paypal-payments'
115
+ ),
116
+ 'error',
117
+ false
118
+ ),
119
+ );
120
+ return $messages;
121
+ }
122
+
123
+ /**
124
+ * Renders the multiselect field.
125
+ *
126
+ * @param string $field The current field HTML.
127
+ * @param string $key The current key.
128
+ * @param array $config The configuration array.
129
+ * @param string $value The current value.
130
+ *
131
+ * @return string
132
+ */
133
+ public function render_multiselect( $field, $key, $config, $value ): string {
134
+
135
+ if ( 'ppcp-multiselect' !== $config['type'] ) {
136
+ return $field;
137
+ }
138
+
139
+ $options = array();
140
+ foreach ( $config['options'] as $option_key => $option_value ) {
141
+ $selected = ( in_array( $option_key, $value, true ) ) ? 'selected="selected"' : '';
142
+
143
+ $options[] = '<option value="' . esc_attr( $option_key ) . '" ' . $selected . '>' .
144
+ esc_html( $option_value ) .
145
+ '</option>';
146
+ }
147
+
148
+ $html = sprintf(
149
+ '<select
150
+ multiple
151
+ class="%s"
152
+ name="%s"
153
+ >%s</select>',
154
+ esc_attr( implode( ' ', isset( $config['input_class'] ) ? $config['input_class'] : array() ) ),
155
+ esc_attr( $key ) . '[]',
156
+ implode( '', $options )
157
+ );
158
+
159
+ return $html;
160
+ }
161
+
162
+ /**
163
+ * Renders the password input field.
164
+ *
165
+ * @param string $field The current field HTML.
166
+ * @param string $key The current key.
167
+ * @param array $config The configuration array.
168
+ * @param string $value The current value.
169
+ *
170
+ * @return string
171
+ */
172
+ public function render_password( $field, $key, $config, $value ): string {
173
+
174
+ if ( 'ppcp-password' !== $config['type'] ) {
175
+ return $field;
176
+ }
177
+
178
+ $html = sprintf(
179
+ '<input
180
+ type="password"
181
+ autocomplete="new-password"
182
+ class="%s"
183
+ name="%s"
184
+ value="%s"
185
+ >',
186
+ esc_attr( implode( ' ', $config['class'] ) ),
187
+ esc_attr( $key ),
188
+ esc_attr( $value )
189
+ );
190
+
191
+ return $html;
192
+ }
193
+
194
+
195
+ /**
196
+ * Renders the text input field.
197
+ *
198
+ * @param string $field The current field HTML.
199
+ * @param string $key The current key.
200
+ * @param array $config The configuration array.
201
+ * @param string $value The current value.
202
+ *
203
+ * @return string
204
+ */
205
+ public function render_text_input( $field, $key, $config, $value ): string {
206
+
207
+ if ( 'ppcp-text-input' !== $config['type'] ) {
208
+ return $field;
209
+ }
210
+
211
+ $html = sprintf(
212
+ '<input
213
+ type="text"
214
+ autocomplete="off"
215
+ class="%s"
216
+ name="%s"
217
+ value="%s"
218
+ >',
219
+ esc_attr( implode( ' ', $config['class'] ) ),
220
+ esc_attr( $key ),
221
+ esc_attr( $value )
222
+ );
223
+
224
+ return $html;
225
+ }
226
+
227
+ /**
228
+ * Renders the heading field.
229
+ *
230
+ * @param string $field The current field HTML.
231
+ * @param string $key The current key.
232
+ * @param array $config The configuration array.
233
+ * @param string $value The current value.
234
+ *
235
+ * @return string
236
+ */
237
+ public function render_heading( $field, $key, $config, $value ): string {
238
+
239
+ if ( 'ppcp-heading' !== $config['type'] ) {
240
+ return $field;
241
+ }
242
+
243
+ $html = sprintf(
244
+ '<h3 class="wc-settings-sub-title %s">%s</h3>',
245
+ esc_attr( implode( ' ', $config['class'] ) ),
246
+ esc_html( $config['heading'] )
247
+ );
248
+
249
+ return $html;
250
+ }
251
+
252
+ /**
253
+ * Renders the settings.
254
+ */
255
+ public function render() {
256
+
257
+ //phpcs:disable WordPress.Security.NonceVerification.Recommended
258
+ //phpcs:disable WordPress.Security.NonceVerification.Missing
259
+ $is_dcc = isset( $_GET[ SectionsRenderer::KEY ] ) && CreditCardGateway::ID === sanitize_text_field( wp_unslash( $_GET[ SectionsRenderer::KEY ] ) );
260
+ //phpcs:enable WordPress.Security.NonceVerification.Recommended
261
+ //phpcs:enable WordPress.Security.NonceVerification.Missing
262
+ $nonce = wp_create_nonce( SettingsListener::NONCE );
263
+ ?>
264
+ <input type="hidden" name="ppcp-nonce" value="<?php echo esc_attr( $nonce ); ?>">
265
+ <?php
266
+ foreach ( $this->fields as $field => $config ) :
267
+ if ( ! in_array( $this->state->current_state(), $config['screens'], true ) ) {
268
+ continue;
269
+ }
270
+ if ( $is_dcc && ! in_array( $config['gateway'], array( 'all', 'dcc' ), true ) ) {
271
+ continue;
272
+ }
273
+ if ( ! $is_dcc && ! in_array( $config['gateway'], array( 'all', 'paypal' ), true ) ) {
274
+ continue;
275
+ }
276
+ if (
277
+ in_array( 'dcc', $config['requirements'], true )
278
+ && ! $this->dcc_applies->for_country_currency()
279
+ ) {
280
+ continue;
281
+ }
282
+ if (
283
+ in_array( 'dcc', $config['requirements'], true )
284
+ && ! $this->dcc_product_status->dcc_is_active()
285
+ ) {
286
+ continue;
287
+ }
288
+ if (
289
+ in_array( 'messages', $config['requirements'], true )
290
+ && ! $this->messages_apply->for_country()
291
+ ) {
292
+ continue;
293
+ }
294
+ $value = $this->settings->has( $field ) ? $this->settings->get( $field ) : null;
295
+ $key = 'ppcp[' . $field . ']';
296
+ $id = 'ppcp-' . $field;
297
+ $config['id'] = $id;
298
+ $th_td = 'ppcp-heading' !== $config['type'] ? 'td' : 'td';
299
+ $colspan = 'ppcp-heading' !== $config['type'] ? 1 : 2;
300
+ $classes = isset( $config['classes'] ) ? $config['classes'] : array();
301
+ $classes[] = sprintf( 'ppcp-settings-field-%s', str_replace( 'ppcp-', '', $config['type'] ) );
302
+ $description = isset( $config['description'] ) ? $config['description'] : '';
303
+ unset( $config['description'] );
304
+ ?>
305
+ <tr valign="top" id="<?php echo esc_attr( 'field-' . $field ); ?>" class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>">
306
+ <?php if ( 'ppcp-heading' !== $config['type'] ) : ?>
307
+ <th scope="row">
308
+ <label
309
+ for="<?php echo esc_attr( $id ); ?>"
310
+ ><?php echo esc_html( $config['title'] ); ?></label>
311
+ <?php if ( isset( $config['desc_tip'] ) && $config['desc_tip'] ) : ?>
312
+ <span
313
+ class="woocommerce-help-tip"
314
+ data-tip="<?php echo esc_attr( $description ); ?>"
315
+ ></span>
316
+ <?php
317
+ $description = '';
318
+ endif;
319
+ ?>
320
+ </th>
321
+ <?php endif; ?>
322
+ <<?php echo esc_attr( $th_td ); ?> colspan="<?php echo (int) $colspan; ?>">
323
+ <?php
324
+ 'ppcp-text' === $config['type'] ?
325
+ $this->render_text( $config )
326
+ : woocommerce_form_field( $key, $config, $value );
327
+ ?>
328
+
329
+ <?php if ( $description ) : ?>
330
+ <p class="<?php echo 'ppcp-heading' === $config['type'] ? '' : 'description'; ?>"><?php echo wp_kses_post( $description ); ?></p>
331
+ <?php endif; ?>
332
+ </<?php echo esc_attr( $th_td ); ?>>
333
+ </tr>
334
+ <?php
335
+ endforeach;
336
+ if ( $is_dcc ) {
337
+ if ( $this->dcc_applies->for_country_currency() ) {
338
+ if ( State::STATE_ONBOARDED > $this->state->current_state() ) {
339
+ $this->render_dcc_onboarding_info();
340
+ } elseif ( State::STATE_ONBOARDED === $this->state->current_state() && $this->dcc_product_status->dcc_is_active() ) {
341
+ $this->render_3d_secure_info();
342
+ } elseif ( ! $this->dcc_product_status->dcc_is_active() ) {
343
+ $this->render_dcc_not_active_yet();
344
+ }
345
+ } else {
346
+ $this->render_dcc_does_not_apply_info();
347
+ }
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Renders the ppcp-text field given a configuration.
353
+ *
354
+ * @param array $config The configuration array.
355
+ */
356
+ private function render_text( array $config ) {
357
+ echo wp_kses_post( $config['text'] );
358
+ if ( isset( $config['hidden'] ) ) {
359
+ $value = $this->settings->has( $config['hidden'] ) ?
360
+ (string) $this->settings->get( $config['hidden'] )
361
+ : '';
362
+ echo ' <input
363
+ type = "hidden"
364
+ name = "ppcp[' . esc_attr( $config['hidden'] ) . ']"
365
+ value = "' . esc_attr( $value ) . '"
366
+ > ';
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Renders the information that the PayPal account can not yet process DCC.
372
+ */
373
+ private function render_dcc_not_active_yet() {
374
+ ?>
375
+ <tr>
376
+ <th><?php esc_html_e( 'Onboarding', 'woocommerce-paypal-payments' ); ?></th>
377
+ <td class="notice notice-error">
378
+ <p>
379
+ <?php
380
+ esc_html_e(
381
+ 'Credit Card processing for your account has not yet been activated by PayPal. If your account is new, this can take some days. Otherwise, please get in contact with PayPal.',
382
+ 'woocommerce-paypal-payments'
383
+ );
384
+ ?>
385
+ </p>
386
+ </td>
387
+ </tr>
388
+ <?php
389
+ }
390
+
391
+ /**
392
+ * Renders the 3d secure info text.
393
+ */
394
+ private function render_3d_secure_info() {
395
+ ?>
396
+ <tr>
397
+ <th><?php esc_html_e( '3D Secure', 'woocommerce-paypal-payments' ); ?></th>
398
+ <td>
399
+ <p>
400
+ <?php
401
+ /**
402
+ * We still need to provide a docs link.
403
+ *
404
+ * @todo: Provide link to documentation.
405
+ */
406
+ echo wp_kses_post(
407
+ sprintf(
408
+ // translators: %1$s and %2$s is a link tag.
409
+ __(
410
+ '3D Secure benefits cardholders and merchants by providing
411
+ an additional layer of verification using Verified by Visa,
412
+ MasterCard SecureCode and American Express SafeKey.
413
+ %1$sLearn more about 3D Secure.%2$s',
414
+ 'woocommerce-paypal-payments'
415
+ ),
416
+ '<a
417
+ rel="noreferrer noopener"
418
+ href="https://woocommerce.com/posts/introducing-strong-customer-authentication-sca/"
419
+ >',
420
+ '</a>'
421
+ )
422
+ );
423
+ ?>
424
+ </p>
425
+ </td>
426
+ </tr>
427
+ <?php
428
+ }
429
+
430
+ /**
431
+ * Renders the DCC onboarding info.
432
+ */
433
+ private function render_dcc_onboarding_info() {
434
+ ?>
435
+ <tr>
436
+ <th><?php esc_html_e( 'Onboarding', 'woocommerce-paypal-payments' ); ?></th>
437
+ <td class="notice notice-error">
438
+ <p>
439
+ <?php
440
+ esc_html_e(
441
+ 'You need to complete your onboarding, before you can use the PayPal Card Processing option.',
442
+ 'woocommerce-paypal-payments'
443
+ );
444
+ ?>
445
+
446
+ <a
447
+ href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway' ) ); ?>"
448
+ >
449
+ <?php esc_html_e( 'Click here to complete your onboarding.', 'woocommerce-paypal-payments' ); ?>
450
+ </a>
451
+ </p>
452
+ </td>
453
+ </tr>
454
+ <?php
455
+ }
456
+
457
+ /**
458
+ * Renders the info, that DCC is not available in the merchant's country.
459
+ */
460
+ private function render_dcc_does_not_apply_info() {
461
+ ?>
462
+ <tr>
463
+ <th><?php esc_html_e( 'Card Processing not available', 'woocommerce-paypal-payments' ); ?></th>
464
+ <td class="notice notice-error">
465
+ <p>
466
+ <?php
467
+ esc_html_e(
468
+ 'Unfortunatly, the card processing option is not yet available in your country.',
469
+ 'woocommerce-paypal-payments'
470
+ );
471
+ ?>
472
+ </p>
473
+ </td>
474
+ </tr>
475
+ <?php
476
+ }
477
+ }
modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Gateway module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
16
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
19
+ use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderAuthorizeAction;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
21
+ use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
23
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
24
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
25
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
26
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
27
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
28
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
29
+ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
30
+ use Interop\Container\ServiceProviderInterface;
31
+ use Psr\Container\ContainerInterface;
32
+
33
+ /**
34
+ * Class WcGatewayModule
35
+ */
36
+ class WcGatewayModule implements ModuleInterface {
37
+
38
+ /**
39
+ * Setup the module.
40
+ *
41
+ * @return ServiceProviderInterface
42
+ */
43
+ public function setup(): ServiceProviderInterface {
44
+ return new ServiceProvider(
45
+ require __DIR__ . '/../services.php',
46
+ require __DIR__ . '/../extensions.php'
47
+ );
48
+ }
49
+
50
+ /**
51
+ * Runs the module.
52
+ *
53
+ * @param ContainerInterface|null $container The container.
54
+ */
55
+ public function run( ContainerInterface $container = null ) {
56
+ $this->register_payment_gateways( $container );
57
+ $this->register_order_functionality( $container );
58
+ $this->register_columns( $container );
59
+ $this->register_checkout_paypal_address_preset( $container );
60
+ $this->ajax_gateway_enabler( $container );
61
+
62
+ add_action(
63
+ 'woocommerce_sections_checkout',
64
+ function() use ( $container ) {
65
+ $section_renderer = $container->get( 'wcgateway.settings.sections-renderer' );
66
+ /**
67
+ * The Section Renderer.
68
+ *
69
+ * @var SectionsRenderer $section_renderer
70
+ */
71
+ $section_renderer->render();
72
+ }
73
+ );
74
+
75
+ add_filter(
76
+ Repository::NOTICES_FILTER,
77
+ static function ( $notices ) use ( $container ): array {
78
+ $notice = $container->get( 'wcgateway.notice.connect' );
79
+ /**
80
+ * The Connect Admin Notice object.
81
+ *
82
+ * @var ConnectAdminNotice $notice
83
+ */
84
+ $connect_message = $notice->connect_message();
85
+ if ( $connect_message ) {
86
+ $notices[] = $connect_message;
87
+ }
88
+ $authorize_order_action = $container->get( 'wcgateway.notice.authorize-order-action' );
89
+ $authorized_message = $authorize_order_action->message();
90
+ if ( $authorized_message ) {
91
+ $notices[] = $authorized_message;
92
+ }
93
+
94
+ $settings_renderer = $container->get( 'wcgateway.settings.render' );
95
+ /**
96
+ * The settings renderer.
97
+ *
98
+ * @var SettingsRenderer $settings_renderer
99
+ */
100
+ $messages = $settings_renderer->messages();
101
+ $notices = array_merge( $notices, $messages );
102
+
103
+ return $notices;
104
+ }
105
+ );
106
+ add_action(
107
+ 'woocommerce_paypal_commerce_gateway_deactivate',
108
+ static function () use ( $container ) {
109
+ delete_option( Settings::KEY );
110
+ delete_option( PayPalRequestIdRepository::KEY );
111
+ delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
112
+ delete_option( 'woocommerce_' . CreditCardGateway::ID . '_settings' );
113
+ }
114
+ );
115
+
116
+ add_action(
117
+ 'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
118
+ static function () use ( $container ) {
119
+ $endpoint = $container->get( 'wcgateway.endpoint.return-url' );
120
+ /**
121
+ * The Endpoint.
122
+ *
123
+ * @var ReturnUrlEndpoint $endpoint
124
+ */
125
+ $endpoint->handle_request();
126
+ }
127
+ );
128
+ }
129
+
130
+ /**
131
+ * Adds the functionality to listen to the ajax enable gateway switch.
132
+ *
133
+ * @param ContainerInterface $container The container.
134
+ */
135
+ private function ajax_gateway_enabler( ContainerInterface $container ) {
136
+ add_action(
137
+ 'wp_ajax_woocommerce_toggle_gateway_enabled',
138
+ static function () use ( $container ) {
139
+ if (
140
+ ! current_user_can( 'manage_woocommerce' )
141
+ || ! check_ajax_referer(
142
+ 'woocommerce-toggle-payment-gateway-enabled',
143
+ 'security'
144
+ )
145
+ || ! isset( $_POST['gateway_id'] )
146
+ ) {
147
+ return;
148
+ }
149
+
150
+ /**
151
+ * The settings.
152
+ *
153
+ * @var Settings $settings
154
+ */
155
+ $settings = $container->get( 'wcgateway.settings' );
156
+ $key = PayPalGateway::ID === $_POST['gateway_id'] ? 'enabled' : '';
157
+ if ( CreditCardGateway::ID === $_POST['gateway_id'] ) {
158
+ $key = 'dcc_enabled';
159
+ }
160
+ if ( ! $key ) {
161
+ return;
162
+ }
163
+ $enabled = $settings->has( $key ) ? $settings->get( $key ) : false;
164
+ if ( ! $enabled ) {
165
+ return;
166
+ }
167
+ $settings->set( $key, false );
168
+ $settings->persist();
169
+ },
170
+ 9
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Registers the payment gateways.
176
+ *
177
+ * @param ContainerInterface|null $container The container.
178
+ */
179
+ private function register_payment_gateways( ContainerInterface $container = null ) {
180
+
181
+ add_filter(
182
+ 'woocommerce_payment_gateways',
183
+ static function ( $methods ) use ( $container ): array {
184
+ $methods[] = $container->get( 'wcgateway.paypal-gateway' );
185
+ $dcc_applies = $container->get( 'api.helpers.dccapplies' );
186
+
187
+ $screen = ! function_exists( 'get_current_screen' ) ? (object) array( 'id' => 'front' ) : get_current_screen();
188
+ if ( ! $screen ) {
189
+ $screen = (object) array( 'id' => 'front' );
190
+ }
191
+ /**
192
+ * The DCC Applies object.
193
+ *
194
+ * @var DccApplies $dcc_applies
195
+ */
196
+ if ( 'woocommerce_page_wc-settings' !== $screen->id && $dcc_applies->for_country_currency() ) {
197
+ $methods[] = $container->get( 'wcgateway.credit-card-gateway' );
198
+ }
199
+ return (array) $methods;
200
+ }
201
+ );
202
+
203
+ add_action(
204
+ 'woocommerce_settings_save_checkout',
205
+ static function () use ( $container ) {
206
+ $listener = $container->get( 'wcgateway.settings.listener' );
207
+
208
+ /**
209
+ * The settings listener.
210
+ *
211
+ * @var SettingsListener $listener
212
+ */
213
+ $listener->listen();
214
+ }
215
+ );
216
+ add_action(
217
+ 'admin_init',
218
+ static function () use ( $container ) {
219
+ $listener = $container->get( 'wcgateway.settings.listener' );
220
+ /**
221
+ * The settings listener.
222
+ *
223
+ * @var SettingsListener $listener
224
+ */
225
+ $listener->listen_for_merchant_id();
226
+ }
227
+ );
228
+
229
+ add_filter(
230
+ 'woocommerce_form_field',
231
+ static function ( $field, $key, $args, $value ) use ( $container ) {
232
+ $renderer = $container->get( 'wcgateway.settings.render' );
233
+ /**
234
+ * The Settings Renderer object.
235
+ *
236
+ * @var SettingsRenderer $renderer
237
+ */
238
+ $field = $renderer->render_multiselect( $field, $key, $args, $value );
239
+ $field = $renderer->render_password( $field, $key, $args, $value );
240
+ $field = $renderer->render_text_input( $field, $key, $args, $value );
241
+ $field = $renderer->render_heading( $field, $key, $args, $value );
242
+ return $field;
243
+ },
244
+ 10,
245
+ 4
246
+ );
247
+
248
+ add_filter(
249
+ 'woocommerce_available_payment_gateways',
250
+ static function ( $methods ) use ( $container ): array {
251
+ $disabler = $container->get( 'wcgateway.disabler' );
252
+ /**
253
+ * The Gateay disabler.
254
+ *
255
+ * @var DisableGateways $disabler
256
+ */
257
+ return $disabler->handler( (array) $methods );
258
+ }
259
+ );
260
+ }
261
+
262
+ /**
263
+ * Registers the authorize order functionality.
264
+ *
265
+ * @param ContainerInterface $container The container.
266
+ */
267
+ private function register_order_functionality( ContainerInterface $container ) {
268
+ add_filter(
269
+ 'woocommerce_order_actions',
270
+ static function ( $order_actions ) use ( $container ): array {
271
+ global $theorder;
272
+
273
+ if ( ! is_a( $theorder, \WC_Order::class ) ) {
274
+ return $order_actions;
275
+ }
276
+
277
+ $render = $container->get( 'wcgateway.admin.render-authorize-action' );
278
+ /**
279
+ * Renders the authorize action in the select field.
280
+ *
281
+ * @var RenderAuthorizeAction $render
282
+ */
283
+ return $render->render( $order_actions, $theorder );
284
+ }
285
+ );
286
+
287
+ add_action(
288
+ 'woocommerce_order_action_ppcp_authorize_order',
289
+ static function ( \WC_Order $wc_order ) use ( $container ) {
290
+ /**
291
+ * The PayPal Gateway.
292
+ *
293
+ * @var PayPalGateway $gateway
294
+ */
295
+ $gateway = $container->get( 'wcgateway.paypal-gateway' );
296
+ $gateway->capture_authorized_payment( $wc_order );
297
+ }
298
+ );
299
+ }
300
+
301
+ /**
302
+ * Registers the additional columns on the order list page.
303
+ *
304
+ * @param ContainerInterface $container The container.
305
+ */
306
+ private function register_columns( ContainerInterface $container ) {
307
+ add_action(
308
+ 'woocommerce_order_actions_start',
309
+ static function ( $wc_order_id ) use ( $container ) {
310
+ /**
311
+ * The Payment Status Order Detail.
312
+ *
313
+ * @var PaymentStatusOrderDetail $class
314
+ */
315
+ $class = $container->get( 'wcgateway.admin.order-payment-status' );
316
+ $class->render( intval( $wc_order_id ) );
317
+ }
318
+ );
319
+
320
+ add_filter(
321
+ 'manage_edit-shop_order_columns',
322
+ static function ( $columns ) use ( $container ) {
323
+ /**
324
+ * The Order Table Payment Status object.
325
+ *
326
+ * @var OrderTablePaymentStatusColumn $payment_status_column
327
+ */
328
+ $payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
329
+ return $payment_status_column->register( $columns );
330
+ }
331
+ );
332
+
333
+ add_action(
334
+ 'manage_shop_order_posts_custom_column',
335
+ static function ( $column, $wc_order_id ) use ( $container ) {
336
+ /**
337
+ * The column object.
338
+ *
339
+ * @var OrderTablePaymentStatusColumn $payment_status_column
340
+ */
341
+ $payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
342
+ $payment_status_column->render( $column, intval( $wc_order_id ) );
343
+ },
344
+ 10,
345
+ 2
346
+ );
347
+ }
348
+
349
+ /**
350
+ * Registers the PayPal Address preset to overwrite Shipping in checkout.
351
+ *
352
+ * @param ContainerInterface $container The container.
353
+ */
354
+ private function register_checkout_paypal_address_preset( ContainerInterface $container ) {
355
+ add_filter(
356
+ 'woocommerce_checkout_get_value',
357
+ static function ( ...$args ) use ( $container ) {
358
+
359
+ /**
360
+ * Its important to not instantiate the service too early as it
361
+ * depends on SessionHandler and WooCommerce Session.
362
+ */
363
+
364
+ /**
365
+ * The CheckoutPayPalAddressPreset object.
366
+ *
367
+ * @var CheckoutPayPalAddressPreset $service
368
+ */
369
+ $service = $container->get( 'wcgateway.checkout.address-preset' );
370
+
371
+ return $service->filter_checkout_field( ...$args );
372
+ },
373
+ 10,
374
+ 2
375
+ );
376
+ }
377
+
378
+
379
+ /**
380
+ * Returns the key for the module.
381
+ *
382
+ * @return string|void
383
+ */
384
+ public function getKey() {
385
+ }
386
+ }
modules/ppcp-webhooks/extensions.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The webhook module extensions.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ return array();
modules/ppcp-webhooks/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The webhook module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return static function (): ModuleInterface {
15
+ return new WebhookModule();
16
+ };
modules/ppcp-webhooks/services.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The webhook module services.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderApproved;
13
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderCompleted;
14
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
15
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
16
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
17
+ use Psr\Container\ContainerInterface;
18
+
19
+ return array(
20
+
21
+ 'webhook.registrar' => function( $container ) : WebhookRegistrar {
22
+ $factory = $container->get( 'api.factory.webhook' );
23
+ $endpoint = $container->get( 'api.endpoint.webhook' );
24
+ $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
25
+ return new WebhookRegistrar(
26
+ $factory,
27
+ $endpoint,
28
+ $rest_endpoint
29
+ );
30
+ },
31
+ 'webhook.endpoint.controller' => function( $container ) : IncomingWebhookEndpoint {
32
+ $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
33
+ $webhook_factory = $container->get( 'api.factory.webhook' );
34
+ $handler = $container->get( 'webhook.endpoint.handler' );
35
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
36
+ $verify_request = ! defined( 'PAYPAL_WEBHOOK_REQUEST_VERIFICATION' ) || PAYPAL_WEBHOOK_REQUEST_VERIFICATION;
37
+
38
+ return new IncomingWebhookEndpoint(
39
+ $webhook_endpoint,
40
+ $webhook_factory,
41
+ $logger,
42
+ $verify_request,
43
+ ... $handler
44
+ );
45
+ },
46
+ 'webhook.endpoint.handler' => function( $container ) : array {
47
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
48
+ $prefix = $container->get( 'api.prefix' );
49
+ $order_endpoint = $container->get( 'api.endpoint.order' );
50
+ return array(
51
+ new CheckoutOrderApproved( $logger, $prefix, $order_endpoint ),
52
+ new CheckoutOrderCompleted( $logger, $prefix ),
53
+ new PaymentCaptureRefunded( $logger, $prefix ),
54
+ new PaymentCaptureReversed( $logger, $prefix ),
55
+ new PaymentCaptureCompleted( $logger, $prefix ),
56
+ );
57
+ },
58
+ );
modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Webhook CHECKOUT.ORDER.APPROVED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+ use Psr\Log\LoggerInterface;
15
+
16
+ /**
17
+ * Class CheckoutOrderApproved
18
+ */
19
+ class CheckoutOrderApproved implements RequestHandler {
20
+
21
+ use PrefixTrait;
22
+
23
+ /**
24
+ * The logger.
25
+ *
26
+ * @var LoggerInterface
27
+ */
28
+ private $logger;
29
+
30
+ /**
31
+ * The order endpoint.
32
+ *
33
+ * @var OrderEndpoint
34
+ */
35
+ private $order_endpoint;
36
+
37
+ /**
38
+ * CheckoutOrderApproved constructor.
39
+ *
40
+ * @param LoggerInterface $logger The logger.
41
+ * @param string $prefix The prefix.
42
+ * @param OrderEndpoint $order_endpoint The order endpoint.
43
+ */
44
+ public function __construct( LoggerInterface $logger, string $prefix, OrderEndpoint $order_endpoint ) {
45
+ $this->logger = $logger;
46
+ $this->prefix = $prefix;
47
+ $this->order_endpoint = $order_endpoint;
48
+ }
49
+
50
+ /**
51
+ * The event types a handler handles.
52
+ *
53
+ * @return array
54
+ */
55
+ public function event_types(): array {
56
+ return array(
57
+ 'CHECKOUT.ORDER.APPROVED',
58
+ );
59
+ }
60
+
61
+ /**
62
+ * Whether a handler is responsible for a given request or not.
63
+ *
64
+ * @param \WP_REST_Request $request The request.
65
+ *
66
+ * @return bool
67
+ */
68
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
69
+ return in_array( $request['event_type'], $this->event_types(), true );
70
+ }
71
+
72
+ /**
73
+ * Responsible for handling the request.
74
+ *
75
+ * @param \WP_REST_Request $request The request.
76
+ *
77
+ * @return \WP_REST_Response
78
+ */
79
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
80
+ $response = array( 'success' => false );
81
+ $custom_ids = array_filter(
82
+ array_map(
83
+ static function ( array $purchase_unit ): string {
84
+ return isset( $purchase_unit['custom_id'] ) ?
85
+ (string) $purchase_unit['custom_id'] : '';
86
+ },
87
+ isset( $request['resource']['purchase_units'] ) ?
88
+ (array) $request['resource']['purchase_units'] : array()
89
+ ),
90
+ static function ( string $order_id ): bool {
91
+ return ! empty( $order_id );
92
+ }
93
+ );
94
+
95
+ if ( empty( $custom_ids ) ) {
96
+ $message = sprintf(
97
+ // translators: %s is the PayPal webhook Id.
98
+ __(
99
+ 'No order for webhook event %s was found.',
100
+ 'woocommerce-paypal-payments'
101
+ ),
102
+ isset( $request['id'] ) ? $request['id'] : ''
103
+ );
104
+ $this->logger->log(
105
+ 'warning',
106
+ $message,
107
+ array(
108
+ 'request' => $request,
109
+ )
110
+ );
111
+ $response['message'] = $message;
112
+ return rest_ensure_response( $response );
113
+ }
114
+
115
+ try {
116
+ $order = isset( $request['resource']['id'] ) ?
117
+ $this->order_endpoint->order( $request['resource']['id'] ) : null;
118
+ if ( ! $order ) {
119
+ $message = sprintf(
120
+ // translators: %s is the PayPal webhook Id.
121
+ __(
122
+ 'No paypal payment for webhook event %s was found.',
123
+ 'woocommerce-paypal-payments'
124
+ ),
125
+ isset( $request['id'] ) ? $request['id'] : ''
126
+ );
127
+ $this->logger->log(
128
+ 'warning',
129
+ $message,
130
+ array(
131
+ 'request' => $request,
132
+ )
133
+ );
134
+ $response['message'] = $message;
135
+ return rest_ensure_response( $response );
136
+ }
137
+
138
+ if ( $order->intent() === 'CAPTURE' ) {
139
+ $this->order_endpoint->capture( $order );
140
+ }
141
+ } catch ( RuntimeException $error ) {
142
+ $message = sprintf(
143
+ // translators: %s is the PayPal webhook Id.
144
+ __(
145
+ 'Could not capture payment for webhook event %s.',
146
+ 'woocommerce-paypal-payments'
147
+ ),
148
+ isset( $request['id'] ) ? $request['id'] : ''
149
+ );
150
+ $this->logger->log(
151
+ 'warning',
152
+ $message,
153
+ array(
154
+ 'request' => $request,
155
+ )
156
+ );
157
+ $response['message'] = $message;
158
+ return rest_ensure_response( $response );
159
+ }
160
+
161
+ $wc_order_ids = array_map(
162
+ array(
163
+ $this,
164
+ 'sanitize_custom_id',
165
+ ),
166
+ $custom_ids
167
+ );
168
+ $args = array(
169
+ 'post__in' => $wc_order_ids,
170
+ 'limit' => -1,
171
+ );
172
+ $wc_orders = wc_get_orders( $args );
173
+ if ( ! $wc_orders ) {
174
+ $message = sprintf(
175
+ // translators: %s is the PayPal order Id.
176
+ __( 'Order for PayPal order %s not found.', 'woocommerce-paypal-payments' ),
177
+ isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''
178
+ );
179
+ $this->logger->log(
180
+ 'warning',
181
+ $message,
182
+ array(
183
+ 'request' => $request,
184
+ )
185
+ );
186
+ $response['message'] = $message;
187
+ return rest_ensure_response( $response );
188
+ }
189
+
190
+ $new_status = $order->intent() === 'CAPTURE' ? 'processing' : 'on-hold';
191
+ $status_message = $order->intent() === 'CAPTURE' ?
192
+ __( 'Payment received.', 'woocommerce-paypal-payments' )
193
+ : __( 'Payment can be captured.', 'woocommerce-paypal-payments' );
194
+ foreach ( $wc_orders as $wc_order ) {
195
+ if ( ! in_array( $wc_order->get_status(), array( 'pending', 'on-hold' ), true ) ) {
196
+ continue;
197
+ }
198
+ /**
199
+ * The WooCommerce order.
200
+ *
201
+ * @var \WC_Order $wc_order
202
+ */
203
+ $wc_order->update_status(
204
+ $new_status,
205
+ $status_message
206
+ );
207
+ $this->logger->log(
208
+ 'info',
209
+ sprintf(
210
+ // translators: %s is the order ID.
211
+ __(
212
+ 'Order %s has been updated through PayPal',
213
+ 'woocommerce-paypal-payments'
214
+ ),
215
+ (string) $wc_order->get_id()
216
+ ),
217
+ array(
218
+ 'request' => $request,
219
+ 'order' => $wc_order,
220
+ )
221
+ );
222
+ }
223
+ $response['success'] = true;
224
+ return rest_ensure_response( $response );
225
+ }
226
+ }
modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Webhook CHECKOUT.ORDER.COMPLETED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use Psr\Log\LoggerInterface;
13
+
14
+ /**
15
+ * Class CheckoutOrderCompleted
16
+ */
17
+ class CheckoutOrderCompleted implements RequestHandler {
18
+
19
+ use PrefixTrait;
20
+
21
+ /**
22
+ * The logger.
23
+ *
24
+ * @var LoggerInterface
25
+ */
26
+ private $logger;
27
+
28
+ /**
29
+ * CheckoutOrderCompleted constructor.
30
+ *
31
+ * @param LoggerInterface $logger The logger.
32
+ * @param string $prefix The prefix.
33
+ */
34
+ public function __construct( LoggerInterface $logger, string $prefix ) {
35
+ $this->logger = $logger;
36
+ $this->prefix = $prefix;
37
+ }
38
+
39
+ /**
40
+ * The event types a handler handles.
41
+ *
42
+ * @return array
43
+ */
44
+ public function event_types(): array {
45
+ return array(
46
+ 'CHECKOUT.ORDER.COMPLETED',
47
+ );
48
+ }
49
+
50
+ /**
51
+ * Whether a handler is responsible for a given request or not.
52
+ *
53
+ * @param \WP_REST_Request $request The request.
54
+ *
55
+ * @return bool
56
+ */
57
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
58
+ return in_array( $request['event_type'], $this->event_types(), true );
59
+ }
60
+
61
+ /**
62
+ * Responsible for handling the request.
63
+ *
64
+ * @param \WP_REST_Request $request The request.
65
+ *
66
+ * @return \WP_REST_Response
67
+ */
68
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
69
+ $response = array( 'success' => false );
70
+ $custom_ids = array_filter(
71
+ array_map(
72
+ static function ( array $purchase_unit ): string {
73
+ return isset( $purchase_unit['custom_id'] ) ?
74
+ (string) $purchase_unit['custom_id'] : '';
75
+ },
76
+ isset( $request['resource']['purchase_units'] ) ?
77
+ (array) $request['resource']['purchase_units'] : array()
78
+ ),
79
+ static function ( string $order_id ): bool {
80
+ return ! empty( $order_id );
81
+ }
82
+ );
83
+
84
+ if ( empty( $custom_ids ) ) {
85
+ $message = sprintf(
86
+ // translators: %s is the PayPal webhook Id.
87
+ __(
88
+ 'No order for webhook event %s was found.',
89
+ 'woocommerce-paypal-payments'
90
+ ),
91
+ isset( $request['id'] ) ? $request['id'] : ''
92
+ );
93
+ $this->logger->log(
94
+ 'warning',
95
+ $message,
96
+ array(
97
+ 'request' => $request,
98
+ )
99
+ );
100
+ $response['message'] = $message;
101
+ return rest_ensure_response( $response );
102
+ }
103
+
104
+ $order_ids = array_map(
105
+ array(
106
+ $this,
107
+ 'sanitize_custom_id',
108
+ ),
109
+ $custom_ids
110
+ );
111
+ $args = array(
112
+ 'post__in' => $order_ids,
113
+ 'limit' => -1,
114
+ );
115
+ $wc_orders = wc_get_orders( $args );
116
+ if ( ! $wc_orders ) {
117
+ $message = sprintf(
118
+ // translators: %s is the PayPal order Id.
119
+ __( 'Order for PayPal order %s not found.', 'woocommerce-paypal-payments' ),
120
+ isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''
121
+ );
122
+ $this->logger->log(
123
+ 'warning',
124
+ $message,
125
+ array(
126
+ 'request' => $request,
127
+ )
128
+ );
129
+ $response['message'] = $message;
130
+ return rest_ensure_response( $response );
131
+ }
132
+
133
+ foreach ( $wc_orders as $wc_order ) {
134
+ if ( ! in_array( $wc_order->get_status(), array( 'pending', 'on-hold' ), true ) ) {
135
+ continue;
136
+ }
137
+ /**
138
+ * The WooCommerce order.
139
+ *
140
+ * @var \WC_Order $wc_order
141
+ */
142
+ $wc_order->update_status(
143
+ 'processing',
144
+ __( 'Payment received.', 'woocommerce-paypal-payments' )
145
+ );
146
+ $this->logger->log(
147
+ 'info',
148
+ sprintf(
149
+ // translators: %s is the order ID.
150
+ __(
151
+ 'Order %s has been updated through PayPal',
152
+ 'woocommerce-paypal-payments'
153
+ ),
154
+ (string) $wc_order->get_id()
155
+ ),
156
+ array(
157
+ 'request' => $request,
158
+ 'order' => $wc_order,
159
+ )
160
+ );
161
+ }
162
+ $response['success'] = true;
163
+ return rest_ensure_response( $response );
164
+ }
165
+ // phpcs:enable Inpsyde.CodeQuality.FunctionLength.TooLong
166
+ }
modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Webhook PAYMENT.CAPTURE.COMPLETED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
+ use Psr\Log\LoggerInterface;
14
+
15
+ /**
16
+ * Class PaymentCaptureCompleted
17
+ */
18
+ class PaymentCaptureCompleted implements RequestHandler {
19
+
20
+ use PrefixTrait;
21
+
22
+ /**
23
+ * The logger.
24
+ *
25
+ * @var LoggerInterface
26
+ */
27
+ private $logger;
28
+
29
+ /**
30
+ * PaymentCaptureCompleted constructor.
31
+ *
32
+ * @param LoggerInterface $logger The logger.
33
+ * @param string $prefix The prefix.
34
+ */
35
+ public function __construct( LoggerInterface $logger, string $prefix ) {
36
+ $this->logger = $logger;
37
+ $this->prefix = $prefix;
38
+ }
39
+
40
+ /**
41
+ * The event types a handler handles.
42
+ *
43
+ * @return array
44
+ */
45
+ public function event_types(): array {
46
+ return array( 'PAYMENT.CAPTURE.COMPLETED' );
47
+ }
48
+
49
+ /**
50
+ * Whether a handler is responsible for a given request or not.
51
+ *
52
+ * @param \WP_REST_Request $request The request.
53
+ *
54
+ * @return bool
55
+ */
56
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
57
+ return in_array( $request['event_type'], $this->event_types(), true );
58
+ }
59
+
60
+ /**
61
+ * Responsible for handling the request.
62
+ *
63
+ * @param \WP_REST_Request $request The request.
64
+ *
65
+ * @return \WP_REST_Response
66
+ */
67
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
68
+ $response = array( 'success' => false );
69
+ $order_id = isset( $request['resource']['custom_id'] ) ?
70
+ $this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
71
+ if ( ! $order_id ) {
72
+ $message = sprintf(
73
+ // translators: %s is the PayPal webhook Id.
74
+ __(
75
+ 'No order for webhook event %s was found.',
76
+ 'woocommerce-paypal-payments'
77
+ ),
78
+ isset( $request['id'] ) ? $request['id'] : ''
79
+ );
80
+ $this->logger->log(
81
+ 'warning',
82
+ $message,
83
+ array(
84
+ 'request' => $request,
85
+ )
86
+ );
87
+ $response['message'] = $message;
88
+ return rest_ensure_response( $response );
89
+ }
90
+ $wc_order = wc_get_order( $order_id );
91
+
92
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
93
+ $message = sprintf(
94
+ // translators: %s is the PayPal webhook Id.
95
+ __(
96
+ 'No order for webhook event %s was found.',
97
+ 'woocommerce-paypal-payments'
98
+ ),
99
+ isset( $request['id'] ) ? $request['id'] : ''
100
+ );
101
+ $this->logger->log(
102
+ 'warning',
103
+ $message,
104
+ array(
105
+ 'request' => $request,
106
+ )
107
+ );
108
+ $response['message'] = $message;
109
+ return rest_ensure_response( $response );
110
+ }
111
+
112
+ if ( $wc_order->get_status() !== 'on-hold' ) {
113
+ $response['success'] = true;
114
+ return rest_ensure_response( $response );
115
+ }
116
+ $wc_order->add_order_note(
117
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
118
+ );
119
+
120
+ $wc_order->set_status( 'processing' );
121
+ $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
122
+ $wc_order->save();
123
+ $this->logger->log(
124
+ 'info',
125
+ sprintf(
126
+ // translators: %s is the order ID.
127
+ __(
128
+ 'Order %s has been updated through PayPal',
129
+ 'woocommerce-paypal-payments'
130
+ ),
131
+ (string) $wc_order->get_id()
132
+ ),
133
+ array(
134
+ 'request' => $request,
135
+ 'order' => $wc_order,
136
+ )
137
+ );
138
+ $response['success'] = true;
139
+ return rest_ensure_response( $response );
140
+ }
141
+ }
modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handels the Webhook PAYMENT.CAPTURE.REFUNDED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use Psr\Log\LoggerInterface;
13
+
14
+ /**
15
+ * Class PaymentCaptureRefunded
16
+ */
17
+ class PaymentCaptureRefunded implements RequestHandler {
18
+
19
+ use PrefixTrait;
20
+
21
+ /**
22
+ * The logger.
23
+ *
24
+ * @var LoggerInterface
25
+ */
26
+ private $logger;
27
+
28
+ /**
29
+ * PaymentCaptureRefunded constructor.
30
+ *
31
+ * @param LoggerInterface $logger The logger.
32
+ * @param string $prefix The prefix.
33
+ */
34
+ public function __construct( LoggerInterface $logger, string $prefix ) {
35
+ $this->logger = $logger;
36
+ $this->prefix = $prefix;
37
+ }
38
+
39
+ /**
40
+ * The event types a handler handles.
41
+ *
42
+ * @return array
43
+ */
44
+ public function event_types(): array {
45
+ return array( 'PAYMENT.CAPTURE.REFUNDED' );
46
+ }
47
+
48
+ /**
49
+ * Whether a handler is responsible for a given request or not.
50
+ *
51
+ * @param \WP_REST_Request $request The request.
52
+ *
53
+ * @return bool
54
+ */
55
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
56
+ return in_array( $request['event_type'], $this->event_types(), true );
57
+ }
58
+
59
+ /**
60
+ * Responsible for handling the request.
61
+ *
62
+ * @param \WP_REST_Request $request The request.
63
+ *
64
+ * @return \WP_REST_Response
65
+ */
66
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
67
+ $response = array( 'success' => false );
68
+ $order_id = isset( $request['resource']['custom_id'] ) ?
69
+ $this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
70
+ if ( ! $order_id ) {
71
+ $message = sprintf(
72
+ // translators: %s is the PayPal webhook Id.
73
+ __(
74
+ 'No order for webhook event %s was found.',
75
+ 'woocommerce-paypal-payments'
76
+ ),
77
+ isset( $request['id'] ) ? $request['id'] : ''
78
+ );
79
+ $this->logger->log(
80
+ 'warning',
81
+ $message,
82
+ array(
83
+ 'request' => $request,
84
+ )
85
+ );
86
+ $response['message'] = $message;
87
+ return rest_ensure_response( $response );
88
+ }
89
+
90
+ $wc_order = wc_get_order( $order_id );
91
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
92
+ $message = sprintf(
93
+ // translators: %s is the PayPal refund Id.
94
+ __( 'Order for PayPal refund %s not found.', 'woocommerce-paypal-payments' ),
95
+ isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''
96
+ );
97
+ $this->logger->log(
98
+ 'warning',
99
+ $message,
100
+ array(
101
+ 'request' => $request,
102
+ )
103
+ );
104
+ $response['message'] = $message;
105
+ return rest_ensure_response( $response );
106
+ }
107
+
108
+ /**
109
+ * The WooCommerce order.
110
+ *
111
+ * @var \WC_Order $wc_order
112
+ */
113
+ $refund = wc_create_refund(
114
+ array(
115
+ 'order_id' => $wc_order->get_id(),
116
+ 'amount' => $request['resource']['amount']['value'],
117
+ )
118
+ );
119
+ if ( is_wp_error( $refund ) ) {
120
+ $this->logger->log(
121
+ 'warning',
122
+ sprintf(
123
+ // translators: %s is the order id.
124
+ __( 'Order %s could not be refunded', 'woocommerce-paypal-payments' ),
125
+ (string) $wc_order->get_id()
126
+ ),
127
+ array(
128
+ 'request' => $request,
129
+ 'error' => $refund,
130
+ )
131
+ );
132
+
133
+ $response['message'] = $refund->get_error_message();
134
+ return rest_ensure_response( $response );
135
+ }
136
+
137
+ $this->logger->log(
138
+ 'info',
139
+ sprintf(
140
+ // translators: %1$s is the order id %2$s is the amount which has been refunded.
141
+ __(
142
+ 'Order %1$s has been refunded with %2$s through PayPal',
143
+ 'woocommerce-paypal-payments'
144
+ ),
145
+ (string) $wc_order->get_id(),
146
+ (string) $refund->get_amount()
147
+ ),
148
+ array(
149
+ 'request' => $request,
150
+ 'order' => $wc_order,
151
+ )
152
+ );
153
+ $response['success'] = true;
154
+ return rest_ensure_response( $response );
155
+ }
156
+ }
modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the following Webhooks:
4
+ * - PAYMENT.CAPTURE.REVERSED
5
+ * - PAYMENT.ORDER.CANCELLED
6
+ * - PAYMENT.CAPTURE.DENIED
7
+ *
8
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
9
+ */
10
+
11
+ declare(strict_types=1);
12
+
13
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
14
+
15
+ use Psr\Log\LoggerInterface;
16
+
17
+ /**
18
+ * Class PaymentCaptureReversed
19
+ */
20
+ class PaymentCaptureReversed implements RequestHandler {
21
+
22
+ use PrefixTrait;
23
+
24
+ /**
25
+ * The logger.
26
+ *
27
+ * @var LoggerInterface
28
+ */
29
+ private $logger;
30
+
31
+ /**
32
+ * PaymentCaptureReversed constructor.
33
+ *
34
+ * @param LoggerInterface $logger The logger.
35
+ * @param string $prefix The prefix.
36
+ */
37
+ public function __construct( LoggerInterface $logger, string $prefix ) {
38
+ $this->logger = $logger;
39
+ $this->prefix = $prefix;
40
+ }
41
+
42
+ /**
43
+ * The event types a handler handles.
44
+ *
45
+ * @return array
46
+ */
47
+ public function event_types(): array {
48
+ return array(
49
+ 'PAYMENT.CAPTURE.REVERSED',
50
+ 'PAYMENT.ORDER.CANCELLED',
51
+ 'PAYMENT.CAPTURE.DENIED',
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Whether a handler is responsible for a given request or not.
57
+ *
58
+ * @param \WP_REST_Request $request The request.
59
+ *
60
+ * @return bool
61
+ */
62
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
63
+ return in_array( $request['event_type'], $this->event_types(), true );
64
+ }
65
+
66
+ /**
67
+ * Responsible for handling the request.
68
+ *
69
+ * @param \WP_REST_Request $request The request.
70
+ *
71
+ * @return \WP_REST_Response
72
+ */
73
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
74
+ $response = array( 'success' => false );
75
+ $order_id = isset( $request['resource']['custom_id'] ) ?
76
+ $this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
77
+ if ( ! $order_id ) {
78
+ $message = sprintf(
79
+ // translators: %s is the PayPal webhook Id.
80
+ __(
81
+ 'No order for webhook event %s was found.',
82
+ 'woocommerce-paypal-payments'
83
+ ),
84
+ isset( $request['id'] ) ? $request['id'] : ''
85
+ );
86
+ $this->logger->log(
87
+ 'warning',
88
+ $message,
89
+ array(
90
+ 'request' => $request,
91
+ )
92
+ );
93
+ $response['message'] = $message;
94
+ return rest_ensure_response( $response );
95
+ }
96
+
97
+ $wc_order = wc_get_order( $order_id );
98
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
99
+ $message = sprintf(
100
+ // translators: %s is the PayPal refund Id.
101
+ __( 'Order for PayPal refund %s not found.', 'woocommerce-paypal-payments' ),
102
+ isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''
103
+ );
104
+ $this->logger->log(
105
+ 'warning',
106
+ $message,
107
+ array(
108
+ 'request' => $request,
109
+ )
110
+ );
111
+ $response['message'] = $message;
112
+ return rest_ensure_response( $response );
113
+ }
114
+
115
+ /**
116
+ * The WooCommerce order.
117
+ *
118
+ * @var \WC_Order $wc_order
119
+ */
120
+ $response['success'] = (bool) $wc_order->update_status( 'cancelled' );
121
+
122
+ $message = $response['success'] ? sprintf(
123
+ // translators: %1$s is the order id.
124
+ __(
125
+ 'Order %1$s has been cancelled through PayPal',
126
+ 'woocommerce-paypal-payments'
127
+ ),
128
+ (string) $wc_order->get_id()
129
+ ) : sprintf(
130
+ // translators: %1$s is the order id.
131
+ __( 'Failed to cancel order %1$s through PayPal', 'woocommerce-paypal-payments' ),
132
+ (string) $wc_order->get_id()
133
+ );
134
+ $this->logger->log(
135
+ $response['success'] ? 'info' : 'warning',
136
+ $message,
137
+ array(
138
+ 'request' => $request,
139
+ 'order' => $wc_order,
140
+ )
141
+ );
142
+ return rest_ensure_response( $response );
143
+ }
144
+ }
modules/ppcp-webhooks/src/Handler/class-prefixtrait.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Trait which helps to remove the prefix of IDs.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ /**
13
+ * Trait PrefixTrait
14
+ */
15
+ trait PrefixTrait {
16
+
17
+
18
+ /**
19
+ * The prefix.
20
+ *
21
+ * @var string
22
+ */
23
+ private $prefix = '';
24
+
25
+ /**
26
+ * Removes the prefix from a given Id.
27
+ *
28
+ * @param string $custom_id The custom id.
29
+ *
30
+ * @return int
31
+ */
32
+ private function sanitize_custom_id( string $custom_id ): int {
33
+
34
+ $id = str_replace( $this->prefix, '', $custom_id );
35
+ return (int) $id;
36
+ }
37
+ }
modules/ppcp-webhooks/src/Handler/class-requesthandler.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The interface for the request handlers.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ /**
13
+ * Interface RequestHandler
14
+ */
15
+ interface RequestHandler {
16
+
17
+ /**
18
+ * The event types a handler handles.
19
+ *
20
+ * @return array
21
+ */
22
+ public function event_types(): array;
23
+
24
+ /**
25
+ * Whether a handler is responsible for a given request or not.
26
+ *
27
+ * @param \WP_REST_Request $request The request.
28
+ *
29
+ * @return bool
30
+ */
31
+ public function responsible_for_request( \WP_REST_Request $request): bool;
32
+
33
+ /**
34
+ * Responsible for handling the request.
35
+ *
36
+ * @param \WP_REST_Request $request The request.
37
+ *
38
+ * @return \WP_REST_Response
39
+ */
40
+ public function handle_request( \WP_REST_Request $request): \WP_REST_Response;
41
+ }
modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the endpoint for the incoming webhooks.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
15
+ use WooCommerce\PayPalCommerce\Webhooks\Handler\RequestHandler;
16
+ use Psr\Log\LoggerInterface;
17
+
18
+ /**
19
+ * Class IncomingWebhookEndpoint
20
+ */
21
+ class IncomingWebhookEndpoint {
22
+
23
+ const NAMESPACE = 'paypal/v1';
24
+ const ROUTE = 'incoming';
25
+
26
+ /**
27
+ * The Webhook endpoint.
28
+ *
29
+ * @var WebhookEndpoint
30
+ */
31
+ private $webhook_endpoint;
32
+
33
+ /**
34
+ * The Webhook Factory.
35
+ *
36
+ * @var WebhookFactory
37
+ */
38
+ private $webhook_factory;
39
+
40
+ /**
41
+ * The Request handlers.
42
+ *
43
+ * @var RequestHandler[]
44
+ */
45
+ private $handlers;
46
+
47
+ /**
48
+ * The logger.
49
+ *
50
+ * @var LoggerInterface
51
+ */
52
+ private $logger;
53
+
54
+ /**
55
+ * Whether requests need to be verified.
56
+ *
57
+ * @var bool
58
+ */
59
+ private $verify_request;
60
+
61
+ /**
62
+ * IncomingWebhookEndpoint constructor.
63
+ *
64
+ * @param WebhookEndpoint $webhook_endpoint The webhook endpoint.
65
+ * @param WebhookFactory $webhook_factory The webhook factory.
66
+ * @param LoggerInterface $logger The logger.
67
+ * @param bool $verify_request Whether requests need to be verified or not.
68
+ * @param RequestHandler ...$handlers The handlers, which process a request in the end.
69
+ */
70
+ public function __construct(
71
+ WebhookEndpoint $webhook_endpoint,
72
+ WebhookFactory $webhook_factory,
73
+ LoggerInterface $logger,
74
+ bool $verify_request,
75
+ RequestHandler ...$handlers
76
+ ) {
77
+
78
+ $this->webhook_endpoint = $webhook_endpoint;
79
+ $this->webhook_factory = $webhook_factory;
80
+ $this->handlers = $handlers;
81
+ $this->logger = $logger;
82
+ $this->verify_request = $verify_request;
83
+ }
84
+
85
+ /**
86
+ * Registers the endpoint.
87
+ *
88
+ * @return bool
89
+ */
90
+ public function register(): bool {
91
+ return (bool) register_rest_route(
92
+ self::NAMESPACE,
93
+ self::ROUTE,
94
+ array(
95
+ 'methods' => array(
96
+ 'POST',
97
+ ),
98
+ 'callback' => array(
99
+ $this,
100
+ 'handle_request',
101
+ ),
102
+ 'permission_callback' => array(
103
+ $this,
104
+ 'verify_request',
105
+ ),
106
+ )
107
+ );
108
+ }
109
+
110
+ /**
111
+ * Verifies the current request.
112
+ *
113
+ * @return bool
114
+ */
115
+ public function verify_request(): bool {
116
+ if ( ! $this->verify_request ) {
117
+ return true;
118
+ }
119
+ try {
120
+ $data = (array) get_option( WebhookRegistrar::KEY, array() );
121
+ $webhook = $this->webhook_factory->from_array( $data );
122
+ $result = $this->webhook_endpoint->verify_current_request_for_webhook( $webhook );
123
+ if ( ! $result ) {
124
+ $this->logger->log(
125
+ 'error',
126
+ __( 'Illegit Webhook request detected.', 'woocommerce-paypal-payments' )
127
+ );
128
+ }
129
+ return $result;
130
+ } catch ( RuntimeException $exception ) {
131
+ $this->logger->log(
132
+ 'error',
133
+ sprintf(
134
+ // translators: %s is the error message.
135
+ __(
136
+ 'Illegit Webhook request detected: %s',
137
+ 'woocommerce-paypal-payments'
138
+ ),
139
+ $exception->getMessage()
140
+ )
141
+ );
142
+ return false;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Handles the request.
148
+ *
149
+ * @param \WP_REST_Request $request The request.
150
+ *
151
+ * @return \WP_REST_Response
152
+ */
153
+ public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
154
+
155
+ foreach ( $this->handlers as $handler ) {
156
+ if ( $handler->responsible_for_request( $request ) ) {
157
+ $response = $handler->handle_request( $request );
158
+ $this->logger->log(
159
+ 'info',
160
+ sprintf(
161
+ // translators: %s is the event type.
162
+ __( 'Webhook has been handled by %s', 'woocommerce-paypal-payments' ),
163
+ ( $handler->event_types() ) ? current( $handler->event_types() ) : ''
164
+ ),
165
+ array(
166
+ 'request' => $request,
167
+ 'response' => $response,
168
+ )
169
+ );
170
+ return $response;
171
+ }
172
+ }
173
+
174
+ $message = sprintf(
175
+ // translators: %s is the request type.
176
+ __( 'Could not find handler for request type %s', 'woocommerce-paypal-payments' ),
177
+ $request['event_type']
178
+ );
179
+ $this->logger->log(
180
+ 'warning',
181
+ $message,
182
+ array(
183
+ 'request' => $request,
184
+ )
185
+ );
186
+ $response = array(
187
+ 'success' => false,
188
+ 'message' => $message,
189
+ );
190
+ return rest_ensure_response( $response );
191
+ }
192
+
193
+ /**
194
+ * Returns the URL to the endpoint.
195
+ *
196
+ * @return string
197
+ */
198
+ public function url(): string {
199
+ return rest_url( self::NAMESPACE . '/' . self::ROUTE );
200
+ }
201
+
202
+ /**
203
+ * Returns the event types, which are handled by the endpoint.
204
+ *
205
+ * @return array
206
+ */
207
+ public function handled_event_types(): array {
208
+ $event_types = array();
209
+ foreach ( $this->handlers as $handler ) {
210
+ $event_types = array_merge( $event_types, $handler->event_types() );
211
+ }
212
+ return array_unique( $event_types );
213
+ }
214
+ }
modules/ppcp-webhooks/src/class-webhookmodule.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The webhook module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use Interop\Container\ServiceProviderInterface;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class WebhookModule
19
+ */
20
+ class WebhookModule implements ModuleInterface {
21
+
22
+ /**
23
+ * Setup the Webhook module.
24
+ *
25
+ * @return ServiceProviderInterface
26
+ */
27
+ public function setup(): ServiceProviderInterface {
28
+ return new ServiceProvider(
29
+ require __DIR__ . '/../services.php',
30
+ require __DIR__ . '/../extensions.php'
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Run the Webhook module.
36
+ *
37
+ * @param ContainerInterface|null $container The Container.
38
+ */
39
+ public function run( ContainerInterface $container = null ) {
40
+ add_action(
41
+ 'rest_api_init',
42
+ static function () use ( $container ) {
43
+ $endpoint = $container->get( 'webhook.endpoint.controller' );
44
+ /**
45
+ * The Incoming Webhook Endpoint.
46
+ *
47
+ * @var IncomingWebhookEndpoint $endpoint
48
+ */
49
+ $endpoint->register();
50
+ }
51
+ );
52
+
53
+ add_action(
54
+ WebhookRegistrar::EVENT_HOOK,
55
+ static function () use ( $container ) {
56
+ $registrar = $container->get( 'webhook.registrar' );
57
+ /**
58
+ * The Webhook Registrar.
59
+ *
60
+ * @var WebhookRegistrar $endpoint
61
+ */
62
+ $registrar->register();
63
+ }
64
+ );
65
+
66
+ add_action(
67
+ 'woocommerce_paypal_payments_gateway_deactivate',
68
+ static function () use ( $container ) {
69
+ $registrar = $container->get( 'webhook.registrar' );
70
+ /**
71
+ * The Webhook Registrar.
72
+ *
73
+ * @var WebhookRegistrar $endpoint
74
+ */
75
+ $registrar->unregister();
76
+ }
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Returns the key for the module.
82
+ *
83
+ * @return string|void
84
+ */
85
+ public function getKey() {
86
+ }
87
+ }
modules/ppcp-webhooks/src/class-webhookregistrar.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The WebhookRegistrar registers and unregisters webhooks with PayPal.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks;
11
+
12
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
15
+
16
+ /**
17
+ * Class WebhookRegistrar
18
+ */
19
+ class WebhookRegistrar {
20
+
21
+
22
+ const EVENT_HOOK = 'ppcp-register-event';
23
+ const KEY = 'ppcp-webhook';
24
+
25
+ /**
26
+ * The Webhook factory.
27
+ *
28
+ * @var WebhookFactory
29
+ */
30
+ private $webhook_factory;
31
+
32
+ /**
33
+ * The Webhook endpoint.
34
+ *
35
+ * @var WebhookEndpoint
36
+ */
37
+ private $endpoint;
38
+
39
+ /**
40
+ * The WordPress Rest API endpoint.
41
+ *
42
+ * @var IncomingWebhookEndpoint
43
+ */
44
+ private $rest_endpoint;
45
+
46
+ /**
47
+ * WebhookRegistrar constructor.
48
+ *
49
+ * @param WebhookFactory $webhook_factory The Webhook factory.
50
+ * @param WebhookEndpoint $endpoint The Webhook endpoint.
51
+ * @param IncomingWebhookEndpoint $rest_endpoint The WordPress Rest API endpoint.
52
+ */
53
+ public function __construct(
54
+ WebhookFactory $webhook_factory,
55
+ WebhookEndpoint $endpoint,
56
+ IncomingWebhookEndpoint $rest_endpoint
57
+ ) {
58
+
59
+ $this->webhook_factory = $webhook_factory;
60
+ $this->endpoint = $endpoint;
61
+ $this->rest_endpoint = $rest_endpoint;
62
+ }
63
+
64
+ /**
65
+ * Register Webhooks with PayPal.
66
+ *
67
+ * @return bool
68
+ */
69
+ public function register(): bool {
70
+ $webhook = $this->webhook_factory->for_url_and_events(
71
+ $this->rest_endpoint->url(),
72
+ $this->rest_endpoint->handled_event_types()
73
+ );
74
+
75
+ try {
76
+ $created = $this->endpoint->create( $webhook );
77
+ if ( empty( $created->id() ) ) {
78
+ return false;
79
+ }
80
+ update_option(
81
+ self::KEY,
82
+ $created->to_array()
83
+ );
84
+ return true;
85
+ } catch ( RuntimeException $error ) {
86
+ wp_schedule_single_event(
87
+ time() - 1,
88
+ self::EVENT_HOOK
89
+ );
90
+ return false;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Unregister webhooks with PayPal.
96
+ *
97
+ * @return bool
98
+ */
99
+ public function unregister(): bool {
100
+ $data = (array) get_option( self::KEY, array() );
101
+ if ( ! $data ) {
102
+ return false;
103
+ }
104
+ try {
105
+ $webhook = $this->webhook_factory->from_array( $data );
106
+ $success = $this->endpoint->delete( $webhook );
107
+ } catch ( RuntimeException $error ) {
108
+ return false;
109
+ }
110
+
111
+ if ( $success ) {
112
+ delete_option( self::KEY );
113
+ }
114
+ return $success;
115
+ }
116
+ }
modules/woocommerce-logging/extensions.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The logging extensions.
4
+ *
5
+ * @package WooCommerce\WooCommerce\Logging
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+
11
+ namespace WooCommerce\PayPalCommerce\Logging;
12
+
13
+ return array();
modules/woocommerce-logging/module.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The logging module.
4
+ *
5
+ * @package WooCommerce\WooCommerce\Logging
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\WooCommerce\Logging;
11
+
12
+ use Dhii\Modular\Module\ModuleInterface;
13
+
14
+ return function (): ModuleInterface {
15
+ return new WooCommerceLoggingModule();
16
+ };
modules/woocommerce-logging/services.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The logging services.
4
+ *
5
+ * @package WooCommerce\WooCommerce\Logging
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\WooCommerce\Logging;
11
+
12
+ use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
13
+ use WooCommerce\WooCommerce\Logging\Logger\WooCommerceLogger;
14
+ use Psr\Container\ContainerInterface;
15
+ use Psr\Log\LoggerInterface;
16
+
17
+ return array(
18
+ 'woocommerce.logger.source' => function(): string {
19
+ return 'woocommerce-paypal-payments';
20
+ },
21
+ 'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
22
+ if ( ! class_exists( \WC_Logger::class ) ) {
23
+ return new NullLogger();
24
+ }
25
+
26
+ $source = $container->get( 'woocommerce.logger.source' );
27
+
28
+ return new WooCommerceLogger(
29
+ wc_get_logger(),
30
+ $source
31
+ );
32
+ },
33
+ );
modules/woocommerce-logging/src/Logger/class-nulllogger.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Null logger is used, when logging is disabled. It does not log at all
4
+ * but complies with the LoggerInterface.
5
+ *
6
+ * @package WooCommerce\WooCommerce\Logging\Logger
7
+ */
8
+
9
+ declare(strict_types=1);
10
+
11
+ namespace WooCommerce\WooCommerce\Logging\Logger;
12
+
13
+ use Psr\Log\LoggerInterface;
14
+ use Psr\Log\LoggerTrait;
15
+
16
+ /**
17
+ * Class NullLogger
18
+ */
19
+ class NullLogger implements LoggerInterface {
20
+
21
+
22
+ use LoggerTrait;
23
+
24
+ /**
25
+ * Logs a message. Since its a NullLogger, it does not log at all.
26
+ *
27
+ * @param mixed $level The logging level.
28
+ * @param string $message The message.
29
+ * @param array $context The context.
30
+ */
31
+ public function log( $level, $message, array $context = array() ) {
32
+ }
33
+ }
modules/woocommerce-logging/src/Logger/class-woocommercelogger.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce includes a logger interface, which is fully compatible to PSR-3,
4
+ * but for some reason does not extend/implement it.
5
+ *
6
+ * This is a decorator that makes any WooCommerce Logger PSR-3-compatible
7
+ *
8
+ * @package WooCommerce\WooCommerce\Logging\Logger
9
+ */
10
+
11
+ declare(strict_types=1);
12
+
13
+ namespace WooCommerce\WooCommerce\Logging\Logger;
14
+
15
+ use Psr\Log\LoggerInterface;
16
+ use Psr\Log\LoggerTrait;
17
+
18
+ /**
19
+ * Class WooCommerceLogger
20
+ */
21
+ class WooCommerceLogger implements LoggerInterface {
22
+
23
+
24
+ use LoggerTrait;
25
+
26
+ /**
27
+ * The WooCommerce logger.
28
+ *
29
+ * @var \WC_Logger_Interface
30
+ */
31
+ private $wc_logger;
32
+
33
+ /**
34
+ * The source (Plugin), which logs the message.
35
+ *
36
+ * @var string The source.
37
+ */
38
+ private $source;
39
+
40
+ /**
41
+ * WooCommerceLogger constructor.
42
+ *
43
+ * @param \WC_Logger_Interface $wc_logger The WooCommerce logger.
44
+ * @param string $source The source.
45
+ */
46
+ public function __construct( \WC_Logger_Interface $wc_logger, string $source ) {
47
+ $this->wc_logger = $wc_logger;
48
+ $this->source = $source;
49
+ }
50
+
51
+ /**
52
+ * Logs a message.
53
+ *
54
+ * @param mixed $level The logging level.
55
+ * @param string $message The message.
56
+ * @param array $context The context.
57
+ */
58
+ public function log( $level, $message, array $context = array() ) {
59
+ if ( ! isset( $context['source'] ) ) {
60
+ $context['source'] = $this->source;
61
+ }
62
+ $this->wc_logger->log( $level, $message, $context );
63
+ }
64
+ }
modules/woocommerce-logging/src/class-woocommerceloggingmodule.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The logging module.
4
+ *
5
+ * @package WooCommerce\WooCommerce\Logging
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\WooCommerce\Logging;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use Interop\Container\ServiceProviderInterface;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class WooCommerceLoggingModule
19
+ */
20
+ class WooCommerceLoggingModule implements ModuleInterface {
21
+
22
+ /**
23
+ * Setup the module.
24
+ *
25
+ * @return ServiceProviderInterface
26
+ */
27
+ public function setup(): ServiceProviderInterface {
28
+ return new ServiceProvider(
29
+ require __DIR__ . '/../services.php',
30
+ require __DIR__ . '/../extensions.php'
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Run the module.
36
+ *
37
+ * @param ContainerInterface $container The container.
38
+ */
39
+ public function run( ContainerInterface $container = null ) {
40
+ }
41
+
42
+
43
+ /**
44
+ * Returns the key for the module.
45
+ *
46
+ * @return string|void
47
+ */
48
+ public function getKey() {
49
+ }
50
+ }
readme.txt ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === WooCommerce PayPal Payments ===
2
+ Contributors: woocommerce, automattic
3
+ Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout
4
+ Requires at least: 5.3
5
+ Tested up to: 5.5
6
+ Requires PHP: 7.0
7
+ Stable tag: 1.0.0
8
+ License: GPLv2
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ PayPal's latest payments processing solution. Accept PayPal, PayPal Credit, credit/debit cards, alternative digital wallets and bank accounts.
12
+
13
+ == Description ==
14
+
15
+ PayPal's latest, most complete payment processing solution. Accept PayPal exclusives, credit/debit cards and local payment methods. Turn on only PayPal options or process a full suite of payment methods. Enable global transactions with extensive currency and country coverage.
16
+ Built and supported by [WooCommerce](https://woocommerce.com) and [PayPal](https://paypal.com).
17
+
18
+ == Installation ==
19
+
20
+ = Requirements =
21
+
22
+ To install WooCommerce PayPal Payments, you need:
23
+
24
+ * WordPress Version 5.3 or newer (installed)
25
+ * WooCommerce Version 3.9 or newer (installed and activated)
26
+ * PHP Version 7.0 or newer
27
+ * PayPal business account
28
+
29
+ = Instructions =
30
+
31
+ 1. Log in to WordPress admin.
32
+ 2. Go to **Plugins > Add New**.
33
+ 3. Search for the **WooCommerce PayPal Payments** plugin.
34
+ 4. Click on **Install Now** and wait until the plugin is installed successfully.
35
+ 5. You can activate the plugin immediately by clicking on **Activate** now on the success page. If you want to activate it later, you can do so via **Plugins > Installed Plugins**.
36
+
37
+ = Setup and Configuration =
38
+
39
+ Follow the steps below to connect the plugin to your PayPal account:
40
+
41
+ 1. After you have activated the WooCommerce PayPal Payments plugin, go to **WooCommerce > Settings**.
42
+ 2. Click the **Payments** tab.
43
+ 3. The Payment methods list will include two PayPal options. Click on **PayPal** (not PayPal Standard).
44
+ 4. Click the **PayPal Checkout** tab.
45
+ 5. Click on the **Connect to PayPal** button.
46
+ 6. Sign in to your PayPal account. If you do not have a PayPal account yet, sign up for a new PayPal business account.
47
+ 7. After you have successfully connected your PayPal account, click on the **Enable the PayPal Gateway** checkbox to enable PayPal.
48
+ 8. Click **Save changes**.
49
+
50
+ == Screenshots ==
51
+
52
+ 1. PayPal buttons on a single product page.
53
+ 2. Cart page.
54
+ 3. Checkout page.
55
+ 4. Enable "PayPal" on the Payment methods tab in WooCommerce.
56
+ 5. Click "Connect to PayPal" to link your site to your PayPal account.
57
+ 6. Main settings screen.
58
+
59
+ == Changelog ==
60
+
61
+ = 1.0 =
62
+ * Initial release.
src/README.md ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ # PHP Sources for WooCommerce PayPal Commerce Gateway
2
+
3
+ This directory is the PSR-4 root for `Inpsyde\PayPalCommerce\`
src/class-pluginmodule.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin module.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce;
11
+
12
+ use Dhii\Container\ServiceProvider;
13
+ use Dhii\Modular\Module\ModuleInterface;
14
+ use Interop\Container\ServiceProviderInterface;
15
+ use Psr\Container\ContainerInterface;
16
+
17
+ /**
18
+ * Class PluginModule
19
+ */
20
+ class PluginModule implements ModuleInterface {
21
+
22
+ /**
23
+ * Sets the module up.
24
+ */
25
+ public function setup(): ServiceProviderInterface {
26
+ return new ServiceProvider( array(), array() );
27
+ }
28
+
29
+ /**
30
+ * Runs the module.
31
+ *
32
+ * @param ContainerInterface|null $container The Container.
33
+ */
34
+ public function run( ContainerInterface $container = null ) {
35
+ }
36
+
37
+ /**
38
+ * Returns the key for the module.
39
+ *
40
+ * @return string|void
41
+ */
42
+ public function getKey() {
43
+ }
44
+ }
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 ComposerAutoloaderInit121f0b0fd6fcff38fa2020e581a9a4ea::getLoader();
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', array_values($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
+ }
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
+
vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => $baseDir . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
10
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => $baseDir . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
11
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
12
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
13
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
14
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
15
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => $baseDir . '/modules/ppcp-api-client/src/class-apimodule.php',
16
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
17
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
18
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
19
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
20
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
21
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
22
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
23
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
24
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
25
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
26
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
27
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
28
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-address.php',
29
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amount.php',
30
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
31
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
32
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
33
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
34
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
35
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-item.php',
36
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-money.php',
37
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-order.php',
38
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
39
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patch.php',
40
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
41
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payee.php',
42
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payer.php',
43
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payername.php',
44
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
45
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
46
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
47
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
48
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
49
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
50
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payments.php',
51
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phone.php',
52
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
53
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
54
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-refund.php',
55
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
56
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
57
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
58
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-token.php',
59
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
60
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
61
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
62
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
63
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
64
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
65
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
66
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
67
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
68
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
69
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
70
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
71
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
72
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
73
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
74
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
75
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
76
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
77
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
78
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
79
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
80
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-cache.php',
81
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
82
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
83
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
84
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
85
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
86
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
87
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
88
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
89
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
90
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
91
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
92
+ 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => $baseDir . '/modules/ppcp-button/src/class-buttonmodule.php',
93
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
94
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
95
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
96
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
97
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
98
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
99
+ 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
100
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => $baseDir . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
101
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => $baseDir . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
102
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => $baseDir . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
103
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => $baseDir . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
104
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => $baseDir . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
105
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => $baseDir . '/modules/ppcp-onboarding/src/class-environment.php',
106
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => $baseDir . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
107
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => $baseDir . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
108
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => $baseDir . '/modules/ppcp-onboarding/src/class-state.php',
109
+ 'WooCommerce\\PayPalCommerce\\PluginModule' => $baseDir . '/src/class-pluginmodule.php',
110
+ 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
111
+ 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
112
+ 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => $baseDir . '/modules/ppcp-session/src/class-sessionhandler.php',
113
+ 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => $baseDir . '/modules/ppcp-session/src/class-sessionmodule.php',
114
+ 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => $baseDir . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
115
+ 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => $baseDir . '/modules/ppcp-subscription/src/class-renewalhandler.php',
116
+ 'WooCommerce\\PayPalCommerce\\Subscription\\Repository\\PaymentTokenRepository' => $baseDir . '/modules/ppcp-subscription/src/Repository/class-paymenttokenrepository.php',
117
+ 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => $baseDir . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
118
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
119
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
120
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
121
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
122
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
123
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => $baseDir . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
124
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
125
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
126
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
127
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
128
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\WcGatewayInterface' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-wcgatewayinterface.php',
129
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
130
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
131
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
132
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
133
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
134
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
135
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
136
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
137
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
138
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => $baseDir . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
139
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
140
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
141
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
142
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
143
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
144
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
145
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
146
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
147
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
148
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
149
+ 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
150
+ 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
151
+ 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => $baseDir . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
152
+ 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capture.php',
153
+ 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => $baseDir . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
154
+ );
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
+ );
vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
10
+ 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
11
+ 'OomphInc\\ComposerInstallersExtender\\' => array($vendorDir . '/oomphinc/composer-installers-extender/src'),
12
+ 'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src'),
13
+ 'Dhii\\Wp\\Containers\\' => array($vendorDir . '/dhii/wp-containers/src'),
14
+ 'Dhii\\Util\\String\\' => array($vendorDir . '/dhii/stringable-interface/src'),
15
+ 'Dhii\\Modular\\Module\\' => array($vendorDir . '/dhii/module-interface/src'),
16
+ 'Dhii\\Factory\\' => array($vendorDir . '/dhii/factory-interface/src'),
17
+ 'Dhii\\Exception\\' => array($vendorDir . '/dhii/exception-interface/src'),
18
+ 'Dhii\\Data\\Container\\' => array($vendorDir . '/dhii/data-container-interface/src'),
19
+ 'Dhii\\Container\\' => array($vendorDir . '/dhii/containers/src'),
20
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
21
+ );
vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInit121f0b0fd6fcff38fa2020e581a9a4ea
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
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
+ public static function getLoader()
20
+ {
21
+ if (null !== self::$loader) {
22
+ return self::$loader;
23
+ }
24
+
25
+ spl_autoload_register(array('ComposerAutoloaderInit121f0b0fd6fcff38fa2020e581a9a4ea', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit121f0b0fd6fcff38fa2020e581a9a4ea', 'loadClassLoader'));
28
+
29
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
+ if ($useStaticLoader) {
31
+ require_once __DIR__ . '/autoload_static.php';
32
+
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit121f0b0fd6fcff38fa2020e581a9a4ea::getInitializer($loader));
34
+ } else {
35
+ $map = require __DIR__ . '/autoload_namespaces.php';
36
+ foreach ($map as $namespace => $path) {
37
+ $loader->set($namespace, $path);
38
+ }
39
+
40
+ $map = require __DIR__ . '/autoload_psr4.php';
41
+ foreach ($map as $namespace => $path) {
42
+ $loader->setPsr4($namespace, $path);
43
+ }
44
+
45
+ $classMap = require __DIR__ . '/autoload_classmap.php';
46
+ if ($classMap) {
47
+ $loader->addClassMap($classMap);
48
+ }
49
+ }
50
+
51
+ $loader->register(true);
52
+
53
+ return $loader;
54
+ }
55
+ }
vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInit121f0b0fd6fcff38fa2020e581a9a4ea
8
+ {
9
+ public static $prefixLengthsPsr4 = array (
10
+ 'P' =>
11
+ array (
12
+ 'Psr\\Log\\' => 8,
13
+ 'Psr\\Container\\' => 14,
14
+ ),
15
+ 'O' =>
16
+ array (
17
+ 'OomphInc\\ComposerInstallersExtender\\' => 36,
18
+ ),
19
+ 'I' =>
20
+ array (
21
+ 'Interop\\Container\\' => 18,
22
+ ),
23
+ 'D' =>
24
+ array (
25
+ 'Dhii\\Wp\\Containers\\' => 19,
26
+ 'Dhii\\Util\\String\\' => 17,
27
+ 'Dhii\\Modular\\Module\\' => 20,
28
+ 'Dhii\\Factory\\' => 13,
29
+ 'Dhii\\Exception\\' => 15,
30
+ 'Dhii\\Data\\Container\\' => 20,
31
+ 'Dhii\\Container\\' => 15,
32
+ ),
33
+ 'C' =>
34
+ array (
35
+ 'Composer\\Installers\\' => 20,
36
+ ),
37
+ );
38
+
39
+ public static $prefixDirsPsr4 = array (
40
+ 'Psr\\Log\\' =>
41
+ array (
42
+ 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
43
+ ),
44
+ 'Psr\\Container\\' =>
45
+ array (
46
+ 0 => __DIR__ . '/..' . '/psr/container/src',
47
+ ),
48
+ 'OomphInc\\ComposerInstallersExtender\\' =>
49
+ array (
50
+ 0 => __DIR__ . '/..' . '/oomphinc/composer-installers-extender/src',
51
+ ),
52
+ 'Interop\\Container\\' =>
53
+ array (
54
+ 0 => __DIR__ . '/..' . '/container-interop/service-provider/src',
55
+ ),
56
+ 'Dhii\\Wp\\Containers\\' =>
57
+ array (
58
+ 0 => __DIR__ . '/..' . '/dhii/wp-containers/src',
59
+ ),
60
+ 'Dhii\\Util\\String\\' =>
61
+ array (
62
+ 0 => __DIR__ . '/..' . '/dhii/stringable-interface/src',
63
+ ),
64
+ 'Dhii\\Modular\\Module\\' =>
65
+ array (
66
+ 0 => __DIR__ . '/..' . '/dhii/module-interface/src',
67
+ ),
68
+ 'Dhii\\Factory\\' =>
69
+ array (
70
+ 0 => __DIR__ . '/..' . '/dhii/factory-interface/src',
71
+ ),
72
+ 'Dhii\\Exception\\' =>
73
+ array (
74
+ 0 => __DIR__ . '/..' . '/dhii/exception-interface/src',
75
+ ),
76
+ 'Dhii\\Data\\Container\\' =>
77
+ array (
78
+ 0 => __DIR__ . '/..' . '/dhii/data-container-interface/src',
79
+ ),
80
+ 'Dhii\\Container\\' =>
81
+ array (
82
+ 0 => __DIR__ . '/..' . '/dhii/containers/src',
83
+ ),
84
+ 'Composer\\Installers\\' =>
85
+ array (
86
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
87
+ ),
88
+ );
89
+
90
+ public static $classMap = array (
91
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
92
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
93
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
94
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
95
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
96
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
97
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/class-apimodule.php',
98
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
99
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
100
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
101
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
102
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
103
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
104
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
105
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
106
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
107
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
108
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
109
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
110
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-address.php',
111
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amount.php',
112
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
113
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
114
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
115
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
116
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
117
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-item.php',
118
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-money.php',
119
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-order.php',
120
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
121
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patch.php',
122
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
123
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payee.php',
124
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payer.php',
125
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payername.php',
126
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
127
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
128
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
129
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
130
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
131
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
132
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payments.php',
133
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phone.php',
134
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
135
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
136
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-refund.php',
137
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
138
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
139
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
140
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-token.php',
141
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
142
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
143
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
144
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
145
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
146
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
147
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
148
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
149
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
150
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
151
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
152
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
153
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
154
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
155
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
156
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
157
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
158
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
159
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
160
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
161
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
162
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-cache.php',
163
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
164
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
165
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
166
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
167
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
168
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
169
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
170
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
171
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
172
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
173
+ 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
174
+ 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => __DIR__ . '/../..' . '/modules/ppcp-button/src/class-buttonmodule.php',
175
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
176
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
177
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
178
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
179
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
180
+ 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
181
+ 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
182
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
183
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
184
+ 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
185
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
186
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
187
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-environment.php',
188
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
189
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
190
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-state.php',
191
+ 'WooCommerce\\PayPalCommerce\\PluginModule' => __DIR__ . '/../..' . '/src/class-pluginmodule.php',
192
+ 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
193
+ 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
194
+ 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionhandler.php',
195
+ 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionmodule.php',
196
+ 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
197
+ 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-renewalhandler.php',
198
+ 'WooCommerce\\PayPalCommerce\\Subscription\\Repository\\PaymentTokenRepository' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/Repository/class-paymenttokenrepository.php',
199
+ 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
200
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
201
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
202
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
203
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
204
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
205
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
206
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
207
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
208
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
209
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
210
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\WcGatewayInterface' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-wcgatewayinterface.php',
211
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
212
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
213
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
214
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
215
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
216
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
217
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
218
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
219
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
220
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
221
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
222
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
223
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
224
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
225
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
226
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
227
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
228
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
229
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
230
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
231
+ 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
232
+ 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
233
+ 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
234
+ 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capture.php',
235
+ 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
236
+ );
237
+
238
+ public static function getInitializer(ClassLoader $loader)
239
+ {
240
+ return \Closure::bind(function () use ($loader) {
241
+ $loader->prefixLengthsPsr4 = ComposerStaticInit121f0b0fd6fcff38fa2020e581a9a4ea::$prefixLengthsPsr4;
242
+ $loader->prefixDirsPsr4 = ComposerStaticInit121f0b0fd6fcff38fa2020e581a9a4ea::$prefixDirsPsr4;
243
+ $loader->classMap = ComposerStaticInit121f0b0fd6fcff38fa2020e581a9a4ea::$classMap;
244
+
245
+ }, null, ClassLoader::class);
246
+ }
247
+ }
vendor/composer/installed.json ADDED
@@ -0,0 +1,781 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "composer/installers",
4
+ "version": "v1.9.0",
5
+ "version_normalized": "1.9.0.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/composer/installers.git",
9
+ "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
14
+ "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "composer-plugin-api": "^1.0 || ^2.0"
19
+ },
20
+ "replace": {
21
+ "roundcube/plugin-installer": "*",
22
+ "shama/baton": "*"
23
+ },
24
+ "require-dev": {
25
+ "composer/composer": "1.6.* || 2.0.*@dev",
26
+ "composer/semver": "1.0.* || 2.0.*@dev",
27
+ "phpunit/phpunit": "^4.8.36",
28
+ "sebastian/comparator": "^1.2.4",
29
+ "symfony/process": "^2.3"
30
+ },
31
+ "time": "2020-04-07T06:57:05+00:00",
32
+ "type": "composer-plugin",
33
+ "extra": {
34
+ "class": "Composer\\Installers\\Plugin",
35
+ "branch-alias": {
36
+ "dev-master": "1.0-dev"
37
+ }
38
+ },
39
+ "installation-source": "dist",
40
+ "autoload": {
41
+ "psr-4": {
42
+ "Composer\\Installers\\": "src/Composer/Installers"
43
+ }
44
+ },
45
+ "notification-url": "https://packagist.org/downloads/",
46
+ "license": [
47
+ "MIT"
48
+ ],
49
+ "authors": [
50
+ {
51
+ "name": "Kyle Robinson Young",
52
+ "email": "kyle@dontkry.com",
53
+ "homepage": "https://github.com/shama"
54
+ }
55
+ ],
56
+ "description": "A multi-framework Composer library installer",
57
+ "homepage": "https://composer.github.io/installers/",
58
+ "keywords": [
59
+ "Craft",
60
+ "Dolibarr",
61
+ "Eliasis",
62
+ "Hurad",
63
+ "ImageCMS",
64
+ "Kanboard",
65
+ "Lan Management System",
66
+ "MODX Evo",
67
+ "MantisBT",
68
+ "Mautic",
69
+ "Maya",
70
+ "OXID",
71
+ "Plentymarkets",
72
+ "Porto",
73
+ "RadPHP",
74
+ "SMF",
75
+ "Thelia",
76
+ "Whmcs",
77
+ "WolfCMS",
78
+ "agl",
79
+ "aimeos",
80
+ "annotatecms",
81
+ "attogram",
82
+ "bitrix",
83
+ "cakephp",
84
+ "chef",
85
+ "cockpit",
86
+ "codeigniter",
87
+ "concrete5",
88
+ "croogo",
89
+ "dokuwiki",
90
+ "drupal",
91
+ "eZ Platform",
92
+ "elgg",
93
+ "expressionengine",
94
+ "fuelphp",
95
+ "grav",
96
+ "installer",
97
+ "itop",
98
+ "joomla",
99
+ "known",
100
+ "kohana",
101
+ "laravel",
102
+ "lavalite",
103
+ "lithium",
104
+ "magento",
105
+ "majima",
106
+ "mako",
107
+ "mediawiki",
108
+ "modulework",
109
+ "modx",
110
+ "moodle",
111
+ "osclass",
112
+ "phpbb",
113
+ "piwik",
114
+ "ppi",
115
+ "puppet",
116
+ "pxcms",
117
+ "reindex",
118
+ "roundcube",
119
+ "shopware",
120
+ "silverstripe",
121
+ "sydes",
122
+ "sylius",
123
+ "symfony",
124
+ "typo3",
125
+ "wordpress",
126
+ "yawik",
127
+ "zend",
128
+ "zikula"
129
+ ],
130
+ "funding": [
131
+ {
132
+ "url": "https://packagist.com",
133
+ "type": "custom"
134
+ },
135
+ {
136
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
137
+ "type": "tidelift"
138
+ }
139
+ ]
140
+ },
141
+ {
142
+ "name": "container-interop/service-provider",
143
+ "version": "v0.4.0",
144
+ "version_normalized": "0.4.0.0",
145
+ "source": {
146
+ "type": "git",
147
+ "url": "https://github.com/container-interop/service-provider.git",
148
+ "reference": "4969b9e49460690b7430b3f1a87cab07be61418a"
149
+ },
150
+ "dist": {
151
+ "type": "zip",
152
+ "url": "https://api.github.com/repos/container-interop/service-provider/zipball/4969b9e49460690b7430b3f1a87cab07be61418a",
153
+ "reference": "4969b9e49460690b7430b3f1a87cab07be61418a",
154
+ "shasum": ""
155
+ },
156
+ "require": {
157
+ "psr/container": "^1.0"
158
+ },
159
+ "time": "2017-09-20T14:13:36+00:00",
160
+ "type": "library",
161
+ "installation-source": "dist",
162
+ "autoload": {
163
+ "psr-4": {
164
+ "Interop\\Container\\": "src/"
165
+ }
166
+ },
167
+ "notification-url": "https://packagist.org/downloads/",
168
+ "license": [
169
+ "MIT"
170
+ ],
171
+ "description": "Promoting container interoperability through standard service providers",
172
+ "homepage": "https://github.com/container-interop/service-provider"
173
+ },
174
+ {
175
+ "name": "dhii/containers",
176
+ "version": "dev-develop",
177
+ "version_normalized": "dev-develop",
178
+ "source": {
179
+ "type": "git",
180
+ "url": "https://github.com/Dhii/containers.git",
181
+ "reference": "3dd6e407e86cf19f7a40989eeb802cf751082902"
182
+ },
183
+ "dist": {
184
+ "type": "zip",
185
+ "url": "https://api.github.com/repos/Dhii/containers/zipball/3dd6e407e86cf19f7a40989eeb802cf751082902",
186
+ "reference": "3dd6e407e86cf19f7a40989eeb802cf751082902",
187
+ "shasum": ""
188
+ },
189
+ "require": {
190
+ "container-interop/service-provider": "^0.4",
191
+ "dhii/data-container-interface": "^0.2",
192
+ "php": "^7.0 | ^8.0"
193
+ },
194
+ "require-dev": {
195
+ "gmazzap/andrew": "^1.1",
196
+ "phpunit/phpunit": "^6",
197
+ "psr/container": "^1.0",
198
+ "slevomat/coding-standard": "~4.0"
199
+ },
200
+ "time": "2020-03-18T17:36:56+00:00",
201
+ "type": "library",
202
+ "extra": {
203
+ "branch-alias": {
204
+ "dev-develop": "0.1.x-dev"
205
+ }
206
+ },
207
+ "installation-source": "source",
208
+ "autoload": {
209
+ "psr-4": {
210
+ "Dhii\\Container\\": "src/"
211
+ }
212
+ },
213
+ "notification-url": "https://packagist.org/downloads/",
214
+ "license": [
215
+ "MIT"
216
+ ],
217
+ "authors": [
218
+ {
219
+ "name": "Dhii Team",
220
+ "email": "development@dhii.co"
221
+ }
222
+ ],
223
+ "description": "A selection of PSR-11 containers for utility, simplicity, and ease.",
224
+ "keywords": [
225
+ "PSR-11",
226
+ "container"
227
+ ]
228
+ },
229
+ {
230
+ "name": "dhii/data-container-interface",
231
+ "version": "v0.2.1-alpha1",
232
+ "version_normalized": "0.2.1.0-alpha1",
233
+ "source": {
234
+ "type": "git",
235
+ "url": "https://github.com/Dhii/data-container-interface.git",
236
+ "reference": "6be46e427184b95785d9dd563d6acf2e0700cc31"
237
+ },
238
+ "dist": {
239
+ "type": "zip",
240
+ "url": "https://api.github.com/repos/Dhii/data-container-interface/zipball/6be46e427184b95785d9dd563d6acf2e0700cc31",
241
+ "reference": "6be46e427184b95785d9dd563d6acf2e0700cc31",
242
+ "shasum": ""
243
+ },
244
+ "require": {
245
+ "dhii/exception-interface": "^0.1 | ^0.2",
246
+ "dhii/factory-interface": "^0.1-alpha1",
247
+ "php": "^5.3 | ^7.0",
248
+ "psr/container": "^1.0"
249
+ },
250
+ "require-dev": {
251
+ "codeclimate/php-test-reporter": "<=0.3.2",
252
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
253
+ "dhii/stringable-interface": "^0.1",
254
+ "phpunit/phpunit": "^4.8",
255
+ "ptrofimov/xpmock": "^1.1"
256
+ },
257
+ "suggest": {
258
+ "dhii/stringable-interface": "To be able to pass Stringables as keys"
259
+ },
260
+ "time": "2019-05-10T14:17:29+00:00",
261
+ "type": "library",
262
+ "extra": {
263
+ "branch-alias": {
264
+ "dev-develop": "0.2.x-dev"
265
+ }
266
+ },
267
+ "installation-source": "dist",
268
+ "autoload": {
269
+ "psr-4": {
270
+ "Dhii\\Data\\Container\\": "src"
271
+ }
272
+ },
273
+ "notification-url": "https://packagist.org/downloads/",
274
+ "license": [
275
+ "MIT"
276
+ ],
277
+ "authors": [
278
+ {
279
+ "name": "Dhii Team",
280
+ "email": "development@dhii.co"
281
+ }
282
+ ],
283
+ "description": "Interfaces for working with data containers",
284
+ "abandoned": "dhii/collections-interface"
285
+ },
286
+ {
287
+ "name": "dhii/exception-interface",
288
+ "version": "v0.2",
289
+ "version_normalized": "0.2.0.0",
290
+ "source": {
291
+ "type": "git",
292
+ "url": "https://github.com/Dhii/exception-interface.git",
293
+ "reference": "b69feebf7cb2879cd43977a03342e2393b73f7fb"
294
+ },
295
+ "dist": {
296
+ "type": "zip",
297
+ "url": "https://api.github.com/repos/Dhii/exception-interface/zipball/b69feebf7cb2879cd43977a03342e2393b73f7fb",
298
+ "reference": "b69feebf7cb2879cd43977a03342e2393b73f7fb",
299
+ "shasum": ""
300
+ },
301
+ "require": {
302
+ "dhii/stringable-interface": "^0.1",
303
+ "php": "^5.3 | ^7.0"
304
+ },
305
+ "require-dev": {
306
+ "codeclimate/php-test-reporter": "<=0.3.2",
307
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
308
+ "phpunit/phpunit": "^4.8",
309
+ "ptrofimov/xpmock": "^1.1"
310
+ },
311
+ "time": "2018-08-29T10:42:04+00:00",
312
+ "type": "library",
313
+ "extra": {
314
+ "branch-alias": {
315
+ "dev-develop": "0.2.x-dev"
316
+ }
317
+ },
318
+ "installation-source": "dist",
319
+ "autoload": {
320
+ "psr-4": {
321
+ "Dhii\\Exception\\": "src"
322
+ }
323
+ },
324
+ "notification-url": "https://packagist.org/downloads/",
325
+ "license": [
326
+ "MIT"
327
+ ],
328
+ "authors": [
329
+ {
330
+ "name": "Dhii Team",
331
+ "email": "development@dhii.co"
332
+ }
333
+ ],
334
+ "description": "Interfaces for most common exceptions"
335
+ },
336
+ {
337
+ "name": "dhii/factory-interface",
338
+ "version": "v0.1",
339
+ "version_normalized": "0.1.0.0",
340
+ "source": {
341
+ "type": "git",
342
+ "url": "https://github.com/Dhii/factory-interface.git",
343
+ "reference": "b8d217aec8838e64ccaa770cb03dc164bf6f0515"
344
+ },
345
+ "dist": {
346
+ "type": "zip",
347
+ "url": "https://api.github.com/repos/Dhii/factory-interface/zipball/b8d217aec8838e64ccaa770cb03dc164bf6f0515",
348
+ "reference": "b8d217aec8838e64ccaa770cb03dc164bf6f0515",
349
+ "shasum": ""
350
+ },
351
+ "require": {
352
+ "dhii/exception-interface": "^0.1|^0.2",
353
+ "php": "^5.3 | ^7.0"
354
+ },
355
+ "require-dev": {
356
+ "codeclimate/php-test-reporter": "<=0.3.2",
357
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
358
+ "dhii/stringable-interface": "^0.1",
359
+ "phpunit/phpunit": "^4.8",
360
+ "psr/container": "^1.0",
361
+ "ptrofimov/xpmock": "^1.1"
362
+ },
363
+ "time": "2018-08-29T11:15:09+00:00",
364
+ "type": "library",
365
+ "extra": {
366
+ "branch-alias": {
367
+ "dev-develop": "0.1.x-dev"
368
+ }
369
+ },
370
+ "installation-source": "dist",
371
+ "autoload": {
372
+ "psr-4": {
373
+ "Dhii\\Factory\\": "src"
374
+ }
375
+ },
376
+ "notification-url": "https://packagist.org/downloads/",
377
+ "license": [
378
+ "MIT"
379
+ ],
380
+ "authors": [
381
+ {
382
+ "name": "Dhii Team",
383
+ "email": "development@dhii.co"
384
+ }
385
+ ],
386
+ "description": "Interfaces for working with factories."
387
+ },
388
+ {
389
+ "name": "dhii/module-interface",
390
+ "version": "dev-develop",
391
+ "version_normalized": "dev-develop",
392
+ "source": {
393
+ "type": "git",
394
+ "url": "https://github.com/Dhii/module-interface.git",
395
+ "reference": "cb2eaaac0fa4bd4a82bc2b38c10e3a794ce32d52"
396
+ },
397
+ "dist": {
398
+ "type": "zip",
399
+ "url": "https://api.github.com/repos/Dhii/module-interface/zipball/cb2eaaac0fa4bd4a82bc2b38c10e3a794ce32d52",
400
+ "reference": "cb2eaaac0fa4bd4a82bc2b38c10e3a794ce32d52",
401
+ "shasum": ""
402
+ },
403
+ "require": {
404
+ "container-interop/service-provider": "^0.4",
405
+ "php": "^7.1",
406
+ "psr/container": "^1.0"
407
+ },
408
+ "require-dev": {
409
+ "phpunit/phpunit": "^6.0 | ^7.0"
410
+ },
411
+ "time": "2020-04-10T14:27:05+00:00",
412
+ "type": "library",
413
+ "extra": {
414
+ "branch-alias": {
415
+ "dev-develop": "0.2.x-dev"
416
+ }
417
+ },
418
+ "installation-source": "source",
419
+ "autoload": {
420
+ "psr-4": {
421
+ "Dhii\\Modular\\Module\\": "src"
422
+ }
423
+ },
424
+ "notification-url": "https://packagist.org/downloads/",
425
+ "license": [
426
+ "MIT"
427
+ ],
428
+ "authors": [
429
+ {
430
+ "name": "Dhii Team",
431
+ "email": "development@dhii.co"
432
+ }
433
+ ],
434
+ "description": "Interfaces for modules"
435
+ },
436
+ {
437
+ "name": "dhii/stringable-interface",
438
+ "version": "v0.1",
439
+ "version_normalized": "0.1.0.0",
440
+ "source": {
441
+ "type": "git",
442
+ "url": "https://github.com/Dhii/stringable-interface.git",
443
+ "reference": "b6653905eef2ebf377749feb80a6d18abbe913ef"
444
+ },
445
+ "dist": {
446
+ "type": "zip",
447
+ "url": "https://api.github.com/repos/Dhii/stringable-interface/zipball/b6653905eef2ebf377749feb80a6d18abbe913ef",
448
+ "reference": "b6653905eef2ebf377749feb80a6d18abbe913ef",
449
+ "shasum": ""
450
+ },
451
+ "require": {
452
+ "php": "^5.3 | ^7.0"
453
+ },
454
+ "require-dev": {
455
+ "codeclimate/php-test-reporter": "<=0.3.2",
456
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
457
+ "phpunit/phpunit": "^4.8",
458
+ "ptrofimov/xpmock": "^1.1"
459
+ },
460
+ "time": "2017-01-23T15:08:20+00:00",
461
+ "type": "library",
462
+ "installation-source": "dist",
463
+ "autoload": {
464
+ "psr-4": {
465
+ "Dhii\\Util\\String\\": "src/"
466
+ }
467
+ },
468
+ "notification-url": "https://packagist.org/downloads/",
469
+ "license": [
470
+ "MIT"
471
+ ],
472
+ "authors": [
473
+ {
474
+ "name": "Dhii Team",
475
+ "email": "development@dhii.co"
476
+ }
477
+ ],
478
+ "description": "Interoperability interface for objects that can be cast to string"
479
+ },
480
+ {
481
+ "name": "dhii/wp-containers",
482
+ "version": "v0.1.0-alpha1",
483
+ "version_normalized": "0.1.0.0-alpha1",
484
+ "source": {
485
+ "type": "git",
486
+ "url": "https://github.com/Dhii/wp-containers.git",
487
+ "reference": "e91a6f741622770ed724a2b594145fa917811f0c"
488
+ },
489
+ "dist": {
490
+ "type": "zip",
491
+ "url": "https://api.github.com/repos/Dhii/wp-containers/zipball/e91a6f741622770ed724a2b594145fa917811f0c",
492
+ "reference": "e91a6f741622770ed724a2b594145fa917811f0c",
493
+ "shasum": ""
494
+ },
495
+ "require": {
496
+ "dhii/data-container-interface": "^0.2.1-alpha1",
497
+ "php": "^7.0 | ^8.0",
498
+ "psr/container": "^1.0"
499
+ },
500
+ "require-dev": {
501
+ "brain/monkey": "^2",
502
+ "gmazzap/andrew": "^1.1",
503
+ "phpunit/phpunit": "^6",
504
+ "slevomat/coding-standard": "~4.0"
505
+ },
506
+ "time": "2019-05-10T15:04:22+00:00",
507
+ "type": "library",
508
+ "extra": {
509
+ "branch-alias": {
510
+ "dev-develop": "0.1.x-dev"
511
+ }
512
+ },
513
+ "installation-source": "dist",
514
+ "autoload": {
515
+ "psr-4": {
516
+ "Dhii\\Wp\\Containers\\": "src/"
517
+ }
518
+ },
519
+ "notification-url": "https://packagist.org/downloads/",
520
+ "license": [
521
+ "MIT"
522
+ ],
523
+ "authors": [
524
+ {
525
+ "name": "Dhii Team",
526
+ "email": "development@dhii.co"
527
+ }
528
+ ],
529
+ "description": "PSR-11 container implementations that wrap some WP features, for convenience and interoperability.",
530
+ "keywords": [
531
+ "container",
532
+ "dependency injection",
533
+ "di",
534
+ "wordpress"
535
+ ]
536
+ },
537
+ {
538
+ "name": "oomphinc/composer-installers-extender",
539
+ "version": "v1.1.2",
540
+ "version_normalized": "1.1.2.0",
541
+ "source": {
542
+ "type": "git",
543
+ "url": "https://github.com/oomphinc/composer-installers-extender.git",
544
+ "reference": "ca1c4b16b0905c81d1e77e608f36a2eff1a56f56"
545
+ },
546
+ "dist": {
547
+ "type": "zip",
548
+ "url": "https://api.github.com/repos/oomphinc/composer-installers-extender/zipball/ca1c4b16b0905c81d1e77e608f36a2eff1a56f56",
549
+ "reference": "ca1c4b16b0905c81d1e77e608f36a2eff1a56f56",
550
+ "shasum": ""
551
+ },
552
+ "require": {
553
+ "composer-plugin-api": "^1.0",
554
+ "composer/installers": "^1.0"
555
+ },
556
+ "time": "2017-03-31T16:57:39+00:00",
557
+ "type": "composer-plugin",
558
+ "extra": {
559
+ "class": "OomphInc\\ComposerInstallersExtender\\Plugin"
560
+ },
561
+ "installation-source": "dist",
562
+ "autoload": {
563
+ "psr-4": {
564
+ "OomphInc\\ComposerInstallersExtender\\": "src/"
565
+ }
566
+ },
567
+ "notification-url": "https://packagist.org/downloads/",
568
+ "license": [
569
+ "MIT"
570
+ ],
571
+ "authors": [
572
+ {
573
+ "name": "Stephen Beemsterboer",
574
+ "email": "stephen@oomphinc.com",
575
+ "homepage": "https://github.com/balbuf"
576
+ }
577
+ ],
578
+ "description": "Extend the composer/installers plugin to accept any arbitrary package type.",
579
+ "homepage": "http://www.oomphinc.com/"
580
+ },
581
+ {
582
+ "name": "psr/container",
583
+ "version": "1.0.0",
584
+ "version_normalized": "1.0.0.0",
585
+ "source": {
586
+ "type": "git",
587
+ "url": "https://github.com/php-fig/container.git",
588
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
589
+ },
590
+ "dist": {
591
+ "type": "zip",
592
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
593
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
594
+ "shasum": ""
595
+ },
596
+ "require": {
597
+ "php": ">=5.3.0"
598
+ },
599
+ "time": "2017-02-14T16:28:37+00:00",
600
+ "type": "library",
601
+ "extra": {
602
+ "branch-alias": {
603
+ "dev-master": "1.0.x-dev"
604
+ }
605
+ },
606
+ "installation-source": "dist",
607
+ "autoload": {
608
+ "psr-4": {
609
+ "Psr\\Container\\": "src/"
610
+ }
611
+ },
612
+ "notification-url": "https://packagist.org/downloads/",
613
+ "license": [
614
+ "MIT"
615
+ ],
616
+ "authors": [
617
+ {
618
+ "name": "PHP-FIG",
619
+ "homepage": "http://www.php-fig.org/"
620
+ }
621
+ ],
622
+ "description": "Common Container Interface (PHP FIG PSR-11)",
623
+ "homepage": "https://github.com/php-fig/container",
624
+ "keywords": [
625
+ "PSR-11",
626
+ "container",
627
+ "container-interface",
628
+ "container-interop",
629
+ "psr"
630
+ ]
631
+ },
632
+ {
633
+ "name": "psr/log",
634
+ "version": "1.1.3",
635
+ "version_normalized": "1.1.3.0",
636
+ "source": {
637
+ "type": "git",
638
+ "url": "https://github.com/php-fig/log.git",
639
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
640
+ },
641
+ "dist": {
642
+ "type": "zip",
643
+ "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
644
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
645
+ "shasum": ""
646
+ },
647
+ "require": {
648
+ "php": ">=5.3.0"
649
+ },
650
+ "time": "2020-03-23T09:12:05+00:00",
651
+ "type": "library",
652
+ "extra": {
653
+ "branch-alias": {
654
+ "dev-master": "1.1.x-dev"
655
+ }
656
+ },
657
+ "installation-source": "dist",
658
+ "autoload": {
659
+ "psr-4": {
660
+ "Psr\\Log\\": "Psr/Log/"
661
+ }
662
+ },
663
+ "notification-url": "https://packagist.org/downloads/",
664
+ "license": [
665
+ "MIT"
666
+ ],
667
+ "authors": [
668
+ {
669
+ "name": "PHP-FIG",
670
+ "homepage": "http://www.php-fig.org/"
671
+ }
672
+ ],
673
+ "description": "Common interface for logging libraries",
674
+ "homepage": "https://github.com/php-fig/log",
675
+ "keywords": [
676
+ "log",
677
+ "psr",
678
+ "psr-3"
679
+ ]
680
+ },
681
+ {
682
+ "name": "psr/simple-cache",
683
+ "version": "1.0.1",
684
+ "version_normalized": "1.0.1.0",
685
+ "source": {
686
+ "type": "git",
687
+ "url": "https://github.com/php-fig/simple-cache.git",
688
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
689
+ },
690
+ "dist": {
691
+ "type": "zip",
692
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
693
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
694
+ "shasum": ""
695
+ },
696
+ "require": {
697
+ "php": ">=5.3.0"
698
+ },
699
+ "time": "2017-10-23T01:57:42+00:00",
700
+ "type": "library",
701
+ "extra": {
702
+ "branch-alias": {
703
+ "dev-master": "1.0.x-dev"
704
+ }
705
+ },
706
+ "installation-source": "dist",
707
+ "autoload": {
708
+ "psr-4": {
709
+ "Psr\\SimpleCache\\": "src/"
710
+ }
711
+ },
712
+ "notification-url": "https://packagist.org/downloads/",
713
+ "license": [
714
+ "MIT"
715
+ ],
716
+ "authors": [
717
+ {
718
+ "name": "PHP-FIG",
719
+ "homepage": "http://www.php-fig.org/"
720
+ }
721
+ ],
722
+ "description": "Common interfaces for simple caching",
723
+ "keywords": [
724
+ "cache",
725
+ "caching",
726
+ "psr",
727
+ "psr-16",
728
+ "simple-cache"
729
+ ]
730
+ },
731
+ {
732
+ "name": "wp-oop/transient-cache",
733
+ "version": "v0.1.0-alpha3",
734
+ "version_normalized": "0.1.0.0-alpha3",
735
+ "source": {
736
+ "type": "git",
737
+ "url": "https://github.com/wp-oop/transient-cache.git",
738
+ "reference": "9eb92e378ad82b29d9d597bc4f41734a57502291"
739
+ },
740
+ "dist": {
741
+ "type": "zip",
742
+ "url": "https://api.github.com/repos/wp-oop/transient-cache/zipball/9eb92e378ad82b29d9d597bc4f41734a57502291",
743
+ "reference": "9eb92e378ad82b29d9d597bc4f41734a57502291",
744
+ "shasum": ""
745
+ },
746
+ "require": {
747
+ "php": "^7.1",
748
+ "psr/simple-cache": "^1.0"
749
+ },
750
+ "require-dev": {
751
+ "brain/monkey": "^2.3",
752
+ "johnpbloch/wordpress-core": "^5.0",
753
+ "phpunit/phpunit": "^7.1"
754
+ },
755
+ "time": "2020-07-08T10:18:00+00:00",
756
+ "type": "library",
757
+ "extra": {
758
+ "branch-alias": {
759
+ "dev-develop": "0.1.x-dev"
760
+ }
761
+ },
762
+ "installation-source": "dist",
763
+ "autoload": {
764
+ "psr-4": {
765
+ "WpOop\\TransientCache\\": "src"
766
+ }
767
+ },
768
+ "notification-url": "https://packagist.org/downloads/",
769
+ "license": [
770
+ "MIT"
771
+ ],
772
+ "authors": [
773
+ {
774
+ "name": "Anton Ukhanev",
775
+ "email": "xedin.unknown@gmail.com",
776
+ "role": "Developer"
777
+ }
778
+ ],
779
+ "description": "A PSR-16 wrapper for WP transients."
780
+ }
781
+ ]
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.
vendor/composer/installers/composer.json ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ "Attogram",
12
+ "Bitrix",
13
+ "CakePHP",
14
+ "Chef",
15
+ "Cockpit",
16
+ "CodeIgniter",
17
+ "concrete5",
18
+ "Craft",
19
+ "Croogo",
20
+ "DokuWiki",
21
+ "Dolibarr",
22
+ "Drupal",
23
+ "Elgg",
24
+ "Eliasis",
25
+ "ExpressionEngine",
26
+ "eZ Platform",
27
+ "FuelPHP",
28
+ "Grav",
29
+ "Hurad",
30
+ "ImageCMS",
31
+ "iTop",
32
+ "Joomla",
33
+ "Kanboard",
34
+ "Known",
35
+ "Kohana",
36
+ "Lan Management System",
37
+ "Laravel",
38
+ "Lavalite",
39
+ "Lithium",
40
+ "Magento",
41
+ "majima",
42
+ "Mako",
43
+ "MantisBT",
44
+ "Mautic",
45
+ "Maya",
46
+ "MODX",
47
+ "MODX Evo",
48
+ "MediaWiki",
49
+ "OXID",
50
+ "osclass",
51
+ "MODULEWork",
52
+ "Moodle",
53
+ "Piwik",
54
+ "pxcms",
55
+ "phpBB",
56
+ "Plentymarkets",
57
+ "PPI",
58
+ "Puppet",
59
+ "Porto",
60
+ "RadPHP",
61
+ "ReIndex",
62
+ "Roundcube",
63
+ "shopware",
64
+ "SilverStripe",
65
+ "SMF",
66
+ "SyDES",
67
+ "Sylius",
68
+ "symfony",
69
+ "Thelia",
70
+ "TYPO3",
71
+ "WHMCS",
72
+ "WolfCMS",
73
+ "WordPress",
74
+ "YAWIK",
75
+ "Zend",
76
+ "Zikula"
77
+ ],
78
+ "homepage": "https://composer.github.io/installers/",
79
+ "authors": [
80
+ {
81
+ "name": "Kyle Robinson Young",
82
+ "email": "kyle@dontkry.com",
83
+ "homepage": "https://github.com/shama"
84
+ }
85
+ ],
86
+ "autoload": {
87
+ "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
88
+ },
89
+ "extra": {
90
+ "class": "Composer\\Installers\\Plugin",
91
+ "branch-alias": {
92
+ "dev-master": "1.0-dev"
93
+ }
94
+ },
95
+ "replace": {
96
+ "shama/baton": "*",
97
+ "roundcube/plugin-installer": "*"
98
+ },
99
+ "require": {
100
+ "composer-plugin-api": "^1.0 || ^2.0"
101
+ },
102
+ "require-dev": {
103
+ "composer/composer": "1.6.* || 2.0.*@dev",
104
+ "composer/semver": "1.0.* || 2.0.*@dev",
105
+ "phpunit/phpunit": "^4.8.36",
106
+ "sebastian/comparator": "^1.2.4",
107
+ "symfony/process": "^2.3"
108
+ },
109
+ "scripts": {
110
+ "test": "phpunit"
111
+ }
112
+ }
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
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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'] = preg_replace('/-module$/', '', $vars['name']);
35
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
36
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
37
+
38
+ return $vars;
39
+ }
40
+
41
+ protected function inflectThemeVars($vars)
42
+ {
43
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
44
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
45
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
46
+
47
+ return $vars;
48
+ }
49
+ }
vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AttogramInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $names = (array) $names;
130
+ if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
131
+ return $path;
132
+ }
133
+ }
134
+
135
+ return false;
136
+ }
137
+ }
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-d7-module` — copy the module to directory `bitrix/modules/<vendor>.<name>`.
10
+ * - `bitrix-d7-component` — copy the component to directory `bitrix/components/<vendor>/<name>`.
11
+ * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/<vendor>_<name>`.
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}/', // deprecated, remove on the major release (Backward compatibility will be broken)
30
+ 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
31
+ 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
32
+ 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
33
+ 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
34
+ 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
35
+ );
36
+
37
+ /**
38
+ * @var array Storage for informations about duplicates at all the time of installation packages.
39
+ */
40
+ private static $checkedDuplicates = array();
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ public function inflectPackageVars($vars)
46
+ {
47
+ if ($this->composer->getPackage()) {
48
+ $extra = $this->composer->getPackage()->getExtra();
49
+
50
+ if (isset($extra['bitrix-dir'])) {
51
+ $vars['bitrix_dir'] = $extra['bitrix-dir'];
52
+ }
53
+ }
54
+
55
+ if (!isset($vars['bitrix_dir'])) {
56
+ $vars['bitrix_dir'] = 'bitrix';
57
+ }
58
+
59
+ return parent::inflectPackageVars($vars);
60
+ }
61
+
62
+ /**
63
+ * {@inheritdoc}
64
+ */
65
+ protected function templatePath($path, array $vars = array())
66
+ {
67
+ $templatePath = parent::templatePath($path, $vars);
68
+ $this->checkDuplicates($templatePath, $vars);
69
+
70
+ return $templatePath;
71
+ }
72
+
73
+ /**
74
+ * Duplicates search packages.
75
+ *
76
+ * @param string $path
77
+ * @param array $vars
78
+ */
79
+ protected function checkDuplicates($path, array $vars = array())
80
+ {
81
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
82
+ $localDir = explode('/', $vars['bitrix_dir']);
83
+ array_pop($localDir);
84
+ $localDir[] = 'local';
85
+ $localDir = implode('/', $localDir);
86
+
87
+ $oldPath = str_replace(
88
+ array('{$bitrix_dir}', '{$name}'),
89
+ array($localDir, $vars['name']),
90
+ $this->locations[$packageType]
91
+ );
92
+
93
+ if (in_array($oldPath, static::$checkedDuplicates)) {
94
+ return;
95
+ }
96
+
97
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
98
+
99
+ $this->io->writeError(' <error>Duplication of packages:</error>');
100
+ $this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
101
+
102
+ while (true) {
103
+ switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
104
+ case 'y':
105
+ $fs = new Filesystem();
106
+ $fs->removeDirectory($oldPath);
107
+ break 2;
108
+
109
+ case 'n':
110
+ break 2;
111
+
112
+ case '?':
113
+ default:
114
+ $this->io->writeError(array(
115
+ ' y - delete package ' . $oldPath . ' and to continue with the installation',
116
+ ' n - don\'t delete and to continue with the installation',
117
+ ));
118
+ $this->io->writeError(' ? - print help');
119
+ break;
120
+ }
121
+ }
122
+ }
123
+
124
+ static::$checkedDuplicates[] = $oldPath;
125
+ }
126
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\DependencyResolver\Pool;
5
+
6
+ class CakePHPInstaller extends BaseInstaller
7
+ {
8
+ protected $locations = array(
9
+ 'plugin' => 'Plugin/{$name}/',
10
+ );
11
+
12
+ /**
13
+ * Format package name to CamelCase
14
+ */
15
+ public function inflectPackageVars($vars)
16
+ {
17
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
18
+ return $vars;
19
+ }
20
+
21
+ $nameParts = explode('/', $vars['name']);
22
+ foreach ($nameParts as &$value) {
23
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
24
+ $value = str_replace(array('-', '_'), ' ', $value);
25
+ $value = str_replace(' ', '', ucwords($value));
26
+ }
27
+ $vars['name'] = implode('/', $nameParts);
28
+
29
+ return $vars;
30
+ }
31
+
32
+ /**
33
+ * Change the default plugin location when cakephp >= 3.0
34
+ */
35
+ public function getLocations()
36
+ {
37
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
38
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
39
+ }
40
+ return $this->locations;
41
+ }
42
+
43
+ /**
44
+ * Check if CakePHP version matches against a version
45
+ *
46
+ * @param string $matcher
47
+ * @param string $version
48
+ * @return bool
49
+ */
50
+ protected function matchesCakeVersion($matcher, $version)
51
+ {
52
+ if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
53
+ $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
54
+ $constraintClass = 'Composer\Semver\Constraint\Constraint';
55
+ } else {
56
+ $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
57
+ $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
58
+ }
59
+
60
+ $repositoryManager = $this->composer->getRepositoryManager();
61
+ if (! $repositoryManager) {
62
+ return false;
63
+ }
64
+
65
+ $repos = $repositoryManager->getLocalRepository();
66
+ if (!$repos) {
67
+ return false;
68
+ }
69
+
70
+ return $repos->findPackage('cakephp/cakephp', new $constraintClass($matcher, $version)) !== null;
71
+ }
72
+ }
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
+
vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CiviCrmInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'ext' => 'ext/{$name}/'
8
+ );
9
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CockpitInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'cockpit/modules/addons/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format module name.
12
+ *
13
+ * Strip `module-` prefix from package name.
14
+ *
15
+ * @param array @vars
16
+ *
17
+ * @return array
18
+ */
19
+ public function inflectPackageVars($vars)
20
+ {
21
+ if ($vars['type'] == 'cockpit-module') {
22
+ return $this->inflectModuleVars($vars);
23
+ }
24
+
25
+ return $vars;
26
+ }
27
+
28
+ public function inflectModuleVars($vars)
29
+ {
30
+ $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
31
+
32
+ return $vars;
33
+ }
34
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class Concrete5Installer extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'core' => 'concrete/',
8
+ 'block' => 'application/blocks/{$name}/',
9
+ 'package' => 'packages/{$name}/',
10
+ 'theme' => 'application/themes/{$name}/',
11
+ 'update' => 'updates/{$name}/',
12
+ );
13
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class DecibelInstaller extends BaseInstaller
5
+ {
6
+ /** @var array */
7
+ protected $locations = array(
8
+ 'app' => 'app/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/DframeInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class DframeInstaller extends BaseInstaller
6
+ {
7
+ protected $locations = array(
8
+ 'module' => 'modules/{$vendor}/{$name}/',
9
+ );
10
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/',
13
+ 'drush' => 'drush/{$name}/',
14
+ 'custom-theme' => 'themes/custom/{$name}/',
15
+ 'custom-module' => 'modules/custom/{$name}/',
16
+ 'custom-profile' => 'profiles/custom/{$name}/',
17
+ 'drupal-multisite' => 'sites/{$name}/',
18
+ 'console' => 'console/{$name}/',
19
+ 'console-language' => 'console/language/{$name}/',
20
+ 'config' => 'config/sync/',
21
+ );
22
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class EliasisInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'component' => 'components/{$name}/',
8
+ 'module' => 'modules/{$name}/',
9
+ 'plugin' => 'plugins/{$name}/',
10
+ 'template' => 'templates/{$name}/',
11
+ );
12
+ }
vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Package\PackageInterface;
5
+
6
+ class ExpressionEngineInstaller extends BaseInstaller
7
+ {
8
+
9
+ protected $locations = array();
10
+
11
+ private $ee2Locations = array(
12
+ 'addon' => 'system/expressionengine/third_party/{$name}/',
13
+ 'theme' => 'themes/third_party/{$name}/',
14
+ );
15
+
16
+ private $ee3Locations = array(
17
+ 'addon' => 'system/user/addons/{$name}/',
18
+ 'theme' => 'themes/user/{$name}/',
19
+ );
20
+
21
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
22
+ {
23
+
24
+ $version = "{$frameworkType}Locations";
25
+ $this->locations = $this->$version;
26
+
27
+ return parent::getInstallPath($package, $frameworkType);
28
+ }
29
+ }
vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class EzPlatformInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'meta-assets' => 'web/assets/ezplatform/',
8
+ 'assets' => 'web/assets/ezplatform/{$name}/',
9
+ );
10
+ }
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
+ }
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
+ }
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
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/Installer.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ use Composer\Composer;
6
+ use Composer\Installer\BinaryInstaller;
7
+ use Composer\Installer\LibraryInstaller;
8
+ use Composer\IO\IOInterface;
9
+ use Composer\Package\PackageInterface;
10
+ use Composer\Repository\InstalledRepositoryInterface;
11
+ use Composer\Util\Filesystem;
12
+
13
+ class Installer extends LibraryInstaller
14
+ {
15
+
16
+ /**
17
+ * Package types to installer class map
18
+ *
19
+ * @var array
20
+ */
21
+ private $supportedTypes = array(
22
+ 'aimeos' => 'AimeosInstaller',
23
+ 'asgard' => 'AsgardInstaller',
24
+ 'attogram' => 'AttogramInstaller',
25
+ 'agl' => 'AglInstaller',
26
+ 'annotatecms' => 'AnnotateCmsInstaller',
27
+ 'bitrix' => 'BitrixInstaller',
28
+ 'bonefish' => 'BonefishInstaller',
29
+ 'cakephp' => 'CakePHPInstaller',
30
+ 'chef' => 'ChefInstaller',
31
+ 'civicrm' => 'CiviCrmInstaller',
32
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
33
+ 'cockpit' => 'CockpitInstaller',
34
+ 'codeigniter' => 'CodeIgniterInstaller',
35
+ 'concrete5' => 'Concrete5Installer',
36
+ 'craft' => 'CraftInstaller',
37
+ 'croogo' => 'CroogoInstaller',
38
+ 'dframe' => 'DframeInstaller',
39
+ 'dokuwiki' => 'DokuWikiInstaller',
40
+ 'dolibarr' => 'DolibarrInstaller',
41
+ 'decibel' => 'DecibelInstaller',
42
+ 'drupal' => 'DrupalInstaller',
43
+ 'elgg' => 'ElggInstaller',
44
+ 'eliasis' => 'EliasisInstaller',
45
+ 'ee3' => 'ExpressionEngineInstaller',
46
+ 'ee2' => 'ExpressionEngineInstaller',
47
+ 'ezplatform' => 'EzPlatformInstaller',
48
+ 'fuel' => 'FuelInstaller',
49
+ 'fuelphp' => 'FuelphpInstaller',
50
+ 'grav' => 'GravInstaller',
51
+ 'hurad' => 'HuradInstaller',
52
+ 'imagecms' => 'ImageCMSInstaller',
53
+ 'itop' => 'ItopInstaller',
54
+ 'joomla' => 'JoomlaInstaller',
55
+ 'kanboard' => 'KanboardInstaller',
56
+ 'kirby' => 'KirbyInstaller',
57
+ 'known' => 'KnownInstaller',
58
+ 'kodicms' => 'KodiCMSInstaller',
59
+ 'kohana' => 'KohanaInstaller',
60
+ 'lms' => 'LanManagementSystemInstaller',
61
+ 'laravel' => 'LaravelInstaller',
62
+ 'lavalite' => 'LavaLiteInstaller',
63
+ 'lithium' => 'LithiumInstaller',
64
+ 'magento' => 'MagentoInstaller',
65
+ 'majima' => 'MajimaInstaller',
66
+ 'mantisbt' => 'MantisBTInstaller',
67
+ 'mako' => 'MakoInstaller',
68
+ 'maya' => 'MayaInstaller',
69
+ 'mautic' => 'MauticInstaller',
70
+ 'mediawiki' => 'MediaWikiInstaller',
71
+ 'microweber' => 'MicroweberInstaller',
72
+ 'modulework' => 'MODULEWorkInstaller',
73
+ 'modx' => 'ModxInstaller',
74
+ 'modxevo' => 'MODXEvoInstaller',
75
+ 'moodle' => 'MoodleInstaller',
76
+ 'october' => 'OctoberInstaller',
77
+ 'ontowiki' => 'OntoWikiInstaller',
78
+ 'oxid' => 'OxidInstaller',
79
+ 'osclass' => 'OsclassInstaller',
80
+ 'pxcms' => 'PxcmsInstaller',
81
+ 'phpbb' => 'PhpBBInstaller',
82
+ 'pimcore' => 'PimcoreInstaller',
83
+ 'piwik' => 'PiwikInstaller',
84
+ 'plentymarkets'=> 'PlentymarketsInstaller',
85
+ 'ppi' => 'PPIInstaller',
86
+ 'puppet' => 'PuppetInstaller',
87
+ 'radphp' => 'RadPHPInstaller',
88
+ 'phifty' => 'PhiftyInstaller',
89
+ 'porto' => 'PortoInstaller',
90
+ 'redaxo' => 'RedaxoInstaller',
91
+ 'redaxo5' => 'Redaxo5Installer',
92
+ 'reindex' => 'ReIndexInstaller',
93
+ 'roundcube' => 'RoundcubeInstaller',
94
+ 'shopware' => 'ShopwareInstaller',
95
+ 'sitedirect' => 'SiteDirectInstaller',
96
+ 'silverstripe' => 'SilverStripeInstaller',
97
+ 'smf' => 'SMFInstaller',
98
+ 'sydes' => 'SyDESInstaller',
99
+ 'sylius' => 'SyliusInstaller',
100
+ 'symfony1' => 'Symfony1Installer',
101
+ 'tao' => 'TaoInstaller',
102
+ 'thelia' => 'TheliaInstaller',
103
+ 'tusk' => 'TuskInstaller',
104
+ 'typo3-cms' => 'TYPO3CmsInstaller',
105
+ 'typo3-flow' => 'TYPO3FlowInstaller',
106
+ 'userfrosting' => 'UserFrostingInstaller',
107
+ 'vanilla' => 'VanillaInstaller',
108
+ 'whmcs' => 'WHMCSInstaller',
109
+ 'wolfcms' => 'WolfCMSInstaller',
110
+ 'wordpress' => 'WordPressInstaller',
111
+ 'yawik' => 'YawikInstaller',
112
+ 'zend' => 'ZendInstaller',
113
+ 'zikula' => 'ZikulaInstaller',
114
+ 'prestashop' => 'PrestashopInstaller'
115
+ );
116
+
117
+ /**
118
+ * Installer constructor.
119
+ *
120
+ * Disables installers specified in main composer extra installer-disable
121
+ * list
122
+ *
123
+ * @param IOInterface $io
124
+ * @param Composer $composer
125
+ * @param string $type
126
+ * @param Filesystem|null $filesystem
127
+ * @param BinaryInstaller|null $binaryInstaller
128
+ */
129
+ public function __construct(
130
+ IOInterface $io,
131
+ Composer $composer,
132
+ $type = 'library',
133
+ Filesystem $filesystem = null,
134
+ BinaryInstaller $binaryInstaller = null
135
+ ) {
136
+ parent::__construct($io, $composer, $type, $filesystem,
137
+ $binaryInstaller);
138
+ $this->removeDisabledInstallers();
139
+ }
140
+
141
+ /**
142
+ * {@inheritDoc}
143
+ */
144
+ public function getInstallPath(PackageInterface $package)
145
+ {
146
+ $type = $package->getType();
147
+ $frameworkType = $this->findFrameworkType($type);
148
+
149
+ if ($frameworkType === false) {
150
+ throw new \InvalidArgumentException(
151
+ 'Sorry the package type of this package is not yet supported.'
152
+ );
153
+ }
154
+
155
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
156
+ $installer = new $class($package, $this->composer, $this->getIO());
157
+
158
+ return $installer->getInstallPath($package, $frameworkType);
159
+ }
160
+
161
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
162
+ {
163
+ parent::uninstall($repo, $package);
164
+ $installPath = $this->getPackageBasePath($package);
165
+ $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
166
+ }
167
+
168
+ /**
169
+ * {@inheritDoc}
170
+ */
171
+ public function supports($packageType)
172
+ {
173
+ $frameworkType = $this->findFrameworkType($packageType);
174
+
175
+ if ($frameworkType === false) {
176
+ return false;
177
+ }
178
+
179
+ $locationPattern = $this->getLocationPattern($frameworkType);
180
+
181
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
182
+ }
183
+
184
+ /**
185
+ * Finds a supported framework type if it exists and returns it
186
+ *
187
+ * @param string $type
188
+ * @return string
189
+ */
190
+ protected function findFrameworkType($type)
191
+ {
192
+ $frameworkType = false;
193
+
194
+ krsort($this->supportedTypes);
195
+
196
+ foreach ($this->supportedTypes as $key => $val) {
197
+ if ($key === substr($type, 0, strlen($key))) {
198
+ $frameworkType = substr($type, 0, strlen($key));
199
+ break;
200
+ }
201
+ }
202
+
203
+ return $frameworkType;
204
+ }
205
+
206
+ /**
207
+ * Get the second part of the regular expression to check for support of a
208
+ * package type
209
+ *
210
+ * @param string $frameworkType
211
+ * @return string
212
+ */
213
+ protected function getLocationPattern($frameworkType)
214
+ {
215
+ $pattern = false;
216
+ if (!empty($this->supportedTypes[$frameworkType])) {
217
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
218
+ /** @var BaseInstaller $framework */
219
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
220
+ $locations = array_keys($framework->getLocations());
221
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
222
+ }
223
+
224
+ return $pattern ? : '(\w+)';
225
+ }
226
+
227
+ /**
228
+ * Get I/O object
229
+ *
230
+ * @return IOInterface
231
+ */
232
+ private function getIO()
233
+ {
234
+ return $this->io;
235
+ }
236
+
237
+ /**
238
+ * Look for installers set to be disabled in composer's extra config and
239
+ * remove them from the list of supported installers.
240
+ *
241
+ * Globals:
242
+ * - true, "all", and "*" - disable all installers.
243
+ * - false - enable all installers (useful with
244
+ * wikimedia/composer-merge-plugin or similar)
245
+ *
246
+ * @return void
247
+ */
248
+ protected function removeDisabledInstallers()
249
+ {
250
+ $extra = $this->composer->getPackage()->getExtra();
251
+
252
+ if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
253
+ // No installers are disabled
254
+ return;
255
+ }
256
+
257
+ // Get installers to disable
258
+ $disable = $extra['installer-disable'];
259
+
260
+ // Ensure $disabled is an array
261
+ if (!is_array($disable)) {
262
+ $disable = array($disable);
263
+ }
264
+
265
+ // Check which installers should be disabled
266
+ $all = array(true, "all", "*");
267
+ $intersect = array_intersect($all, $disable);
268
+ if (!empty($intersect)) {
269
+ // Disable all installers
270
+ $this->supportedTypes = array();
271
+ } else {
272
+ // Disable specified installers
273
+ foreach ($disable as $key => $installer) {
274
+ if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
275
+ unset($this->supportedTypes[$installer]);
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
vendor/composer/installers/src/Composer/Installers/ItopInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ItopInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'extensions/{$name}/',
8
+ );
9
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ *
6
+ * Installer for kanboard plugins
7
+ *
8
+ * kanboard.net
9
+ *
10
+ * Class KanboardInstaller
11
+ * @package Composer\Installers
12
+ */
13
+ class KanboardInstaller extends BaseInstaller
14
+ {
15
+ protected $locations = array(
16
+ 'plugin' => 'plugins/{$name}/',
17
+ );
18
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/KnownInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KnownInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'IdnoPlugins/{$name}/',
8
+ 'theme' => 'Themes/{$name}/',
9
+ 'console' => 'ConsolePlugins/{$name}/',
10
+ );
11
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class LanManagementSystemInstaller extends BaseInstaller
6
+ {
7
+
8
+ protected $locations = array(
9
+ 'plugin' => 'plugins/{$name}/',
10
+ 'template' => 'templates/{$name}/',
11
+ 'document-template' => 'documents/templates/{$name}/',
12
+ 'userpanel-module' => 'userpanel/modules/{$name}/',
13
+ );
14
+
15
+ /**
16
+ * Format package name to CamelCase
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
21
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
22
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
23
+
24
+ return $vars;
25
+ }
26
+
27
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LavaLiteInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'packages/{$vendor}/{$name}/',
8
+ 'theme' => 'public/themes/{$name}/',
9
+ );
10
+ }
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
+ }
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
+ }
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
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Plugin/theme installer for majima
6
+ * @author David Neustadt
7
+ */
8
+ class MajimaInstaller extends BaseInstaller
9
+ {
10
+ protected $locations = array(
11
+ 'plugin' => 'plugins/{$name}/',
12
+ );
13
+
14
+ /**
15
+ * Transforms the names
16
+ * @param array $vars
17
+ * @return array
18
+ */
19
+ public function inflectPackageVars($vars)
20
+ {
21
+ return $this->correctPluginName($vars);
22
+ }
23
+
24
+ /**
25
+ * Change hyphenated names to camelcase
26
+ * @param array $vars
27
+ * @return array
28
+ */
29
+ private function correctPluginName($vars)
30
+ {
31
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
32
+ return strtoupper($matches[0][1]);
33
+ }, $vars['name']);
34
+ $vars['name'] = ucfirst($camelCasedName);
35
+ return $vars;
36
+ }
37
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\DependencyResolver\Pool;
5
+
6
+ class MantisBTInstaller extends BaseInstaller
7
+ {
8
+ protected $locations = array(
9
+ 'plugin' => 'plugins/{$name}/',
10
+ );
11
+
12
+ /**
13
+ * Format package name to CamelCase
14
+ */
15
+ public function inflectPackageVars($vars)
16
+ {
17
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
18
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
19
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
20
+
21
+ return $vars;
22
+ }
23
+ }
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
+ }
vendor/composer/installers/src/Composer/Installers/MayaInstaller.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MayaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name.
12
+ *
13
+ * For package type maya-module, cut off a trailing '-module' if present.
14
+ *
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ if ($vars['type'] === 'maya-module') {
19
+ return $this->inflectModuleVars($vars);
20
+ }
21
+
22
+ return $vars;
23
+ }
24
+
25
+ protected function inflectModuleVars($vars)
26
+ {
27
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
28
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
29
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
30
+
31
+ return $vars;
32
+ }
33
+ }
vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MediaWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'core' => 'core/',
8
+ 'extension' => 'extensions/{$name}/',
9
+ 'skin' => 'skins/{$name}/',
10
+ );
11
+
12
+ /**
13
+ * Format package name.
14
+ *
15
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
16
+ * to CamelCase keeping existing uppercase chars.
17
+ *
18
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
19
+ *
20
+ */
21
+ public function inflectPackageVars($vars)
22
+ {
23
+
24
+ if ($vars['type'] === 'mediawiki-extension') {
25
+ return $this->inflectExtensionVars($vars);
26
+ }
27
+
28
+ if ($vars['type'] === 'mediawiki-skin') {
29
+ return $this->inflectSkinVars($vars);
30
+ }
31
+
32
+ return $vars;
33
+ }
34
+
35
+ protected function inflectExtensionVars($vars)
36
+ {
37
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
38
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
39
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
40
+
41
+ return $vars;
42
+ }
43
+
44
+ protected function inflectSkinVars($vars)
45
+ {
46
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
47
+
48
+ return $vars;
49
+ }
50
+
51
+ }
vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MicroweberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'userfiles/modules/{$install_item_dir}/',
8
+ 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
9
+ 'template' => 'userfiles/templates/{$install_item_dir}/',
10
+ 'element' => 'userfiles/elements/{$install_item_dir}/',
11
+ 'vendor' => 'vendor/{$install_item_dir}/',
12
+ 'components' => 'components/{$install_item_dir}/'
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
+
26
+
27
+ if ($this->package->getTargetDir()) {
28
+ $vars['install_item_dir'] = $this->package->getTargetDir();
29
+ } else {
30
+ $vars['install_item_dir'] = $vars['name'];
31
+ if ($vars['type'] === 'microweber-template') {
32
+ return $this->inflectTemplateVars($vars);
33
+ }
34
+ if ($vars['type'] === 'microweber-templates') {
35
+ return $this->inflectTemplatesVars($vars);
36
+ }
37
+ if ($vars['type'] === 'microweber-core') {
38
+ return $this->inflectCoreVars($vars);
39
+ }
40
+ if ($vars['type'] === 'microweber-adapter') {
41
+ return $this->inflectCoreVars($vars);
42
+ }
43
+ if ($vars['type'] === 'microweber-module') {
44
+ return $this->inflectModuleVars($vars);
45
+ }
46
+ if ($vars['type'] === 'microweber-modules') {
47
+ return $this->inflectModulesVars($vars);
48
+ }
49
+ if ($vars['type'] === 'microweber-skin') {
50
+ return $this->inflectSkinVars($vars);
51
+ }
52
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
53
+ return $this->inflectElementVars($vars);
54
+ }
55
+ }
56
+
57
+
58
+ return $vars;
59
+ }
60
+
61
+ protected function inflectTemplateVars($vars)
62
+ {
63
+ $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']);
64
+ $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']);
65
+
66
+ return $vars;
67
+ }
68
+
69
+ protected function inflectTemplatesVars($vars)
70
+ {
71
+ $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']);
72
+ $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']);
73
+
74
+ return $vars;
75
+ }
76
+
77
+ protected function inflectCoreVars($vars)
78
+ {
79
+ $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']);
80
+ $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']);
81
+ $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']);
82
+
83
+ return $vars;
84
+ }
85
+
86
+ protected function inflectModuleVars($vars)
87
+ {
88
+ $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']);
89
+ $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']);
90
+
91
+ return $vars;
92
+ }
93
+
94
+ protected function inflectModulesVars($vars)
95
+ {
96
+ $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']);
97
+ $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']);
98
+
99
+ return $vars;
100
+ }
101
+
102
+ protected function inflectSkinVars($vars)
103
+ {
104
+ $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']);
105
+ $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']);
106
+
107
+ return $vars;
108
+ }
109
+
110
+ protected function inflectElementVars($vars)
111
+ {
112
+ $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']);
113
+ $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']);
114
+ $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']);
115
+ $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']);
116
+
117
+ return $vars;
118
+ }
119
+ }
vendor/composer/installers/src/Composer/Installers/ModxInstaller.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * An installer to handle MODX specifics when installing packages.
6
+ */
7
+ class ModxInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'extra' => 'core/packages/{$name}/'
11
+ );
12
+ }
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 'customcertelement' => 'mod/customcert/element/{$name}/',
24
+ 'datafield' => 'mod/data/field/{$name}/',
25
+ 'datapreset' => 'mod/data/preset/{$name}/',
26
+ 'editor' => 'lib/editor/{$name}/',
27
+ 'enrol' => 'enrol/{$name}/',
28
+ 'filter' => 'filter/{$name}/',
29
+ 'gradeexport' => 'grade/export/{$name}/',
30
+ 'gradeimport' => 'grade/import/{$name}/',
31
+ 'gradereport' => 'grade/report/{$name}/',
32
+ 'gradingform' => 'grade/grading/form/{$name}/',
33
+ 'local' => 'local/{$name}/',
34
+ 'logstore' => 'admin/tool/log/store/{$name}/',
35
+ 'ltisource' => 'mod/lti/source/{$name}/',
36
+ 'ltiservice' => 'mod/lti/service/{$name}/',
37
+ 'message' => 'message/output/{$name}/',
38
+ 'mnetservice' => 'mnet/service/{$name}/',
39
+ 'plagiarism' => 'plagiarism/{$name}/',
40
+ 'portfolio' => 'portfolio/{$name}/',
41
+ 'qbehaviour' => 'question/behaviour/{$name}/',
42
+ 'qformat' => 'question/format/{$name}/',
43
+ 'qtype' => 'question/type/{$name}/',
44
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
45
+ 'quiz' => 'mod/quiz/report/{$name}/',
46
+ 'report' => 'report/{$name}/',
47
+ 'repository' => 'repository/{$name}/',
48
+ 'scormreport' => 'mod/scorm/report/{$name}/',
49
+ 'search' => 'search/engine/{$name}/',
50
+ 'theme' => 'theme/{$name}/',
51
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
52
+ 'profilefield' => 'user/profile/field/{$name}/',
53
+ 'webservice' => 'webservice/{$name}/',
54
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
55
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
56
+ 'workshopform' => 'mod/workshop/form/{$name}/'
57
+ );
58
+ }
vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php ADDED
@@ -0,0 +1,47 @@
 
 
1
+ <?php
2
+ namespace