Add custom cart item data in WooCommerce

Your ultimate guide to the woocommerce_add_cart_item_data action

WooCommerce lets you add your own custom cart item data. This article is your ultimate guide to two filters – woocommerce_add_cart_item_data and woocommerce_add_to_cart_validation – and how you can use them to validate custom fields then add the data to the cart and the order.

How to add WooCommerce custom cart item data

I’m going to walk through two methods for adding WooCommerce custom cart item meta:

We’ll create an example scenario and you can view a working demo product.

As part of method two, we’ll look at how you extend this functionality with some powerful extra features, like:

But first, let’s check out method one – adding cart item data programmatically.

Adding cart item data programmatically

As part of this, we’ll look at adding custom fields to WooCommerce products. You can also find further information in this detailed tutorial here on WooCommerce custom fields.

In this article, we’ll concentrate on adding meta data from a single field, all the way from the product page to the new order email.

In total, we’ll cover the following:

Add a custom field to the product page

Let’s say that we are running an online printing business and we’re offering customers the chance to have their name printed on one of our posters.

WooCommerce add custom cart item data using woocommerce_add_cart_item_data

To achieve this, we’ll need to add a text field on the product page where the user will be able to enter their name.

<?php
/**
* Add a custom text input field to the product page
*/
function plugin_republic_add_text_field() { ?>
<div class="pr-field-wrap">
<label for="pr-field"><?php _e( 'Your name', 'plugin-republic' ); ?></label>
<input type="text" name='pr-field' id='pr-field' value=''>
</div>
<?php }
add_action( 'woocommerce_before_add_to_cart_button', 'plugin_republic_add_text_field' );

Note that we are inserting our field using an action – woocommerce_before_add_to_cart_button. As you might guess from its name, this action is triggered just before the ‘Add to Cart’ button is displayed on the product page.

If you’re wondering what this means, here’s a brief explanation of actions and filters in WordPress.

Understanding hooks, actions and filters

Hooks are WordPress’s way of allowing you, the developer, to insert your own code into WordPress code. WooCommerce contains hundreds of places that you can hook into, making it a really flexible plugin to extend with custom functionality.

There are two types of hook: actions and filters. Actions are convenient ways to add functionality; filters are a way of modifying content.

We’ll look at both types of hook during this article but, for now, it’s enough to know that hooks are a way of inserting your own functionality into a plugin like WooCommerce or to WordPress itself.

The woocommerce_before_add_to_cart_button action

Take a look at the WooCommerce template file for a simple product:

