Commit 46af826b778 for woocommerce
commit 46af826b7783246fb6148f6166837ae0651f395f
Author: Seghir Nadir <nadir.seghir@gmail.com>
Date: Thu Jul 9 14:55:41 2026 +0100
Fix Local Pickup settings save confirmation notice (#66459)
The success notice was gated on the API response deep-equaling the sent
payload. The controller sanitizes input (wp_kses_post/sanitize_text_field)
before echoing it back, so values like "Ring bell & wait" come back as
"Ring bell & wait" and the notice never fired despite a successful,
persisted save. Gate the notice on request success instead, and surface an
error notice on failure.
diff --git a/plugins/woocommerce/changelog/66404-fix-local-pickup-save-notice b/plugins/woocommerce/changelog/66404-fix-local-pickup-save-notice
new file mode 100644
index 00000000000..e1bf21b6525
--- /dev/null
+++ b/plugins/woocommerce/changelog/66404-fix-local-pickup-save-notice
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Show the Local Pickup settings save confirmation on a successful save (and an error notice on failure), instead of only when the server response matched the sent payload, which suppressed the notice when values were sanitized (e.g. "&" normalized to "&").
diff --git a/plugins/woocommerce/client/blocks/assets/js/extensions/shipping-methods/pickup-location/settings-context.tsx b/plugins/woocommerce/client/blocks/assets/js/extensions/shipping-methods/pickup-location/settings-context.tsx
index a90aa308e8c..7b3d83c273b 100644
--- a/plugins/woocommerce/client/blocks/assets/js/extensions/shipping-methods/pickup-location/settings-context.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/extensions/shipping-methods/pickup-location/settings-context.tsx
@@ -12,7 +12,6 @@ import type { UniqueIdentifier } from '@dnd-kit/core';
import apiFetch from '@wordpress/api-fetch';
import { dispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
-import fastDeepEqual from 'fast-deep-equal/es6';
import { store as noticesStore } from '@wordpress/notices';
/**
@@ -145,32 +144,37 @@ export const SettingsProvider = ( {
setIsSaving( true );
setIsDirty( false );
- // @todo This should be improved to include error handling in case of API failure, or invalid data being sent that
- // does not match the schema. This would fail silently on the API side.
+ // A resolved apiFetch means the request succeeded (2xx); the server
+ // sanitizes the payload before echoing it back, so the response will not
+ // necessarily match what we sent. Gate the notice on success, not on the
+ // response matching the payload, otherwise sanitized values (e.g. "&"
+ // normalized to "&") would suppress the confirmation on a save that
+ // actually persisted.
apiFetch( {
path: '/wc/v3/pickup-locations',
method: 'POST',
data,
- } ).then( ( response ) => {
- setIsSaving( false );
- if (
- fastDeepEqual(
- response.pickup_location_settings,
- data.pickup_location_settings
- ) &&
- fastDeepEqual(
- response.pickup_locations,
- data.pickup_locations
- )
- ) {
+ } )
+ .then( () => {
dispatch( noticesStore ).createSuccessNotice(
__(
'Local Pickup settings have been saved.',
'woocommerce'
)
);
- }
- } );
+ } )
+ .catch( () => {
+ setIsDirty( true );
+ dispatch( noticesStore ).createErrorNotice(
+ __(
+ 'There was an error saving your Local Pickup settings. Please try again.',
+ 'woocommerce'
+ )
+ );
+ } )
+ .finally( () => {
+ setIsSaving( false );
+ } );
}, [ settings, pickupLocations ] );
const settingsData = {