Email recipient based on a custom field value in WooCommerce - php

I've added a custom field to the checkout page on my Woocommerce store. The field is 'Restaurant Location'. Upon a customer placing an order, my goal is to use the 'Restaurant Location' field to determine which email to send the order confirmation to.
Here's how I defined the custom field.
/////// Hook custom field in ///////
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields' );
function custom_checkout_fields( $fields ) {
$fields['order']['restaurant_location'] = array(
'label' => __('Food options', 'woocommerce'),
'placeholder' => _x('', 'placeholder', 'woocommerce'),
'required' => true,
'clear' => false,
'type' => 'select',
'options' => array(
'no' => __('New Orleans', 'woocommerce' ),
'br' => __('Baton Rouge', 'woocommerce' )
)
);
return $fields;
}
Here's my attempt at the email filter.
add_filter( 'woocommerce_email_recipient_new_order', 'gon_conditional_email_recipient', 10, 2 );
function gon_conditional_email_recipient( $recipient, $order ) {
$gon_order_data = $order->get_data();
$gon_restaurant_location = $gon_order_data['order']['restaurant_location'];
if ( $gon_restaurant_location == 'New Orleans' ) {
$recipient = 'test1#gmail.com';
return $recipient;
}
else if ( $gon_restaurant_location == 'Baton Rouge' ) {
$recipient = 'test2#gmail.com';
return $recipient;
}
return $recipient;
}
The email filter is working, i.e. I can get an email to go to either address, but I can't seem to pull in the '$gon_restaurant_location' variable properly. Any ideas?
Thanks,
pS

Your custom field value is not saved in database, so that's why is not working. Try this complete solution instead:
// Add the custom checkout field
add_filter( 'woocommerce_after_order_notes', 'restaurant_location_checkout_field' );
function restaurant_location_checkout_field( $checkout ) {
woocommerce_form_field( 'restaurant_location', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Food options', 'woocommerce'),
'required' => true,
'options' => array(
'' => __('Please select an option', 'woocommerce' ),
'New Orleans' => __('New Orleans', 'woocommerce' ),
'Baton Rouge' => __('Baton Rouge', 'woocommerce' )
)
), $checkout->get_value( 'restaurant_location' ));
}
// Process the checkout (checking)
add_action('woocommerce_checkout_process', 'restaurant_location_field_process');
function restaurant_location_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['restaurant_location'] )
wc_add_notice( __( 'Please select a food option .' ), 'error' );
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'restaurant_location_field_update_order_meta' );
function restaurant_location_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['restaurant_location'] ) ) {
update_post_meta( $order_id, '_restaurant_location', sanitize_text_field( $_POST['restaurant_location'] ) );
}
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Food options', 'woocommerce').':</strong> ' . get_post_meta( $order->get_id(), '_restaurant_location', true ) . '</p>';
}
// Conditional Email recipient filter based on restaurant location
add_filter( 'woocommerce_email_recipient_new_order', 'conditional_email_recipient', 10, 2 );
function conditional_email_recipient( $recipient, $order ) {
if( is_admin() ) return $recipient;
$location = get_post_meta( $order->get_id(), '_restaurant_location', true );
$recipient = $location == 'New Orleans' ? ',test1#example.com' : ',test1#example.com';
return $recipient;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works
Based on official developer documentation: Adding a custom special field

Related

Save multiple WooCommerce custom checkout fields as order meta data

Im looking to find some php code that will allow me to extract information (Name, address etc) from the checkout fields and add it to the order meta data.
Looking for this to be a simple as possible
Ive previously found this code which allows a custom box to be added to the checkout page, and I sort of understand how it works, however I want to capture their name when they type it into the billing first name box. I can seem to grasp how to capture this data and put it into the order meta data, Ive tried shortening the code and editing it a few times but I dont seem to be winning
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Phone From Checkout Form').':</strong> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
I like this and it does work but just not in the way i need it to work. thanks for any and all help
There are some mistakes and missing things in your codeā€¦ Try the following replacement code instead:
// Add shipping phone (in checkout and My account edit shipping address) and save field value
add_action( 'woocommerce_shipping_fields', 'add_shipping_phone_field' );
function add_shipping_phone_field( $fields ) {
$fields['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
// Display shipping phone value on the order edit pages under shipping section
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_shipping_phone_in_admin_orders' );
function display_shipping_phone_in_admin_orders( $order ){
$phone_value = $order->get_meta('_shipping_phone');
if ( ! empty($phone_value) ) {
echo '<p><strong>'.__('Shipping phone').':</strong> ' . $phone_value . '</p>';
}
}
// Add a custom checkout field
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_slug', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My custom field'),
'placeholder' => __('Enter somethingā€¦ '),
'required' => true,
), $checkout->get_value( 'my_field_slug' ) );
echo '</div>';
}
// Validate required checkout fields
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['my_field_slug']) && empty($_POST['my_field_slug']) ) {
wc_add_notice( __( '"My custom field" is a required field.' ), 'error' );
}
}
// Add custom checkout field value as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order ) {
if ( isset($_POST['my_field_slug']) && ! empty($_POST['my_field_slug']) ) {
$order->update_meta_data( 'My Field', sanitize_text_field( $_POST['my_field_slug'] ) );
}
}
// Display "My field" value on the order edit pages under billing section
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_my_custom_checkout_field_in_admin_orders', 10, 1 );
function display_my_custom_checkout_field_in_admin_orders($order){
$my_field_value = $order->get_meta('My Field');
if ( ! empty($my_field_value) ) {
echo '<p><strong>'.__('My field').':</strong> ' . $my_field_value . '</p>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Now If you need to extract some data from Woocommerce existing checkout fields and combine it in a custom way to save it as custom order meta data, try to be more explicit:
What fields?
How you want to combine it?
What is the custom field slug to be used to save that data combination?

Custom phone number field not showing in WooCommerce order email

I have successfully added the phone number field in Ship to different address and the phone number is showing in back-end as well. However I am not receiving the phone number in email.
Kindly Help
This code helps me to add field:
add_filter( 'woocommerce_checkout_fields', 'bbloomer_shipping_phone_checkout' );
function bbloomer_shipping_phone_checkout( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => 'Phone',
'required' => true,
'class' => array( 'form-row-wide' ),
);
return $fields;
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'bbloomer_shipping_phone_checkout_display' );
function bbloomer_shipping_phone_checkout_display( $order ){
echo '<p><b>Shipping Phone:</b> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
I have tried adding additional code in the above code (shown below) to show the phone number in email. Still doesn't work!
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['meta_key'] = array(
'label' => __( 'Shipping Phone' ),
'value' => get_post_meta( $order->id, '_shipping_phone', true ),
);
return $fields;
}
You're missing the correct meta_key, I have also slightly modified your existing code.
Note: by adjusting the priority argument, you can set your field in the correct location.
So you get:
// Shipping field on my account edit-addresses and checkout
function filter_woocommerce_shipping_fields( $fields ) {
$fields['shipping_phone'] = array(
'label' => __( 'Shipping Phone', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-wide' ),
'priority' => 55
);
return $fields;
}
add_filter( 'woocommerce_shipping_fields' , 'filter_woocommerce_shipping_fields', 10, 1 );
// Display on the order edit page (backend)
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
if ( $value = $order->get_meta( '_shipping_phone' ) ) {
echo '<p><strong>' . __( 'Shipping Phone', 'woocommerce' ) . ':</strong> ' . $value . '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
// Display on email notifications
function filter_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
// Get meta
$shipping_phone = $order->get_meta( '_shipping_phone' );
// NOT empty
if ( ! empty( $shipping_phone ) ) {
$fields['_shipping_phone'] = array(
'label' => __( 'Shipping Phone', 'woocommerce' ),
'value' => $shipping_phone,
);
}
return $fields;
}
add_filter( 'woocommerce_email_order_meta_fields', 'filter_woocommerce_email_order_meta_fields', 10, 3 );

WooCommerce Custom Field not showing in email or order info

I have a custom field for customer-id for client's ordering system, the field works and everything but for some odd reason, it won't send in an email or show in the order information in the admin areas. I have all of the proper code from WooDocs but it doesn't seem to work, my code is below. The link for the docs below.
Customizing checkout fields using actions and filters
/**
* Add the field to the checkout
**/
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field',30);
function my_custom_checkout_field( $checkout ) {
woocommerce_form_field( 'customer_number', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Customer Number <small>(Enter a customer number or leave empty)</small>'),
'placeholder' => __('Enter a number'),
'required' => false,
), $checkout->get_value( 'customer_number' ));
}
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['customer_number'] ) ) {
update_post_meta( $order_id, 'Customer Number', sanitize_text_field( $_POST['customer_number'] ) );
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Customer Number').':</strong> ' . get_post_meta( $order->id, 'Customer Number', true ) . '</p>';
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'Customer Number'; // This will look for a custom field called 'Customer Number' and add it to emails
return $keys;
}
Thanks in advance!

