Add Custom Cart Item Data in WooCommerce

One of the greatest things about WooCommerce is the flexibility it gives you as a store owner. I’m currently working on a side project where I needed to add some custom data to a product when adding it to the cart. Using hooks means I can achieve this quite easily.

In the following tutorial I will guide you through the process of adding a field to your product, showing that data in your cart, saving it to the order, and then displaying it to the customer and admin users.

This is an advanced tutorial. You’re best off building this functionality into a custom plugin, but I’ll leave that decision up to you.

Add a Custom Field to Your Product

Firstly, we’ll want to add a custom field to our product. Let’s consider this scenario as our example; you run a store which makes custom engraved wooden signs. You want your customer to be able to enter the text for their engraving into an input field on your product, which is then saved with the order for the production team to start building the sign.

I have set up a simple product 1 to act as the base of our customisable product.

Before the add to cart button, let’s add a simple input field called “Engraving”.

We want our custom field to be within the add to cart form, otherwise the data will not be posted along with the form when the customer adds it to their cart. Within the /single-product/add-to-cart/simple.php template, there are a number of hooks we could use. It makes sense to add our field before the add to cart button, so we’ll use the woocommerce_before_add_to_cart_button hook.

There’s a few things going on here:

  • Firstly, I’m checking that this is our product with a hardcoded ID. Ideally we’d have a meta field in the edit product page where we can toggle the engraving field from showing. But for the sake of clarity and speed, I’ve done it like this.
  • Next, we’re breaking out of PHP and outputting our field HTML.
  • I’ve dropped in a maxlength on the input field.
  • Finally, I add the action to output that field before the add to cart button.

Add Engraving Data to the Cart Item

Our customer can now enter their engraving text before they add the product to the cart. Currently, when they do add the product to the cart, nothing will happen. We need to grab that data when it’s posted, and add it to our product before it’s added to the cart.

WooCommerce is quite clever in the way it adds multiple items to the cart. For example, if we add the sign to the cart twice with the same text, we’d want that to show as a single item in the cart with a quantity of 2. However, if we add the product to the cart with 2 different engravings, we’d want that to show as 2 separate items in the cart.

WooCommerce has this covered. It uses any item meta we add to the cart item (among other things) to generate the cart ID. This means if our item meta is unique, it will be shown as a unique product in the cart.

To catch this engraving data when the product is added to the cart, we want to use the woocommerce_add_cart_item_data filter.

This filter accepts 3 parameters:

  • $cart_item_data
    An array containing any other cart item data for this product. As with any filter in WordPress, this is also what we want the function to return.
  • $product_id
    The ID of the product we’re adding to the cart.
  • $variation_id
    If we’re adding a variation, this is the variation ID.

Firstly, we’re using filter_input() to sanitise our posted data. If $engraving_text is empty (i.e. no value was entered or the data was not even posted), then we go right ahead and return the $cart_item_data.

If it does have a value, we assign it to the $cart_item_data array with a key of iconic-engraving. Then we return $cart_item_data.

Our custom engraving data is now associated to the item in the cart. However, it won’t actually save with the order or show up anywhere yet.

Display Engraving Data in the Cart

Now that we’ve associated our engraving data with the cart item, we can access it and display it in the cart. By default, WooCommerce shows variation data in the cart after the product title, so it makes sense for us to add it there. We’ll append it after the product title using the woocommerce_cart_item_name filter.

As you can see, woocommerce_cart_item_name accepts 3 parameters:

  • $product_name
    This is a string containing our product name.
  • $cart_item
    This is an array of our cart item and its associated data.
  • $cart_item_key
    This is a string containing our unique cart item ID.

Because we assigned our engraving data to the cart item, it is now accessible in the $cart_item array. Firstly we check that it exists. If not, we return the product title as normal. Otherwise, we use sprintf() to return a new string of data; our product title, then a new <p></p> tag containing our engraving text.

Save Engraving Data to the Order

The next step is to save the data to the order when it is processed. This is actually very straightforward when we use the new CRUD methods in WooCommerce. All we need to do is hook into the woocommerce_checkout_create_order_line_item hook and add our order item meta. WooCommerce will then handle displaying that data in the order receipt, account area, and admin area.

