diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js index bec1827c3..c8441c624 100644 --- a/modules/ppcp-blocks/resources/js/checkout-block.js +++ b/modules/ppcp-blocks/resources/js/checkout-block.js @@ -2,6 +2,7 @@ import {useEffect, useState} from '@wordpress/element'; import {registerExpressPaymentMethod, registerPaymentMethod} from '@woocommerce/blocks-registry'; import {paypalAddressToWc, paypalOrderToWcAddresses} from "./Helper/Address"; import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading' +import buttonModuleWatcher from "../../../ppcp-button/resources/js/modules/ButtonModuleWatcher"; const config = wc.wcSettings.getSetting('ppcp-gateway_data'); @@ -28,6 +29,7 @@ const PayPalComponent = ({ if (!loaded) { loadPaypalScript(config.scriptData, () => { setLoaded(true); + buttonModuleWatcher.registerContextBootstrap(config.scriptData.context, this); }); } }, [loaded]); diff --git a/modules/ppcp-button/resources/js/button.js b/modules/ppcp-button/resources/js/button.js index 8b63b26bb..e93232e2d 100644 --- a/modules/ppcp-button/resources/js/button.js +++ b/modules/ppcp-button/resources/js/button.js @@ -19,6 +19,7 @@ import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler"; import FormSaver from './modules/Helper/FormSaver'; import FormValidator from "./modules/Helper/FormValidator"; import {loadPaypalScript} from "./modules/Helper/ScriptLoading"; +import buttonModuleWatcher from "./modules/ButtonModuleWatcher"; // TODO: could be a good idea to have a separate spinner for each gateway, // but I think we care mainly about the script loading, so one spinner should be enough. @@ -60,6 +61,11 @@ const bootstrap = () => { } }); + const hasMessages = () => { + return PayPalCommerceGateway.messages.is_hidden === false + && document.querySelector(PayPalCommerceGateway.messages.wrapper); + } + const onSmartButtonClick = async (data, actions) => { window.ppcpFundingSource = data.fundingSource; const requiredFields = jQuery('form.woocommerce-checkout .validate-required:visible :input'); @@ -146,6 +152,7 @@ const bootstrap = () => { ); miniCartBootstrap.init(); + buttonModuleWatcher.registerContextBootstrap('mini-cart', miniCartBootstrap); } if ( @@ -163,6 +170,7 @@ const bootstrap = () => { ); singleProductBootstrap.init(); + buttonModuleWatcher.registerContextBootstrap('product', singleProductBootstrap); } if (context === 'cart') { @@ -174,6 +182,7 @@ const bootstrap = () => { ); cartBootstrap.init(); + buttonModuleWatcher.registerContextBootstrap('cart', cartBootstrap); } if (context === 'checkout') { @@ -186,6 +195,7 @@ const bootstrap = () => { ); checkoutBootstap.init(); + buttonModuleWatcher.registerContextBootstrap('checkout', checkoutBootstap); } if (context === 'pay-now' ) { @@ -197,15 +207,11 @@ const bootstrap = () => { errorHandler, ); payNowBootstrap.init(); + buttonModuleWatcher.registerContextBootstrap('pay-now', payNowBootstrap); } }; -const hasMessages = () => { - return PayPalCommerceGateway.messages.is_hidden === false - && document.querySelector(PayPalCommerceGateway.messages.wrapper); -} - document.addEventListener( 'DOMContentLoaded', () => { diff --git a/modules/ppcp-button/resources/js/modules/ButtonModuleWatcher.js b/modules/ppcp-button/resources/js/modules/ButtonModuleWatcher.js new file mode 100644 index 000000000..3fccca178 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/ButtonModuleWatcher.js @@ -0,0 +1,31 @@ + +class ButtonModuleWatcher { + + constructor() { + this.contextBootstrapRegistry = {}; + this.contextBootstrapWatchers = []; + } + + watchContextBootstrap(callable) { + this.contextBootstrapWatchers.push(callable); + Object.values(this.contextBootstrapRegistry).forEach(callable); + } + + registerContextBootstrap(context, handler) { + this.contextBootstrapRegistry[context] = { + context: context, + handler: handler + } + + // Call registered watchers + for (const callable of this.contextBootstrapWatchers) { + callable(this.contextBootstrapRegistry[context]); + } + } + +} + +window.ppcpResources = window.ppcpResources || {}; +const buttonModuleWatcher = window.ppcpResources['ButtonModuleWatcher'] = window.ppcpResources['ButtonModuleWatcher'] || new ButtonModuleWatcher(); + +export default buttonModuleWatcher; diff --git a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js index 1d61e3bb5..bb143eb08 100644 --- a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js +++ b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js @@ -1,5 +1,4 @@ import {loadScript} from "@paypal/paypal-js"; -import widgetBuilder from "./Renderer/WidgetBuilder"; const storageKey = 'ppcp-data-client-id'; diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index a1edd25ac..6fbe65b29 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -480,11 +480,10 @@ class SmartButton implements SmartButtonInterface { return; } - echo '

'; + echo '

'; + echo ''; do_action( 'woocommerce_paypal_payments_minicart_button_render' ); + echo ''; }, 30 ); diff --git a/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php b/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php index 58350f6f8..971f678cb 100644 --- a/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint; use Psr\Log\LoggerInterface; use Throwable; +use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\Button\Assets\SmartButton; /** @@ -71,12 +72,24 @@ class CartScriptParamsEndpoint implements EndpointInterface { $script_data = $this->smart_button->script_data(); + $total = (float) WC()->cart->get_total( 'numeric' ); + + // Shop settings. + $base_location = wc_get_base_location(); + $shop_country_code = $base_location['country']; + $currency_code = get_woocommerce_currency(); + wp_send_json_success( array( 'url_params' => $script_data['url_params'], 'button' => $script_data['button'], 'messages' => $script_data['messages'], 'amount' => WC()->cart->get_total( 'raw' ), + + 'total' => $total, + 'total_str' => ( new Money( $total, $currency_code ) )->value_str(), + 'currency_code' => $currency_code, + 'country_code' => $shop_country_code, ) ); diff --git a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php index 5e3796dbb..ba23a403d 100644 --- a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint; use Exception; use Psr\Log\LoggerInterface; +use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\Button\Assets\SmartButton; /** @@ -100,18 +101,26 @@ class SimulateCartEndpoint extends AbstractCartEndpoint { $button_enabled = $button_enabled && ! $this->smart_button->is_button_disabled( 'product', $context_data ); } + // Shop settings. + $base_location = wc_get_base_location(); + $shop_country_code = $base_location['country']; + $currency_code = get_woocommerce_currency(); + wp_send_json_success( array( - 'total' => $total, - 'funding' => array( + 'total' => $total, + 'total_str' => ( new Money( $total, $currency_code ) )->value_str(), + 'currency_code' => $currency_code, + 'country_code' => $shop_country_code, + 'funding' => array( 'paylater' => array( 'enabled' => $pay_later_enabled, ), ), - 'button' => array( + 'button' => array( 'is_disabled' => ! $button_enabled, ), - 'messages' => array( + 'messages' => array( 'is_hidden' => ! $pay_later_messaging_enabled, ), ) diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 2e9c6211d..eea5d0efb 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -619,8 +619,24 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), + 'alternative_payment_methods' => array( + 'heading' => __( 'Alternative Payment Methods', 'woocommerce-paypal-payments' ), + 'description' => sprintf( + // translators: %1$s, %2$s, %3$s and %4$s are a link tags. + __( '%1$sAlternative Payment Methods%2$s allow you to accept payments from customers around the globe who use their credit cards, bank accounts, wallets, and local payment methods. When a buyer pays in a currency different than yours, PayPal handles currency conversion for you and presents conversion information to the buyer during checkout.', 'woocommerce-paypal-payments' ), + '', + '' + ), + 'type' => 'ppcp-heading', + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), 'disable_funding' => array( - 'title' => __( 'Hide Funding Source(s)', 'woocommerce-paypal-payments' ), + 'title' => __( 'Disable Alternative Payment Methods', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), @@ -628,7 +644,7 @@ return array( 'desc_tip' => false, 'description' => sprintf( // translators: %1$s and %2$s are the opening and closing of HTML tag. - __( 'By default, all possible funding sources will be shown. This setting can disable funding sources such as Credit Cards, Pay Later, Venmo, or other %1$sAlternative Payment Methods%2$s.', 'woocommerce-paypal-payments' ), + __( 'Choose to hide specific %1$sAlternative Payment Methods%2$s such as Credit Cards, Venmo, or others.', 'woocommerce-paypal-payments' ), ' 'paypal', ), 'card_billing_data_mode' => array( - 'title' => __( 'Card billing data handling', 'woocommerce-paypal-payments' ), + 'title' => __( 'Send checkout billing data to card fields', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), 'input_class' => array( 'wc-enhanced-select' ), @@ -664,10 +680,10 @@ return array( 'gateway' => array( 'paypal', CardButtonGateway::ID ), ), 'allow_card_button_gateway' => array( - 'title' => __( 'Separate Card Button from PayPal gateway', 'woocommerce-paypal-payments' ), + 'title' => __( 'Create gateway for Standard Card Button', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, - 'label' => __( 'Enable a separate payment gateway for the branded PayPal Debit or Credit Card button.', 'woocommerce-paypal-payments' ), + 'label' => __( 'Moves the Standard Card Button from the PayPal gateway into its own dedicated gateway.', 'woocommerce-paypal-payments' ), 'description' => __( 'By default, the Debit or Credit Card button is displayed in the Standard Payments payment gateway. This setting creates a second gateway for the Card button.', 'woocommerce-paypal-payments' ), 'default' => $container->get( 'wcgateway.settings.allow_card_button_gateway.default' ), 'screens' => array(