woocommerce – customise notice error in checkout page

The message itself is not filterable, so the simplest way to change it is to basically ‘translate’ it using the gettext filter:

function wpse_284393_checkout_message( $translated_text, $text, $domain ) {
    if ( $domain !== 'woocommerce' ) {
        return $translated_text;
    }

    if ( $text="Unfortunately <strong>we do not ship %s</strong>. Please enter an alternative shipping address." ) {
        $translated_text="New message goes here, %s will be replaced with shipping location.";
    } 

    return $translated_text;
}
add_filter( 'gettext', 'wpse_284393_checkout_message', 10, 3 );

But, the problem with this solution is that gettext is run for every single line of text in WordPress. Meaning that every line of text will be checked for the woocommerce domain, and then every line of text in WooCommerce will be checked to see if it’s the text you want to replace. This can be a big performance problem.

So, we can try to solve this another way, using the woocommerce_after_checkout_validation hook. This hook fires at the end of checkout validation, and is where the error message is generated. Rather than doing a site-wide text replace of the message, we can use this hook to first see if the error message exists, and if so replace it with a new message. Since this will only occur on checkout, it will have much smaller performance implications:

function wpse_284393_checkout_message( $data, $errors ) {
    if ( empty( $errors ) ) {
        return;
    }

    $shipping_error = $errors->get_error_message( 'shipping' );

    if ( $shipping_error && $shipping_error === 'Unfortunately <strong>we do not ship %s</strong>. Please enter an alternative shipping address.' ) {
        $errors->remove( 'shipping' );
        $errors->add( 'shipping', sprintf( 'My new error message about shipping %s here.', WC()->countries->shipping_to_prefix() . ' ' . WC()->customer->get_shipping_country() );
    }
}
add_action( 'woocommerce_after_checkout_validation', 'wpse_284393_checkout_message' );

By using sprintf() and WC()->countries->shipping_to_prefix() . ' ' . WC()->customer->get_shipping_country() I was able to set the message up to use %s the same way as the original message does.