Adding a second email address to a completed order in WooCommerce

Before I ask this question, I know there is a (legitimate) hesitation to answer questions here about Woo products since they have their own support and their users should be encouraged to use that. I am a paying Woo user but couldn’t solve this with their paid support, and my question is about overriding classes in WP so I hope it will get a fair hearing.

My question: when a completed order email is sent out to a customer, I also need to receive this email, verbatim and automatically, exactly as it is sent to the customer rather than in some other format such as is created by the various invoice PDF plugins for WooCommerce. I can very easily accomplish this by changing the following line in /woocommerce/classes/emails/class-wc-email-customer-completed-order.php:

$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

to read:

$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
$this->send( me@myemail.com, $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

However, obviously a hack like this isn’t going to survive an upgrade. I have a child theme which overrides WooCommerce templates. Is there any equivalent mechanism by which I can override a class in a similarly encapsulated way? Or can you recommend an alternate approach (besides setting the SMTP server to bcc all outgoing emails to the second address) for accomplishing my specific task of receiving this email when the customer also receives it?

Solutions Collecting From Web of "Adding a second email address to a completed order in WooCommerce"

There’s actually a filter that you can use, see abstract-wc-email.php, line 214:

return apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object );

you can put the following in your functions.php:

add_filter( 'woocommerce_email_recipient_customer_completed_order', 'your_email_recipient_filter_function', 10, 2);

function your_email_recipient_filter_function($recipient, $object) {
    $recipient = $recipient . ', me@myemail.com';
    return $recipient;
}

the only drawback is that the recipient will see both your address & his own in the To: field.


Alternatively, building on Steve’s answer, you can use the woocommerce_email_headers filter. the $object passed allows you to only apply this to the completed order email:

add_filter( 'woocommerce_email_headers', 'mycustom_headers_filter_function', 10, 2);

function mycustom_headers_filter_function( $headers, $object ) {
    if ($object == 'customer_completed_order') {
        $headers .= 'BCC: My name <my@email.com>' . "\r\n";
    }

    return $headers;
}

And there is another filter that will give you access to the $header variable which can allow you to BCC your emails so that you get a carbon copy of every email that goes to your clients on Woocommerce. This is just as easy as the code above except your clients will not see your email address.

Just like the solution above you would add the following code:

add_filter( 'woocommerce_email_headers', 'mycustom_headers_filter_function', 10, 2);

function mycustom_headers_filter_function($headers, $object) {
    $headers = array();
    $headers[] = 'Bcc: your name <me@myemail.com>';
    $headers[] = 'Content-Type: text/html';
    return $headers;
}

This filter applies to all $headers and also hard codes the type as text/html. Note that you do not include the ‘/r/n’ in the content type declaration – this might cause an error in wp_mail() – which is what Woocommerce uses to send your messages.

I’m using this code so I can verify that Woocommerce v2.0.14. Should also work in earlier versions but not sure how long the filter has been included.