Commit a114dffd3b for woocommerce
commit a114dffd3bef1914d48a1bd448d9a809c5665f6b
Author: Ayush Pahwa <ayush.pahwa@automattic.com>
Date: Fri Jan 23 17:19:15 2026 +0700
fix: block checkout local pickup fails to render (#62873)
* update: move local pickup escape hatch outside of the if block
* test: add coverage for the fix
* chore: add changelog entry
* Apply woocommerce_cart_ready_to_calc_shipping filter on local pickup early return
* chore: add since tag to the docblock
* chore: update tag version since the functionality hasn't changed
diff --git a/plugins/woocommerce/changelog/fix-wooplug-6140-block-checkout-local-pickup-fails-to-render b/plugins/woocommerce/changelog/fix-wooplug-6140-block-checkout-local-pickup-fails-to-render
new file mode 100644
index 0000000000..dbe69a165b
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-wooplug-6140-block-checkout-local-pickup-fails-to-render
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix Local Pickup not rendering in Block Checkout when third-party plugins call calculate_totals() early with shortcode cart context.
diff --git a/plugins/woocommerce/includes/class-wc-cart.php b/plugins/woocommerce/includes/class-wc-cart.php
index c266b5e9bd..374ca729d5 100644
--- a/plugins/woocommerce/includes/class-wc-cart.php
+++ b/plugins/woocommerce/includes/class-wc-cart.php
@@ -1764,6 +1764,16 @@ class WC_Cart extends WC_Legacy_Cart {
}
if ( 'yes' === get_option( 'woocommerce_shipping_cost_requires_address' ) ) {
+ // If local pickup is enabled, shipping should be shown so that pickup locations are visible before address entry.
+ if ( LocalPickupUtils::is_local_pickup_enabled() ) {
+ /**
+ * This filter is documented below.
+ *
+ * @since 2.7.0
+ */
+ return apply_filters( 'woocommerce_cart_ready_to_calc_shipping', true );
+ }
+
if ( 'shortcode' === $this->cart_context ) {
$country = $this->get_customer()->get_shipping_country();
if ( ! $country ) {
@@ -1803,11 +1813,6 @@ class WC_Cart extends WC_Legacy_Cart {
return false;
}
} else {
- // If local pickup is enabled, shipping should be shown so that pickup locations are visible before address entry.
- if ( LocalPickupUtils::is_local_pickup_enabled() ) {
- return true;
- }
-
$customer = $this->get_customer();
if ( ! $customer instanceof \WC_Customer || ! $customer->has_full_shipping_address() ) {
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
index 69fbcb41c9..3a23a7cd40 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
@@ -413,6 +413,62 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
WC()->cart->get_customer()->set_shipping_postcode( '' );
}
+ /**
+ * Test that show_shipping returns true when Local Pickup is enabled,
+ * even when "Hide shipping costs until an address is entered" is enabled
+ * and no customer address is set.
+ *
+ * This tests the fix for https://github.com/woocommerce/woocommerce/issues/62785
+ * where Local Pickup would not display in the Block Checkout when a third-party
+ * plugin called calculate_totals() early with the shortcode cart context.
+ */
+ public function test_show_shipping_returns_true_with_local_pickup_enabled_and_no_address() {
+ // Save original settings.
+ $default_shipping_cost_requires_address = get_option( 'woocommerce_shipping_cost_requires_address', 'no' );
+ $default_pickup_location_settings = get_option( 'woocommerce_pickup_location_settings', array() );
+
+ // Enable "Hide shipping costs until an address is entered".
+ update_option( 'woocommerce_shipping_cost_requires_address', 'yes' );
+
+ // Enable Local Pickup.
+ update_option(
+ 'woocommerce_pickup_location_settings',
+ array(
+ 'enabled' => 'yes',
+ 'title' => 'Pickup',
+ )
+ );
+
+ // Add a product to the cart.
+ $product = WC_Helper_Product::create_simple_product();
+ WC()->cart->add_to_cart( $product->get_id(), 1 );
+
+ // Clear customer address to simulate a new guest user.
+ WC()->cart->get_customer()->set_shipping_country( '' );
+ WC()->cart->get_customer()->set_shipping_state( '' );
+ WC()->cart->get_customer()->set_shipping_postcode( '' );
+
+ // Test with shortcode context (the bug scenario).
+ WC()->cart->cart_context = 'shortcode';
+ $this->assertTrue(
+ WC()->cart->show_shipping(),
+ 'show_shipping() should return true when Local Pickup is enabled, even with shortcode context and no address'
+ );
+
+ // Test with store-api context (should also work).
+ WC()->cart->cart_context = 'store-api';
+ $this->assertTrue(
+ WC()->cart->show_shipping(),
+ 'show_shipping() should return true when Local Pickup is enabled with store-api context and no address'
+ );
+
+ // Clean up.
+ update_option( 'woocommerce_shipping_cost_requires_address', $default_shipping_cost_requires_address );
+ update_option( 'woocommerce_pickup_location_settings', $default_pickup_location_settings );
+ $product->delete( true );
+ WC()->cart->cart_context = 'shortcode'; // Reset to default.
+ }
+
/**
* Test show_shipping for countries with various state/postcode requirement.
*/