21 Jul

Adding custom data to WooCommerce orders

woocommerce-mijireh-largeNot long ago I was working on an integration between WooCommerce and some payment gateway. WooCommerce is an e-commerce solution in a form of a WordPress plugin. It extends your WP website to provide you with an online store, and it is a widely-known and recognized solution.

I needed to develop something very simple that required me to save some additional data about orders that used a certain payment gateway for checkout. I was surprised when I failed to find a functionality in WooCommerce core that would enable me to do this. Naturally, I wrote a plugin.

As one would expect from a WordPress plugin, WooCommerce uses WP to the maximum. For example, your products are actually WP posts with metadata, taxonomies and all those WP thingies people use when extending this popular CMS. If you developed WP themes or plugins – you know what I’m talking about.

WooCommerce provided a lot of useful things – such as Action and Filter Hooks – that enables you to extend the online store with your custom behavior.  However, I just couldn’t find a way to store any custom data to a WC order. I was expecting something like this:

// get order
$order = new WC_Order($order_id);

// set some custom data
$order->custom_data = 'my_custom_data';

If that looks too complicated to develop, I was expecting something like this:

// set some custom data
$order->setCustomData('custom_key','custom value');

// get custom data

But no, nothing. People actually create some extra databases to store additional data and then write funny code to get or set that data. Added to the fact people document their code vary poorly, current solutions are terrible and not supported by WooCommerce core. So I wrote a plugin that takes care of this – WooCommerce Custom Order Data.

It’s easy for me to add custom data to any WC order. The following lines of code should demonstrate the full power of the plugin:

// extend order with custom data

// set custom data
$order->custom->my_data = array(
    'id' => 'some id or something',
    'info' => array(
        'key_1' => 1,
        'key_2' => 2

// save custom data

// check if custom data is set
if(isset($order->custom->my_data)) {
    // use custom data
    $custom_data = $order->custom->my_data;

As you can see, all the options are there and it is really easy to use. You can now extend your WC orders with any kind of data and use and modify that data anywhere in your code.

Visit the product page for additional info and feel free to download  and use this plugin in your projects. I hope you’ll find it useful.

21 thoughts on “Adding custom data to WooCommerce orders

  1. The code may work but documentation is very poor.
    You havnt mentioned any action or filter of woocommerce.

    What is $order and where to place this code?

  2. Hi,

    I disagree with your statement about documentation being poor – you have a working example with comments on every line of code. What else would you need from a simple plugin like this?

    Why would I mention any filter or action when this plugin has nothing to do with them?

    You asked what is $order? How about taking a look at the very first line of code in the article:

    // get order
    $order = new WC_Order($order_id);

    So, that’s a WC_Order object. If you don’t know what WC_Order is, you are not the intended user of this particular plugin.


  3. Why not simply do this?

    add_action(‘woocommerce_add_order_item_meta’, function ($item_id, array $values) {
    woocommerce_add_order_item_meta($item_id, ‘some key’, ‘some value’, );



    What is that supposed to do? And how is it comparable to, for example:

    // check if custom data is set
    if(isset($order->custom->my_data)) {
    // use custom data
    $custom_data = $order->custom->my_data;

    We are talking about 100% object-oriented usage of custom order data in the backend. No silly WordPress actions and hooks, but pure OO code. If you don’t see that, I encourage you to use your example. And please feel free to post an entire usage scenario as I did in the article, so that we can compare it for real.

    Thank you.

  5. Hi Milos,

    thanks for your plugin but for the 90% of use cases I’m pretty sure that you can use:

    update_post_meta( $order->id, 'custom_key', 'custom_value' );

    when you need to add a custom data, and:

    $my_value = get_post_meta( $order->id, 'custom_key', true );

    when you need to retrieve and use it.

    Anyway, your solution can be really useful if you don’t want to let the admin see the custom fields in the order’s page.

    Thanks, cheers! 🙂

  6. Hi Mauro,

    You are correct. There are a number of aspects of WordPress as a platform that I don’t like – adding meta data is one of them. The two advantages of the plugin I built are:

    1 – Ease of use in the backend
    2 – No traces of use for the user in the back office

    So, when you have a sales person managing a bunch of orders, he/she will not be able to mess up some data you’re using for integrations, synchronizations etc.

    Thank you for your insight.

  7. Hi!

    This looks like exactly what I need. Thank you! I cannot locate the download link on your product page… Am I just missing it? If you could email me the direct link, I am most grateful…


  8. Hi Milos,

    If I want to get the id from other site by url like xxxx.com/xxx?order_id=999.
    Can I do that and how can I pass the ID to your plugin? Thanks.


  9. Hi, I am not sure I understand what you want. Do you want to save custom data for orders that are not stored on your website/store? If that’s what you are aiming at, it cannot be done like this.

  10. This plugin looks great. I’m wondering if I could extend this plug to append the order_id to a custom table?
    The data that’s written to a custom table after the add to cart and then append the order_id to the row in the table once checkout is complete.

    Thanks, Josh

  11. Thanks for offering to assist. When user clicks the Add to Cart button the site redirects to a survey and writes the data to a wp_survey_table in the DB. When the survey is submitted the site redirects to the cart which allows the user to checkout. After checkout I’d like to add the order id to the to the survey table so I can identify the survey to the order.

  12. Josh,

    From what you’re saying it seems like your users are completing an entire survey when ever they add something to the cart. That is a bit strange to me. I suppose you’ve attached that survey just before the actual checkout…

    Anyways, orders are created when a customer completes the checkout process, so order ID does not exist before that. From the perspective of what you want in the end, you can do one of the two things:

    1) Save the survey ID somewhere in the user session and add it as a custom field for the order that is created after checkout. Than you will always be able to access the survey via the order using that ID.
    2) Again, save the survey ID somewhere in the session and add the order ID to it after checkout.

    In case 1 you can use my plugin. In case 2 you don’t need it. In any case, you need to handle that survey ID in the session.

    Hope I helped…

  13. Milos,

    How can I use your plugin to collect ACH (ie. Bank Name, Routing, & Account number) data for each order for offline processing?

  14. Hey,

    This works great; Thank you! I’m having trouble with output to the e-mail template though. I’m calling on the data through $order->custom->my_custom_id but I don’t get an output. It works when I output $order->billing_email.

    I’m also using the woocommerce e-mail customizer deluxe templates. Let me know if you think I should add something to the e-mail template.

  15. Hi Chris,

    The problem is that the following line of code must be envoked before custom data can be used:

    I don’t think this happens when emails are created. I could consider adding this functionality provided that some kind of a hook exists to facilitate that.

  16. i may be in the wrong place here but what im attempting to do is attach a number value to a product
    product a = 2
    product b = 3 that number then attaches to the order
    order a = 3

    is it possible to do this with your extension

  17. Yes and no. You still have to code the part where you pick up that value from the product and save it within the order. The point of this plugin is to make it easier to deal with order meta-data, that doesn’t have much to do with products I’d say. It could, but I don’t see that as optimal at all.

  18. Hi Miloš,

    To bring this up to date and get rid of the warning message, please update line 30 in WC_CustomOrderData.php:

    $order->custom = new WC_CustomOrderData($order->get_id());

Leave a Reply

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

Copyright: Miloš Đekić