Dealing with digital products, I've added a GIFT function which works fine, but it does not work if the custom GIFT field is not filled in. If the GIFT field is filled in and when the order is set to Complete, the order complete email is sent to the email put in the GIFT field instead of the one entered as the billing email.
Any idea for where I'm going wrong here? I need it to send to the billing email if the GIFT field is not filled in and if the GIFT field is filled in, send only to the email entered in the GIFT field.
Here is the code:
// add gift message on checkout
add_action( 'woocommerce_after_order_notes', 'custom_checkout_field_before_billing' );
function custom_checkout_field_before_billing() {
$domain = 'woocommerce';
?>
<style>p#gift_field{display:none;}</style>
<div id="message">
<h3><i class="fa fa-gift"></i><?php _e( ' Is this a gift?', 'woocommerce' ); ?></h3>
<?php
woocommerce_form_field( 'gift_msg', array(
'type' => 'checkbox',
'class' => array( 'gift-checkbox' ),
'label' => __( 'To whom is this a gift?', 'woocommerce' ),
), WC()->checkout->get_value( 'cb_msg' ));
woocommerce_form_field( 'gift', array(
'type' => 'text',
'class' => array('msg t_msg'),
'label' => __('Enter the recipient\'s e-mail address, e.g: john.smith#email.com '),
'placeholder' => __(''),
), WC()->checkout->get_value( 'gift' ));
echo '</div>';
?><script>
jQuery(document).ready(function($) {
var a = '#gift_field';
$('input#gift_msg').change( function(){
if( $(this).is(':checked') )
$(a).show();
else
$(a).hide();
});
});
</script><?php
}
// add validation if box is checked but field is not filled in
add_action('woocommerce_after_checkout_validation', 'is_this_a_gift_validation', 20, 2 );
function is_this_a_gift_validation( $data, $errors ) {
if( isset($_POST['gift_msg']) && empty($_POST['gift']) )
$errors->add( 'gift', __( "You've chosen to send this as a gift, but did not submit a recipient email address.", "woocommerce" ) );
}
// update the gift field meta
add_action( 'woocommerce_checkout_update_order_meta', 'is_this_a_gift_save_meta');
function is_this_a_gift_save_meta( $order_id ) {
$gift_recipient_address = $_POST['gift'];
if ( ! empty( $gift_recipient_address ) )
update_post_meta( $order_id, 'gift', sanitize_text_field( $gift_recipient_address ) );
}
// add gift message to order page
function is_this_a_gift_order_display( $order ) { ?>
<div class="order_data_column">
<h3><?php _e( '<br>Gift For:', 'woocommerce' ); ?></h3>
<?php
echo get_post_meta( $order->id, 'gift', true ); ?>
</div>
<?php }
add_action( 'woocommerce_admin_order_data_after_order_details', 'is_this_a_gift_order_display' );
Here is the code that does not work as I need it to:
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'is_this_a_gift_replace_email_recipient', 10, 2 );
function is_this_a_gift_replace_email_recipient( $recipient, $order ) {
if ( ! is_a( $order, 'WC_Order' ) && ( ! empty( $gift_recipient_address ))) return $recipient;
$recipient = get_post_meta( $order->id, 'gift', true );
return $recipient;
}
I would appreciate some help with this. Thanks in advance!
There are some mistakes in your two last functions… try the following (that will replace your two last functions):
// add gift message to order page
add_action( 'woocommerce_admin_order_data_after_order_details', 'is_this_a_gift_order_display' );
function is_this_a_gift_order_display( $order ) {
if( $value = $order->get_meta('gift') ) :
echo '<div class="order_data_column">
<h3>' . __( '<br>Gift For:', 'woocommerce' ) . '</h3>
<p>' . $value . '</p>
</div>';
endif;
}
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'is_this_a_gift_replace_email_recipient', 10, 2 );
function is_this_a_gift_replace_email_recipient( $recipient, $order ) {
$gift_recipient = $order->get_meta('gift');
if ( is_a( $order, 'WC_Order' ) && $order->get_meta('gift') )
$recipient = $order->get_meta('gift');
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). It should work.
Related
In WooCommerce, I use code that shows a custom field on the checkout page. After filling out this field and placing the order by the client, the data is displayed on the "Thank You" page, when editing the order and in email notifications.
// Add the delivery custom field to the checkout
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {
echo '<div><h3>' . __('Custom Delivery') . '</h3>';
woocommerce_form_field( 'my_custom_delivery', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My Custom Delivery'),
'placeholder' => __(''),
), $checkout->get_value( 'my_custom_delivery' ));
echo '</div>';
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_custom_delivery'] ) ) {
update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
}
}
// Display custom delivery field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}
// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}
// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
$fields['Custom Delivery'] = array(
'label' => __( 'Custom Delivery' ),
'value' => $order->get_meta( 'my_custom_delivery' ),
);
return $fields;
}
But there are two problems that I would like to fix:
The field name "Custom Delivery" is constantly displayed on the order editing page and in email notifications, even when this field is not filled in by the client.
I need to hide the name "Custom Delivery" on these pages if the field is not filled by the client.
The data of the "Custom Delivery" field is shown after the table with the order data.
I need to show the data of this field in the order table on the "Thank You" page and in email notifications.
I will be happy for your help!
The field name "Custom Delivery" is constantly displayed on the order editing page and in email notifications, even when this field is
not filled in by the client.
I need to hide the name "Custom Delivery" on these pages if the field
is not filled by the client.
Replace
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
With
$my_custom_delivery = get_post_meta( $order->id, 'my_custom_delivery', true );
if ( !empty( $my_custom_delivery ) ) {
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . $my_custom_delivery . '</div>';
}
The data of the "Custom Delivery" field is shown after the table with the order data.
I need to show the data of this field in the order table on the "Thank
You" page and in email notifications.
Remove this
// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}
// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
$fields['Custom Delivery'] = array(
'label' => __( 'Custom Delivery' ),
'value' => $order->get_meta( 'my_custom_delivery' ),
);
return $fields;
}
And replace with
// Display the chosen delivery information everywhere on frontend order pages and on email notifications
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
$new_total_rows = [];
// Loop through Order total lines
foreach($total_rows as $key => $total ){
// Get the custom delivery
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
// Display delivery information before payment method
if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
$label = __('Custom Delivery:');
$value = $my_custom_delivery;
// Display 'Custom delivery' line
$new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
}
$new_total_rows[$key] = $total;
}
return $new_total_rows;
}
So then you get
// Add the delivery custom field to the checkout (backend)
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {
echo '<div><h3>' . __('Custom Delivery') . '</h3>';
woocommerce_form_field( 'my_custom_delivery', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My Custom Delivery'),
'placeholder' => __(''),
), $checkout->get_value( 'my_custom_delivery' ));
echo '</div>';
}
// Update the order meta with field value (backend)
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_custom_delivery'] ) ) {
update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
}
}
// Display custom delivery field value on the order edit page (frontend)
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}
// Display the chosen delivery information everywhere on frontend order pages and on email notifications (frontend)
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
$new_total_rows = [];
// Loop through Order total lines
foreach($total_rows as $key => $total ){
// Get the custom delivery
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
// Display delivery information before payment method
if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
$label = __('Custom Delivery:');
$value = $my_custom_delivery;
// Display 'Custom delivery' line
$new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
}
$new_total_rows[$key] = $total;
}
return $new_total_rows;
}
I have created some custom text fields to add to name field and custom message fields in cart page.So once user goes to cart page if he fills the data and click on proceed to checkout those data should be displayed in checkout page and once the customer place the order those custom fields data should be stored in orders page in admin as well.
As of now for order notes it is working fine and the field To is not working.Here is the code which i have tired.It i displaying only To as a heading in the admin panel But not displaying the name in to field in admin panel.
// Add the order_comments field to the cart
add_action( 'woocommerce_cart_collaterals', 'order_comments_custom_cart_field' );
function order_comments_custom_cart_field() {
?>
<div class="customer_notes_on_cart" style="clear:both;">
<?php
woocommerce_form_field('to_notes_text', array(
'placeholder' => __('To'),
'class' => array('form-row-last'),
'clear' => true,
), '');
?></div><?php
}
// PHP: Remove "(optional)" from non required fields
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
// Only on cart page
if( is_cart() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
// Process the checkout and overwriting the normal button
add_action( 'woocommerce_proceed_to_checkout', 'change_proceed_to_checkout', 15 );
function change_proceed_to_checkout() {
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
?>
<form id="checkout_form" method="POST" action="<?php echo wc_get_checkout_url(); ?>">
<input type="hidden" name="to_notes" id="to_notes" value="">
<button type="submit" class="checkout-button button alt wc-forward" style="width:100%;"><?php
esc_html_e( 'Proceed to checkout', 'woocommerce' ) ?></button>
</form>
<?php
}
// Jquery script for cart and checkout pages
add_action('wp_footer', 'customer_notes_jquery' );
function customer_notes_jquery() {
?>
<script>
jQuery(function($) {
<?php // For cart
if( is_cart() ) : ?>
$('#to_notes_text').on( 'blur', function(){
$('#to_notes').val($(this).val());
});
<?php // For checkout
elseif( is_checkout() && ! is_wc_endpoint_url() ) : ?>
$('#to_comments' ).val("<?php echo sanitize_text_field($_POST['to_notes']); ?>");
<?php endif; ?>
});
</script>
<?php
}
/**
* 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 ) {
?>
<?php
if ( ! empty( $_POST['to_notes_text'] ) ) {
update_post_meta( $order_id, 'To', sanitize_text_field( $_POST['to_notes_text'] ) );
}
}
/**
* 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){
?>
<?php
echo '<p><strong>'.__('TO').':</strong> ' . get_post_meta( $order->id, 'TO', true ) . '</p>';
}
Solved it by doing in this way
/**
* 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 ) {
?>
<?php
if ( ! empty( $_POST['from_comments'] ) ) {
update_post_meta( $order_id, 'FROM', sanitize_text_field( $_POST['from_comments']
) );
}
}
/**
* Update the order meta with field value
**/
add_action( 'woocommerce_checkout_update_order_meta',
'my_customs_checkout_field_update_order_meta' );
function my_customs_checkout_field_update_order_meta( $order_id ) {
?>
<?php
if ( ! empty( $_POST['to_comments'] ) ) {
update_post_meta( $order_id, 'TO', sanitize_text_field( $_POST['to_comments'] )
);
}
}
/**
* 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){
?>
<?php
echo '<p><strong>'.__('FROM').':</strong> ' . get_post_meta( $order->id, 'FROM', true
) . '</p>';
echo '<p><strong>'.__('TO').':</strong> ' . get_post_meta( $order->id, 'TO', true )
. '</p>';
}
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
?>
<?php
echo '<div id="my_custom_checkout_field"><h2>' . __('TO ') . '</h2>';
woocommerce_form_field( 'from_comments', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'placeholder' => __('FROM'),
), $checkout->get_value( 'from_comments' ));
woocommerce_form_field( 'to_comments', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'placeholder' => __('TO'),
), $checkout->get_value( 'to_comments' ));
echo '</div>';
}
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
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
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.