WooCommerce 自定义结账字段图文详解

优质
小牛编辑
138浏览
2023-12-01

向结账表单添加WooCommerce自定义结账字段,可以使用插件WooCommerce checkout manager或者filter:woocommerce_checkout_fields,本文介绍的方法非上述两种,而是使用woocommerce_form_field()函数在订单备注之后添加自定义结账字段,并将字段显示在订单详情、订单邮件和后台中的方法。

2021年10月更新:WooCommerce自定义结账字段(2021)

代码测试环境和使用方法

WordPress 3.9.1 + WooCommerce 2.1.2 + 主题Twentytwelve

所有代码放在主题的functions.php中执行,每段代码后面的图片为改代码的执行效果。

代码段1 – 在订单备注后添加WooCommerce自定义结账字段

注意在最开头输出了带有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>';

	// 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' );
验证送货时间是否选择,如果没选,提交订单时会有错误提示
WooCommerce自定义结账字段

代码段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 );
在order-received页面的不同位置显示自定义字段
WooCommerce自定义结账字段

代码段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 );
将字段加到order email notification中
WooCommerce自定义结账字段

代码段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' );
将字段加到order email notification中
WooCommerce自定义结账字段