<?php
/**
* Simple product add to cart
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/add-to-cart/simple.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
global $product;
if ( ! $product->is_purchasable() ) {
return;
}
echo wc_get_stock_html( $product ); // WPCS: XSS ok.
if ( $product->is_in_stock() ) : ?>
<?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<form class="cart" action="<?php echo esc_url( apply_filters( 'woocommerce_add_to_cart_form_action', $product->get_permalink() ) ); ?>" method="post" enctype='multipart/form-data'>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<?php
do_action( 'woocommerce_before_add_to_cart_quantity' );
woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( wp_unslash( $_POST['quantity'] ) ) : $product->get_min_purchase_quantity(), // WPCS: CSRF ok, input var ok.
) );
do_action( 'woocommerce_after_add_to_cart_quantity' );
?>
<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
</form>
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
<?php endif; ?>
view raw simple.php hosted with ❤ by GitHub

If you look at line 33, you can see the woocommerce_before_add_to_cart_button, just before the code to display the quantity field and the Add to Cart button.

Add a custom field after the Add to Cart button

If we wanted to change our field’s position so that it appears after the Add to Cart button, we can replace the woocommerce_before_add_to_cart_button action with woocommerce_after_add_to_cart_button.

Note that both these hooks appear within the <form> element. This is important for us when we’re adding the custom field value to the cart object.

Validating the custom field data

So far so good, hopefully. Now let’s look at what happens when the customer clicks the Add to Cart button.

When the users clicks Add to Cart, the data from the product form is submitted to the server. This data would normally include things like the product ID and the quantity but, because we’ve added our field, it will also submit the field’s value as custom data.

All this data is passed through a couple of WooCommerce hooks, which allows us to check our field’s content, then add it to the order.

Validating custom field data with woocommerce_add_to_cart_validation

Let’s say that we require the customer to enter their name in the custom field – otherwise they won’t be able to add the product to the cart.

We can enforce this by using validation – that is, we check the value of the custom field when the product is added to the cart. If it’s empty, then we fail validation. We do this using the woocommerce_add_to_cart_validation hook.

Earlier on, we talked about two types of hook – filters and actions. The woocommerce_add_to_cart_validation hook is a filter: it’s passed a parameter, which we can modify if we want, before that parameter is passed back.

In the case of woocommerce_add_to_cart_validation, the parameter is called $passed, and it can be either true or false. If it’s passed back as true, then the product will be added to the cart and we can move on to the next step. But if it’s passed back as false, the product won’t be added to the cart and we can display an error message.

Here’s our validation function:

<?php
/**
* Validate our custom text input field value
*/
function plugin_republic_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id=null ) {
if( empty( $_POST['pr-field'] ) ) {
$passed = false;
wc_add_notice( __( 'Your name is a required field.', 'plugin-republic' ), 'error' );
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'plugin_republic_add_to_cart_validation', 10, 4 );

Okay, there are a few things to note here:

woocommerce_add_to_cart_validation parameters

We are passing 4 parameters in total to our custom validation function:

  • $passed – this is a boolean (true/false) value which is used to decide whether the product has passed validation or not
  • $product_id – the ID of the product
  • $quantity – this is the quantity
  • $variation_id – this parameter will only have a value if we’re on a variable product

Using the $_POST object in validation

When the Add to Cart button is submitted, all the form data is sent to the server and collected by the $_POST object.

This means that we can look in the $_POST object for our custom field value. So, the function checks to see if the field called pr-field is empty. If it is, we change the value of $passed to false.

Adding a notice when validation fails

If the custom field is empty and validation is going to fail, we should probably add a nice message to the user telling them what’s wrong. We can do that using the wc_add_notice function.

The first parameter is the error message that will display; the second parameter is the type of message.

Returning the $passed parameter

Finally, because woocommerce_add_to_cart_validation is a filter, we need to return the $passed parameter. If validation has passed, the value of $passed won’t have changed. But if validation has failed because the user didn’t enter their name, then the value of $passed will be false.

WooCommerce product failed validation using woocommerce_add_to_cart_validation

Adding the custom field data in WooCommerce

Now we’re getting down to the main business – how to add the WooCommerce custom cart meta data.

If the product has passed validation, we want to add the custom field data to the cart meta data. Once it’s in the cart meta data, we can then use it at checkout and in the order once it’s placed.

The woocommerce_add_cart_item_data filter

We’re using woocommerce_add_cart_item_data, another filter, to add the custom cart item data. Take a look at the following function:

<?php
/**
* Add custom cart item data
*/
function plugin_republic_add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
if( isset( $_POST['pr-field'] ) ) {
$cart_item_data['pr_field'] = sanitize_text_field( $_POST['pr-field'] );
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'plugin_republic_add_cart_item_data', 10, 3 );

This time, the woocommerce_add_cart_item_data passes $cart_item_data, which is an array of data for each item in the cart. We can add our data to this array then pass it back to WooCommerce.

Notice again that we’re using the $_POST object to collect our custom data. We also use sanitize_text_field to sanitise the user input. We add our sanitised data to the $cart_item_data array. We’re going to be able to use that later.

Purchasing the same product multiple times

What happens if your customer wants to buy two items – one with their name, the other with a friend’s name?

WooCommerce will realise that the custom data is different in each case and will create separate line items in the cart.

On the other hand, if your customer adds the same product with the same custom text twice, WooCommerce will display them as a single line item with a quantity of 2.

Display the custom WooCommerce meta data in the cart

With our custom meta data successfully stored in the $cart_item_data object, we can display it in the cart.

Custom WooCommerce meta data in the cart

The woocommerce_get_item_data filter

To display the custom data in the cart, we’re going to use another filter, this time the woocommerce_get_item_data filter. You can see it in the following function:

<?php
/**
* Display custom item data in the cart
*/
function plugin_republic_get_item_data( $item_data, $cart_item_data ) {
if( isset( $cart_item_data['pr_field'] ) ) {
$item_data[] = array(
'key' => __( 'Your name', 'plugin-republic' ),
'value' => wc_clean( $cart_item_data['pr_field'] )
);
}
return $item_data;
}
add_filter( 'woocommerce_get_item_data', 'plugin_republic_get_item_data', 10, 2 );

Here we see a parameter, $item_data, where we store data for each line item in the cart. The second parameter is $cart_item_data, where we’ve already stored our custom field value.

So all we need to do is transfer the custom field value from the $cart_item_data array to the $item_data array. We format it slightly differently, assigning the label we want to use in the cart to the ‘key’ element. Then the value of the field itself is assigned to the ‘value’ element.

Updating existing cart meta

The above works perfectly when the customer is adding a new product to the cart. But what about updating custom meta data for an item that is already in the cart? To do that, you need to take a look at this article on updating existing WooCommerce cart meta data.

Add the custom cart meta data to the WooCommerce order

Custom meta data is only really going to be useful for us if we can retrieve it from the order.

To help us with this, we use an action called woocommerce_checkout_create_order_line_item which allows us to update line items as they’re saved to the order.

Note that this is an action, not a filter, as it doesn’t return a value.

<?php
/**
* Add custom meta to order
*/
function plugin_republic_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
if( isset( $values['pr_field'] ) ) {
$item->add_meta_data(
__( 'Your name', 'plugin-republic' ),
$values['pr_field'],
true
);
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'plugin_republic_checkout_create_order_line_item', 10, 4 );

Again, this allows you to set a label – the first parameter passed to add_meta_data – then add the value of the custom field. The $values parameter is product data from the cart. We check that to see if our custom field has been set and, if it has, we pass the value to the $item array to be saved in the order meta.

Viewing custom meta data on the order review page

You can see how this is displayed on the order review page after the user has checked out.

WooCommerce custom meta data order received page

Viewing custom meta data in the order admin page

The function above also ensures that the custom meta data is displayed on the order page in the admin.

Custom meta data in WooCommerce order screen admin

Adding WooCommerce custom meta data to emails

Finally, you will probably want to add your custom meta data to the emails that get sent to you as the admin receiving the order, and to the customer as a record of their order.

To do this, we filter the name of the product as it appears in the line items in the email. We add our custom field values:

<?php
/**
* Add custom cart item data to emails
*/
function plugin_republic_order_item_name( $product_name, $item ) {
if( isset( $item['pr_field'] ) ) {
$product_name .= sprintf(
'<ul><li>%s: %s</li></ul>',
__( 'Your name', 'plugin_republic' ),
esc_html( $item['pr_field'] )
);
}
return $product_name;
}
add_filter( 'woocommerce_order_item_name', 'plugin_republic_order_item_name', 10, 2 );

There are two parameters – the first is the HTML for the product name, the second is the data for the line item. We check the line data for our custom field and, if it exists, we append it to the product name.

Admin order email
Customer email

In that way, you’ve easily added your custom field data to the email.

Programmatically adding custom meta data to the cart in WooCommerce – recap

Okay, hopefully you’ve now got everything you need to know about how to add custom data to the WooCommerce cart.

I’m now going to show you a way that you can get all this done in only a few seconds.

Add WooCommerce custom cart item data using a plugin

There are a couple of big reasons why you might prefer to use a plugin to add custom meta data:

  • Maybe you’re not a developer and you’re not comfortable working with code
  • Even if you are a developer, you could be short of time – so using a ready-made plugin makes sense
  • And, the main one, whether you are a developer or not, a plugin will contain multiple features that you just don’t have time to create

I’m going to step through adding a custom text field for the same product above, but this time using a plugin.

We’ll look at all the extra features that are available, just with the text field alone, but remember that the plugin has at least another 12 field types, plus multiple other features. Find out more about the Product Add-Ons Ultimate plugin here, or read on for steps to add a text field.

WooCommerce custom product add-ons plugin

Adding a text field using a plugin

Let’s assume you’ve got the Product Add-Ons plugin installed and set up. If you need some guidance on getting started, you can check out the documentation.

Add your custom field by editing your product, then clicking Product Add-Ons in the Product data section.

WooCommerce Product Add Ons Ultimate panel

Click Add Group then Add Field and set your parameters like the image below:

That’s it. In less than a minute, you can achieve exactly the same result as all the code in the first part of this article.

So that’s the time-saving and technical aspects covered. Let’s look at some of the extra features you get from the Add-Ons Ultimate plugin.

Text field extra options

Please note that many of these extra settings are available to other field types as well. We’re just concentrating on the text field as part of this article.

You can see a demo product with many of the features below here.

Adding a price to custom meta data

One of the biggest things you might want to do is to assign a price to your custom meta data field. So if the customer enters their name, an extra cost will get added to the product price.

To do this – just enter the additional price in the ‘Field Price’ field. This will get added to the product price when the user enters a value in the field.

Field price

Defining a minimum or maximum number of characters in a text field

If you would like to set a minimum and/or maximum number of characters that the user can enter in the field, just add values to the ‘Min Chars’ and ‘Max Chars’ fields.

The user will be prevented from entering too many characters and the product will fail validation when the user clicks Add to Cart.

Add minimum or maximum number of characters to text field

Charging a price per character in WooCommerce

Depending on your print or engraving costs, you might want to charge a price per character for your custom field. Select the ‘Price Per Character’ checkbox to multiply the number of characters by the field price.

WooCommerce text field price per character

Charging per character but allow some free characters

If you’ve got the ‘Price Per Character’ field enabled, you might want to let your customers enter some free characters before you start charging them. Just enter a figure in the ‘Free Chars’ field.

Alphanumeric characters

There are a couple of options for the use of alphanumeric characters. If you wish, you can restrict the input to alphanumeric characters only. Secondly, you could allow non-alphanumeric characters (like spaces or punctuation) but only charge for alphanumeric.

Charging custom meta data as a fixed fee

By default, the field price that you set will get charged for each item that the user adds to the cart. So if they add a quantity of 5 items, the price for the custom field will get multiplied by 5.

But if you prefer to only charge a fee once, select the ‘Flat Rate’ checkbox.

Charging a percentage of product price

If you would like to charge for your custom meta data as a percentage of the product price, check the ‘Percentage?’ field. Then the value you’ve entered in the ‘Field Price’ will be used as the percentage value.

Setting a default value for custom meta data in WooCommerce

You can choose to set a default for your custom meta field so that the field will already contain a value. Just enter the value in the ‘Default’ field.

Displaying custom meta data using conditional logic

Finally, you might want to make the custom data field available to your users only under certain circumstances. You can do this using conditional logic.

For more information on setting up conditional logic for custom fields, take a look at this support article.

You can also find out more about extra product options in WooCommerce in this article.

Adding WooCommerce custom cart item data – final thoughts

Hopefully this article has been comprehensive enough to give you everything you need to know about adding custom cart item data in WooCommerce.

We looked at how to do it programmatically; and we looked at how to do it with a plugin, plus some of the advantages of doing it this.

Take a look at the WooCommerce Product Add-Ons Ultimate plugin for more information about everything you can do with this plugin.

WooCommerce custom product add-ons plugin

Popular Posts

5 thoughts on “Add custom cart item data in WooCommerce

Avatar

Thank you for your great help but when I use these codes. I realized that if I add to cart same product with 2 different name, it is not allowing to do that.

Reply
Avatar

Hi Omer – assuming you’re using the programmatic method here and not the plugin, it’s difficult for me to troubleshoot without reviewing your entire code.

Reply
Avatar

Thank you . You save my lot of time. last two days i am worked on this issue, but when follow your step my ssue resolve in 1hr.

Thanks
Pardeep kumar

Reply
Avatar

You’re welcome. Glad it helped.

Reply
Avatar

Really great article. Was a breeze to follow along and do stuff.

Thanks a bunch !

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *