phpwordpresswoocommerce

WooCommerce notification is deleted when updating the cart


I am using a custom code that shows a notification of the minimum order amount and blocks the checkout button if the amount is less.

/* Minimum Order Notification */
add_action('woocommerce_check_cart_items', 'custom_checkout_min_order_amount');
function custom_checkout_min_order_amount() {
    $minimum_amount = 1000;

    if (WC()->cart && WC()->cart->subtotal < $minimum_amount) {
        wc_add_notice(
            sprintf(
                'The minimum order is %s. Your order is for %s. You need to add more %s',
                wc_price($minimum_amount),
                wc_price(WC()->cart->subtotal),
                wc_price($minimum_amount - (WC()->cart->subtotal))
            ),
            'error'
        );
    }
}
remove_action( 'woocommerce_before_cart', 'woocommerce_output_all_notices', 10 );
add_action( 'woocommerce_cart_totals_after_order_total', 'woocommerce_output_all_notices', 10 );

/* Blocking the checkout button */
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button', 1 );
function disable_checkout_button() { 

    $minimum_amount = 1000;
    $total = WC()->cart->cart_contents_total;
    if( $total < $minimum_amount ){
        remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        echo '<a style="pointer-events: none !important; background: #fb7df3;" href="#" class="checkout-button button alt wc-forward">Proceed to checkout</a>';
    }  
}

I added this notification to the "Your Order" block. There is a problem when automatically updating the quantity of products in the cart, this notification disappears.

How to make the notification not respond to the cart update or show the notification again after the update. I can't find the right code for this.


Solution

  • Since you're displaying the custom notice inside the "Your Order" block using the woocommerce_cart_totals_after_order_total hook, you'll need to make sure it's added back each time the cart updates.

    That's because WooCommerce clears notices during AJAX updates, so when you change quantities, add, or remove items, your custom notice disappears unless it's dynamically refreshed.

    WooCommerce uses AJAX fragments to update parts of the cart page, so you can hook into that system to keep the notice visible.

    1) Add placeholder for the notice

    First, add a placeholder for your custom notice, to the "Your Order" block using woocommerce_cart_totals_after_order_total hook. This gives WooCommerce a specific spot to inject/add the notice:

    /* Placeholder for custom cart notice */
    add_action('woocommerce_cart_totals_after_order_total', 'add_min_order_notice_placeholder');
    function add_min_order_notice_placeholder() {
        echo '<div id="custom-min-order-notice"></div>';
    }
    

    2) Add the notice via AJAX fragments

    Next, hook into woocommerce_add_to_cart_fragments to update the notice dynamically when the cart changes:

    /* Hook into WooCommerce's AJAX cart update system */
    add_filter('woocommerce_add_to_cart_fragments', 'custom_min_order_notice_fragment');
    function custom_min_order_notice_fragment($fragments) {
        $minimum_amount = 1000; // Minimum order amount required
        $subtotal = WC()->cart->subtotal; // Get current cart subtotal (excluding shipping and taxes)
    
        // Store the notice markup for later use
        ob_start();
    
        // Display notice if subtotal is below minimum required amount
        if ($subtotal < $minimum_amount) {
            ?>
            <div id="custom-min-order-notice" class="woocommerce-error">
                <?php
                echo sprintf(
                    'The minimum order is %s. Your order is for %s. You need to add more %s',
                    wc_price($minimum_amount),
                    wc_price($subtotal),
                    wc_price($minimum_amount - $subtotal)
                );
                ?>
            </div>
            <?php
        }
    
        // Add the notice to WooCommerce's AJAX fragments
        $fragments['#custom-min-order-notice'] = ob_get_clean();
    
        // Return the updated fragments to WooCommerce
        return $fragments;
    }
    

    3) Block the checkout button

    And then your code for blocking the checkout button:

    /* Blocking the checkout button */
    add_action('woocommerce_proceed_to_checkout', 'disable_checkout_button', 1);
    function disable_checkout_button() {
        $minimum_amount = 1000;
        $total = WC()->cart->cart_contents_total;
    
        if ($total < $minimum_amount) {
            remove_action('woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20);
            echo '<a style="pointer-events: none !important; background: #fb7df3;" href="#" class="checkout-button button alt wc-forward">Proceed to checkout</a>';
        }
    }
    

    NOTICE!: This solution is designed for WooCommerce's legacy checkout system. The hooks used here (woocommerce_cart_totals_after_order_total, woocommerce_add_to_cart_fragments, etc.) are not supported in the block-based architecture.

    Reference: