I want to stop send Woocommerce email for specific user/email. this is my example code to stop send email when order is completed.
<?php
add_filter( 'woocommerce_email_headers', 'ieo_ignore_function', 10, 2);
function ieo_ignore_function($headers, $email_id, $order) {
$list = 'admin#example.com,cs#example.com';
$user_email = (method_exists( $order, 'get_billing_email' ))? $order->get_billing_email(): $order->billing_email;
$email_class = wc()->mailer();
if($email_id == 'customer_completed_order'){
if(stripos($list, $user_email)!==false){
remove_action( 'woocommerce_order_status_completed_notification', array( $email_class->emails['WC_Email_Customer_Completed_Order'], 'trigger' ) );
}
}
}
But WP keep send the email. I try to search in Woocommerce docs and source (github) and Stackoverflow also but still cant solve this.
In this example "Customer completed order" notification is disable for specific customer email addresses:
// Disable "Customer completed order" for specifics emails
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
// Disable "Customer completed order
if( is_a('WC_Order', $order) && in_array($order->get_billing_email(), array('jack#mail.com','emma#mail.com') ) ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Note: A filter hook needs always to return the filtered main function argument
It can also be done from User IDs like:
// Disable "Customer completed order" for specifics User IDs
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
// Disable "Customer completed order
if( is_a('WC_Order', $order) && in_array($order->get_customer_id(), array(25,87) ) ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Similar: Stop specific customer email notification based on payment methods in Woocommerce
While answer above is working, this seems to be more straighforward solution:
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
if( in_array($recipient, ['some#email2block.com', 'another#email2block.com'] ) ) {
$recipient = '';
}
return $recipient;
}
Related
I am trying to add additional email recipient based on payment method Id on WooCommerce "New order" email notification.
Here is my code:
function at_conditional_admin_email_recipient($recipient, $order){
// if( ! is_a($order, 'WC_Order') ) return $recipient;
if ( get_post_meta($order->id, '_payment_method', true) == 'my_custom_gateway_id' ) {
$recipient .= ', xx1#xx.com';
} else {
$recipient .= ', xx2#xx.com';
}
return $recipient;
};
add_filter( 'woocommerce_email_recipient_new_order', 'at_conditional_admin_email_recipient', 10, 2 );
But the hook doesn't seem firing my function. What could be the reason?
Your code is outdated since Woocommerce 3, try the following instead:
add_filter( 'woocommerce_email_recipient_new_order', 'payment_id_based_new_order_email_recipient', 10, 2 );
function payment_id_based_new_order_email_recipient( $recipient, $order ){
// Avoiding backend displayed error in Woocommerce email settings (mandatory)
if( ! is_a($order, 'WC_Order') )
return $recipient;
// Here below set in the array the desired payment Ids
$targeted_payment_ids = array('bacs');
if ( in_array( $order->get_payment_method(), $targeted_payment_ids ) ) {
$recipient .= ', manager1#gmail.com';
} else {
$recipient .= ', manager2#gmail.com';
}
return $recipient;
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Also sometimes the problem can be related to a wrong payment method Id string in your code (so try first for example with WooCommerce "cod" or "bacs" payment methods ids, to see if the code works).
In Woocommerce, I need to stop email notifications sent to the customer when order place except when payment_method is BACS (Direct bank transfer).
I tried following in my active theme's function.php file:
add_filter( 'woocommerce_email_recipient_customer_on_hold_order_order', 'customer_order_email_if_bacs', 10, 2 );
function customer_order_email_if_bacs( $recipient, $order ) {
if( $order->payment_method() !== 'bacs' ) $recipient = '';
return $recipient;
}
But it don't work. Any help is appreciated.
Update 2
The woocommerce_email_recipient_{$email_id} filter is a composite hook and the right email ID to set in it is customer_on_hold_order and not customer_on_hold_order_order which will not work…
With the WC_Order object, since Woocommerce 3, you need to use get_payment_method() method.
To avoid Customer ON Hold email notification except for "Bacs" payment method use:
add_filter( 'woocommerce_email_recipient_customer_on_hold_order', 'customer_on_hold_order_for_bacs', 10, 2 );
function customer_on_hold_order_for_bacs( $recipient, $order ) {
if( is_a('WC_Order', $order) && $order->get_payment_method() !== 'bacs' ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
I want to be able to change who receives the Woocommerce email notifications based on what role the user is when ordering.
For example, If the user is logged in as a Wholesale Customer then a different email will be notified.
I've found how to change it when a new order is complete using the woocommerce_email_recipient_new_order hook but i can't find any hooks related to the failed or cancelled notifications.
add_filter( 'woocommerce_email_recipient_new_order', 'sv_conditional_email_recipient', 10, 2 );
function sv_conditional_email_recipient( $recipient, $order ) {
// Bail on WC settings pages since the order object isn't yet set yet
// Not sure why this is even a thing, but shikata ga nai
$page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
if ( 'wc-settings' === $page ) {
return $recipient;
}
// just in case
if ( ! $order instanceof WC_Order ) {
return $recipient;
}
if ( in_array( 'wholesale_customer', (array) $user->roles ) ) {
$recipient .= ', shaun#example.com';
return $recipient;
}
return $recipient;
}
add_filter( 'woocommerce_email_recipient_new_order', 'sv_conditional_email_recipient', 10, 2 );
Can anyone help please?
The hook you are already using is a composite hook: woocommerce_email_recipient_{$this->id}, where {$this->id} is the WC_Email ID like new_order. So you can set any email ID instead to make it work for the desired email notification.
Below You have the 3 hooks for "New Order", "Cancelled Order" and "Failed Order" that you can use for the same hooked function.
In your function, I have removed some unnecessary code and completed the code to get the customer data (the user roles) related to the order:
add_filter( 'woocommerce_email_recipient_new_order', 'user_role_conditional_email_recipient', 10, 2 );
add_filter( 'woocommerce_email_recipient_cancelled_order', 'user_role_conditional_email_recipient', 10, 2 );
add_filter( 'woocommerce_email_recipient_failed_order', 'user_role_conditional_email_recipient', 10, 2 );
function user_role_conditional_email_recipient( $recipient, $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;
// Get the customer ID
$user_id = $order->get_user_id();
// Get the user data
$user_data = get_userdata( $user_id );
// Adding an additional recipient for a custom user role
if ( in_array( 'wholesale_customer', $user_data->roles ) )
$recipient .= ', shaun#example.com';
return $recipient;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.
I am trying to send a PDF file to shop admin once the new order is placed. The issue with woocommerce_email_attachments hook is that email is sent to both customer and admin.
add_filter( 'woocommerce_email_attachments', 'attach_order_notice', 10, 3 );
function attach_order_notice ( $attachments, $id, $object ) {
$pdf_path = get_template_directory() . '/notice.pdf';
$attachments[] = $pdf_path;
return $attachments;
}
At the moment both customer and admin receive new order emails (including attachments) and I expect both customer and admin receive new order emails but only send an attachment to admin.
Is this even possible?
The $id is the WC_Email ID that you can use to target a specific email notification like "New order" that is sent to admin when an Order have been successfully placed, this way:
add_filter( 'woocommerce_email_attachments', 'attach_order_notice', 10, 3 );
function attach_order_notice ( $attachments, $email_id, $order )
{
// Only for "New Order" email notification (for admin)
if( $email_id == 'new_order' ){
$attachments[] = get_template_directory() . '/notice.pdf';
}
return $attachments;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and working
I am trying to send an email to the client when an order gets cancelled. By default, woocommerce only sends this email only to the admin of the site.
This code has solved the issue for related posts on the web:
function wc_cancelled_order_add_customer_email( $recipient, $order ){
return $recipient . ',' . $order->billing_email;
}
add_filter( 'woocommerce_email_recipient_cancelled_order', 'wc_cancelled_order_add_customer_email', 10, 2 );
add_filter( 'woocommerce_email_recipient_failed_order', 'wc_cancelled_order_add_customer_email', 10, 2 );
However, it seems like woocommerce removed those filter hooks completely.
Is there any way of doing this?
Thanks in advance!
In this custom function hooked in woocommerce_order_status_changed action hook, I am targeting "cancelled" and "failed" orders sending an the corresponding email notification to the customer (as admin will receive it on his side by WooCommerce automated notifications):
add_action('woocommerce_order_status_changed', 'send_custom_email_notifications', 10, 4 );
function send_custom_email_notifications( $order_id, $old_status, $new_status, $order ){
if ( $new_status == 'cancelled' || $new_status == 'failed' ){
$wc_emails = WC()->mailer()->get_emails(); // Get all WC_emails objects instances
$customer_email = $order->get_billing_email(); // The customer email
}
if ( $new_status == 'cancelled' ) {
// change the recipient of this instance
$wc_emails['WC_Email_Cancelled_Order']->recipient = $customer_email;
// Sending the email from this instance
$wc_emails['WC_Email_Cancelled_Order']->trigger( $order_id );
}
elseif ( $new_status == 'failed' ) {
// change the recipient of this instance
$wc_emails['WC_Email_Failed_Order']->recipient = $customer_email;
// Sending the email from this instance
$wc_emails['WC_Email_Failed_Order']->trigger( $order_id );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This should works in WooCommerce 3+
If you need, instead of changing the email, you can add it, to existing recipients:
// Add a recipient in this instance
$wc_emails['WC_Email_Failed_Order']->recipient .= ',' . $customer_email;
Related answer: Send an email notification when order status change from pending to cancelled