From 59afa81160c9ca74e8d36ffb4409cf058d0cb5e2 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 13 Jul 2023 16:22:57 +0200 Subject: [PATCH] Introduce paypal-js loading wrapper to be able to reload script --- modules/ppcp-button/package.json | 5 +- .../SingleProductActionHandler.js | 3 +- .../modules/ContextBootstrap/CartBootstap.js | 3 +- .../ContextBootstrap/SingleProductBootstap.js | 22 +++++--- .../js/modules/Helper/ScriptLoading.js | 7 +++ .../js/modules/Helper/Subscriptions.js | 12 ----- .../ppcp-button/src/Assets/SmartButton.php | 52 ++++++++++--------- modules/ppcp-button/yarn.lock | 12 +++++ .../resources/js/paypal-subscription.js | 2 - .../src/Checkout/DisableGateways.php | 9 ---- 10 files changed, 65 insertions(+), 62 deletions(-) diff --git a/modules/ppcp-button/package.json b/modules/ppcp-button/package.json index 61e31d70f..77828e436 100644 --- a/modules/ppcp-button/package.json +++ b/modules/ppcp-button/package.json @@ -11,9 +11,10 @@ "Edge >= 14" ], "dependencies": { + "@paypal/paypal-js": "^6.0.0", "core-js": "^3.25.0", - "formdata-polyfill": "^4.0.10", - "deepmerge": "^4.2.2" + "deepmerge": "^4.2.2", + "formdata-polyfill": "^4.0.10" }, "devDependencies": { "@babel/core": "^7.19", diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js index 123381912..1aa3e47bd 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js @@ -35,7 +35,6 @@ class SingleProductActionHandler { subscriptionsConfiguration(selected_variation = null) { const subscription_plan = selected_variation !== null ? this.getPlanIdFromVariation(selected_variation) : this.config.subscription_plan_id - console.log(subscription_plan) return { createSubscription: (data, actions) => { @@ -56,7 +55,7 @@ class SingleProductActionHandler { return res.json(); }).then(() => { const id = document.querySelector('[name="add-to-cart"]').value; - const products = [new Product(id, 1, null)]; + const products = [new Product(id, 1, [])]; fetch(this.config.ajax.change_cart.endpoint, { method: 'POST', diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js index 6e65e9be8..504fc4c42 100644 --- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js +++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js @@ -1,7 +1,6 @@ import CartActionHandler from '../ActionHandler/CartActionHandler'; import BootstrapHelper from "../Helper/BootstrapHelper"; import {setVisible} from "../Helper/Hiding"; -import {subscriptionHasPlan} from "../Helper/Subscriptions"; class CartBootstrap { constructor(gateway, renderer, errorHandler) { @@ -53,7 +52,7 @@ class CartBootstrap { } shouldRender() { - return document.querySelector(this.gateway.button.wrapper) !== null && subscriptionHasPlan(); + return document.querySelector(this.gateway.button.wrapper) !== null; } shouldEnable() { diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js index b3d3e2359..61f167d31 100644 --- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js +++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js @@ -2,7 +2,7 @@ import UpdateCart from "../Helper/UpdateCart"; import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler"; import {hide, show} from "../Helper/Hiding"; import BootstrapHelper from "../Helper/BootstrapHelper"; -import {subscriptionHasPlan} from "../Helper/Subscriptions"; +import {loadPaypalJsScript} from "../Helper/ScriptLoading"; class SingleProductBootstap { constructor(gateway, renderer, messages, errorHandler) { @@ -80,8 +80,7 @@ class SingleProductBootstap { shouldRender() { return this.form() !== null - && !this.isWcsattSubscriptionMode() - && subscriptionHasPlan(); + && !this.isWcsattSubscriptionMode(); } shouldEnable() { @@ -120,10 +119,6 @@ class SingleProductBootstap { } priceAmountIsZero() { - if(subscriptionHasPlan()) { - return false; - } - const price = this.priceAmount(); return !price || price === 0; } @@ -168,7 +163,18 @@ class SingleProductBootstap { PayPalCommerceGateway.data_client_id.has_subscriptions && PayPalCommerceGateway.data_client_id.paypal_subscriptions_enabled ) { - this.renderer.render(actionHandler.subscriptionsConfiguration(this.variations())); + const buttonWrapper = document.getElementById('ppc-button-ppcp-gateway'); + buttonWrapper.innerHTML = ''; + loadPaypalJsScript( + { + clientId: PayPalCommerceGateway.client_id, + currency: PayPalCommerceGateway.currency, + intent: 'subscription', + vault: true + }, + actionHandler.subscriptionsConfiguration(this.variations()), + this.gateway.button.wrapper + ); return; } diff --git a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js index c5742ab19..5925d6263 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js +++ b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js @@ -1,4 +1,5 @@ import dataClientIdAttributeHandler from "../DataClientIdAttributeHandler"; +import {loadScript} from "@paypal/paypal-js"; export const loadPaypalScript = (config, onLoaded) => { if (typeof paypal !== 'undefined') { @@ -22,3 +23,9 @@ export const loadPaypalScript = (config, onLoaded) => { document.body.appendChild(script); } + +export const loadPaypalJsScript = (options, buttons, container) => { + loadScript(options).then((paypal) => { + paypal.Buttons(buttons).render(container); + }); +} diff --git a/modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js b/modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js index bac46fbad..a205ac459 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js +++ b/modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js @@ -2,15 +2,3 @@ export const isChangePaymentPage = () => { const urlParams = new URLSearchParams(window.location.search) return urlParams.has('change_payment_method'); } - -export const subscriptionHasPlan = () => { - if (PayPalCommerceGateway.data_client_id.paypal_subscriptions_enabled && PayPalCommerceGateway.data_client_id.has_subscriptions) { - if (PayPalCommerceGateway.subscription_plan_id !== '') { - return true; - } - - return false; - } - - return true; -} diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index d86798eea..9b7f20acc 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -813,10 +813,12 @@ class SmartButton implements SmartButtonInterface { $this->request_data->enqueue_nonce_fix(); $localize = array( - 'url' => add_query_arg( $url_params, 'https://www.paypal.com/sdk/js' ), - 'url_params' => $url_params, - 'script_attributes' => $this->attributes(), - 'data_client_id' => array( + 'url' => add_query_arg( $url_params, 'https://www.paypal.com/sdk/js' ), + 'url_params' => $url_params, + 'script_attributes' => $this->attributes(), + 'client_id' => $this->client_id, + 'currency' => $this->currency, + 'data_client_id' => array( 'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(), 'endpoint' => \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ), @@ -824,9 +826,9 @@ class SmartButton implements SmartButtonInterface { 'has_subscriptions' => $this->has_subscriptions(), 'paypal_subscriptions_enabled' => $this->paypal_subscriptions_enabled(), ), - 'redirect' => wc_get_checkout_url(), - 'context' => $this->context(), - 'ajax' => array( + 'redirect' => wc_get_checkout_url(), + 'context' => $this->context(), + 'ajax' => array( 'change_cart' => array( 'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ), @@ -859,15 +861,15 @@ class SmartButton implements SmartButtonInterface { 'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ), ), ), - 'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(), + 'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(), 'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(), - 'enforce_vault' => $this->has_subscriptions(), - 'can_save_vault_token' => $this->can_save_vault_token(), - 'is_free_trial_cart' => $is_free_trial_cart, - 'vaulted_paypal_email' => ( is_checkout() && $is_free_trial_cart ) ? $this->get_vaulted_paypal_email() : '', - 'bn_codes' => $this->bn_codes(), - 'payer' => $this->payerData(), - 'button' => array( + 'enforce_vault' => $this->has_subscriptions(), + 'can_save_vault_token' => $this->can_save_vault_token(), + 'is_free_trial_cart' => $is_free_trial_cart, + 'vaulted_paypal_email' => ( is_checkout() && $is_free_trial_cart ) ? $this->get_vaulted_paypal_email() : '', + 'bn_codes' => $this->bn_codes(), + 'payer' => $this->payerData(), + 'button' => array( 'wrapper' => '#ppc-button-' . PayPalGateway::ID, 'is_disabled' => $this->is_button_disabled(), 'mini_cart_wrapper' => '#ppc-button-minicart', @@ -889,7 +891,7 @@ class SmartButton implements SmartButtonInterface { 'tagline' => $this->style_for_context( 'tagline', $this->context() ), ), ), - 'separate_buttons' => array( + 'separate_buttons' => array( 'card' => array( 'id' => CardButtonGateway::ID, 'wrapper' => '#ppc-button-' . CardButtonGateway::ID, @@ -899,7 +901,7 @@ class SmartButton implements SmartButtonInterface { ), ), ), - 'hosted_fields' => array( + 'hosted_fields' => array( 'wrapper' => '#ppcp-hosted-fields', 'labels' => array( 'credit_card_number' => '', @@ -922,8 +924,8 @@ class SmartButton implements SmartButtonInterface { 'valid_cards' => $this->dcc_applies->valid_cards(), 'contingency' => $this->get_3ds_contingency(), ), - 'messages' => $this->message_values(), - 'labels' => array( + 'messages' => $this->message_values(), + 'labels' => array( 'error' => array( 'generic' => __( 'Something went wrong. Please try again or choose another payment source.', @@ -950,12 +952,12 @@ class SmartButton implements SmartButtonInterface { // phpcs:ignore WordPress.WP.I18n 'shipping_field' => _x( 'Shipping %s', 'checkout-validation', 'woocommerce' ), ), - 'order_id' => 'pay-now' === $this->context() ? $this->get_order_pay_id() : 0, - 'single_product_buttons_enabled' => $this->settings_status->is_smart_button_enabled_for_location( 'product' ), - 'mini_cart_buttons_enabled' => $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' ), - 'basic_checkout_validation_enabled' => $this->basic_checkout_validation_enabled, - 'early_checkout_validation_enabled' => $this->early_validation_enabled, - 'funding_sources_without_redirect' => $this->funding_sources_without_redirect, + 'order_id' => 'pay-now' === $this->context() ? $this->get_order_pay_id() : 0, + 'single_product_buttons_enabled' => $this->settings_status->is_smart_button_enabled_for_location( 'product' ), + 'mini_cart_buttons_enabled' => $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' ), + 'basic_checkout_validation_enabled' => $this->basic_checkout_validation_enabled, + 'early_checkout_validation_enabled' => $this->early_validation_enabled, + 'funding_sources_without_redirect' => $this->funding_sources_without_redirect, ); if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) { diff --git a/modules/ppcp-button/yarn.lock b/modules/ppcp-button/yarn.lock index e76c992e1..9d5ebef6e 100644 --- a/modules/ppcp-button/yarn.lock +++ b/modules/ppcp-button/yarn.lock @@ -956,6 +956,13 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@paypal/paypal-js@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@paypal/paypal-js/-/paypal-js-6.0.0.tgz#a5a9556af29e4a0124049bf9a093606f52b8a951" + integrity sha512-FYzjYby9F7tgg4tUxYNseZ6vkeDJcdcjoULsyNhfrWZZjicDpdj5932fZlyUlQXDSR9KlhjXH6H4nPIJ0Lq0Kw== + dependencies: + promise-polyfill "^8.3.0" + "@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" @@ -1858,6 +1865,11 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +promise-polyfill@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" + integrity sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" diff --git a/modules/ppcp-subscription/resources/js/paypal-subscription.js b/modules/ppcp-subscription/resources/js/paypal-subscription.js index ae71a1b8e..c42ca2597 100644 --- a/modules/ppcp-subscription/resources/js/paypal-subscription.js +++ b/modules/ppcp-subscription/resources/js/paypal-subscription.js @@ -15,8 +15,6 @@ document.addEventListener( subscriptionTrial.style.display = 'none'; } - console.log('testing') - const unlinkBtn = document.getElementById('ppcp_unlink_sub_plan'); unlinkBtn?.addEventListener('click', (event)=>{ event.preventDefault(); diff --git a/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php b/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php index 380f64818..6afa24f31 100644 --- a/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php +++ b/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php @@ -129,15 +129,6 @@ class DisableGateways { return true; } - $subscription_mode = $this->settings->has( 'subscriptions_mode' ) ? $this->settings->get( 'subscriptions_mode' ) : ''; - if ( - (is_checkout() && $subscription_mode === 'subscriptions_api') - && $this->subscription_helper->cart_contains_subscription() - && ! $this->subscription_helper->checkout_subscription_product_allowed() - ) { - return true; - } - return false; }