Search code examples
phpwordpresswoocommerceordersemail-notifications

Display custom checkout field value in WooCommerce orders and email notifications


I have the following code which adds a custom field to checkout for a specific product, adds it to the new order page and send's it in the new order email.

add_action( 'woocommerce_after_checkout_billing_form', 'my_custom_checkout_field', 10, 1 );
function my_custom_checkout_field( $checkout ) {
    
    $targeted_product_id = 6270; //Global Membership ID

    foreach( WC()->cart->get_cart() as $item ){
        if ( ! in_array($targeted_product_id, [$item['product_id'], $item['variation_id']]) ) {
            return; // Exit if there are other products in cart that the targeted one.
        }
    }

    echo '<div id="my_custom_checkout_field">
    <h2>' . __('Please select your Delivery Partner') . '</h2>';

    woocommerce_form_field( 'delivery_partner', array(
        'type'          => 'select',
        'required'  => 'true',
        'options'     => array(
   '---Please select your Delivery Partner' => __('---Please select your Delivery Partner', 'woocommerce' ),
   'Learners University College (LUC), Dubai' => __('Learners University College (LUC), Dubai', 'woocommerce' ),
   'Elite Training Services (ECS), KSA' => __('Elite Training Services (ECS), KSA ', 'woocommerce' ),
   'MELI, KSA' => __('MELI, KSA', 'woocommerce' ),
   'KLD Management Training, Dubai' => __('KLD Management Training, Dubai', 'woocommerce' )),
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Delivery Partner'),
        ), $checkout->get_value( 'delivery_partner' ));

    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_partner']) && ! empty($_POST['delivery_partner']) ) {
        $order->update_meta_data( 'Delivery Partner', sanitize_text_field( $_POST['delivery_partner'] ) );
    } 
}

// 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>'.__('Delivery Partner').':</strong> ' . $order->get_meta('Delivery Partner') . '</p>'; 
}

// 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_partner').':</strong> ' . $order->get_meta('Delivery Partner') . '</p>';
}

What I need is to add it to the "Thank you for your order" page after payment is made as its currently not working.


Solution

  • Update: Enabled back multiple targeted product IDs and simplified the code.

    There are some mistakes and missing things, use the following code replacement instead:

    // Utility function: Delivery partner options (array)
    function get_delivery_partner_options() {
        return array(
            ''  => __('---Please select your Delivery Partner', 'woocommerce'),
            '1' => __('Learners University College (LUC), Dubai', 'woocommerce' ),
            '2' => __('Elite Training Services (ECS), KSA ', 'woocommerce' ),
            '3' => __('MELI, KSA', 'woocommerce' ),
            '4' => __('KLD Management Training, Dubai', 'woocommerce' ),
        );
    }
    
    // Display "Delivery Partner" custom checkout field 
    add_action( 'woocommerce_after_checkout_billing_form', 'my_custom_checkout_field', 10, 1 );
    function my_custom_checkout_field( $checkout ) {
        
        $targeted_product_ids = array(6270, 6288); // Handle multiple product IDs
        $other_items = false; // Initializing
    
        foreach( WC()->cart->get_cart() as $item ){
            if ( ! array_intersect($targeted_product_ids, [$item['product_id'], $item['variation_id']]) ) {
                $other_items = true;
                break;
            }
        }
    
        if ( $other_items ) return; // Exit
    
        echo '<div id="my_custom_checkout_field">
        <h2>' . __('Please select your Delivery Partner', 'woocommerce') . '</h2>';
    
        woocommerce_form_field( 'delivery_partner', array(
            'type'       => 'select',
            'required'   => 'true',
            'options'    => get_delivery_partner_options(),
            'class'      => array('my-field-class form-row-wide'),
            'label'      => __('Delivery Partner', 'woocommerce'),
        ), $checkout->get_value( 'delivery_partner' ));
    
        echo '</div>';
    }
    
    // Validate delivery partner field
    add_action( 'woocommerce_checkout_process', 'custom_checkout_field_validation' );
    function custom_checkout_field_validation() {
        $field_key = 'delivery_partner';
        if ( isset($_POST[$field_key]) && empty($_POST[$field_key]) ) {
            wc_add_notice( __('<strong>'.__('Delivery Partner', 'woocommerce').'</strong> is a required field.', 'woocommerce'),'error' );
        }
    }
    
    // Save the selected delivery partner as order custom metadata:
    add_action( 'woocommerce_checkout_create_order', 'save_selected_delivery_partner' );
    function save_selected_delivery_partner( $order ) {
        $field_key = 'delivery_partner';
        $options   = get_delivery_partner_options();
        if ( isset($_POST[$field_key]) && ! empty($_POST[$field_key]) ) {
            $order->update_meta_data( 'delivery_partner', $options[esc_attr($_POST[$field_key])] );
        } 
    }
    
    // Display the custom field value on admin order pages after billing adress:
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_selected_delivery_partner_in_admin_orders', 10, 1 );
    function display_selected_delivery_partner_in_admin_orders( $order ) {
        if ( $delivery_partner = $order->get_meta('delivery_partner') ) {
            echo '<p><strong>'.__('Delivery Partner', 'woocommerce').':</strong> ' . $delivery_partner . '</p>'; 
        }
    }
    
    // Display on customer orders and email notifications
    add_filter( 'woocommerce_get_order_item_totals', 'display_delivery_on_order_item_totals', 10, 3 );
    function display_delivery_on_order_item_totals( $total_rows, $order, $tax_display ) {
        if ( $delivery_partner = $order->get_meta('delivery_partner') ) {
            $new_total_rows = [];
    
            // Loop through order total rows
            foreach( $total_rows as $key => $values ) {
                // Inserting coupon(s) code(s) before discount total
                if( $key === 'discount' ) {
                    $new_total_rows['gift_order'] = array(
                        'label' =>__('Coupon(s)', 'woocommerce') . ':',
                        'value' => implode(', ', $order->get_coupon_codes() ),
                    );
                }
                // Inserting "Delivery Partner" before payment method
                if( $key === 'payment_method' ) {
                    $new_total_rows['delivery_partner'] = array(
                        'label' =>__('Delivery Partner', 'woocommerce') . ':',
                        'value' => $delivery_partner,
                    );
                }
                $new_total_rows[$key] = $values;
            }
            return $new_total_rows;
        }
        return $total_rows;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

    enter image description here