Show the result of custom delivery field on the checkout page in WooCommerce frontend, backend & email notifications

In WooCommerce, I use code that shows a custom field on the checkout page. After filling out this field and placing the order by the client, the data is displayed on the “Thank You” page, when editing the order and in email notifications.

// Add the delivery custom field to the checkout
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {

    echo '<div><h3>' . __('Custom Delivery') . '</h3>';

    woocommerce_form_field( 'my_custom_delivery', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('My Custom Delivery'),
        'placeholder'   => __(''),
        ), $checkout->get_value( 'my_custom_delivery' ));

    echo '</div>';
}

// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['my_custom_delivery'] ) ) {
        update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
    }
}

// Display custom delivery field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
    echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}

// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
    $my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
    echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}

// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
    $fields['Custom Delivery'] = array(
        'label' => __( 'Custom Delivery' ),
        'value' => $order->get_meta( 'my_custom_delivery' ),
    );
    return $fields;
}

But there are two problems that I would like to fix:

  1. The field name “Custom Delivery” is constantly displayed on the order editing page and in email notifications, even when this field is not filled in by the client.

I need to hide the name “Custom Delivery” on these pages if the field is not filled by the client.

  1. The data of the “Custom Delivery” field is shown after the table with the order data.

I need to show the data of this field in the order table on the “Thank You” page and in email notifications.

I will be happy for your help!

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

  1. The field name “Custom Delivery” is constantly displayed on the order editing page and in email notifications, even when this field is
    not filled in by the client.

I need to hide the name “Custom Delivery” on these pages if the field
is not filled by the client.

Replace

$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';

With

$my_custom_delivery = get_post_meta( $order->id, 'my_custom_delivery', true );

if ( !empty( $my_custom_delivery ) ) {
    echo '<div><strong>'.__('Custom Delivery').':</strong> ' . $my_custom_delivery . '</div>';      
}

  1. The data of the “Custom Delivery” field is shown after the table with the order data.

I need to show the data of this field in the order table on the “Thank
You” page and in email notifications.

Remove this

// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
    $my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
    echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}

// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
    $fields['Custom Delivery'] = array(
        'label' => __( 'Custom Delivery' ),
        'value' => $order->get_meta( 'my_custom_delivery' ),
    );
    return $fields;
}

And replace with

// Display the chosen delivery information everywhere on frontend order pages and on email notifications
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
    $new_total_rows = [];

    // Loop through Order total lines
    foreach($total_rows as $key => $total ){
        // Get the custom delivery
        $my_custom_delivery = $order->get_meta( 'my_custom_delivery' );

        // Display delivery information before payment method
        if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
            $label  = __('Custom Delivery:');
            $value  = $my_custom_delivery;

            // Display 'Custom delivery' line
            $new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
        }
        $new_total_rows[$key] = $total;
    }

    return $new_total_rows;
}

So then you get

// Add the delivery custom field to the checkout (backend)
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {

    echo '<div><h3>' . __('Custom Delivery') . '</h3>';

    woocommerce_form_field( 'my_custom_delivery', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('My Custom Delivery'),
        'placeholder'   => __(''),
        ), $checkout->get_value( 'my_custom_delivery' ));

    echo '</div>';
}

// Update the order meta with field value (backend)
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['my_custom_delivery'] ) ) {
        update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
    }
}

// Display custom delivery field value on the order edit page (frontend)
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
    echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}

// Display the chosen delivery information everywhere on frontend order pages and on email notifications (frontend)
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
    $new_total_rows = [];

    // Loop through Order total lines
    foreach($total_rows as $key => $total ){
        // Get the custom delivery
        $my_custom_delivery = $order->get_meta( 'my_custom_delivery' );

        // Display delivery information before payment method
        if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
            $label  = __('Custom Delivery:');
            $value  = $my_custom_delivery;

            // Display 'Custom delivery' line
            $new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
        }
        $new_total_rows[$key] = $total;
    }

    return $new_total_rows;
}

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply