You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Woocommerce自动修改订单状态并向指定地址发送邮件实现方案

问题描述

我正在基于Woocommerce搭建餐饮预订系统,已经完成以下操作:

  • 移除了所有不必要的结账字段
  • 禁用了支付网关,仅保留订单登记功能
  • 通过Elementor和自定义插件为结账页面添加了自定义字段(代码如下)

现在需要实现两个需求:

  1. 客户提交预订(订单)时,自动将订单状态修改为已完成
  2. 向客户通过自定义结账字段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();

关键代码说明

  1. 保存自定义字段:通过woocommerce_checkout_update_order_meta钩子,将前端提交的自定义字段值存储到订单元数据中,后续可通过get_post_meta获取使用。
  2. 订单状态修改:调用update_status方法将订单状态设为completed,第二个参数是状态变更备注,第三个参数true表示触发系统默认的状态变更邮件(不需要可设为false)。
  3. 发送自定义邮件:使用Woocommerce内置的wc_mail函数,自动沿用你已配置的Mailtrap环境,确保邮件发送配置统一。

内容的提问来源于stack exchange,提问作者OHICT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:52:34