Add Order Meta to Emails

We already discussed on my blog how to add custom order meta to view order page or to order details metabox in WooCommerce admin. It is time to add the same custom fields to WooCommerce emails.

We are going to use primary woocommerce_email_order_meta action hook for that. There is also another hook – woocommerce_email_order_meta_fields, we will also take a look on it, but I recommend you the first one.

Method 1. woocommerce_email_order_meta

On the screenshot below you can see that the additional “Gift Information” section has been added. We already worked with these fields in posts I mentioned above.

WooCommerce add additional section with order meta fields to emails.
Customer invoice / Order details email.

If you add the code below to your functions.php, the “Gift” section will be added mostly for all default WooCommerce emails, except “New Account” and “Reset Password” emails.

<?php
/**
 * Add custom order meta to WooCommerce emails
 *
 * @author Misha Rudrastyh
 * @link https://rudrastyh.com/woocommerce/order-meta-in-emails.html
 */
add_action( 'woocommerce_email_order_meta', 'misha_add_email_order_meta', 10, 3 );

function misha_add_email_order_meta( $order, $sent_to_admin, $plain_text ){

	// this order meta checks if order is marked as a gift
	$is_gift = $order->get_meta( 'is_gift' );

	// we won't display anything if it is not a gift
	if( empty( $is_gift ) ) {
		return;
	}

	// ok, if it is the gift order, get all the other fields
	$gift_wrap = esc_html( $order->get_meta( 'gift_wrap' ) );
	$gift_recipient = esc_html( $order->get_meta( 'gift_name' ) );
	$gift_message = esc_html( $order->get_meta( 'gift_message' ) );


	// ok, we will add the separate version for plaintext emails
	if ( false === $plain_text ) {

		// you shouldn't have to worry about inline styles, WooCommerce adds them itself depending on the theme you use
		?>
			<h2>Gift Information</h2>
			<ul>
				<li><strong>Is gift?</strong> Yes</li>
				<li><strong>Gift Wrap:</strong> <?php echo $gift_wrap ?></li>
				<li><strong>Recipient name:</strong> <?php echo $gift_recipient ?></li>
				<li><strong>Gift message:</strong> <?php echo wpautop( $gift_message ) ?></li>
			</ul>
		<?php

	} else {

		echo "\nGIFT INFORMATION\n"
		. "Is gift: Yes\n"
		. "Gift Wrap: $gift_wrap\n"
		. "Recipient name: $gift_recipient\n"
		. "Gift message: $gift_message\n";

	}

}

Each WooCommerce email can be configured to be sent and displayed as a plain text email. Lines 27 and 40–48 in the above code are just for that.

The same email in plain text:

WooCommerce New Order plain text email with Meta Fields we added.

Method 2. woocommerce_email_order_meta_fields

If you look through official WooCommerce tutorials and some other tutorials over the internet, you will find out that people use woocommerce_email_order_meta_fields and woocommerce_email_order_meta_keys filter hooks.

First of all woocommerce_email_order_meta_keys is deprecated since WooCommerce 2.3.0. woocommerce_email_order_meta_fields seems ok, but it is less customizable that woocommerce_email_order_meta, for example you can not add some custom HTML with it.

Example:

That is how it looks when you add order meta to emails with woocommerce_email_order_meta_fields filter hook.
That’s how it looks when you add order meta to emails with woocommerce_email_order_meta_fields filter hook.

But for plain text emails and some other email themes everything looks good. Anyway, I want to share the code with you:

add_filter('woocommerce_email_order_meta_fields', 'misha_add_email_meta', 10, 3 );
function misha_add_email_meta( $fields, $sent_to_admin, $order ) {

	$is_gift = $order->get_meta( 'is_gift' );

	// we won't display anything if it is not a gift
	if( empty( $is_gift ) ) {
		return $fields;
	}

	$fields[ 'is_gift' ] = array(
		'label' => 'Is gift?',
		'value' => 'Yes'
	);

	$fields[ 'gift_wrap' ] = array(
		'label' => 'Gift Wrap',
		'value' => $order->get_meta( 'gift_wrap' )
	);

	$fields[ 'gift_name' ] = array(
		'label' => 'Recipient name',
		'value' => $order->get_meta( 'gift_name' )
	);

	$fields[ 'gift_message' ] = array(
		'label' => 'Gift message',
		'value' => wpautop( $order->get_meta( 'gift_message' ) )
	);

	return $fields;

}

By the way, this filter can be useful when you want to unset() some of fields that were set by a plugin.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X