The woocommerce_checkout_create_order_line_item action accepts 4 parameters:

  • $item
    This is the order line item object.
  • $cart_item_key
    This is the string containing our cart item key.
  • $values
    This is an array containing all the data for our cart item, including our custom data.
  • $order
    This is a WC_Order instance containing the new order object.

Firstly, we check whether the iconic-engraving value is set. If not, we return and do nothing else. If it is, we use the add_meta_data() method on the $item to add the engraving data to our order item.

The add_meta_data() method accepts 3 parameters:

  • $meta_key
    This is the meta key. This is also what is displayed alongside the order item to the customer, so I have entered it as the label “Engraving”.
  • $meta_value
    This is the value of our meta data, the engraving text in this instance.
  • $unique ( bool – optional )
    Setting this to true makes sure this meta key is unique. It is false by default.

One interesting thing to note; if you want to add meta data to order item that only the admin can see, prefix the $meta_key with an underscore: $item->add_meta_data( '_private_meta', 'Some Value' ). This will then show in the admin area only.

As mentioned, this meta data is now saved to the order item, and is displayed throughout:

Conclusion

So there you have it; that’s how you add custom cart item data and then save it to your final order. There’s many scenarios for this, so I hope this tutorial gets you off to a good start. Let me know what you do with it in the comments below.

Footnotes

  1. Image courtesy of The Rustic Dish
  • yusra

    the data i am typing in text box at single product page is not being displayed on my cart page.
    where should i write this filter add_filter( ‘woocommerce_add_cart_item_data’, ‘iconic_add_engraving_text_to_cart_item’, 10, 3 );
    i am writing it on same simple product page but nothing is happening

    • Hey, you would need to add this functionality as a custom plugin (preferred), or to your theme/child theme’s functions.php file (not preferred!).

      • yusra

        ok james .let me add it as a plugin in my plugins folder and active it..i hope it will work.. thank u soo much for quick response .

        • It’ll need some additional setup to work out of the box as a plugin, if you’re not too familiar with it I’d suggest the theme functions.php file, or there’s a plugin called Code Snippets which may work for you: https://en-gb.wordpress.org/plugins/code-snippets/

          • yusra

            it is working in both conditions 🙂 .. in themes functions.php file and as a plugin too ..
            you have done a great job James…. thnks alot

            i have one question more..
            i am using WCfrontend manager.[my client’s site is based on multivendor concept]
            how can i make it possible for my vendor to see this custom data.

          • Hey, I’m not familiar with using that plugin, I’m afraid. Best of luck!

          • yusra

            its ok james. thnx again
            but can u tell me how can i pass an array of data instead of a word typed in the text box, or how can i send multiple variables instead of a word typed in the text box

          • Hey, just change your input field name to: name="iconic-field[engraving]"

            Then you will have an array under “iconic-field” with “engraving” as the first array item key. You can add more like so:

            name="iconic-field[another-input]"
            name="iconic-field[something-else]"

            etc.

          • yusra

            james this is my drop down list (coming from database) .
            i m showing it instead of textbox
            my task is is to show details on cart page as per selection of drop down option.
            m succesfully done with calling data etc .
            only task is left is that how to pass an array from single product page to last action i.e add_action( ‘woocommerce_checkout_create_order_line_item’, ‘iconic_add_engraving_text_to_order_items’, 10, 4 );

          • Hey, why does it need to be an array? Selecting an option would return a single value.

          • yusra

            on the basis of that single value m calling some data from database that needs to be shown in cart and ordered item list.
            the data is in an array. thts why i need to passan array

          • But you’re only passing through one value from the data pulled from the database, right? The value selected in the select field?

          • yusra

            M done with it successfully…
            i wanted to pass multiple values coming from database on the basis of option selected in dropdown at single product page.
            what i have done is just pulled data from data base on the basis of drop down selection and with the help of concatenation i stored all variables in $cart_item_data[‘iconic-engraving’], so that the have reached till the end i.e Store admin

            thnx once again james for your support, help and quick responses

          • yusra