向 WooCommerce 的结账表单添加自定义字段,可以使用插件 WooCommerce checkout manager 或者 filter:WooCommerce_checkout_fields,本文介绍的方法非上述两种,而是使用 WooCommerce_form_field() 函数在订单备注之后添加自定义字段,并将字段显示在订单详情、订单邮件和后台中的方法。
代码测试环境和使用方法
WordPress 3.9.1 + WooCommerce 2.1.2 + 主题 Twentytwelve
所有代码放在主题的 functions.php 中执行,每段代码后面的图片为改代码的执行效果。
本文原代码下载 WooCommerce 添加自定义结账字段源代码 已下载 270 次
代码段 1 – 在订单备注后添加自定义选项
注意在最开头输出了带有 my_custom_section class 的 div,可以用该 class 修改这个区域的样式,突出该区域。
/**
* 代码段 1 - 在订单备注后添加自定义选项
*/
function my_custom_checkout_section( $checkout ){
// $checkout stores all checkout fields
// Section starts, output wrapper or header
echo '<div class="my_custom_section">';
// Create a select field
$options = array(
'只工作日送货' => '只工作日送货',
'只双休日送' => '只双休日送货',
'工作日、双休日均可送货' => '工作日、双休日均可送货'
);
WooCommerce_form_field("my_custom_field_1", array(
'type' => 'select',
'class' => array('form-row-wide my_custom_field'),
'label' => '送货时间: ',
'options' => array( '' => '-----选择送货时间-----') + $options,
'required' => true
), $checkout->get_value( 'my_custom_field_1' ) );
echo '</div>';
}
add_action( 'WooCommerce_after_order_notes', 'my_custom_checkout_section' );

代码段 2 – 验证自定义字段
虽然第一步中强调了 required=true,但只是改变了长相,真正的验证还得自己来。这里只验证是否有值。
/**
* 代码段 2 - 验证自定义字段
*
* required=true 只改变了长相,验证还得自己写代码
*/
function my_custom_checkout_field_process(){
global $WooCommerce;
if( empty($_POST['my_custom_field_1']) )
$WooCommerce->add_error( '<strong> 请选择送货时间</strong>' );
}
add_action('WooCommerce_checkout_process', 'my_custom_checkout_field_process' );

代码段 3 – 存储自定义字段的值
用户选择后还要把值存到订单中方便以后查询。 order 的本质是 post,所以 order meta 就是 post meta,用 update_post_meta 存储,用 get_post_meta 查询。
/**
* 代码段 3 - 存储自定义字段的值
*
* 如果和用户属性相关,存到 usermeta 表里,否则存在 order meta(postmeta) 里即可
*/
function my_custom_checkout_field_save( $order_id ){
// custom field 名称,最前面的下划线的作用是使该 custom field 在后台不可见,必须通过自定义程序显示
$ordermeta_name = '_my_custom_field_1';
// 将送货时间存到订单的 custom field 里
if( !empty($_POST['my_custom_field_1'] ) )
update_post_meta( $order_id, $ordermeta_name, wc_clean( $_POST['my_custom_field_1'] ) );
}
add_action('WooCommerce_checkout_update_order_meta', 'my_custom_checkout_field_save' );
代码段 4.1-4.3 – 在成功下单页面不同位置显示自定义值
提供三个位置显示,一般只需要选择其中一个即可。
代码段 4.1 – 在订单详情之后,customer details 之前显示
/**
* 代码段 4.1 - 在 order-received 页面显示自定义字段的值
*
* 在订单详情之后,customer details 之前显示
*/
function my_custom_field_display_on_order_received( $order ){
$my_custom_field_1 = get_post_meta( $order->id, '_my_custom_field_1', true );
if( !empty($my_custom_field_1) ){
echo '<h2> 送货时间</h2>';
echo '<p><strong> 送货时间:</strong>' .$my_custom_field_1. '</p>';
}
}
add_action('WooCommerce_order_details_after_order_table', 'my_custom_field_display_on_order_received' );
代码段 4.2 – 在产品列表后显示
/**
* 代码段 4.2 在产品列表后显示
*
* 在 tbody 内、产品列表后显示
*/
function my_custom_field_display_after_product_list( $order ){
$my_custom_field_1 = get_post_meta( $order->id, '_my_custom_field_1', true );
if( !empty($my_custom_field_1) ){
?>
<tr><td> 送货时间</td><td><?php echo $my_custom_field_1; ?></td></tr>
<?php
}
}
add_action( 'WooCommerce_order_items_table', 'my_custom_field_display_after_product_list' );
代码段 4.3 – 在配送方式前面显示
/**
* 代码段 4.3 - 在配送方式前面显示
*
* 在 tfoot 内、 shipping 方式前显示
*/
function my_custom_field_display_before_shipping( $total_rows, $order ){
$my_custom_field_1 = get_post_meta( $order->id, '_my_custom_field_1', true );
$new_total_rows = array();
if( !empty($my_custom_field_1) ){
$new_row['my_custom_field_1'] = array(
'label' => '送货时间:',
'value' => $my_custom_field_1
);
// Insert $new_row after shipping field
$total_rows = array_merge( array_splice( $total_rows,0,2), $new_row, $total_rows );
}
return $total_rows;
}
add_filter( 'WooCommerce_get_order_item_totals', 'my_custom_field_display_before_shipping', 10, 2 );

代码段 5 – 在订单邮件中显示
若选择代码段 4.2 将字段加入订单详情页面,则字段也会自动加到邮件中,就不需要代码段 5 了。
/**
* 代码段 5 - 在 email 中显示
*
* 在 email 的订单详情表格之后显示
* 若使用 WooCommerce_get_order_item_totals 添加字段,
* 无需下面的代码,就可以在订单详情表格里显示
*
* $sent_to_admin - 为 true 表示该邮件发送给管理员
*/
function my_custom_field_order_email( $order, $sent_to_admin ){
$my_custom_field_1 = get_post_meta( $order->id, '_my_custom_field_1', true );
if( !empty($my_custom_field_1) ){
echo '<h3> 送货时间</h3>';
echo "<p> 送货时间: $my_custom_field_1 </p>";
if( $sent_to_admin ) {
echo '这是发给管理员的通知邮件';
}
}
}
add_action( 'WooCommerce_email_after_order_table', 'my_custom_field_order_email', 10, 2 );

代码段 6 – 在后台订单详情中显示自定义字段
/**
* 代码段 6 - 在后台订单详情中显示自定义字段
*/
function my_custom_field_admin_info( $order ){
$my_custom_field_1 = get_post_meta( $order->id, '_my_custom_field_1', true );
if( !empty($my_custom_field_1) ){
echo '<h4> 送货时间</h4>';
echo "<p>$my_custom_field_1</p>";
}
}
add_action( 'WooCommerce_admin_order_data_after_shipping_address', 'my_custom_field_admin_info' );
