Adding custom data to Woocommerce Order items

Tostino picture Tostino · May 21, 2018 · Viewed 7.5k times · Source

I have a custom plugin that allows the customer to add custom information to their order.

The item is added to cart and the custom data displayed on the cart page. However, the custom information does not get carried over to the orders page on the back end. Ideally I would also like the custom data to be added to the customers order email.

The current code is as follows:

<?php
function wcpc_save_custom_product_field( $cart_item_data, $product_id ) {
    if( isset( $_REQUEST['wcpc_custom_product'] ) ) {
        $cart_item_data[ 'wcpc_custom_product' ] = $_REQUEST['wcpc_custom_product'];
        $cart_item_data[ 'wcpc_custom_price' ] = $_REQUEST['wcpc_custom_price'];
        /* below statement make sure every add to cart action as unique line item */
        $cart_item_data['unique_key'] = md5( microtime().rand() );
    }
    return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'wcpc_save_custom_product_field', 10, 2 );

function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {
    $custom_items = array();
    /* Woo 2.4.2 updates */
    if( !empty( $cart_data ) ) {
        $custom_items = $cart_data;
    }
    if( isset( $cart_item['wcpc_custom_product'] ) &&  $cart_item['wcpc_custom_product'] != '' ) {
        $custom_items[] = array( "name" => 'Custom', "value" => $cart_item['wcpc_custom_product'] );
    }
    return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );

add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );

function add_custom_price( $cart_object ) {

//  This is necessary for WC 3.0+
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    foreach ( $cart_object->get_cart() as $key => $value ) {
        if(isset($value['wcpc_custom_price'])) {
            $value['data']->set_price( $value['wcpc_custom_price'] );
        }
    }

}
?>

I have tried modifying a code snippet I found online and adding to the above code. However, when I implement this, the cart breaks altogether:

function wcpc_order_item_product( $cart_item, $order_item ){

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

    return $cart_item;

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

Any help would be greatly appreciated. I don't have too much coding experience and I am struggling to find a way to get this to work.

Answer

LoicTheAztec picture LoicTheAztec · May 21, 2018

The hook woocommerce_add_order_item_meta is going to be deprecated soon. Since Woocommerce 3 a better hook is available. Try this:

add_action( 'woocommerce_checkout_create_order_line_item', 'custom_checkout_create_order_line_item', 20, 4 );
function custom_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
    if( ! isset( $values['wcpc_custom_product'] ) ) return;

    if( ! empty( $values['wcpc_custom_product'] ) )
        $item->update_meta_data( 'Custom label', $values['wcpc_custom_product'] );

}

enter image description here

You will have to replace 'Custom label' by the label you want to be displayed with the value…

This way your custom field will be displayed everywhere, on backend and frontend orders and email notifications.

See this related thread that will give you all explanations:
Woocommerce: which hook to use instead of deprecated "woocommerce_add_order_item_meta"