Adding Emails tPHP code

I found this code on here earlier today and I tried modifying it but I get an error code when I try to add more emails to the code (it starts with 2) not sure what I'm doing wrong.
Here is the example
This is my modified Code (tried adding a third email to the bottom and I'm getting a php error)
// Add the custom checkout field
add_filter( 'woocommerce_after_order_notes', 'restaurant_location_checkout_field' );
function restaurant_location_checkout_field( $checkout ) {
woocommerce_form_field( 'restaurant_location', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Select Location', 'woocommerce'),
'required' => true,
'options' => array(
'' => __('Please select an option', 'woocommerce' ),
'4289 boul St-Jean' => __('4289 boul St-Jean', 'woocommerce' ),
'3559 boul St-Charles' => __('3559 boul St-Charles', 'woocommerce' ),
'Baton Rouge' => __('Baton Rouge', 'woocommerce' )
)
), $checkout->get_value( 'restaurant_location' ));
}
// Process the checkout (checking)
add_action('woocommerce_checkout_process', 'restaurant_location_field_process');
function restaurant_location_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['restaurant_location'] )
wc_add_notice( __( 'Please select a food option .' ), 'error' );
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'restaurant_location_field_update_order_meta' );
function restaurant_location_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['restaurant_location'] ) ) {
update_post_meta( $order_id, '_restaurant_location', sanitize_text_field( $_POST['restaurant_location'] ) );
}
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Food options', 'woocommerce').':</strong> ' . get_post_meta( $order->get_id(), '_restaurant_location', true ) . '</p>';
}
// Conditional Email recipient filter based on restaurant location
add_filter( 'woocommerce_email_recipient_new_order', 'conditional_email_recipient', 10, 2 );
function conditional_email_recipient( $recipient, $order ) {
$location = get_post_meta( $order->get_id(), '_restaurant_location', true );
$recipient = $location == '4289 boul St-Jean' ? ',nicks#mtygroup.com' : ',nicsoti#yahoo.com' : ',nicks#mtygroup.com' ;
return $recipient;
}
This is the original Code I found
// Add the custom checkout field
add_filter( 'woocommerce_after_order_notes', 'restaurant_location_checkout_field' );
function restaurant_location_checkout_field( $checkout ) {
woocommerce_form_field( 'restaurant_location', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Food options', 'woocommerce'),
'required' => true,
'options' => array(
'' => __('Please select an option', 'woocommerce' ),
'New Orleans' => __('New Orleans', 'woocommerce' ),
'Baton Rouge' => __('Baton Rouge', 'woocommerce' )
)
), $checkout->get_value( 'restaurant_location' ));
}
// Process the checkout (checking)
add_action('woocommerce_checkout_process', 'restaurant_location_field_process');
function restaurant_location_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['restaurant_location'] )
wc_add_notice( __( 'Please select a food option .' ), 'error' );
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'restaurant_location_field_update_order_meta' );
function restaurant_location_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['restaurant_location'] ) ) {
update_post_meta( $order_id, '_restaurant_location', sanitize_text_field( $_POST['restaurant_location'] ) );
}
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Food options', 'woocommerce').':</strong> ' . get_post_meta( $order->get_id(), '_restaurant_location', true ) . '</p>';
}
// Conditional Email recipient filter based on restaurant location
add_filter( 'woocommerce_email_recipient_new_order', 'conditional_email_recipient', 10, 2 );
function conditional_email_recipient( $recipient, $order ) {
$location = get_post_meta( $order->get_id(), '_restaurant_location', true );
$recipient = $location == 'New Orleans' ? ',test1#example.com' : ',test1#example.com';
return $recipient;
}
Change this line :
$recipient = $location == '4289 boul St-Jean' ? ',nicks#mtygroup.com' : ',nicsoti#yahoo.com' : ',nicks#mtygroup.com' ;
to :
switch ($location) {
case '4289 boul St-Jean':
$recipient = ',nicks#mtygroup.com';
break;
case '3559 boul St-Charles':
$recipient = ',nicsoti#yahoo.com';
break;
default:
$recipient = ',nicks#mtygroup.com';
break;
}
Or just modify it to suits your needs

