From 3171e943baaf9bbbf6cb25fbb44ed492d70cb95c Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 9 Oct 2024 16:38:11 +0200 Subject: [PATCH] Try to fix Google Pay in the editor --- .ddev/config.yaml | 8 +- modules/ppcp-blocks/yarn.lock | 102 +++++++++++++- modules/ppcp-googlepay/package.json | 6 +- .../js/Block/components/GooglepayButton.js | 31 +++++ .../js/Block/hooks/useButtonStyles.js | 19 +++ .../hooks/useGooglepayApiToGenerateButton.js | 62 +++++++++ .../js/Block/hooks/useGooglepayConfig.js | 26 ++++ .../js/Block/hooks/useGooglepayScript.js | 32 +++++ .../js/Block/hooks/usePayPalScript.js | 25 ++++ .../js/GooglepayManagerBlockEditor.js | 84 ++++-------- .../ppcp-googlepay/resources/js/boot-block.js | 61 ++++----- modules/ppcp-googlepay/yarn.lock | 128 +++++++++++++++++- 12 files changed, 487 insertions(+), 97 deletions(-) create mode 100644 modules/ppcp-googlepay/resources/js/Block/components/GooglepayButton.js create mode 100644 modules/ppcp-googlepay/resources/js/Block/hooks/useButtonStyles.js create mode 100644 modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayApiToGenerateButton.js create mode 100644 modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayConfig.js create mode 100644 modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayScript.js create mode 100644 modules/ppcp-googlepay/resources/js/Block/hooks/usePayPalScript.js diff --git a/.ddev/config.yaml b/.ddev/config.yaml index 5686c7920..d4da9318b 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -3,8 +3,8 @@ type: php docroot: .ddev/wordpress php_version: "7.4" webserver_type: apache-fpm -router_http_port: "80" -router_https_port: "443" +router_http_port: "6070" +router_https_port: "6443" xdebug_enabled: false additional_hostnames: ['wc-pp'] additional_fqdns: [] @@ -18,7 +18,7 @@ hooks: pre-start: - exec-host: "mkdir -p .ddev/wordpress/wp-content/plugins/${DDEV_PROJECT}" web_environment: - - WP_VERSION=6.3.3 + - WP_VERSION=6.6.2 - WP_LOCALE=en_US - WP_TITLE=WooCommerce PayPal Payments - WP_MULTISITE=true @@ -26,7 +26,7 @@ web_environment: - ADMIN_USER=admin - ADMIN_PASS=admin - ADMIN_EMAIL=admin@example.com - - WC_VERSION=7.7.2 + - WC_VERSION=9.3.3 # Key features of ddev's config.yaml: diff --git a/modules/ppcp-blocks/yarn.lock b/modules/ppcp-blocks/yarn.lock index 1debd6e24..56bee181f 100644 --- a/modules/ppcp-blocks/yarn.lock +++ b/modules/ppcp-blocks/yarn.lock @@ -911,6 +911,13 @@ "@babel/plugin-transform-react-jsx-development" "^7.18.6" "@babel/plugin-transform-react-pure-annotations" "^7.18.6" +"@babel/runtime@^7.16.0": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" + integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.8.4": version "7.20.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3" @@ -1027,6 +1034,31 @@ dependencies: hi-base32 "^0.5.0" +"@tannin/compile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/compile/-/compile-1.1.0.tgz#1e4d1c5364cbfeffa1c20352c053e19ef20ffe93" + integrity sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg== + dependencies: + "@tannin/evaluate" "^1.2.0" + "@tannin/postfix" "^1.1.0" + +"@tannin/evaluate@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@tannin/evaluate/-/evaluate-1.2.0.tgz#468a13c45eff45340108836fc46c708457199c3f" + integrity sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg== + +"@tannin/plural-forms@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/plural-forms/-/plural-forms-1.1.0.tgz#cffbb060d2640a56a314e3c77cbf6ea6072b51d5" + integrity sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw== + dependencies: + "@tannin/compile" "^1.1.0" + +"@tannin/postfix@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/postfix/-/postfix-1.1.0.tgz#6071f4204ae26c2e885cf3a3f1203a9f71e3f291" + integrity sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw== + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -1216,6 +1248,25 @@ json2php "^0.0.4" webpack-sources "^3.2.2" +"@wordpress/hooks@^4.9.0": + version "4.9.0" + resolved "https://registry.yarnpkg.com/@wordpress/hooks/-/hooks-4.9.0.tgz#9464a9d4a08e08182937d4f2e9d67a69d4b75312" + integrity sha512-nan2w5imPhTaJwWdKjm/0ZMDbWR3P6Vhl4OqnBZZcJqOyNSfwsnJ98I+BWjq0U6SmiCnZQERjN0SjVdmD1tCjw== + dependencies: + "@babel/runtime" "^7.16.0" + +"@wordpress/i18n@^5.6.0": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@wordpress/i18n/-/i18n-5.9.0.tgz#79185503ab2115b38271504e98a756f194e2b7f6" + integrity sha512-pKFV9S/l0TFlm0mlWLW51hAoRDNmZPGnfEpNXq43VKZkm1cco3Z1E54PHMGk8HdCECHqYNiJuQJOBOlqcYmnVQ== + dependencies: + "@babel/runtime" "^7.16.0" + "@wordpress/hooks" "^4.9.0" + gettext-parser "^1.3.1" + memize "^2.1.0" + sprintf-js "^1.1.1" + tannin "^1.2.0" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -1457,6 +1508,13 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + enhanced-resolve@^5.10.0: version "5.12.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" @@ -1582,6 +1640,14 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +gettext-parser@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" + integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.1" + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1626,6 +1692,13 @@ hi-base32@^0.5.0: resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.1.tgz#1279f2ddae2673219ea5870c2121d2a33132857e" integrity sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA== +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + immutable@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" @@ -1786,6 +1859,11 @@ make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +memize@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/memize/-/memize-2.1.0.tgz#6ddd4717887d94825748149ece00d04cf868ce0d" + integrity sha512-yywVJy8ctVlN5lNPxsep5urnZ6TTclwPEyigM9M3Bi8vseJBOfqNrGWN/r8NzuIt3PovM323W04blJfGQfQSVg== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -1944,6 +2022,11 @@ regenerator-runtime@^0.13.11: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" @@ -1996,11 +2079,16 @@ resolve@^1.14.2, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@^5.1.1: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + sass-loader@^12.1.0: version "12.6.0" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" @@ -2093,6 +2181,11 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2112,6 +2205,13 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +tannin@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tannin/-/tannin-1.2.0.tgz#1da6fe65280dca4c3d84efb075b077b1b94362a6" + integrity sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA== + dependencies: + "@tannin/plural-forms" "^1.1.0" + tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" diff --git a/modules/ppcp-googlepay/package.json b/modules/ppcp-googlepay/package.json index e302398f1..04809bf6d 100644 --- a/modules/ppcp-googlepay/package.json +++ b/modules/ppcp-googlepay/package.json @@ -11,14 +11,16 @@ ], "dependencies": { "@paypal/paypal-js": "^6.0.0", - "core-js": "^3.25.0" + "core-js": "^3.25.0", + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { "@babel/core": "^7.19", "@babel/preset-env": "^7.19", "@babel/preset-react": "^7.18.6", - "@wordpress/i18n": "^5.6.0", "@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0", + "@wordpress/i18n": "^5.6.0", "babel-loader": "^8.2", "cross-env": "^7.0.3", "file-loader": "^6.2.0", diff --git a/modules/ppcp-googlepay/resources/js/Block/components/GooglepayButton.js b/modules/ppcp-googlepay/resources/js/Block/components/GooglepayButton.js new file mode 100644 index 000000000..00438da7a --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/components/GooglepayButton.js @@ -0,0 +1,31 @@ +import { useState, useEffect } from '@wordpress/element'; +import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton'; + +const GooglepayButton = ( { + namespace, + buttonConfig, + ppcpConfig, + googlepayConfig, +} ) => { + const [ buttonHtml, setButtonHtml ] = useState( '' ); + const googlepayButton = useGooglepayApiToGenerateButton( + namespace, + buttonConfig, + ppcpConfig, + googlepayConfig + ); + + useEffect( () => { + if ( googlepayButton ) { + setButtonHtml( googlepayButton.outerHTML ); + } + }, [ googlepayButton ] ); + + if ( ! buttonHtml ) { + return null; + } + + return
; +}; + +export default GooglepayButton; diff --git a/modules/ppcp-googlepay/resources/js/Block/hooks/useButtonStyles.js b/modules/ppcp-googlepay/resources/js/Block/hooks/useButtonStyles.js new file mode 100644 index 000000000..6e214acb2 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/hooks/useButtonStyles.js @@ -0,0 +1,19 @@ +import { useMemo } from '@wordpress/element'; +import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers'; + +const useButtonStyles = ( buttonConfig, ppcpConfig ) => { + return useMemo( () => { + const styles = combineStyles( + ppcpConfig?.button || {}, + buttonConfig?.button || {} + ); + + if ( styles.MiniCart && styles.MiniCart.type === 'buy' ) { + styles.MiniCart.type = 'pay'; + } + + return styles; + }, [ buttonConfig, ppcpConfig ] ); +}; + +export default useButtonStyles; diff --git a/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayApiToGenerateButton.js b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayApiToGenerateButton.js new file mode 100644 index 000000000..99fb2d305 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayApiToGenerateButton.js @@ -0,0 +1,62 @@ +import { useEffect, useState } from '@wordpress/element'; +import useButtonStyles from './useButtonStyles'; + +const useGooglepayApiToGenerateButton = ( + namespace, + buttonConfig, + ppcpConfig, + googlepayConfig +) => { + const [ googlepayButton, setGooglepayButton ] = useState( null ); + const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig ); + + useEffect( () => { + if ( + ! buttonConfig || + ! googlepayConfig || + ! window.google || + ! window.google.payments || + ! window.google.payments.api + ) { + return; + } + + const paymentsClient = new window.google.payments.api.PaymentsClient( { + environment: 'TEST', + } ); + + console.log( 'paymentsClient', paymentsClient ); + + console.log( 'googlepayConfig', googlepayConfig ); + console.log( 'buttonStyles?.Default', buttonStyles?.Default ); + + const button = paymentsClient.createButton( { + onClick: () => { + console.log( 'Google Pay button clicked' ); + }, + allowedPaymentMethods: googlepayConfig.allowedPaymentMethods, + buttonColor: buttonConfig.buttonColor || 'black', + buttonType: buttonConfig.buttonType || 'pay', + buttonLocale: buttonConfig.buttonLocale || 'en', + buttonSizeMode: 'fill', + } ); + + console.log( { + allowedPaymentMethods: googlepayConfig.allowedPaymentMethods, + buttonColor: buttonConfig.buttonColor || 'black', + buttonType: buttonConfig.buttonType || 'pay', + buttonLocale: buttonConfig.buttonLocale || 'en', + buttonSizeMode: 'fill', + } ); + + setGooglepayButton( button ); + + return () => { + setGooglepayButton( null ); + }; + }, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] ); + + return googlepayButton; +}; + +export default useGooglepayApiToGenerateButton; diff --git a/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayConfig.js b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayConfig.js new file mode 100644 index 000000000..21971e871 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayConfig.js @@ -0,0 +1,26 @@ +import { useState, useEffect } from '@wordpress/element'; + +const useGooglepayConfig = ( namespace, isGooglepayLoaded ) => { + const [ googlePayConfig, setGooglePayConfig ] = useState( null ); + + useEffect( () => { + const fetchConfig = async () => { + if ( ! isGooglepayLoaded ) { + return; + } + + try { + const config = await window[ namespace ].Googlepay().config(); + setGooglePayConfig( config ); + } catch ( error ) { + console.error( 'Failed to fetch Google Pay config:', error ); + } + }; + + fetchConfig(); + }, [ namespace, isGooglepayLoaded ] ); + + return googlePayConfig; +}; + +export default useGooglepayConfig; diff --git a/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayScript.js b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayScript.js new file mode 100644 index 000000000..25731c696 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/hooks/useGooglepayScript.js @@ -0,0 +1,32 @@ +import { useState, useEffect } from '@wordpress/element'; +import { loadCustomScript } from '@paypal/paypal-js'; + +const useGooglepayScript = ( buttonConfig, isPayPalLoaded ) => { + const [ isGooglepayLoaded, setIsGooglepayLoaded ] = useState( false ); + + useEffect( () => { + const loadGooglepayScript = async () => { + if ( ! isPayPalLoaded ) { + return; + } + + if ( ! buttonConfig || ! buttonConfig.sdk_url ) { + console.error( 'Invalid buttonConfig or missing sdk_url' ); + return; + } + + try { + await loadCustomScript( { url: buttonConfig.sdk_url } ); + setIsGooglepayLoaded( true ); + } catch ( error ) { + console.error( 'Failed to load Googlepay script:', error ); + } + }; + + loadGooglepayScript(); + }, [ buttonConfig, isPayPalLoaded ] ); + + return isGooglepayLoaded; +}; + +export default useGooglepayScript; diff --git a/modules/ppcp-googlepay/resources/js/Block/hooks/usePayPalScript.js b/modules/ppcp-googlepay/resources/js/Block/hooks/usePayPalScript.js new file mode 100644 index 000000000..fb2e0005d --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/Block/hooks/usePayPalScript.js @@ -0,0 +1,25 @@ +import { useState, useEffect } from '@wordpress/element'; +import { loadPayPalScript } from '../../../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading'; + +const usePayPalScript = ( namespace, ppcpConfig ) => { + const [ isPayPalLoaded, setIsPayPalLoaded ] = useState( false ); + + ppcpConfig.url_params.components += ',googlepay'; + + useEffect( () => { + const loadScript = async () => { + try { + await loadPayPalScript( namespace, ppcpConfig ); + setIsPayPalLoaded( true ); + } catch ( error ) { + console.error( `Error loading PayPal script: ${ error }` ); + } + }; + + loadScript(); + }, [ namespace, ppcpConfig ] ); + + return isPayPalLoaded; +}; + +export default usePayPalScript; diff --git a/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js b/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js index 2bf5a55c3..572b0aabb 100644 --- a/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js +++ b/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js @@ -1,62 +1,32 @@ -import GooglepayButton from './GooglepayButton'; -import ContextHandlerFactory from './Context/ContextHandlerFactory'; +import GooglepayButton from './Block/components/GooglepayButton'; +import usePayPalScript from './Block/hooks/usePayPalScript'; +import useGooglepayScript from './Block/hooks/useGooglepayScript'; +import useGooglepayConfig from './Block/hooks/useGooglepayConfig'; -class GooglepayManagerBlockEditor { - constructor( namespace, buttonConfig, ppcpConfig ) { - this.namespace = namespace; - this.buttonConfig = buttonConfig; - this.ppcpConfig = ppcpConfig; - this.googlePayConfig = null; - this.transactionInfo = null; - this.contextHandler = null; +const GooglepayManagerBlockEditor = ( { + namespace, + buttonConfig, + ppcpConfig, +} ) => { + const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig ); + const isGooglepayLoaded = useGooglepayScript( + buttonConfig, + isPayPalLoaded + ); + const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded ); + + if ( ! googlepayConfig ) { + return
Loading Google Pay...
; // Or any other loading indicator } - init() { - ( async () => { - await this.config(); - } )(); - } - - async config() { - try { - // Gets GooglePay configuration of the PayPal merchant. - this.googlePayConfig = await window[ this.namespace ] - .Googlepay() - .config(); - - // Fetch transaction information. - this.transactionInfo = await this.fetchTransactionInfo(); - - const button = new GooglepayButton( - this.ppcpConfig.context, - null, - this.buttonConfig, - this.ppcpConfig, - this.contextHandler - ); - - button.init( this.googlePayConfig, this.transactionInfo ); - } catch ( error ) { - console.error( 'Failed to initialize Google Pay:', error ); - } - } - - async fetchTransactionInfo() { - try { - if ( ! this.contextHandler ) { - this.contextHandler = ContextHandlerFactory.create( - this.ppcpConfig.context, - this.buttonConfig, - this.ppcpConfig, - null - ); - } - return null; - } catch ( error ) { - console.error( 'Error fetching transaction info:', error ); - throw error; - } - } -} + return ( + + ); +}; export default GooglepayManagerBlockEditor; diff --git a/modules/ppcp-googlepay/resources/js/boot-block.js b/modules/ppcp-googlepay/resources/js/boot-block.js index bc359be7d..398cc488c 100644 --- a/modules/ppcp-googlepay/resources/js/boot-block.js +++ b/modules/ppcp-googlepay/resources/js/boot-block.js @@ -1,4 +1,5 @@ import { useEffect, useState } from '@wordpress/element'; +import { loadCustomScript } from '@paypal/paypal-js'; import { registerExpressPaymentMethod, registerPaymentMethod, @@ -6,7 +7,6 @@ import { import { __ } from '@wordpress/i18n'; import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading'; import GooglepayManager from './GooglepayManager'; -import { loadCustomScript } from '@paypal/paypal-js'; import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor'; const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' ); @@ -20,56 +20,55 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) { window.PayPalCommerceGateway = ppcpConfig; } -const GooglePayComponent = ( props ) => { - const [ bootstrapped, setBootstrapped ] = useState( false ); +const GooglePayComponent = ( { isEditing } ) => { const [ paypalLoaded, setPaypalLoaded ] = useState( false ); const [ googlePayLoaded, setGooglePayLoaded ] = useState( false ); const [ manager, setManager ] = useState( null ); useEffect( () => { - // Load GooglePay SDK - loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => { - setGooglePayLoaded( true ); - } ); - - ppcpConfig.url_params.components += ',googlepay'; - - // Load PayPal - loadPayPalScript( namespace, ppcpConfig ) - .then( () => { - setPaypalLoaded( true ); - } ) - .catch( ( error ) => { - console.error( 'Failed to load PayPal script: ', error ); + if ( ! isEditing ) { + loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => { + setGooglePayLoaded( true ); } ); - }, [] ); + + ppcpConfig.url_params.components += ',googlepay'; + + loadPayPalScript( namespace, ppcpConfig ) + .then( () => { + setPaypalLoaded( true ); + } ) + .catch( ( error ) => { + console.error( 'Failed to load PayPal script: ', error ); + } ); + } + }, [ isEditing, buttonConfig, ppcpConfig ] ); useEffect( () => { - if ( paypalLoaded && googlePayLoaded && ! manager ) { - const ManagerClass = props.isEditing - ? GooglepayManagerBlockEditor - : GooglepayManager; - const newManager = new ManagerClass( + if ( ! isEditing && paypalLoaded && googlePayLoaded && ! manager ) { + const newManager = new GooglepayManager( namespace, buttonConfig, ppcpConfig ); setManager( newManager ); } - }, [ paypalLoaded, googlePayLoaded, props.isEditing ] ); + }, [ paypalLoaded, googlePayLoaded, isEditing, manager ] ); - useEffect( () => { - if ( manager && ! bootstrapped ) { - setBootstrapped( true ); - manager.init(); - } - }, [ manager, bootstrapped ] ); + if ( isEditing ) { + return ( + + ); + } return (
+ /> ); }; diff --git a/modules/ppcp-googlepay/yarn.lock b/modules/ppcp-googlepay/yarn.lock index ec5854d6c..1d4c770b0 100644 --- a/modules/ppcp-googlepay/yarn.lock +++ b/modules/ppcp-googlepay/yarn.lock @@ -945,6 +945,13 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== +"@babel/runtime@^7.16.0": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" + integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.8.4": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" @@ -1038,6 +1045,31 @@ dependencies: promise-polyfill "^8.3.0" +"@tannin/compile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/compile/-/compile-1.1.0.tgz#1e4d1c5364cbfeffa1c20352c053e19ef20ffe93" + integrity sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg== + dependencies: + "@tannin/evaluate" "^1.2.0" + "@tannin/postfix" "^1.1.0" + +"@tannin/evaluate@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@tannin/evaluate/-/evaluate-1.2.0.tgz#468a13c45eff45340108836fc46c708457199c3f" + integrity sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg== + +"@tannin/plural-forms@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/plural-forms/-/plural-forms-1.1.0.tgz#cffbb060d2640a56a314e3c77cbf6ea6072b51d5" + integrity sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw== + dependencies: + "@tannin/compile" "^1.1.0" + +"@tannin/postfix@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tannin/postfix/-/postfix-1.1.0.tgz#6071f4204ae26c2e885cf3a3f1203a9f71e3f291" + integrity sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw== + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -1222,6 +1254,25 @@ json2php "^0.0.4" webpack-sources "^3.2.2" +"@wordpress/hooks@^4.9.0": + version "4.9.0" + resolved "https://registry.yarnpkg.com/@wordpress/hooks/-/hooks-4.9.0.tgz#9464a9d4a08e08182937d4f2e9d67a69d4b75312" + integrity sha512-nan2w5imPhTaJwWdKjm/0ZMDbWR3P6Vhl4OqnBZZcJqOyNSfwsnJ98I+BWjq0U6SmiCnZQERjN0SjVdmD1tCjw== + dependencies: + "@babel/runtime" "^7.16.0" + +"@wordpress/i18n@^5.6.0": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@wordpress/i18n/-/i18n-5.9.0.tgz#79185503ab2115b38271504e98a756f194e2b7f6" + integrity sha512-pKFV9S/l0TFlm0mlWLW51hAoRDNmZPGnfEpNXq43VKZkm1cco3Z1E54PHMGk8HdCECHqYNiJuQJOBOlqcYmnVQ== + dependencies: + "@babel/runtime" "^7.16.0" + "@wordpress/hooks" "^4.9.0" + gettext-parser "^1.3.1" + memize "^2.1.0" + sprintf-js "^1.1.1" + tannin "^1.2.0" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -1463,6 +1514,13 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + enhanced-resolve@^5.15.0: version "5.15.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" @@ -1588,6 +1646,14 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +gettext-parser@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" + integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.1" + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1627,6 +1693,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + immutable@^4.0.0: version "4.3.2" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.2.tgz#f89d910f8dfb6e15c03b2cae2faaf8c1f66455fe" @@ -1702,7 +1775,7 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -1773,6 +1846,13 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -1787,6 +1867,11 @@ make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +memize@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/memize/-/memize-2.1.0.tgz#6ddd4717887d94825748149ece00d04cf868ce0d" + integrity sha512-yywVJy8ctVlN5lNPxsep5urnZ6TTclwPEyigM9M3Bi8vseJBOfqNrGWN/r8NzuIt3PovM323W04blJfGQfQSVg== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -1892,6 +1977,21 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +react-dom@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1970,11 +2070,16 @@ resolve@^1.14.2, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@^5.1.1: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + sass-loader@^12.1.0: version "12.6.0" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" @@ -1992,6 +2097,13 @@ sass@^1.42.1: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" @@ -2059,6 +2171,11 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2078,6 +2195,13 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +tannin@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tannin/-/tannin-1.2.0.tgz#1da6fe65280dca4c3d84efb075b077b1b94362a6" + integrity sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA== + dependencies: + "@tannin/plural-forms" "^1.1.0" + tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"