Woocommerce自动修改订单状态并向指定地址发送邮件实现方案
问题描述
我正在基于Woocommerce搭建餐饮预订系统,已经完成以下操作:
- 移除了所有不必要的结账字段
- 禁用了支付网关,仅保留订单登记功能
- 通过Elementor和自定义插件为结账页面添加了自定义字段(代码如下)
现在需要实现两个需求:
- 客户提交预订(订单)时,自动将订单状态修改为已完成
- 向客户通过自定义结账字段
pdvselector选择的指定邮箱发送邮件
请问该需求是否可行?应该使用什么钩子?
现有自定义插件代码
class CustomCheckout { public function __construct() { add_action( 'woocommerce_checkout_fields', array( $this, 'remove_default_checkout_fields') ); add_action( 'woocommerce_after_checkout_billing_form', array( $this, 'add_custom_checkout_fields') ); add_action( 'phpmailer_init', array( $this, 'mailtrap') ); add_filter( 'woocommerce_cart_needs_payment', '__return_false' ); } // 配置Mailtrap用于邮件调试 public function mailtrap( $phpmailer ) { $phpmailer->isSMTP(); $phpmailer->Host = 'sandbox.smtp.mailtrap.io'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 2525; $phpmailer->Username = '****'; $phpmailer->Password = '***'; } // 移除默认结账字段 public function remove_default_checkout_fields( $fields ) { //unset( $fields['billing']['first_name'] ); //unset( $fields['billing']['last_name'] ); unset( $fields['billing']['billing_company'] ); unset( $fields['billing']['billing_country'] ); unset( $fields['billing']['billing_address_1'] ); unset( $fields['billing']['billing_address_2'] ); unset( $fields['billing']['billing_city'] ); unset( $fields['billing']['billing_state'] ); unset( $fields['billing']['billing_postcode'] ); // 移除配送字段 unset( $fields['shipping']['shipping_first_name'] ); unset( $fields['shipping']['shipping_last_name'] ); unset( $fields['shipping']['shipping_company'] ); unset( $fields['shipping']['shipping_country'] ); unset( $fields['shipping']['shipping_address_1'] ); unset( $fields['shipping']['shipping_addredd_2'] ); unset( $fields['shipping']['shipping_city'] ); unset( $fields['shipping']['shipping_state'] ); unset( $fields['shipping']['shipping_postcode'] ); return $fields; } // 添加自定义结账字段 public function add_custom_checkout_fields( $checkout ) { woocommerce_form_field( 'pdvselector', array( 'type' => 'select', 'required' => true, 'class' => array('form-row-first'), 'label' => '取餐点', 'options' => array( '' => '选择门店', 'email1@email.com' => '门店1', 'email2@email.com' => '门店2', 'email3@email.com' => '门店3' ) ), $checkout->get_value( 'pdvselector' ) ); woocommerce_form_field( 'dateselector', array( 'type' => 'date', 'required' => true, 'class' => array('form-row-last'), 'label' => '预订日期' ), $checkout->get_value( 'dateselector' ) ); woocommerce_form_field( 'hourselector', array( 'type' => 'time', 'required' => true, 'class' => array('form-row-last'), 'label' => '预订时间' ), $checkout->get_value( 'hourselector' ) ); } public function send_order_status_change_email( $order_id ) { $order = wc_get_order( $order_id ); //$order->update_status( '' ); } } $checkout = new CustomCheckout();
解答
需求可行性
完全可行,Woocommerce提供了丰富的钩子和API可以实现这两个需求。
推荐使用的钩子
woocommerce_checkout_update_order_meta:用于将前端提交的自定义字段值保存到订单元数据中,方便后续调用。woocommerce_checkout_order_processed:订单成功创建并保存后触发,适合处理订单提交后的后续操作(修改状态、发送邮件)。
修改后的完整代码
class CustomCheckout { public function __construct() { add_action( 'woocommerce_checkout_fields', array( $this, 'remove_default_checkout_fields') ); add_action( 'woocommerce_after_checkout_billing_form', array( $this, 'add_custom_checkout_fields') ); add_action( 'phpmailer_init', array( $this, 'mailtrap') ); add_filter( 'woocommerce_cart_needs_payment', '__return_false' ); // 新增:保存自定义字段到订单元数据 add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_custom_checkout_fields' ), 10, 1 ); // 新增:订单处理完成后修改状态并发送邮件 add_action( 'woocommerce_checkout_order_processed', array( $this, 'handle_order_submission' ), 10, 1 ); } // 配置Mailtrap用于邮件调试 public function mailtrap( $phpmailer ) { $phpmailer->isSMTP(); $phpmailer->Host = 'sandbox.smtp.mailtrap.io'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 2525; $phpmailer->Username = '****'; $phpmailer->Password = '***'; } // 移除默认结账字段 public function remove_default_checkout_fields( $fields ) { //unset( $fields['billing']['first_name'] ); //unset( $fields['billing']['last_name'] ); unset( $fields['billing']['billing_company'] ); unset( $fields['billing']['billing_country'] ); unset( $fields['billing']['billing_address_1'] ); unset( $fields['billing']['billing_address_2'] ); unset( $fields['billing']['billing_city'] ); unset( $fields['billing']['billing_state'] ); unset( $fields['billing']['billing_postcode'] ); // 移除配送字段 unset( $fields['shipping']['shipping_first_name'] ); unset( $fields['shipping']['shipping_last_name'] ); unset( $fields['shipping']['shipping_company'] ); unset( $fields['shipping']['shipping_country'] ); unset( $fields['shipping']['shipping_address_1'] ); unset( $fields['shipping']['shipping_address_2'] ); unset( $fields['shipping']['shipping_city'] ); unset( $fields['shipping']['shipping_state'] ); unset( $fields['shipping']['shipping_postcode'] ); return $fields; } // 添加自定义结账字段 public function add_custom_checkout_fields( $checkout ) { woocommerce_form_field( 'pdvselector', array( 'type' => 'select', 'required' => true, 'class' => array('form-row-first'), 'label' => '取餐点', 'options' => array( '' => '选择门店', 'email1@email.com' => '门店1', 'email2@email.com' => '门店2', 'email3@email.com' => '门店3' ) ), $checkout->get_value( 'pdvselector' ) ); woocommerce_form_field( 'dateselector', array( 'type' => 'date', 'required' => true, 'class' => array('form-row-last'), 'label' => '预订日期' ), $checkout->get_value( 'dateselector' ) ); woocommerce_form_field( 'hourselector', array( 'type' => 'time', 'required' => true, 'class' => array('form-row-last'), 'label' => '预订时间' ), $checkout->get_value( 'hourselector' ) ); } // 保存自定义字段到订单元数据 public function save_custom_checkout_fields( $order_id ) { if ( isset( $_POST['pdvselector'] ) ) { update_post_meta( $order_id, '_pdv_selector', sanitize_email( $_POST['pdvselector'] ) ); } if ( isset( $_POST['dateselector'] ) ) { update_post_meta( $order_id, '_date_selector', sanitize_text_field( $_POST['dateselector'] ) ); } if ( isset( $_POST['hourselector'] ) ) { update_post_meta( $order_id, '_hour_selector', sanitize_text_field( $_POST['hourselector'] ) ); } } // 处理订单提交:修改状态+发送邮件 public function handle_order_submission( $order_id ) { $order = wc_get_order( $order_id ); // 1. 修改订单状态为已完成 $order->update_status( 'completed', '预订自动确认', true ); // 2. 获取自定义字段中的目标邮箱 $target_email = get_post_meta( $order_id, '_pdv_selector', true ); if ( ! is_email( $target_email ) ) { return; // 邮箱无效则终止 } // 3. 构建邮件内容 $subject = '新的餐饮预订通知 - 订单#' . $order->get_order_number(); $order_date = get_post_meta( $order_id, '_date_selector', true ); $order_hour = get_post_meta( $order_id, '_hour_selector', true ); $message = ' <h3>您收到一个新的预订</h3> <p>订单编号:' . $order->get_order_number() . '</p> <p>预订日期:' . $order_date . '</p> <p>预订时间:' . $order_hour . '</p> <p>客户信息:' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() . '</p> <p>客户邮箱:' . $order->get_billing_email() . '</p> <p>客户电话:' . $order->get_billing_phone() . '</p> '; // 4. 发送邮件 wc_mail( $target_email, $subject, $message ); } } $checkout = new CustomCheckout();
关键代码说明
- 保存自定义字段:通过
woocommerce_checkout_update_order_meta钩子,将前端提交的自定义字段值存储到订单元数据中,后续可通过get_post_meta获取使用。 - 订单状态修改:调用
update_status方法将订单状态设为completed,第二个参数是状态变更备注,第三个参数true表示触发系统默认的状态变更邮件(不需要可设为false)。 - 发送自定义邮件:使用Woocommerce内置的
wc_mail函数,自动沿用你已配置的Mailtrap环境,确保邮件发送配置统一。
内容的提问来源于stack exchange,提问作者OHICT
相关产品推荐
相关产品推荐