Adding a custom email recipient depending on selected custom checkout field value

I need for Woocommerce to send a custom email to different individuals depending on the option selected for Field Checkout (technically, the custom field is the person reporting on the product variant they have purchased, but I was not sure how to customize email receipt based on product variant purchased, so it is as follows).
First I established the custom field using the following code
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('Membership') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'select',
'class' => array('wps-drop'),
'label' => __('Membership purchased'),
'options' => array(
'blank' => __( 'Select membership ordered', 'wps' ),
'premium' => __( 'Premium Membership', 'wps' ),
'gold' => __( 'Gold Membership', 'wps' ),
'silver' => __( 'Silver Membership', 'wps' ),
'bronze' => __( 'Bronze Membership', 'wps' )
)
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] =='blank')
wc_add_notice( __( 'Please select status.' ), 'error' );
}
Then I setup email receipts based on value selected:
add_filter( 'woocommerce_email_recipient_new_order', 'new_order_conditional_email_recipient', 10, 2 );
function new_order_conditional_email_recipient( $recipient, $order ) {
// Get the order ID (retro compatible)
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
// Get the custom field value (with the right $order_id)
$my_field_name = get_post_meta($order_id, 'my_field_name', true);
if ($my_field_name == "premium")
$recipient .= ', emailreceipt1#gmail.com';
elseif ($my_field_name == "gold")
$recipient .= ', emailreceipt2#gmail.com';
elseif ($my_field_name == "silver")
$recipient .= ', emailreceipt1#gmail.com';
elseif ($my_field_name == "bronze")
$recipient .= ', emailreceipt2#gmail.com';
return $recipient;
}
When I use this code though, none of the receipts who are supposed to receive their designated email actually do. What's wrong with the code?
You have just missed to save the selected custom field value in the order meta data. I have also revisited your code a bit:
// Add custom checkout field
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('Membership') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'select',
'class' => array('wps-drop'),
'label' => __('Membership purchased'),
'required' => true, // Missing
'options' => array(
'' => __( 'Select membership ordered', 'wps' ),
'premium' => __( 'Premium Membership', 'wps' ),
'gold' => __( 'Gold Membership', 'wps' ),
'silver' => __( 'Silver Membership', 'wps' ),
'bronze' => __( 'Bronze Membership', 'wps' )
)
), $checkout->get_value( 'my_field_name' ) );
echo '</div>';
}
// Process the checkout
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( empty( $_POST['my_field_name'] ) )
wc_add_notice( __( 'Please select status.' ), 'error' );
}
// Save the custom checkout field in the order meta
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_field_checkout_update_order_meta', 10, 1 );
function my_custom_field_checkout_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) )
update_post_meta( $order_id, 'my_field_name', $_POST['my_field_name'] );
}
add_filter( 'woocommerce_email_recipient_new_order', 'new_order_conditional_email_recipient', 10, 2 );
function new_order_conditional_email_recipient( $recipient, $order ) {
if( is_admin() ) return $recipient;
// Get the order ID (Woocommerce retro compatibility)
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
// Get the custom field value (with the right $order_id)
$my_field_name = get_post_meta( $order_id, 'my_field_name', true );
if ($my_field_name == "premium")
$recipient .= ',emailreceipt1#gmail.com';
elseif ($my_field_name == "gold")
$recipient .= ',emailreceipt2#gmail.com';
elseif ($my_field_name == "silver")
$recipient .= ',emailreceipt1#gmail.com';
elseif ($my_field_name == "bronze")
$recipient .= ',emailreceipt2#gmail.com';
return $recipient;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested in WooCommerce 3+ and works.
As you will see the recipient is correctly added in "New Order" email notification depending on the customer choice.

Categories