From 4a45962396586347d6d51162fb72f6668df039fc Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 5 Dec 2024 15:12:52 -0300 Subject: [PATCH 01/31] Add condition to identify button context when dismissed --- client/express-checkout/event-handlers.js | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 2d1345ff752..f09d82cf851 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -171,5 +171,28 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - unblockUI(); + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + switch ( context ) { + case 'cart': + if ( isBlocks ) { + alert( 'Cart block context' ); + } else { + alert( 'Cart shortcode context' ); + } + location.reload( true ); + break; + case 'checkout': + if ( isBlocks ) { + alert( 'Checkout block context' ); + } else { + alert( 'Checkout shortcode context' ); + } + location.reload( true ); + break; + default: + alert( 'Default context' ); + unblockUI(); + } }; From e1be2e25083c1ed225f4b870cca060d9ffc24158 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 5 Dec 2024 15:16:44 -0300 Subject: [PATCH 02/31] Add flag to control if a refresh is needed. --- client/express-checkout/event-handlers.js | 55 +++++++++++++---------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index f09d82cf851..0e1dddf587e 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -19,6 +19,9 @@ import { trackExpressCheckoutButtonLoad, } from './tracking'; +// Used to control if we need to refresh the cart/checkout information when ECE is dismissed. +let wasShippingInfoUpdated = false; + export const shippingAddressChangeHandler = async ( api, event, elements ) => { try { const response = await api.expressCheckoutECECalculateShippingOptions( @@ -26,6 +29,7 @@ export const shippingAddressChangeHandler = async ( api, event, elements ) => { ); if ( response.result === 'success' ) { + wasShippingInfoUpdated = true; elements.update( { amount: response.total.amount, } ); @@ -48,6 +52,7 @@ export const shippingRateChangeHandler = async ( api, event, elements ) => { ); if ( response.result === 'success' ) { + wasShippingInfoUpdated = true; elements.update( { amount: response.total.amount } ); event.resolve( { lineItems: normalizeLineItems( response.displayItems ), @@ -171,28 +176,32 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - const context = getExpressCheckoutData( 'button_context' ); - const isBlocks = getExpressCheckoutData( 'has_block' ); - - switch ( context ) { - case 'cart': - if ( isBlocks ) { - alert( 'Cart block context' ); - } else { - alert( 'Cart shortcode context' ); - } - location.reload( true ); - break; - case 'checkout': - if ( isBlocks ) { - alert( 'Checkout block context' ); - } else { - alert( 'Checkout shortcode context' ); - } - location.reload( true ); - break; - default: - alert( 'Default context' ); - unblockUI(); + if ( wasShippingInfoUpdated ) { + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + switch ( context ) { + case 'cart': + if ( isBlocks ) { + alert( 'Cart block context' ); + } else { + alert( 'Cart shortcode context' ); + } + location.reload( true ); + break; + case 'checkout': + if ( isBlocks ) { + alert( 'Checkout block context' ); + } else { + alert( 'Checkout shortcode context' ); + } + location.reload( true ); + break; + default: + alert( 'Default context' ); + } } + + wasShippingInfoUpdated = false; + unblockUI(); }; From 21e38d7833478ba5804908deb4ba069602e26b53 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 5 Dec 2024 16:16:54 -0300 Subject: [PATCH 03/31] Simplify logic to refresh page. --- client/express-checkout/event-handlers.js | 30 +++++------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 0e1dddf587e..498c73dbecf 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -176,30 +176,12 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - if ( wasShippingInfoUpdated ) { - const context = getExpressCheckoutData( 'button_context' ); - const isBlocks = getExpressCheckoutData( 'has_block' ); - - switch ( context ) { - case 'cart': - if ( isBlocks ) { - alert( 'Cart block context' ); - } else { - alert( 'Cart shortcode context' ); - } - location.reload( true ); - break; - case 'checkout': - if ( isBlocks ) { - alert( 'Checkout block context' ); - } else { - alert( 'Checkout shortcode context' ); - } - location.reload( true ); - break; - default: - alert( 'Default context' ); - } + const context = getExpressCheckoutData( 'button_context' ); + if ( + wasShippingInfoUpdated && + [ 'cart', 'checkout' ].includes( context ) + ) { + location.reload( true ); } wasShippingInfoUpdated = false; From c03c2291a6d4b5c02b1209bd7cfbec86c472e0bd Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 5 Dec 2024 16:23:48 -0300 Subject: [PATCH 04/31] Add changelog --- changelog/fix-9794-refresh-page-when-ece-dismissed | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog/fix-9794-refresh-page-when-ece-dismissed diff --git a/changelog/fix-9794-refresh-page-when-ece-dismissed b/changelog/fix-9794-refresh-page-when-ece-dismissed new file mode 100644 index 00000000000..7ec81b4760e --- /dev/null +++ b/changelog/fix-9794-refresh-page-when-ece-dismissed @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Refresh the cart and checkout pages when ECE is dismissed and the shipping options were modified in the payment sheet. From ffa128641fd27859574e59d51ee648500f029d34 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Wed, 11 Dec 2024 16:33:34 -0300 Subject: [PATCH 05/31] Add prototype for shortcode cart handling --- client/express-checkout/event-handlers.js | 86 +++++++++++++++++++---- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 498c73dbecf..01f899c8198 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -19,20 +19,73 @@ import { trackExpressCheckoutButtonLoad, } from './tracking'; -// Used to control if we need to refresh the cart/checkout information when ECE is dismissed. -let wasShippingInfoUpdated = false; +const updateBlocksShippingUI = ( eventAddress ) => { + console.log( 'TODO: implement update_checkout' ); +}; + +const updateShortcodeShippingUI = ( eventAddress ) => { + const context = getExpressCheckoutData( 'button_context' ); + // const mapFields = { + // shipping_city: 'city', + // shipping_state: 'state', + // shipping_postcode: 'postcode', + // country: 'country', + // }; + const address = normalizeShippingAddress( eventAddress ); + + if ( context === 'cart' ) { + Object.keys( address ).forEach( ( key ) => { + if ( + address[ key ] && + document.querySelector( + `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` + ) + ) { + document.querySelector( + `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` + ).value = address[ key ]; + } else { + console.error( + `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` + ); + console.error( address[ key ] ); + } + } ); + } +}; + +const onShippingRatesCalculated = ( eventAddress, response ) => { + console.log( eventAddress, response ); + + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + console.log( context, isBlocks ); + + if ( ! [ 'cart', 'checkout' ].includes( context ) ) return; + + if ( isBlocks ) { + updateBlocksShippingUI( eventAddress ); + } else { + console.log( 'onShippingRatesCalculated shortcode: ', eventAddress ); + updateShortcodeShippingUI( eventAddress ); + } +}; export const shippingAddressChangeHandler = async ( api, event, elements ) => { + console.log( event ); try { const response = await api.expressCheckoutECECalculateShippingOptions( normalizeShippingAddress( event.address ) ); if ( response.result === 'success' ) { - wasShippingInfoUpdated = true; elements.update( { amount: response.total.amount, } ); + + onShippingRatesCalculated( event.address, response ); + event.resolve( { shippingRates: response.shipping_options, lineItems: normalizeLineItems( response.displayItems ), @@ -41,6 +94,7 @@ export const shippingAddressChangeHandler = async ( api, event, elements ) => { event.reject(); } } catch ( e ) { + console.error( e ); event.reject(); } }; @@ -52,7 +106,6 @@ export const shippingRateChangeHandler = async ( api, event, elements ) => { ); if ( response.result === 'success' ) { - wasShippingInfoUpdated = true; elements.update( { amount: response.total.amount } ); event.resolve( { lineItems: normalizeLineItems( response.displayItems ), @@ -176,14 +229,21 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - const context = getExpressCheckoutData( 'button_context' ); - if ( - wasShippingInfoUpdated && - [ 'cart', 'checkout' ].includes( context ) - ) { - location.reload( true ); - } - - wasShippingInfoUpdated = false; + // + // if ( + // wasShippingInfoUpdated && + // [ 'cart', 'checkout' ].includes( context ) + // ) { + // jQuery('body').trigger('update_checkout'); + // alert(); + // // location.reload( true ); + // } + + // wasShippingInfoUpdated = false; + document + .querySelector( + 'form.woocommerce-shipping-calculator [name="calc_shipping"]' + ) + ?.click(); unblockUI(); }; From 41d527c9eb9e98f4bce114891a33f82fab608bc9 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 15:10:48 -0300 Subject: [PATCH 06/31] remove unused comment --- client/express-checkout/event-handlers.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 01f899c8198..d910205412f 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -25,12 +25,6 @@ const updateBlocksShippingUI = ( eventAddress ) => { const updateShortcodeShippingUI = ( eventAddress ) => { const context = getExpressCheckoutData( 'button_context' ); - // const mapFields = { - // shipping_city: 'city', - // shipping_state: 'state', - // shipping_postcode: 'postcode', - // country: 'country', - // }; const address = normalizeShippingAddress( eventAddress ); if ( context === 'cart' ) { @@ -240,6 +234,9 @@ export const onCancelHandler = () => { // } // wasShippingInfoUpdated = false; + + // TODO: refine logic to click on this button. It's only available in the shortcode cart. + // Information is already updated in the backend when Payment sheet is opened so no reason to bother to only trigger after changes. document .querySelector( 'form.woocommerce-shipping-calculator [name="calc_shipping"]' From 46defc4efc430d136195a69f856479a503caf952 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 17:06:24 -0300 Subject: [PATCH 07/31] create helper to interact with shortcode fields --- .../utils/shortcodeCheckout.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 client/express-checkout/utils/shortcodeCheckout.js diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js new file mode 100644 index 00000000000..b52bd75532d --- /dev/null +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -0,0 +1,58 @@ +/* global jQuery */ +/** + * External dependencies + */ + +/** + * Internal dependencies + */ +import { normalizeShippingAddress, getExpressCheckoutData } from './'; + +export const updateShortcodeShippingUI = ( eventAddress ) => { + const context = getExpressCheckoutData( 'button_context' ); + const address = normalizeShippingAddress( eventAddress ); + + const keys = [ 'country', 'state', 'city', 'postcode' ]; + + if ( context === 'cart' ) { + keys.forEach( ( key ) => { + const field = document.querySelector( + `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` + ); + if ( address[ key ] && field ) { + field.value = address[ key ]; + } else { + console.error( + `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` + ); + console.error( address[ key ] ); + } + } ); + document + .querySelector( + 'form.woocommerce-shipping-calculator [name="calc_shipping"]' + ) + ?.click(); + } else if ( context === 'checkout' ) { + // TODO: because of select2, we will need to just update the fields when the operation is cancelled... + keys.forEach( ( key ) => { + const field = document.querySelector( + `form.woocommerce-checkout [name="billing_${ key }"]` + ); + if ( address[ key ] && field ) { + field.value = address[ key ]; + + if ( [ 'country', 'state' ].includes( key ) ) { + jQuery( field ).trigger( 'change' ).trigger( 'close' ); + } else { + field.dispatchEvent( new Event( 'change' ) ); + } + } else { + console.error( + `form.woocommerce-checkout [name="billing_${ key }"]` + ); + console.error( address[ key ] ); + } + } ); + } +}; From 0db8da6d8639d97f8bea359dd521d7a89012b957 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 17:07:36 -0300 Subject: [PATCH 08/31] Only update UI in the cancel event --- client/express-checkout/event-handlers.js | 65 +++++++---------------- 1 file changed, 20 insertions(+), 45 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index d910205412f..3e045cb7352 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -13,42 +13,21 @@ import { normalizeShippingAddress, normalizeLineItems, getExpressCheckoutData, + updateShortcodeShippingUI, } from './utils'; import { trackExpressCheckoutButtonClick, trackExpressCheckoutButtonLoad, } from './tracking'; +let lastSelectedAddress = null; + const updateBlocksShippingUI = ( eventAddress ) => { console.log( 'TODO: implement update_checkout' ); }; -const updateShortcodeShippingUI = ( eventAddress ) => { - const context = getExpressCheckoutData( 'button_context' ); - const address = normalizeShippingAddress( eventAddress ); - - if ( context === 'cart' ) { - Object.keys( address ).forEach( ( key ) => { - if ( - address[ key ] && - document.querySelector( - `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` - ) - ) { - document.querySelector( - `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` - ).value = address[ key ]; - } else { - console.error( - `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` - ); - console.error( address[ key ] ); - } - } ); - } -}; - const onShippingRatesCalculated = ( eventAddress, response ) => { + lastSelectedAddress = eventAddress; console.log( eventAddress, response ); const context = getExpressCheckoutData( 'button_context' ); @@ -62,7 +41,7 @@ const onShippingRatesCalculated = ( eventAddress, response ) => { updateBlocksShippingUI( eventAddress ); } else { console.log( 'onShippingRatesCalculated shortcode: ', eventAddress ); - updateShortcodeShippingUI( eventAddress ); + // updateShortcodeShippingUI( eventAddress ); } }; @@ -223,24 +202,20 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - // - // if ( - // wasShippingInfoUpdated && - // [ 'cart', 'checkout' ].includes( context ) - // ) { - // jQuery('body').trigger('update_checkout'); - // alert(); - // // location.reload( true ); - // } - - // wasShippingInfoUpdated = false; - - // TODO: refine logic to click on this button. It's only available in the shortcode cart. - // Information is already updated in the backend when Payment sheet is opened so no reason to bother to only trigger after changes. - document - .querySelector( - 'form.woocommerce-shipping-calculator [name="calc_shipping"]' - ) - ?.click(); + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + console.log( context, isBlocks ); + + if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress ) + return; + + if ( isBlocks ) { + // updateBlocksShippingUI( eventAddress ); + } else { + console.log( 'onShippingRatesCalculated shortcode: ', lastSelectedAddress ); + updateShortcodeShippingUI( lastSelectedAddress ); + } + unblockUI(); }; From 84ced5a497de0fa593c4aa39a3a5f893d3566c2b Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 17:14:13 -0300 Subject: [PATCH 09/31] Add shortcodeCheckout to utils index --- client/express-checkout/utils/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client/express-checkout/utils/index.ts b/client/express-checkout/utils/index.ts index cfbc2b25b2b..e1a45ff1409 100644 --- a/client/express-checkout/utils/index.ts +++ b/client/express-checkout/utils/index.ts @@ -2,6 +2,7 @@ * Internal dependencies */ export * from './normalize'; +export * from './shortcodeCheckout'; import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; interface MyWindow extends Window { From ee2b1d2afbca95291dd48780760fe8ee6a8287cd Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 18:35:15 -0300 Subject: [PATCH 10/31] use select2 triggers for cart interactions --- client/express-checkout/utils/shortcodeCheckout.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js index b52bd75532d..61c965393fd 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -21,6 +21,11 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { ); if ( address[ key ] && field ) { field.value = address[ key ]; + if ( [ 'country', 'state' ].includes( key ) ) { + jQuery( field ).trigger( 'change' ).trigger( 'close' ); + } else { + field.dispatchEvent( new Event( 'change' ) ); + } } else { console.error( `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` From eaf650d42b6e4e1354974a9ea3fe8812a65a5eff Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Thu, 12 Dec 2024 18:51:36 -0300 Subject: [PATCH 11/31] Update shipping addr on blocks cart and checkout --- client/express-checkout/event-handlers.js | 25 +++---------------- .../utils/shortcodeCheckout.js | 7 ++++++ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 3e045cb7352..3f8d24fb9db 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -13,6 +13,7 @@ import { normalizeShippingAddress, normalizeLineItems, getExpressCheckoutData, + updateBlocksShippingUI, updateShortcodeShippingUI, } from './utils'; import { @@ -22,27 +23,8 @@ import { let lastSelectedAddress = null; -const updateBlocksShippingUI = ( eventAddress ) => { - console.log( 'TODO: implement update_checkout' ); -}; - -const onShippingRatesCalculated = ( eventAddress, response ) => { +const onShippingRatesCalculated = ( eventAddress ) => { lastSelectedAddress = eventAddress; - console.log( eventAddress, response ); - - const context = getExpressCheckoutData( 'button_context' ); - const isBlocks = getExpressCheckoutData( 'has_block' ); - - console.log( context, isBlocks ); - - if ( ! [ 'cart', 'checkout' ].includes( context ) ) return; - - if ( isBlocks ) { - updateBlocksShippingUI( eventAddress ); - } else { - console.log( 'onShippingRatesCalculated shortcode: ', eventAddress ); - // updateShortcodeShippingUI( eventAddress ); - } }; export const shippingAddressChangeHandler = async ( api, event, elements ) => { @@ -211,9 +193,8 @@ export const onCancelHandler = () => { return; if ( isBlocks ) { - // updateBlocksShippingUI( eventAddress ); + updateBlocksShippingUI( lastSelectedAddress ); } else { - console.log( 'onShippingRatesCalculated shortcode: ', lastSelectedAddress ); updateShortcodeShippingUI( lastSelectedAddress ); } diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js index 61c965393fd..20df10a0308 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -8,6 +8,13 @@ */ import { normalizeShippingAddress, getExpressCheckoutData } from './'; +export const updateBlocksShippingUI = ( eventAddress ) => { + console.log( 'updateBlocksShippingUI' ); + const address = normalizeShippingAddress( eventAddress ); + + wp.data.dispatch( 'wc/store/cart' ).setShippingAddress( address ); +}; + export const updateShortcodeShippingUI = ( eventAddress ) => { const context = getExpressCheckoutData( 'button_context' ); const address = normalizeShippingAddress( eventAddress ); From c04f201e53abb39a69a289923dc4648dcc968d21 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Sun, 15 Dec 2024 22:47:17 -0300 Subject: [PATCH 12/31] Remove console statements --- client/express-checkout/event-handlers.js | 4 ---- client/express-checkout/utils/shortcodeCheckout.js | 11 ----------- 2 files changed, 15 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 3f8d24fb9db..a763db40a42 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -28,7 +28,6 @@ const onShippingRatesCalculated = ( eventAddress ) => { }; export const shippingAddressChangeHandler = async ( api, event, elements ) => { - console.log( event ); try { const response = await api.expressCheckoutECECalculateShippingOptions( normalizeShippingAddress( event.address ) @@ -49,7 +48,6 @@ export const shippingAddressChangeHandler = async ( api, event, elements ) => { event.reject(); } } catch ( e ) { - console.error( e ); event.reject(); } }; @@ -187,8 +185,6 @@ export const onCancelHandler = () => { const context = getExpressCheckoutData( 'button_context' ); const isBlocks = getExpressCheckoutData( 'has_block' ); - console.log( context, isBlocks ); - if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress ) return; diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js index 20df10a0308..f55cee9f21f 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -9,7 +9,6 @@ import { normalizeShippingAddress, getExpressCheckoutData } from './'; export const updateBlocksShippingUI = ( eventAddress ) => { - console.log( 'updateBlocksShippingUI' ); const address = normalizeShippingAddress( eventAddress ); wp.data.dispatch( 'wc/store/cart' ).setShippingAddress( address ); @@ -33,11 +32,6 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { } else { field.dispatchEvent( new Event( 'change' ) ); } - } else { - console.error( - `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` - ); - console.error( address[ key ] ); } } ); document @@ -59,11 +53,6 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { } else { field.dispatchEvent( new Event( 'change' ) ); } - } else { - console.error( - `form.woocommerce-checkout [name="billing_${ key }"]` - ); - console.error( address[ key ] ); } } ); } From 752a88e8756971a9d57f78e4a398418bfa505e6e Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Sun, 15 Dec 2024 22:50:08 -0300 Subject: [PATCH 13/31] Remove todo comment and add check for cart data store --- client/express-checkout/utils/shortcodeCheckout.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js index f55cee9f21f..39164acf168 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -9,9 +9,9 @@ import { normalizeShippingAddress, getExpressCheckoutData } from './'; export const updateBlocksShippingUI = ( eventAddress ) => { - const address = normalizeShippingAddress( eventAddress ); - - wp.data.dispatch( 'wc/store/cart' ).setShippingAddress( address ); + wp?.data + ?.dispatch( 'wc/store/cart' ) + ?.setShippingAddress( normalizeShippingAddress( eventAddress ) ); }; export const updateShortcodeShippingUI = ( eventAddress ) => { @@ -40,7 +40,6 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { ) ?.click(); } else if ( context === 'checkout' ) { - // TODO: because of select2, we will need to just update the fields when the operation is cancelled... keys.forEach( ( key ) => { const field = document.querySelector( `form.woocommerce-checkout [name="billing_${ key }"]` From 7d8c479ff2d483b42e157fab07890b353e1fca72 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 00:04:48 -0300 Subject: [PATCH 14/31] Remove code redundancy --- .../utils/shortcodeCheckout.js | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/shortcodeCheckout.js index 39164acf168..ffe4817a9e9 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/shortcodeCheckout.js @@ -8,6 +8,17 @@ */ import { normalizeShippingAddress, getExpressCheckoutData } from './'; +const updateShortcodeField = ( formSelector, fieldName, value ) => { + const field = document.querySelector( + `${ formSelector } [name="${ fieldName }"]` + ); + if ( ! field ) { + return; + } + field.value = value; + jQuery( field ).trigger( 'change' ).trigger( 'close' ); +}; + export const updateBlocksShippingUI = ( eventAddress ) => { wp?.data ?.dispatch( 'wc/store/cart' ) @@ -22,16 +33,12 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { if ( context === 'cart' ) { keys.forEach( ( key ) => { - const field = document.querySelector( - `form.woocommerce-shipping-calculator [name="calc_shipping_${ key }"]` - ); - if ( address[ key ] && field ) { - field.value = address[ key ]; - if ( [ 'country', 'state' ].includes( key ) ) { - jQuery( field ).trigger( 'change' ).trigger( 'close' ); - } else { - field.dispatchEvent( new Event( 'change' ) ); - } + if ( address[ key ] ) { + updateShortcodeField( + 'form.woocommerce-shipping-calculator', + `calc_shipping_${ key }`, + address[ key ] + ); } } ); document @@ -41,17 +48,12 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { ?.click(); } else if ( context === 'checkout' ) { keys.forEach( ( key ) => { - const field = document.querySelector( - `form.woocommerce-checkout [name="billing_${ key }"]` - ); - if ( address[ key ] && field ) { - field.value = address[ key ]; - - if ( [ 'country', 'state' ].includes( key ) ) { - jQuery( field ).trigger( 'change' ).trigger( 'close' ); - } else { - field.dispatchEvent( new Event( 'change' ) ); - } + if ( address[ key ] ) { + updateShortcodeField( + 'form.woocommerce-checkout', + `billing_${ key }`, + address[ key ] + ); } } ); } From b399fb69c771a737379db970dce98f4a73164368 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 00:06:43 -0300 Subject: [PATCH 15/31] Simplify assignment of last addr --- client/express-checkout/event-handlers.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index a763db40a42..9b7c038fa7a 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -23,10 +23,6 @@ import { let lastSelectedAddress = null; -const onShippingRatesCalculated = ( eventAddress ) => { - lastSelectedAddress = eventAddress; -}; - export const shippingAddressChangeHandler = async ( api, event, elements ) => { try { const response = await api.expressCheckoutECECalculateShippingOptions( @@ -38,7 +34,7 @@ export const shippingAddressChangeHandler = async ( api, event, elements ) => { amount: response.total.amount, } ); - onShippingRatesCalculated( event.address, response ); + lastSelectedAddress = event.address; event.resolve( { shippingRates: response.shipping_options, From e57f86aad3d881da9ea4b71b131286c5d27dc694 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 00:07:47 -0300 Subject: [PATCH 16/31] Rename utils file --- .../utils/{shortcodeCheckout.js => checkout.js} | 2 +- client/express-checkout/utils/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename client/express-checkout/utils/{shortcodeCheckout.js => checkout.js} (99%) diff --git a/client/express-checkout/utils/shortcodeCheckout.js b/client/express-checkout/utils/checkout.js similarity index 99% rename from client/express-checkout/utils/shortcodeCheckout.js rename to client/express-checkout/utils/checkout.js index ffe4817a9e9..f761359cdd7 100644 --- a/client/express-checkout/utils/shortcodeCheckout.js +++ b/client/express-checkout/utils/checkout.js @@ -6,7 +6,7 @@ /** * Internal dependencies */ -import { normalizeShippingAddress, getExpressCheckoutData } from './'; +import { normalizeShippingAddress, getExpressCheckoutData } from '.'; const updateShortcodeField = ( formSelector, fieldName, value ) => { const field = document.querySelector( diff --git a/client/express-checkout/utils/index.ts b/client/express-checkout/utils/index.ts index e1a45ff1409..1b4e372043f 100644 --- a/client/express-checkout/utils/index.ts +++ b/client/express-checkout/utils/index.ts @@ -2,7 +2,7 @@ * Internal dependencies */ export * from './normalize'; -export * from './shortcodeCheckout'; +export * from './checkout'; import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; interface MyWindow extends Window { From 5ca6d0829e03c8237a172f54ab7406f845b69dcc Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 00:09:05 -0300 Subject: [PATCH 17/31] Simplify null check in updateShortcodeField --- client/express-checkout/utils/checkout.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/express-checkout/utils/checkout.js b/client/express-checkout/utils/checkout.js index f761359cdd7..8ecd4e5ed7b 100644 --- a/client/express-checkout/utils/checkout.js +++ b/client/express-checkout/utils/checkout.js @@ -12,11 +12,10 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { const field = document.querySelector( `${ formSelector } [name="${ fieldName }"]` ); - if ( ! field ) { - return; + if ( field ) { + field.value = value; + jQuery( field ).trigger( 'change' ).trigger( 'close' ); } - field.value = value; - jQuery( field ).trigger( 'change' ).trigger( 'close' ); }; export const updateBlocksShippingUI = ( eventAddress ) => { From 0e665d73a657677377233f1cafc14467e11e0ea4 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 01:15:35 -0300 Subject: [PATCH 18/31] Add doc to new functions --- client/express-checkout/utils/checkout.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/express-checkout/utils/checkout.js b/client/express-checkout/utils/checkout.js index 8ecd4e5ed7b..a845fa57e32 100644 --- a/client/express-checkout/utils/checkout.js +++ b/client/express-checkout/utils/checkout.js @@ -18,12 +18,22 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { } }; +/** + * Updates the WooCommerce Blocks shipping UI to reflect a new shipping address. + * + * @param {Object} eventAddress - The shipping address returned by the payment event. + */ export const updateBlocksShippingUI = ( eventAddress ) => { wp?.data ?.dispatch( 'wc/store/cart' ) ?.setShippingAddress( normalizeShippingAddress( eventAddress ) ); }; +/** + * Updates the WooCommerce shortcode cart/checkout shipping UI to reflect a new shipping address. + * + * @param {Object} eventAddress - The shipping address returned by the payment event. + */ export const updateShortcodeShippingUI = ( eventAddress ) => { const context = getExpressCheckoutData( 'button_context' ); const address = normalizeShippingAddress( eventAddress ); From f68ea839d23f85d661e6f18883e9fed633f2a1ee Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 01:16:34 -0300 Subject: [PATCH 19/31] Rename util --- client/express-checkout/utils/index.ts | 2 +- .../express-checkout/utils/{checkout.js => shipping-fields.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename client/express-checkout/utils/{checkout.js => shipping-fields.js} (100%) diff --git a/client/express-checkout/utils/index.ts b/client/express-checkout/utils/index.ts index 866337d794c..3fcb6286071 100644 --- a/client/express-checkout/utils/index.ts +++ b/client/express-checkout/utils/index.ts @@ -2,7 +2,7 @@ * Internal dependencies */ export * from './normalize'; -export * from './checkout'; +export * from './shipping-fields'; import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; interface MyWindow extends Window { diff --git a/client/express-checkout/utils/checkout.js b/client/express-checkout/utils/shipping-fields.js similarity index 100% rename from client/express-checkout/utils/checkout.js rename to client/express-checkout/utils/shipping-fields.js From b5a0e47a4e09ed30f89b29a8e309b959e824676e Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 01:18:35 -0300 Subject: [PATCH 20/31] Add reset to lastSelectedAddress in the onCancelHandler --- client/express-checkout/event-handlers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 9b7c038fa7a..98ce8833035 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -190,5 +190,6 @@ export const onCancelHandler = () => { updateShortcodeShippingUI( lastSelectedAddress ); } + lastSelectedAddress = null; unblockUI(); }; From 1831e70996aeb768f5a049c2568f6dd1f6924403 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 11:12:30 -0300 Subject: [PATCH 21/31] Add doc for updateShortcodeField --- client/express-checkout/utils/shipping-fields.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index a845fa57e32..a76ba8d8a21 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -8,6 +8,13 @@ */ import { normalizeShippingAddress, getExpressCheckoutData } from '.'; +/* + * Updates a field in a form with a new value. + * + * @param {String} formSelector - The selector for the form containing the field. + * @param {Object} fieldName - The name of the field to update. + * @param {Object} value - The new value for the field. + */ const updateShortcodeField = ( formSelector, fieldName, value ) => { const field = document.querySelector( `${ formSelector } [name="${ fieldName }"]` From 64f118e5361449e4fb2342082d38cef1b3a7fd33 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 11:17:13 -0300 Subject: [PATCH 22/31] Add implementation for tokenized express checkout --- .../event-handlers.js | 24 +++++- .../tokenized-express-checkout/utils/index.ts | 1 + .../utils/shipping-fields.js | 76 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 client/tokenized-express-checkout/utils/shipping-fields.js diff --git a/client/tokenized-express-checkout/event-handlers.js b/client/tokenized-express-checkout/event-handlers.js index 12ec2513cc7..7611ebc2e56 100644 --- a/client/tokenized-express-checkout/event-handlers.js +++ b/client/tokenized-express-checkout/event-handlers.js @@ -8,7 +8,12 @@ import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies */ -import { getErrorMessageFromNotice, getExpressCheckoutData } from './utils'; +import { + getErrorMessageFromNotice, + getExpressCheckoutData, + updateBlocksShippingUI, + updateShortcodeShippingUI, +} from './utils'; import { trackExpressCheckoutButtonClick, trackExpressCheckoutButtonLoad, @@ -24,6 +29,7 @@ import { transformPrice, } from './transformers/wc-to-stripe'; +let lastSelectedAddress = null; let cartApi = new ExpressCheckoutCartApi(); export const setCartApiHandler = ( handler ) => ( cartApi = handler ); export const getCartApiHandler = () => cartApi; @@ -56,6 +62,9 @@ export const shippingAddressChangeHandler = async ( event, elements ) => { cartData.totals ), } ); + + lastSelectedAddress = event.address; + event.resolve( { shippingRates: transformCartDataForShippingRates( cartData ), lineItems: transformCartDataForDisplayItems( cartData ), @@ -216,5 +225,18 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress ) + return; + + if ( isBlocks ) { + updateBlocksShippingUI( lastSelectedAddress ); + } else { + updateShortcodeShippingUI( lastSelectedAddress ); + } + + lastSelectedAddress = null; unblockUI(); }; diff --git a/client/tokenized-express-checkout/utils/index.ts b/client/tokenized-express-checkout/utils/index.ts index 98ee8b90091..bae962363b2 100644 --- a/client/tokenized-express-checkout/utils/index.ts +++ b/client/tokenized-express-checkout/utils/index.ts @@ -3,6 +3,7 @@ */ import { WCPayExpressCheckoutParams } from 'wcpay/express-checkout/utils'; export * from './normalize'; +export * from './shipping-fields'; import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; export const getExpressCheckoutData = < diff --git a/client/tokenized-express-checkout/utils/shipping-fields.js b/client/tokenized-express-checkout/utils/shipping-fields.js new file mode 100644 index 00000000000..a76ba8d8a21 --- /dev/null +++ b/client/tokenized-express-checkout/utils/shipping-fields.js @@ -0,0 +1,76 @@ +/* global jQuery */ +/** + * External dependencies + */ + +/** + * Internal dependencies + */ +import { normalizeShippingAddress, getExpressCheckoutData } from '.'; + +/* + * Updates a field in a form with a new value. + * + * @param {String} formSelector - The selector for the form containing the field. + * @param {Object} fieldName - The name of the field to update. + * @param {Object} value - The new value for the field. + */ +const updateShortcodeField = ( formSelector, fieldName, value ) => { + const field = document.querySelector( + `${ formSelector } [name="${ fieldName }"]` + ); + if ( field ) { + field.value = value; + jQuery( field ).trigger( 'change' ).trigger( 'close' ); + } +}; + +/** + * Updates the WooCommerce Blocks shipping UI to reflect a new shipping address. + * + * @param {Object} eventAddress - The shipping address returned by the payment event. + */ +export const updateBlocksShippingUI = ( eventAddress ) => { + wp?.data + ?.dispatch( 'wc/store/cart' ) + ?.setShippingAddress( normalizeShippingAddress( eventAddress ) ); +}; + +/** + * Updates the WooCommerce shortcode cart/checkout shipping UI to reflect a new shipping address. + * + * @param {Object} eventAddress - The shipping address returned by the payment event. + */ +export const updateShortcodeShippingUI = ( eventAddress ) => { + const context = getExpressCheckoutData( 'button_context' ); + const address = normalizeShippingAddress( eventAddress ); + + const keys = [ 'country', 'state', 'city', 'postcode' ]; + + if ( context === 'cart' ) { + keys.forEach( ( key ) => { + if ( address[ key ] ) { + updateShortcodeField( + 'form.woocommerce-shipping-calculator', + `calc_shipping_${ key }`, + address[ key ] + ); + } + } ); + document + .querySelector( + 'form.woocommerce-shipping-calculator [name="calc_shipping"]' + ) + ?.click(); + } else if ( context === 'checkout' ) { + keys.forEach( ( key ) => { + if ( address[ key ] ) { + updateShortcodeField( + 'form.woocommerce-checkout', + `billing_${ key }`, + address[ key ] + ); + } + } ); + } +}; From 86f69cf462a75105fd727dce258dc47875ebc4ad Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 18:27:58 -0300 Subject: [PATCH 23/31] Remove update for CA and GB addresses --- client/express-checkout/event-handlers.js | 17 ++++++++++------- .../event-handlers.js | 8 +++++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 98ce8833035..2353219a752 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -181,13 +181,16 @@ export const onCancelHandler = () => { const context = getExpressCheckoutData( 'button_context' ); const isBlocks = getExpressCheckoutData( 'has_block' ); - if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress ) - return; - - if ( isBlocks ) { - updateBlocksShippingUI( lastSelectedAddress ); - } else { - updateShortcodeShippingUI( lastSelectedAddress ); + if ( + [ 'cart', 'checkout' ].includes( context ) && + lastSelectedAddress && + ! [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) + ) { + if ( isBlocks ) { + updateBlocksShippingUI( lastSelectedAddress ); + } else { + updateShortcodeShippingUI( lastSelectedAddress ); + } } lastSelectedAddress = null; diff --git a/client/tokenized-express-checkout/event-handlers.js b/client/tokenized-express-checkout/event-handlers.js index 7611ebc2e56..d287d8b7e9c 100644 --- a/client/tokenized-express-checkout/event-handlers.js +++ b/client/tokenized-express-checkout/event-handlers.js @@ -228,8 +228,14 @@ export const onCancelHandler = () => { const context = getExpressCheckoutData( 'button_context' ); const isBlocks = getExpressCheckoutData( 'has_block' ); - if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress ) + if ( + ! [ 'cart', 'checkout' ].includes( context ) || + ! lastSelectedAddress || + [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) + ) { + unblockUI(); return; + } if ( isBlocks ) { updateBlocksShippingUI( lastSelectedAddress ); From c0728be1351e74c7c900f69dbacc725dba86dac6 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 18:30:48 -0300 Subject: [PATCH 24/31] Add comment to clarify why CA and UK addresses are not included --- client/express-checkout/event-handlers.js | 5 +++++ client/tokenized-express-checkout/event-handlers.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index 2353219a752..e6612c10b2f 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -181,6 +181,11 @@ export const onCancelHandler = () => { const context = getExpressCheckoutData( 'button_context' ); const isBlocks = getExpressCheckoutData( 'has_block' ); + /* + * CA and GB addresses are redacted and are causing errors until WooCommerce is able to + * handle redacted addresses. + * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress + */ if ( [ 'cart', 'checkout' ].includes( context ) && lastSelectedAddress && diff --git a/client/tokenized-express-checkout/event-handlers.js b/client/tokenized-express-checkout/event-handlers.js index d287d8b7e9c..e36214175e3 100644 --- a/client/tokenized-express-checkout/event-handlers.js +++ b/client/tokenized-express-checkout/event-handlers.js @@ -228,6 +228,11 @@ export const onCancelHandler = () => { const context = getExpressCheckoutData( 'button_context' ); const isBlocks = getExpressCheckoutData( 'has_block' ); + /* + * CA and GB addresses are redacted and are causing errors until WooCommerce is able to + * handle redacted addresses. + * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress + */ if ( ! [ 'cart', 'checkout' ].includes( context ) || ! lastSelectedAddress || From ce9aa797c72a236265614b59c007a8cdb8e9ff63 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Mon, 16 Dec 2024 18:32:40 -0300 Subject: [PATCH 25/31] Mirror code for tokenized ece --- .../event-handlers.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/client/tokenized-express-checkout/event-handlers.js b/client/tokenized-express-checkout/event-handlers.js index e36214175e3..740bc554eee 100644 --- a/client/tokenized-express-checkout/event-handlers.js +++ b/client/tokenized-express-checkout/event-handlers.js @@ -234,18 +234,15 @@ export const onCancelHandler = () => { * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress */ if ( - ! [ 'cart', 'checkout' ].includes( context ) || - ! lastSelectedAddress || - [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) + [ 'cart', 'checkout' ].includes( context ) && + lastSelectedAddress && + ! [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) ) { - unblockUI(); - return; - } - - if ( isBlocks ) { - updateBlocksShippingUI( lastSelectedAddress ); - } else { - updateShortcodeShippingUI( lastSelectedAddress ); + if ( isBlocks ) { + updateBlocksShippingUI( lastSelectedAddress ); + } else { + updateShortcodeShippingUI( lastSelectedAddress ); + } } lastSelectedAddress = null; From b47ab71b09850fd1ec924368919d1f1f2423a714 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 09:25:16 -0300 Subject: [PATCH 26/31] Refactor logic to determine countries with redacted addresses --- client/express-checkout/event-handlers.js | 24 ++-------- .../express-checkout/utils/shipping-fields.js | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/client/express-checkout/event-handlers.js b/client/express-checkout/event-handlers.js index e6612c10b2f..3c59d456251 100644 --- a/client/express-checkout/event-handlers.js +++ b/client/express-checkout/event-handlers.js @@ -13,8 +13,7 @@ import { normalizeShippingAddress, normalizeLineItems, getExpressCheckoutData, - updateBlocksShippingUI, - updateShortcodeShippingUI, + updateShippingAddressUI, } from './utils'; import { trackExpressCheckoutButtonClick, @@ -178,26 +177,9 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - const context = getExpressCheckoutData( 'button_context' ); - const isBlocks = getExpressCheckoutData( 'has_block' ); - - /* - * CA and GB addresses are redacted and are causing errors until WooCommerce is able to - * handle redacted addresses. - * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress - */ - if ( - [ 'cart', 'checkout' ].includes( context ) && - lastSelectedAddress && - ! [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) - ) { - if ( isBlocks ) { - updateBlocksShippingUI( lastSelectedAddress ); - } else { - updateShortcodeShippingUI( lastSelectedAddress ); - } + if ( lastSelectedAddress ) { + updateShippingAddressUI( lastSelectedAddress ); } - lastSelectedAddress = null; unblockUI(); }; diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index a76ba8d8a21..b7c8301ef1a 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -8,6 +8,20 @@ */ import { normalizeShippingAddress, getExpressCheckoutData } from '.'; +/** + * Checks if the intermediate address is redacted for the given country. + * CA and GB addresses are redacted and are causing errors until WooCommerce is able to + * handle redacted addresses. + * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress + * + * @param {string} country - The country code. + * + * @return {boolean} True if the postcode is redacted for the country, false otherwise. + */ +const isPostcodeRedactedForCountry = ( country ) => { + return country.length === 2 && [ 'CA', 'GB' ].includes( country ); +}; + /* * Updates a field in a form with a new value. * @@ -30,7 +44,7 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { * * @param {Object} eventAddress - The shipping address returned by the payment event. */ -export const updateBlocksShippingUI = ( eventAddress ) => { +const updateBlocksShippingUI = ( eventAddress ) => { wp?.data ?.dispatch( 'wc/store/cart' ) ?.setShippingAddress( normalizeShippingAddress( eventAddress ) ); @@ -41,7 +55,7 @@ export const updateBlocksShippingUI = ( eventAddress ) => { * * @param {Object} eventAddress - The shipping address returned by the payment event. */ -export const updateShortcodeShippingUI = ( eventAddress ) => { +const updateShortcodeShippingUI = ( eventAddress ) => { const context = getExpressCheckoutData( 'button_context' ); const address = normalizeShippingAddress( eventAddress ); @@ -74,3 +88,31 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { } ); } }; + +/** + * Updates the WooCommerce shipping UI to reflect a new shipping address. + * + * Determines the current context (cart or checkout) and updates either + * WooCommerce Blocks or shortcode-based shipping forms, if applicable. + * + * @param {Object} newAddress - The new shipping address object returned by the payment event. + * @param {string} newAddress.country - The country code of the shipping address. + * @param {string} [newAddress.state] - The state/province of the shipping address. + * @param {string} [newAddress.city] - The city of the shipping address. + * @param {string} [newAddress.postcode] - The postal/ZIP code of the shipping address. + */ +export const updateShippingAddressUI = ( newAddress ) => { + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + if ( + [ 'cart', 'checkout' ].includes( context ) && + ! isPostcodeRedactedForCountry( newAddress.country ) + ) { + if ( isBlocks ) { + updateBlocksShippingUI( newAddress ); + } else { + updateShortcodeShippingUI( newAddress ); + } + } +}; From 08d18fcbe1a5d0c09749708d0bea8c5c1c834ba4 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 11:05:24 -0300 Subject: [PATCH 27/31] Add logic to fallback to option text when value is not found --- .../express-checkout/utils/shipping-fields.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index b7c8301ef1a..a9e7deb54f3 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -33,9 +33,24 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { const field = document.querySelector( `${ formSelector } [name="${ fieldName }"]` ); - if ( field ) { + + if ( ! field ) return; + + // Check if the field is a dropdown (country/state). + if ( field.tagName === 'SELECT' && /country|state/.test( fieldName ) ) { + const options = Array.from( field.options ); + const match = options.find( + ( opt ) => opt.value === value || opt.textContent.trim() === value + ); + + if ( match ) { + field.value = match.value; + jQuery( field ).trigger( 'change' ).trigger( 'close' ); + } + } else { + // Default behavior for text inputs. field.value = value; - jQuery( field ).trigger( 'change' ).trigger( 'close' ); + jQuery( field ).trigger( 'change' ); } }; From 42dad17e9ec1f9ad725f807bc2a531257f36f2e3 Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 11:09:58 -0300 Subject: [PATCH 28/31] Remove comment for external dependencies --- client/express-checkout/utils/shipping-fields.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index a9e7deb54f3..4dc1951a37d 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -1,8 +1,4 @@ /* global jQuery */ -/** - * External dependencies - */ - /** * Internal dependencies */ From ec81858bf9af96bc8e1e94185343abab12ae8eda Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 11:13:59 -0300 Subject: [PATCH 29/31] Fix comparison to be case-insensitive. --- client/express-checkout/utils/shipping-fields.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index 4dc1951a37d..cc26eb2c096 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -36,7 +36,9 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { if ( field.tagName === 'SELECT' && /country|state/.test( fieldName ) ) { const options = Array.from( field.options ); const match = options.find( - ( opt ) => opt.value === value || opt.textContent.trim() === value + ( opt ) => + opt.value === value || + opt.textContent.trim().toLowerCase() === value.toLowerCase() ); if ( match ) { From 80f40dccf12f743e08b449e66b8ebfb3339952df Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 14:53:39 -0300 Subject: [PATCH 30/31] Copy changes to tokenized carts. --- .../event-handlers.js | 24 +------ .../utils/shipping-fields.js | 69 +++++++++++++++++-- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/client/tokenized-express-checkout/event-handlers.js b/client/tokenized-express-checkout/event-handlers.js index 740bc554eee..db2bc4c2c3e 100644 --- a/client/tokenized-express-checkout/event-handlers.js +++ b/client/tokenized-express-checkout/event-handlers.js @@ -11,8 +11,7 @@ import { applyFilters } from '@wordpress/hooks'; import { getErrorMessageFromNotice, getExpressCheckoutData, - updateBlocksShippingUI, - updateShortcodeShippingUI, + updateShippingAddressUI, } from './utils'; import { trackExpressCheckoutButtonClick, @@ -225,26 +224,9 @@ export const onCompletePaymentHandler = () => { }; export const onCancelHandler = () => { - const context = getExpressCheckoutData( 'button_context' ); - const isBlocks = getExpressCheckoutData( 'has_block' ); - - /* - * CA and GB addresses are redacted and are causing errors until WooCommerce is able to - * handle redacted addresses. - * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress - */ - if ( - [ 'cart', 'checkout' ].includes( context ) && - lastSelectedAddress && - ! [ 'CA', 'GB' ].includes( lastSelectedAddress.country ) - ) { - if ( isBlocks ) { - updateBlocksShippingUI( lastSelectedAddress ); - } else { - updateShortcodeShippingUI( lastSelectedAddress ); - } + if ( lastSelectedAddress ) { + updateShippingAddressUI( lastSelectedAddress ); } - lastSelectedAddress = null; unblockUI(); }; diff --git a/client/tokenized-express-checkout/utils/shipping-fields.js b/client/tokenized-express-checkout/utils/shipping-fields.js index a76ba8d8a21..cc26eb2c096 100644 --- a/client/tokenized-express-checkout/utils/shipping-fields.js +++ b/client/tokenized-express-checkout/utils/shipping-fields.js @@ -1,12 +1,22 @@ /* global jQuery */ /** - * External dependencies + * Internal dependencies */ +import { normalizeShippingAddress, getExpressCheckoutData } from '.'; /** - * Internal dependencies + * Checks if the intermediate address is redacted for the given country. + * CA and GB addresses are redacted and are causing errors until WooCommerce is able to + * handle redacted addresses. + * https://developers.google.com/pay/api/web/reference/response-objects#IntermediateAddress + * + * @param {string} country - The country code. + * + * @return {boolean} True if the postcode is redacted for the country, false otherwise. */ -import { normalizeShippingAddress, getExpressCheckoutData } from '.'; +const isPostcodeRedactedForCountry = ( country ) => { + return country.length === 2 && [ 'CA', 'GB' ].includes( country ); +}; /* * Updates a field in a form with a new value. @@ -19,9 +29,26 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { const field = document.querySelector( `${ formSelector } [name="${ fieldName }"]` ); - if ( field ) { + + if ( ! field ) return; + + // Check if the field is a dropdown (country/state). + if ( field.tagName === 'SELECT' && /country|state/.test( fieldName ) ) { + const options = Array.from( field.options ); + const match = options.find( + ( opt ) => + opt.value === value || + opt.textContent.trim().toLowerCase() === value.toLowerCase() + ); + + if ( match ) { + field.value = match.value; + jQuery( field ).trigger( 'change' ).trigger( 'close' ); + } + } else { + // Default behavior for text inputs. field.value = value; - jQuery( field ).trigger( 'change' ).trigger( 'close' ); + jQuery( field ).trigger( 'change' ); } }; @@ -30,7 +57,7 @@ const updateShortcodeField = ( formSelector, fieldName, value ) => { * * @param {Object} eventAddress - The shipping address returned by the payment event. */ -export const updateBlocksShippingUI = ( eventAddress ) => { +const updateBlocksShippingUI = ( eventAddress ) => { wp?.data ?.dispatch( 'wc/store/cart' ) ?.setShippingAddress( normalizeShippingAddress( eventAddress ) ); @@ -41,7 +68,7 @@ export const updateBlocksShippingUI = ( eventAddress ) => { * * @param {Object} eventAddress - The shipping address returned by the payment event. */ -export const updateShortcodeShippingUI = ( eventAddress ) => { +const updateShortcodeShippingUI = ( eventAddress ) => { const context = getExpressCheckoutData( 'button_context' ); const address = normalizeShippingAddress( eventAddress ); @@ -74,3 +101,31 @@ export const updateShortcodeShippingUI = ( eventAddress ) => { } ); } }; + +/** + * Updates the WooCommerce shipping UI to reflect a new shipping address. + * + * Determines the current context (cart or checkout) and updates either + * WooCommerce Blocks or shortcode-based shipping forms, if applicable. + * + * @param {Object} newAddress - The new shipping address object returned by the payment event. + * @param {string} newAddress.country - The country code of the shipping address. + * @param {string} [newAddress.state] - The state/province of the shipping address. + * @param {string} [newAddress.city] - The city of the shipping address. + * @param {string} [newAddress.postcode] - The postal/ZIP code of the shipping address. + */ +export const updateShippingAddressUI = ( newAddress ) => { + const context = getExpressCheckoutData( 'button_context' ); + const isBlocks = getExpressCheckoutData( 'has_block' ); + + if ( + [ 'cart', 'checkout' ].includes( context ) && + ! isPostcodeRedactedForCountry( newAddress.country ) + ) { + if ( isBlocks ) { + updateBlocksShippingUI( newAddress ); + } else { + updateShortcodeShippingUI( newAddress ); + } + } +}; From 20c4e424bbd3932e307fdb157a606a5e0cb6c55b Mon Sep 17 00:00:00 2001 From: Rafael Zaleski Date: Tue, 17 Dec 2024 14:54:42 -0300 Subject: [PATCH 31/31] Remove redundant check in isPostcodeRedactedForCountry --- client/express-checkout/utils/shipping-fields.js | 2 +- client/tokenized-express-checkout/utils/shipping-fields.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/express-checkout/utils/shipping-fields.js b/client/express-checkout/utils/shipping-fields.js index cc26eb2c096..f097b1eca59 100644 --- a/client/express-checkout/utils/shipping-fields.js +++ b/client/express-checkout/utils/shipping-fields.js @@ -15,7 +15,7 @@ import { normalizeShippingAddress, getExpressCheckoutData } from '.'; * @return {boolean} True if the postcode is redacted for the country, false otherwise. */ const isPostcodeRedactedForCountry = ( country ) => { - return country.length === 2 && [ 'CA', 'GB' ].includes( country ); + return [ 'CA', 'GB' ].includes( country ); }; /* diff --git a/client/tokenized-express-checkout/utils/shipping-fields.js b/client/tokenized-express-checkout/utils/shipping-fields.js index cc26eb2c096..f097b1eca59 100644 --- a/client/tokenized-express-checkout/utils/shipping-fields.js +++ b/client/tokenized-express-checkout/utils/shipping-fields.js @@ -15,7 +15,7 @@ import { normalizeShippingAddress, getExpressCheckoutData } from '.'; * @return {boolean} True if the postcode is redacted for the country, false otherwise. */ const isPostcodeRedactedForCountry = ( country ) => { - return country.length === 2 && [ 'CA', 'GB' ].includes( country ); + return [ 'CA', 'GB' ].includes( country ); }; /*