简体   繁体   中英

Display a WooCommerce custom checkout field value on email notification

I'm having some problems with passing my custom field variables to the email receipt. I've browsed through StackOverflow but unfortunately none of the answers/solutions helped in my case.

The fields I have created do actually show up properly in the admin dashboard and in the after checkout page, it just won't show the variables in any email.

Here's where I am creating my custom field in functions.php:

function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('Bezorg moment') . '</h2>';

woocommerce_form_field( 'delivery_date', array(
    'type'          => 'select',
    'options'     => array(
        '17:30-18:00' => __('17:30 - 18:00', 'woocommerce' ),
        '18:00-18:30' => __('18:00 - 18:30', 'woocommerce' )),
    'class'         => array('my-field-class form-row-wide'),
    'label'         => __('Bezorgtijd'),
    'placeholder'   => __('Zo snel mogelijk'),
    ), $checkout->get_value( 'delivery_date' ));

echo '</div>';  }

add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

Here's where I update the post meta:

function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['delivery_date'] ) ) {
    update_post_meta( $order_id, 'Bezorg moment', sanitize_text_field( $_POST['delivery_date'] ) );
} }

add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );

Here's where I pass the value to the admin order dashboard:

function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Bezorg moment').':</strong> ' . get_post_meta( $order->id, 'Bezorg moment', true ) . '</p>'; }

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

And here's where I am attempting to pass these values to new-order notification:

function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
echo '<p><strong>'.__('Bezorg moment').':</strong> ' . get_post_meta( $order->id, 'Bezorg moment', true ) . '</p>'; }

add_action( 'woocommerce_email_after_order_table', 'custom_woocommerce_email_order_meta_fields', 10, 3 );

However, no matter what I try, the label will show up in the email but the variables always pass an empty value. I can't really figure it out because the exact same echo does properly display the values on the front end and in the dashboard backend. What am I doing wrong or what is different about the email part?

Many thanks in advance.

WordPress: 5.1 WooCommerce: 3.5.5

Updated - There are some small mistakes like:

  • Since Woocommerce 3, to get the order ID from the Order object use: $order->get_id()
  • On your last function, there is a missing parameter variable from the hooked function, So you can't get the correct WC_Order Object $order variable required in your code.
  • The correct post meta key is

Optional advices:

  • It's better to use woocommerce_checkout_create_order action hook introduce in Woocommerce 3, instead of old woocommerce_checkout_update_order_meta action hook.
  • You can use WC_Data get_meta() method with the WC_Order object instead of get_post_meta()

Here is your complete revisited code:

// Display a custom checkout select field after Order notes
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field', 10, 1 );
function my_custom_checkout_field( $checkout ) {
    echo '<div id="my_custom_checkout_field">
    <h2>' . __('Bezorg moment') . '</h2>';

    woocommerce_form_field( 'delivery_date', array(
        'type'          => 'select',
        'options'     => array(
            '17:30-18:00' => __('17:30 - 18:00', 'woocommerce' ),
            '18:00-18:30' => __('18:00 - 18:30', 'woocommerce' )),
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Bezorgtijd'),
        'placeholder'   => __('Zo snel mogelijk'),
        ), $checkout->get_value( 'delivery_date' ));

    echo '</div>';
}

// Save the dropdown custom field selected value as order custom meta data:
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta', 10, 2 );
function my_custom_checkout_field_update_order_meta( $order, $data ) {
    if ( isset($_POST['delivery_date']) && ! empty($_POST['delivery_date']) ) {
        $order->update_meta_data( 'Bezorg moment', sanitize_text_field( $_POST['delivery_date'] ) );
    } 
}

// Display the custom field value on admin order pages after billing adress:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ) {
    echo '<p><strong>'.__('Bezorg moment').':</strong> ' . $order->get_meta('Bezorg moment') . '</p>'; 
}

// Display the custom field value on email notifications:
add_action( 'woocommerce_email_after_order_table', 'custom_woocommerce_email_order_meta_fields', 10, 4 );
function custom_woocommerce_email_order_meta_fields( $order, $sent_to_admin, $plain_text, $email ) {
    echo '<p><strong>'.__('Bezorg moment').':</strong> ' . $order->get_meta('Bezorg moment') . '</p>';
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.


If you want to target "New Order" email notification only use this instead:

// Display the custom field value on "New Order" notification:
add_action( 'woocommerce_email_after_order_table', 'custom_woocommerce_email_order_meta_fields', 10, 4 );
function custom_woocommerce_email_order_meta_fields( $order, $sent_to_admin, $plain_text, $email ) {
    if( 'new_order' === $email->id )
        echo '<p><strong>'.__('delivery_date').':</strong> ' . $order->get_meta('Bezorg moment') . '</p>';
}

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM