Support » Plugin: WooCommerce » Add custom fields to New Order emails

  • Resolved dllive

    (@dllive)


    Hi,
    Ive added 2 fields to the Checkout page (Card Message and Preferred Date of Delivery). This is all working fine, but the 2 fields are not being included in the New Order email to the client.

    The code I have so far is:

    // ADD Custom Fields to Checkout Page
    /**
     * Add the field to the checkout
     **/
    
    add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
    
    function my_custom_checkout_field( $checkout ) {
    	
    	
    	// card message
    	    $cardoptions = array('' => __('Select CardMessage', 'woocommerce' )); 
    
        echo '<div id="my_custom_checkout_field"><h3>'.__('Card message').'</h3>';
    
       woocommerce_form_field( 'card_message', array(
            'type'          => 'textarea',
            'class'         => array('my-field-class form-row-wide'),
            'id'            => 'card_message',
            'required'      => true,
            'label'         => __('Enter your message to appear on the card'),
            'placeholder'       => __(''),
            'options'     =>   $cardoptions
            ),$checkout->get_value( 'card_message' ));
    
        echo '</div>';
    
    // select delivery date
        $mydateoptions = array('' => __('Select DeliveryDay', 'woocommerce' )); 
    
        echo '<div id="my_custom_checkout_field"><h3>'.__('Delivery date').'</h3>';
    
       woocommerce_form_field( 'order_delivery_date', array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-wide'),
            'id'            => 'datepicker',
            'required'      => true,
            'label'         => __('We deliver Mon to Sat. Any orders received on a Sunday will be delivered on the next working day'),
            'placeholder'       => __('Select Date'),
            'options'     =>   $mydateoptions
            ),$checkout->get_value( 'order_delivery_date' ));
    
        echo '</div>';
    }
    
    /**
     * Process the checkout
     **/
    add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
    
    function my_custom_checkout_field_process() {
        global $woocommerce;
    
        // Check if set, if its not set add an error.
        if (!$_POST['card_message'])
             wc_add_notice( '<strong>CardMessage</strong> ' . __( 'is a required field.', 'woocommerce' ), 'error' );
    	if (!$_POST['order_delivery_date'])
             wc_add_notice( '<strong>DeliveryDay</strong> ' . __( 'is a required field.', 'woocommerce' ), 'error' );
    }
    
    /**
     * Update the order meta with field value
     **/
    add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
    
    function my_custom_checkout_field_update_order_meta( $order_id ) {
        if ($_POST['card_message']) update_post_meta( $order_id, 'CardMessage', esc_attr($_POST['card_message']));
    	if ($_POST['order_delivery_date']) update_post_meta( $order_id, 'DeliveryDay', esc_attr($_POST['order_delivery_date']));
    }

    What do I need to add so that the 2 new fields are included on the New Order and Failed Order emails?
    Thanks

