在 WooCommerce 中保存并显示自定义结帐字段

Save and display custom checkout field in WooCommerce

我有这个片段,它在 WooCommerce 结帐页面上显示了 CustomPostType。

function wps_add_select_checkout_field( $checkout ) {
    echo '<h2>'.__('Select a Good Cause').'</h2>';

    $args = array(
        'post_type' => 'good_cause',
        'posts_per_page' => -1,
    );
    $query = new WP_Query($args);

    // Set variable (array)
    $options = array();

    if ( $query->have_posts() ) :
        while ( $query->have_posts() ) : $query->the_post();
            // Add to $options array
            $options[get_the_ID()] = get_the_title();
        endwhile;
        wp_reset_postdata();
     endif;

    woocommerce_form_field( 'daypart', array(
        'type'          => 'select',
        'class'         => array( 'wps-drop' ),
        'label'         => __( 'Delivery options' ),
        'options'       => $options
    ), $checkout->get_value( 'daypart' ));

}
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field', 10, 1 );

但这不会存储在后端,也不会显示在发送给用户的电子邮件或用户帐户中的订单中...

有谁知道我需要添加什么才能在后端显示它,显示在通过 WP 发送的电子邮件和订单页面中?

我也重新访问了您的代码。要将您的自定义结帐字段值保存为自定义订单元数据并将其显示在订单和电子邮件通知中,请使用以下内容:

// Checkout: Display a custom checkout field (dropdown)
add_action( 'woocommerce_before_order_notes', 'wps_add_select_checkout_field' );
function wps_add_select_checkout_field( $checkout ) {
    echo '<h2>'.__('Select a Good Cause').'</h2>';

    $posts = get_posts( array(
        'post_type' => 'good_cause',
        'posts_per_page' => -1,
    ) );

    $options = array(); // Initializing

    foreach ( $posts as $value ) {
        $options[$value->ID] = $value->post_title;
    }

    woocommerce_form_field( 'daypart', array(
        'type'          => 'select',
        'class'         => array( 'wps-drop' ),
        'label'         => __( 'Delivery options' ),
        'options'       => $options,
    ), $checkout->get_value( 'daypart' ));
}

// Save chosen custom field option as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'action_checkout_create_order' );
function action_checkout_create_order( $order ) {
    $key_field = 'daypart';

    if( isset($_POST[$key_field]) && $_POST[$key_field] > 0 ) {
        $post = get_post( intval($_POST[$key_field]) ); // Get the post object from the post ID

        $order->update_meta_data( $key_field, $post->post_title); // Save the post title
        $order->update_meta_data( $key_field.'_id', $post->ID); // Save post ID (optional if needed)
    }
}

// Display on admin orders
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_chosen_delivery_on_admin_orders' );
function display_chosen_delivery_on_admin_orders( $order ){
    if( $daypart = $order->get_meta( 'daypart' ) ) {
        $daypart_id = $order->get_meta( 'daypart_id' );
        $daypart_id = empty($daypart_id) ? '' : ' ('. $daypart_id .')';

        // Display the delivery option (post title + post id)
        echo '<p><strong>' . __("Delivery") . ':</strong> ' . $daypart . $daypart_id . '</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( $daypart = $order->get_meta( 'daypart' ) ) {
        $new_total_rows = [];

        // Loop through order total rows
        foreach( $total_rows as $key => $values ) {
            // Inserting before payment method
            if( $key === 'payment_method' ) {
                $new_total_rows[$field_id] = array(
                    'label' => __("Delivery", "woocommerce") . ':',
                    'value' => $daypart,
                );
            }
            $new_total_rows[$key] = $values;
        }
        return $new_total_rows;
    }
    return $total_rows;
}

代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。