1

I'm using the following code in my theme functions.php file to send order failed email only to customer instead of admin:

function wc_failed_order_email_to_customer( $recipient, $order ){
     return $recipient = $order->billing_email;
}
add_filter( 'woocommerce_email_recipient_failed_order', 'wc_failed_order_email_to_customer', 10, 2 );

And it works…

But I'm getting the following error in php log file:

Error: billing_email was called incorrectly. Order properties should not be accessed directly. Backtrace: require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), do_action('template_redirect'), WP_Hook->do_action, WP_Hook->apply_filters, WC_AJAX::do_wc_ajax, do_action('wc_ajax_checkout'), WP_Hook->do_action, WP_Hook->apply_filters, WC_AJAX::checkout, WC_Checkout->process_checkout, WC_Checkout->process_order_payment, WC_Braintree\Plugin_Framework\SV_WC_Payment_Gateway_Direct->process_payment, WC_Braintree\Plugin_Framework\SV_WC_Payment_Gateway_Direct->do_transaction, WC_Braintree\Plugin_Framework\SV_WC_Payment_Gateway->do_transaction_failed_result, WC_Braintree\Plugin_Framework\SV_WC_Payment_Gateway->mark_order_as_failed, WC_Order->update_status, WC_Order->save, WC_Order->status_transition, do_action('woocommerce_order_status_pending_to_failed'), WP_Hook->do_action, WP_Hook->apply_filters, WC_Emails::send_transactional_email, do_action_ref_array, WP_Hook->do_action, WP_Hook->apply_filters, WC_Email_Failed_Order->trigger, WC_Email->get_recipient, apply_filters('woocommerce_email_recipient_failed_order'), WP_Hook->apply_filters, wc_failed_order_email_to_customer, WC_Abstract_Legacy_Order->__get, wc_doing_it_wrong. This message was added in version 3.0.

How can I solve this error?

Community
  • 1
  • 1
tatifox
  • 119
  • 4
  • 13

2 Answers2

2

You need to replace billing_email by the WC_Order method get_billing_email() like:

add_filter( 'woocommerce_email_recipient_failed_order', 'wc_failed_order_email_to_customer', 10, 2 );
function wc_failed_order_email_to_customer( $recipient, $order ){
     if( ! is_a( $order, 'WC_Order' ) ) 
         return $recipient;

     if( $billing_email = $order->get_billing_email() ) 
         $recipient = $billing_email;
     return $recipient;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you, in the 4th line it should be $recipient, also in the Emails settings tab, there is an "Fatal error" message and it doesn't load the page fully, something wrong. – tatifox Dec 13 '18 at 20:50
  • @tatifox I have updated my code… You should not get any error now. – LoicTheAztec Dec 13 '18 at 23:29
  • 2
    It doesn't send the email, but when `is_admin()` was replaced with `! is_a( $order, 'WC_Order' )` it worked. – tatifox Dec 14 '18 at 05:39
  • @talifox Yes you are right… I have made other answers with that… I was tired, sorry (updated). – LoicTheAztec Dec 14 '18 at 10:05
  • It did not work for me. Instead, tried https://stackoverflow.com/a/47649154/4446644 and done! – José Augustinho Aug 03 '20 at 17:56
  • Does anyone know if the above code still works with the current version of Wordpress + Woocommerce? – user1481153 Jul 05 '23 at 16:14
  • With all admin notifications (new, cancelled, failed), the composite hook `woocommerce_email_recipient_{$email_id}` doesn't work. See [this thread](https://stackoverflow.com/a/47649154/4446644) as a replacement. Or use woocommerce_email_headers` hook to add a custom email recipient as CC or BCC. – LoicTheAztec Jul 05 '23 at 16:56
0

If, the previous code not working, then try this:

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 );
    } 
}