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();
1. Hook into the
woocommerce_thankyouaction: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_emailmethod:3. Add the action hook in your
CustomCheckoutconstructor: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_changedaction. 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_emailmethod: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.