Hook for Woocommerce checkout fields

Your code seems to be correct and should generally work for all fields. However, the ‘billing_postcode’ and ‘billing_city’ fields may be processed differently or not be considered required based on the customer’s country or other settings, which could explain why they’re not being modified.

If you want to ensure a message appears for all fields, you might need to use JavaScript to achieve this.

Here’s a jQuery snippet that will append a custom error message to all required WooCommerce checkout fields:

add_action( 'wp_footer', 'custom_required_field_error_message' );
function custom_required_field_error_message() {
    if( is_checkout() && ! is_wc_endpoint_url( 'order-received' ) ) :
    ?>
    <script type="text/javascript">
    jQuery(function($){
        var required_fields = $('form.checkout .validate-required');
        required_fields.each(function(){
            var label = $(this).find('label');
            var error_message="<span class="error" style="display:none">" + label.text().replace('*', '') + ' <?php echo __("is a required field.", "woocommerce"); ?></span>';
            label.append(error_message);
        });
    });
    </script>
    <?php
    endif;
}

The jQuery script targets the form.checkout .validate-required selector which should include all required fields on the checkout page, regardless of whether they’re billing, shipping or account fields. The error message is initially hidden (style=”display:none”) and can be made visible using additional scripts or CSS rules.

Remember to replace “woocommerce” in the __() function with your actual text domain if it’s different.