From c48c94e09d7030d86a4dfc6b3afc1fad25cd6596 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 20 Aug 2024 14:19:41 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20New=20CheckoutBootstrap=20for=20Goo?= =?UTF-8?q?glePay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new module uses previously stored payer details to populate the checkout form on the classic checkout page. --- .../js/ContextBootstrap/CheckoutBootstrap.js | 64 +++++++++++++++++++ .../resources/js/GooglepayButton.js | 43 +++++++------ modules/ppcp-googlepay/resources/js/boot.js | 18 ++++-- 3 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 modules/ppcp-googlepay/resources/js/ContextBootstrap/CheckoutBootstrap.js diff --git a/modules/ppcp-googlepay/resources/js/ContextBootstrap/CheckoutBootstrap.js b/modules/ppcp-googlepay/resources/js/ContextBootstrap/CheckoutBootstrap.js new file mode 100644 index 000000000..b5e0c1a48 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/ContextBootstrap/CheckoutBootstrap.js @@ -0,0 +1,64 @@ +import { GooglePayStorage } from '../Helper/GooglePayStorage'; +import { setPayerData } from '../../../../ppcp-button/resources/js/modules/Helper/PayerData'; + +const CHECKOUT_FORM_SELECTOR = 'form.woocommerce-checkout'; + +export class CheckoutBootstrap { + /** + * @type {GooglePayStorage} + */ + #storage; + + /** + * @type {null|HTMLFormElement} + */ + #checkoutForm = null; + + constructor( storage ) { + this.#storage = storage; + + this.onFormSubmit = this.onFormSubmit.bind( this ); + } + + /** + * Returns the WooCommerce checkout form element. + * + * @return {HTMLFormElement|null} The form, or null if not a checkout page. + */ + get checkoutForm() { + if ( null === this.#checkoutForm ) { + this.#checkoutForm = document.querySelector( + CHECKOUT_FORM_SELECTOR + ); + } + + return this.#checkoutForm; + } + + /** + * Indicates, if the current page contains a checkout form. + * + * @return {boolean} True, if a checkout form is present. + */ + get isPageWithCheckoutForm() { + return this.checkoutForm instanceof HTMLElement; + } + + init() { + if ( ! this.isPageWithCheckoutForm ) { + return; + } + + const billingData = this.#storage.getPayer(); + + if ( billingData ) { + setPayerData( billingData ); + + this.checkoutForm.addEventListener( 'submit', this.onFormSubmit ); + } + } + + onFormSubmit() { + this.#storage.clearPayer(); + } +} diff --git a/modules/ppcp-googlepay/resources/js/GooglepayButton.js b/modules/ppcp-googlepay/resources/js/GooglepayButton.js index a68e22f4a..26acd0139 100644 --- a/modules/ppcp-googlepay/resources/js/GooglepayButton.js +++ b/modules/ppcp-googlepay/resources/js/GooglepayButton.js @@ -7,6 +7,7 @@ import widgetBuilder from '../../../ppcp-button/resources/js/modules/Renderer/Wi import UpdatePaymentData from './Helper/UpdatePaymentData'; import { PaymentMethods } from '../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState'; import { setPayerData } from '../../../ppcp-button/resources/js/modules/Helper/PayerData'; +import moduleStorage from './Helper/GooglePayStorage'; /** * Plugin-specific styling. @@ -74,6 +75,26 @@ import { setPayerData } from '../../../ppcp-button/resources/js/modules/Helper/P * Google Pay payment sheet. */ +function payerDataFromPaymentResponse( response ) { + const raw = response?.paymentMethodData?.info?.billingAddress; + + return { + email_address: response?.email, + name: { + given_name: raw.name.split( ' ' )[ 0 ], // Assuming first name is the first part + surname: raw.name.split( ' ' ).slice( 1 ).join( ' ' ), // Assuming last name is the rest + }, + address: { + country_code: raw.countryCode, + address_line_1: raw.address1, + address_line_2: raw.address2, + admin_area_1: raw.administrativeArea, + admin_area_2: raw.locality, + postal_code: raw.postalCode, + }, + }; +} + class GooglepayButton extends PaymentButton { /** * @inheritDoc @@ -643,30 +664,16 @@ class GooglepayButton extends PaymentButton { } }; - const propagatePayerDataToForm = () => { - const raw = paymentData?.paymentMethodData?.info?.billingAddress; - const payer = { - email_address: paymentData?.email, - name: { - given_name: raw.name.split( ' ' )[ 0 ], // Assuming first name is the first part - surname: raw.name.split( ' ' ).slice( 1 ).join( ' ' ), // Assuming last name is the rest - }, - address: { - country_code: raw.countryCode, - address_line_1: raw.address1, - address_line_2: raw.address2, - admin_area_1: raw.administrativeArea, - admin_area_2: raw.locality, - postal_code: raw.postalCode, - }, - }; + const addBillingDataToSession = () => { + const payer = payerDataFromPaymentResponse( paymentData ); + moduleStorage.setPayer( payer ); setPayerData( payer ); }; return new Promise( async ( resolve ) => { try { - propagatePayerDataToForm(); + addBillingDataToSession(); await processPaymentPromise( resolve ); } catch ( err ) { resolve( paymentError( err.message ) ); diff --git a/modules/ppcp-googlepay/resources/js/boot.js b/modules/ppcp-googlepay/resources/js/boot.js index 99dd414f5..3071998a9 100644 --- a/modules/ppcp-googlepay/resources/js/boot.js +++ b/modules/ppcp-googlepay/resources/js/boot.js @@ -2,13 +2,23 @@ import { loadCustomScript } from '@paypal/paypal-js'; import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'; import GooglepayManager from './GooglepayManager'; import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Helper/ButtonRefreshHelper'; +import { CheckoutBootstrap } from './ContextBootstrap/CheckoutBootstrap'; +import moduleStorage from './Helper/GooglePayStorage'; + +( function ( { buttonConfig, ppcpConfig } ) { + const context = ppcpConfig.context; -( function ( { buttonConfig, ppcpConfig, jQuery } ) { let manager; const bootstrap = function () { manager = new GooglepayManager( buttonConfig, ppcpConfig ); manager.init(); + + if ( 'continuation' === context || 'checkout' === context ) { + const checkoutBootstap = new CheckoutBootstrap( moduleStorage ); + + checkoutBootstap.init(); + } }; setupButtonEvents( function () { @@ -18,10 +28,7 @@ import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Hel } ); document.addEventListener( 'DOMContentLoaded', () => { - if ( - typeof buttonConfig === 'undefined' || - typeof ppcpConfig === 'undefined' - ) { + if ( ! buttonConfig || ! ppcpConfig ) { // No PayPal buttons present on this page. return; } @@ -52,5 +59,4 @@ import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Hel } )( { buttonConfig: window.wc_ppcp_googlepay, ppcpConfig: window.PayPalCommerceGateway, - jQuery: window.jQuery, } );