Web Analytics

Saving (and Displaying) WooCommerce Order Custom Fields

by Jason Unger, Founder

If you’ve built your e-commerce shop with WordPress and WooCommerce, then you know how extensible the platform can be; from extensions to custom fields to emails, you can do pretty much anything with it.

While we’ve talked before about saving custom fields for WooCommerce products, today, let’s focus on saving data specific to your customers’ orders.

These custom fields are usually saved on the Checkout page of your shop, so think order information like the order’s pickup date, pickup time, location, or delivery method.

This can be crucial information for fulfilling, so it’s critical that it’s stored and displayed correctly.

Let’s take a look.

Capturing and Saving Order Information in Custom Fields

While there’s plenty of information that can be captured, let’s keep it simple. Consider a situation where you want to offer your customers three different time windows when they can pick up their order.

After reviewing their order, we’ll display:

add_action('woocommerce_review_order_before_order_total', 'choose_pickup_time');

function choose_pickup_time(){?>
<tr>
     <th colspan="1">Choose Pickup Time </th>
     <td>
          <select name="pickupTime">
               <option value="" selected disabled hidden>Select a pickup time</option>
               <option value="9:00am - 12:00pm">9:00am - 12:00pm</option>
               <option value="12:00pm - 2:00pm">12:00pm - 2:00pm</option>
               <option value="2:00pm - 4:00pm">2:00pm - 4:00pm</option>
          </select>
     </td>
</tr>
<?php }?>

This displays a select dropdown at the end of the Checkout page, where the user can select the time range they want their order to be available. It’s relatively straightforward, but just displaying the dropdown won’t actually save the selected time range.

In order to save the selected pickup time, we need to capture it when the order is submitted. Here’s how.

add_action( 'woocommerce_checkout_update_order_meta', 'save_pickup_time' );

function save_pickup_time( $order_id ){
     if ( ! empty( $_POST['pickupTime'] ) ) {
          update_post_meta( $order_id, 'pickup_time', sanitize_text_field( $_POST['pickupTime'] ) );
     }
}

Essentially, we’re saving the pickup time as a custom field in the Orders custom post type, using the typical method for updating custom field data.

Displaying WooCommerce Custom Fields: Emails, Orders, and My Account

Now that we have the pickup information saved, we have to display it in all of the right places. In this case, it means:

  • in the emails both the customer and the site administrator receive about the order
  • in the backend of the site, when reviewing the orders
  • in the user’s My Account page, where they can see all of the orders they’ve placed

Thankfully, pulling the information from the Orders custom post type is relatively straightforward in all three places – but there are some unique layouts to consider.

Order Received and My Account Pages

Let’s start with displaying the order information on the Order Received and the “My Account” pages. The formatting is the same for both of these places, so the same function can be used for both.

add_action( 'woocommerce_thankyou', 'dgtlnk_custom_order_fields', 20 );
add_action( 'woocommerce_view_order', 'dgtlnk_custom_order_fields', 20 );

function dgtlnk_custom_order_fields( $order_id ){ ?>
     <?php if(get_post_meta( $order_id, 'pickup_time', true )){?>
     <h3><?php _e( 'Pickup Information' ); ?></h3>
     <table class="shop_table shop_table_responsive additional_info">
          <tbody>
               <tr>
                    <th style="width:25%;"><?php _e( 'Pickup Time:' ); ?></th>
                    <td style="width:75%;"><?php echo get_post_meta( $order_id, 'pickup_time', true ); ?></td>
               </tr>
          </tbody>
     </table>
<?php }?>

Pretty straightforward: if our custom field exists, add a header, table, label, and the value of the custom field itself.

Backend Edit Order Page

The idea is similar for the Edit Order page you (the site administrator) see in the backend of WordPress. For this page, you don’t need a table – so it’s just checking for the field values, adding a header, and then outputting the saved data.

add_action( 'woocommerce_admin_order_data_after_billing_address', 'dgtlnk_backend_custom_order_fields', 10, 1 );

function dgtlnk_backend_custom_order_fields($order){
     if(get_post_meta( $order->id, 'pickup_time', true )){ 
          echo '<h4>Pickup Time</h4>';
          echo '<p><strong>'.__('Pickup Time').':</strong> ' . get_post_meta( $order->id, 'pickup_time', true ) . '</p>'; 
     }
}

Confirmation/Processing Email

Lastly, but perhaps most importantly to your customers, is making sure the custom order fields display in their confirmation email.

This one is a two-parter because of where we like to put the custom order details.

We need to make a copy of the /woocommerce/templates/emails/customer-processing-order.php file, insert it into our theme, and make a few edits. (If your email notification process is different for new orders, then adjust the correct file in that folder for your setup.)

In order to display the custom fields outside of the order table, we’re going to add an action hook after the current woocommerce_email_customer_details action. Here’s a template you can use:

do_action('email_order_custom_fields', $order, $sent_to_admin, $plain_text, $email );

That gives us an action to hook into where we can display our custom fields in the “Order Processing” email customers receive after purchasing.

Just like with the My Account and Edit Order functions, we’re going to check for the existence of our custom fields, output a label, and then display the field data.

add_action( "email_order_custom_fields", "dgtlnk_email_custom_order_fields", 20, 10);

function dgtlnk_email_custom_order_fields( $order ) {
     if(get_post_meta( $order->id, 'pickup_time', true )){
          echo '<h2>Pickup Time</h2>';
          echo '<p><strong>'.__('Pickup Time').':</strong> ' . get_post_meta( $order->id, 'pickup_time', true ) . '</p>';
     }
}

There you have it: capture your order custom fields, save them, and then easily display them in all of the places where your team and your customers need to find them.

Have any WooCommerce or digital marketing questions? Reach out and let’s chat.

Avatar photo
About Jason Unger

Jason Unger is the Founder of Digital Ink. He built his first website on Geocities, and hasn't looked back since. Digital Ink tells stories for forward-thinking businesses, mission-driven organizations, and marketing and technology agencies in need of a creative and digital partner.

Other Stories You May Like

What’s your story?

Let’s share it with the world.

Let’s Do This

Close Window
All the Cool Kids are Doing it

Sign Up for the Digital Ink Newsletter

All the cool kids are doing it.