Viewing 12 replies - 1 through 12 (of 12 total)
  • Plugin Support Michael

    (@mikkamp)

    Automattic Happiness Engineer

    Hi,

    You can use one of the hooks in the email templates. Either “woocommerce_email_order_details” or “woocommerce_email_customer_details”.

    I’d suggest to have a look through the templates/email directory and have a look which templates are used for the order emails. So you can hook into the right location.

    The following guide explains more on the template structures: https://docs.woocommerce.com/document/template-structure/

    Another alternative is to use the Checkout Field Editor: https://woocommerce.com/products/woocommerce-checkout-field-editor/

    This will allow you to add fields which will show up both in the order details and emails.

    Thread Starter dllive

    (@dllive)

    Thanks.

    The client doesnt want to pay for the Checkout Field Editor plugin. πŸ™

    Im not sure how to “…hook into the right location”

    Ive tried the following which I found on a forum post, but it doesnt work:

    add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
    
    function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
        $fields['meta_key'] = array(
            'label' => __( 'Enter your message to appear on the card' ),
            'value' => get_post_meta( $order->id, 'card_message', true ),
        );
        return $fields;
    }
    Plugin Support Michael

    (@mikkamp)

    Automattic Happiness Engineer

    If you have a look at the email order template you can see that the hook it uses is called “woocommerce_email_order_meta”

    See: https://github.com/woocommerce/woocommerce/blob/release/3.3/templates/emails/customer-completed-order.php#L43

    Also the variables which are passed to the hook are very different. So you would need to adjust these accordingly. You will get an instance of $order which you can use to get your custom fields.

    Thread Starter dllive

    (@dllive)

    So sorry Michael, as you can tell, Im not the most experienced developer. πŸ™‚

    So Ive changed my code to:

    add_filter( 'woocommerce_email_order_meta', 'custom_woocommerce_email_order_meta', 10, 3 );
    
    function custom_woocommerce_email_order_meta( $fields, $sent_to_admin, $order ) {
        $fields['meta_key'] = array(
            'label' => __( 'Enter your message to appear on the card' ),
            'value' => get_post_meta( $order->id, 'card_message', true ),
        );
        return $fields;
    }

    How would I pass the card_message variable to the email?

    Plugin Support Michael

    (@mikkamp)

    Automattic Happiness Engineer

    There are many ways to get it done. My suggestion was to add it on an action hook if the other code wasn’t working for you. Although you would need to change the code completely in how it displays the custom data.
    The following documentation explains more on how actions hooks vs filters work:
    https://docs.woocommerce.com/document/introduction-to-hooks-actions-and-filters/

    The original code you were using should also work. There isn’t any specific reason why that isn’t working. Although I would suggest to get the data directly from the $order object. Something like this works perfectly for me:

    add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
    function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
        $fields['card_message'] = array(
            'label' => __( 'Enter your message to appear on the card' ),
            'value' => $order->get_meta( 'card_message', true ),
        );
        return $fields;
    }
    
    • This reply was modified 3 years, 7 months ago by Michael.
    • This reply was modified 3 years, 7 months ago by Michael.
    Thread Starter dllive

    (@dllive)

    Hmm, I just tried your code and still nothing. Am I right in thinking that it should show up in the Failed Email too? Or is it just going to work in the New Order emails?

    What would the code be if I used an action (presumably “woocommerce_email_order_meta_fields” ?)

    Sorry. Thanks for your continued assistance. :/

    Plugin Support Dustin Hartzler

    (@dustinhartzler)

    Automattic Happiness Engineer

    Where are you adding this code on your site?

    Thread Starter dllive

    (@dllive)

    Hi Dustin. Im adding it to my theme’s functions.php file.

    Just to clarify: I need to display the 2 new fields on both the New Order emails and the Failed Order emails.

    Plugin Support Dustin Hartzler

    (@dustinhartzler)

    Automattic Happiness Engineer

    This level of customization goes a bit beyond the free level of support for forums. I recommend higher a developer to get things working properly.

    Thread Starter dllive

    (@dllive)

    Hi guys, just reopening this.

    Ive *almost* got this working. My code in my functions.php:

    add_filter( 'woocommerce_email_order_meta_fields', 'woocommerce_email_order_meta_fields_func', 10, 3 );
    function woocommerce_email_order_meta_fields_func( $fields, $sent_to_admin, $order ) {
    
    	$fields['card_message'] = array(
    		'label' => __( 'Enter your message to appear on the card', 'woocommerce' ),
    		'value' => wptexturize( get_post_meta( $order->id, 'card_message', true ) ),
    	);
    	
    	$fields['delivery_instructions'] = array(
    		'label' => __( 'Delivery date' ),
    		'value' => get_post_meta( $order->id, 'order_delivery_date', true ),
    	);
    
    	//... more meta fields goes here
    
    	return $fields;
    }
    
    add_action( 'woocommerce_email_after_order_table', 'woocommerce_email_after_order_table_func' );
    function woocommerce_email_after_order_table_func( $order ) {
    	?>
    
    	<h3>Additional information</h3>
    	<table>
    		<tr>
    			<td>Card message: </td>
    			<td><?php echo wptexturize( get_post_meta( $order->id, 'card_message', true ) ); ?></td>
    		</tr>
    		<tr>
    			<td>Order delivery date: </td>
    			<td><?php echo wptexturize( get_post_meta( $order->id, 'order_delivery_date', true ) ); ?></td>
    		</tr>
    	</table>
    
    	<?php
    }

    This displays the html in my emails, BUT it doesnt pass through the 2 variables.

    I feel Im almost there, just need to get those 2 variables to display in the emails.

    Thanks so much for your help πŸ™‚

    Sorry, can’t say why its not working but can offer what worked for me:

    1. add field to checkout – OK

    2. collect metadata and add to postmeta table – I am not using the same hook, can’t say if that makes a difference.

    add_action( 'woocommerce_new_order', 'tp_new_order' );
    function tp_new_order( $order_id ) {
      $tp_preferred_slot_nr = isset( $_POST['tp_preferred_slot_nr'] ) ? $_POST['tp_preferred_slot_nr'] : 0;
        add_post_meta( $order_id, 'tp_preferred_slot_nr', $tp_preferred_slot_nr, true ); 
    }

    3. Check the postmeta table in phpMyAdmin to ensure the values are being added to the table

    4. Get the value from the postmeta table – I’m also using get_post_meta() but its inside my custom email template ($order is automatically passed to the template)
    $preferred_slot_nr = get_post_meta( $order->get_id(), 'tp_preferred_slot_nr', true );

    Thread Starter dllive

    (@dllive)

    AH! Thanks so much lorro – its now working!!! πŸ™‚

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Add custom fields to New Order emails’ is closed to new replies.