I’m customizing woocommerce to create a food reservation system. I’ve successfully removed all unnecessary checkout fields and I’ve disabled the payments gateway because I just need to register the order. I’m now adding some custom fields to the checkout page using elementor and a custom plugin I’m writing. I have this code ath the moment and I need to customize the checkout, when a client place a reservation (order), I will need to send an email to some custom email adresses that can be selected from the user using a custom checkout field I’ve added. Is possible to automatically change the order status to completed and send the email, and what is the hook to use?
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' );
}
# debug email woocommerce
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'] );
# Rimuovo campi spedizione
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' => 'Punto di ritiro',
//'label_class'
'options' => array(
'' => 'Select a store',
'[email protected]' => 'Value 1',
'[email protected]' => 'Value 2',
'[email protected]' => 'Value 3'
)
),
$checkout->get_value( 'pdvselector' )
);
#
woocommerce_form_field(
'dateselector',
array(
'type' => 'date',
'required' => true,
'class' => array('form-row-last'),
'label' => 'Reservation day'
),
$checkout->get_value( 'dateselector' )
);
#
woocommerce_form_field(
'hourselector',
array(
'type' => 'time',
'required' => true,
'class' => array('form-row-last'),
'label' => 'Reservation hour'
),
$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();
2
Answers
1. Hook into the
woocommerce_thankyou
action:This action fires when an order is placed successfully, making it ideal for handling post-order tasks like status changes and email notifications.
2. Modify your
send_order_status_change_email
method:3. Add the action hook in your
CustomCheckout
constructor:When a customer places an order, the send_order_status_change_email method will be triggered. It will retrieve the selected email address from the pdvselector custom field. The order status will be updated to "completed". The "customer_completed_order" email template will be sent to the selected email address, informing them of the reservation.
EDIT 1
You can avoid sending two emails by utilizing a different hook and making some adjustments to your code.
1. Hook into
woocommerce_order_status_changed
:Instead of using
woocommerce_thankyou
, leverage thewoocommerce_order_status_changed
action. This fires whenever the order status changes, allowing you to capture the completion moment without relying on the checkout page completion.2. Refine your
send_order_status_change_email
method:Modify your existing method to check the new order status before sending the email.
3. Register the action hook:
Update your constructor’s code to register the hook with the updated method:
With this, the email will only be sent when the order status changes to "completed," effectively preventing duplicate emails and confirming the successful order completion to the selected email address.
The correct hook to be used is not
woocommerce_thankyou
butwoocommerce_new_order
to avoid multiple email notifications…For email debugging, you can use WP Mail Catcher plugin…
In the code below, I have added some functions to validate and save the custom checkout field values… When the order is submitted, the order is auto-completed, and an email notification is sent to the selected store as CC…
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.