How To Allow Customers To Add Order Notes For Each Product In WooCommerce?

Credit to Brian from AOV Up for the original code.

A customer recently asked me if it was possible to allow their customers select their own variations on a bulk order. As I considered the options, the simplest one was to allow a customer to enter notes at the product order stage. WooCommerce does not allow notes at this stage of the ordering process. The only notes available are at the checkout stage and usually refer to delivery instructions. After searching for a solution, I did not find many plugins that offer this solution. The plugin linked via the button below seems the best solution if you want full customisation of the solution without having to implement your own code. However, I personally prefer using custom PHP code in the child theme over using a plugin to avoid bloating of the theme with other unnecessary Javascript. If you are not comfortable with custom code, I suggest trying the AOV UP solution below. This is a customisation of the original code to allow the custom notes to be added to products in a specific product category and notes on how to make the notes non obligatory on the order page.

Do you offer build-to-order products where customization is key? For customers crafting their dream item, frustration can arise during checkout if they can’t provide specific notes per product. This article tackles that issue by guiding you through adding a custom note field directly on the product page using code. This will empower your customers to effortlessly add detailed instructions for each item, streamlining the customisation process.

The following code will add a note field for a WooCommerce product category, and users will be able to add notes for each product in that category. 

I highly recommend using a Child Theme to add custom code. This is considered best practice for any commercial website. I recommend using Child Theme Configurator By Lilaea Media

1. Here’s the code to add a custom product note field:

This code allows users to enter notes for each product on the product page. The entered notes will be saved and displayed on the cart, checkout page, order details page, and customer emails. Additionally, the code can validate the field, preventing users from adding products to the cart with an empty note. This can be commented out if you don’t want to force customer notes. For my purposes, I have left the code commented out, just remove the comment code to turn this function on. See notes in the code.

Important Note:

Before modifying the code, ensure you understand its functionality. This code has been tested with the Divi themes and WordPress 6.5.2 with WooCommerce Version 8.8.3.

This code only works with a Simple Product (i.e. Not a variable product)

// Display custom field on single product page
add_action( 'woocommerce_after_add_to_cart_button', 'd_extra_product_field', 9 );
function d_extra_product_field() {
    global $product;
    if ( in_array( 29, $product->get_category_ids() ) ) {
        printf( '<div><label>%s</label><br><textarea name="extra_product_field" value="%s"></textarea></div>', 
        __( 'Notes: Add custom notes for this product' ), 
        isset($_POST['extra_product_field']) ? sanitize_text_field( $_POST['extra_product_field'] ) : '' );
    }
}
    // validate when add to cart
    // Comment out the function below to remove requirement for compulsory custom notes
//    function d_extra_field_validation($passed, $product_id, $qty){

//        if( isset( $_POST['extra_product_field'] ) && sanitize_text_field( $_POST['extra_product_field'] ) == '' ){
//            $product = wc_get_product( $product_id );
//            wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter some text.' ), $product->get_title() ), 'error' );
//            return false;
//        }

//        return $passed;

//    }
//    add_filter( 'woocommerce_add_to_cart_validation', 'd_extra_field_validation', 10, 3 );

     // add custom field data in to cart
    function d_add_cart_item_data( $cart_item, $product_id ){

        if( isset( $_POST['extra_product_field'] ) ) {
            $cart_item['extra_product_field'] = sanitize_text_field( $_POST['extra_product_field'] );
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_add_cart_item_data', 'd_add_cart_item_data', 10, 2 );

    // load data from session
    function d_get_cart_data_f_session( $cart_item, $values ) {

        if ( isset( $values['extra_product_field'] ) ){
            $cart_item['extra_product_field'] = $values['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_get_cart_item_from_session', 'd_get_cart_data_f_session', 20, 2 );


    //add meta to order
    function d_add_order_meta( $item_id, $values ) {

        if ( ! empty( $values['extra_product_field'] ) ) {
            woocommerce_add_order_item_meta( $item_id, 'extra_product_field', $values['extra_product_field'] );           
        }
    }
    add_action( 'woocommerce_add_order_item_meta', 'd_add_order_meta', 10, 2 );

    // display data in cart
    function d_get_itemdata( $other_data, $cart_item ) {

        if ( isset( $cart_item['extra_product_field'] ) ){

            $other_data[] = array(
                'name' => __( 'Your extra field text' ),
                'value' => sanitize_text_field( $cart_item['extra_product_field'] )
            );

        }

        return $other_data;

    }
    add_filter( 'woocommerce_get_item_data', 'd_get_itemdata', 10, 2 );


    // display custom field data in order view
    function d_dis_metadata_order( $cart_item, $order_item ){

        if( isset( $order_item['extra_product_field'] ) ){
            $cart_item_meta['extra_product_field'] = $order_item['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_order_item_product', 'd_dis_metadata_order', 10, 2 );


    // add field data in email
    function d_order_email_data( $fields ) { 
        $fields['extra_product_field'] = __( 'Your extra field text' ); 
        return $fields; 
    } 
    add_filter('woocommerce_email_order_meta_fields', 'd_order_email_data');

    // again order
    function d_order_again_meta_data( $cart_item, $order_item, $order ){

        if( isset( $order_item['extra_product_field'] ) ){
            $cart_item_meta['extra_product_field'] = $order_item['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_order_again_cart_item_data', 'd_order_again_meta_data', 10, 3 );

2. Add Code To WooCommerce

After copying the code, you need to add it to your WordPress child theme. Click on ‘Appearance’ and then ‘Theme File Editor’. Select the Child Theme you are using and then select the functions.php file. Paste the code here. 

3. Find the Product Category ID

In WordPress, navigate to Products, then Categories. Find or create the category that you will allow your customers to have custom product order notes on. Make sure you then go to the products and add this product category to each product that will require customer product notes. Back at the product category, click edit on the relevant category and then look at the URL to find ID=xx. This is your product category ID. The URL should look something like this:

“/wp-admin/term.php?taxonomy=product_cat&tag_ID=29”

4. Check The Results

After you have added the code and changed the product category ID to your relevant category to your site, It’s time to test it. 

I suggest clearing any cache first, then opening a new incognito or private browsing tab so that your WordPress login is To test your product order page. Visit any of the product pages on your store, and you’ll notice that a custom note field has been added, and customers can add notes while ordering the product.