Use an SPF Record to stop emails going into the Junk or Spam folder
Had problems sending emails from Woocommerce, they were going into the Spam folder. This often happens and turns out to be an easy fix - add an SPF record to the DNS for your domain and add the WH Tweaks plugin to set Return-Path to Sender.
Step 1 - set up an SPF record for your domain.
This will tell email servers that you're sending emails from a legit IP address for that domain eg. the SPF record below tells web-servers that an email ending with @startnet.co.uk is legit if it's sent from 22.214.171.124.
The easy way to create an SPF is to use a generator or modify the example below. I like http://www.spfwizard.net
Check "Softfail" at the end and should be fine. The value given should be something like :
v=spf1 mx a ptr ip4:126.96.36.199 ~all
NOTE: your web server might using IP6 so that address will also need to be added. You can mix ip4 and ip6 addresses like this:
v=spf1 mx a ptr ip4:188.8.131.52 ip6:2a02:4e8:4:2014::6d68:5837 ~all
Now go to your DNS control panel and add a TXT/SPF record with the address as blank or @ and with the value as above. So the result will look like:
@ TXT/SPF v=spf1 mx a ptr ip4:184.108.40.206 ~all
From the command line you can check the SPF record for a domain by using "host -t txt mywebsite.com".
Step 2 - Send a test to a Gmail address
I say send a test to Gmail, as I found Gmail makes it easy to analyse results. For example my emails were still going in the Spam folder, so I had a look at the message source and found this :
Return-Path: <firstname.lastname@example.org> Received: from email@example.com ([2b02:4e8:4:2016::6d68:5877]) by mx.google.com with ESMTPS id y32si10916651wmh.56.2016.10.28.09.10.52 for <firstname.lastname@example.org> (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Oct 2016 09:10:52 -0700 (PDT) Received-SPF: neutral (google.com: 2b02:4e8:4:2016::6d68:5877 is neither permitted nor denied by best guess record for domain of email@example.com) client-ip=2b02:4e8:4:2016::6d68:5877; Authentication-Results: mx.google.com; spf=neutral (google.com: 2b02:4e8:4:2016::6d68:5877 is neither permitted nor denied by best guess record for domain of firstname.lastname@example.org) email@example.com
Now "somelogin" was the username running the website and "crazyservername.poundhost.co.uk" was the server sending the emails.
This told me that the server was using IP6 and so the SPF had to be updated to that IP6 address - 2b02:4e8:4:2016::6d68:5877
Also more importantly, it told me that the email server was checking the Return-Path above everything else! So I had to somehow change the Return-Path header. Turned out to be quite easy to do, just...
Install the WP Tweaks to set Return-Path to Sender
I found the "WP Tweaks" plugin fixes the Return-Path header problem by setting it to the Sender address.
Just go to Settings -> WP Tweaks. I turned the other bits off, except for the "set Return-Path" option.
Once I did this, emails started going into the Inbox as they should do! 😀
How to test Woocommerce emails manually?
I should say I first of all used the command line to test sending emails from the server using this simple PHP script.
<?php $to = 'firstname.lastname@example.org'; $subject = 'the subject'; $message = 'hello'; $headers = 'From: My Website Shop <email@example.com>' . "\r\n"; mail($to, $subject, $message, $headers,"-f firstname.lastname@example.org"); ?>
Adding the "-f email@example.com" changed the Return-Path to the Sender, but bhe problem is this is from the command line and NOT Woocommerce! So, I found, borrowed and edited the following code from here and used it to manually test email sending from Woocommerce!
Note: The guy who originally wrote this has now written a useful plugin for Woocommerce so you can see what emails will look like when they send - it's called Woocommerce Email Test
<?php // include WordPress' wp-load include "./wp-load.php"; // verbose errors ini_set('display_errors', 1); error_reporting(E_ALL); // the order ID we're testing the email with - change this to a real order number $order_id =1234; // set up the email we want to send $email_class = 'WC_Email_Customer_Processing_Order'; // load the WooCommerce Emails $wc_emails = new WC_Emails(); $emails = $wc_emails->get_emails(); // select the email we want, update the recipient & trigger it to send $new_email = $emails[$email_class]; $new_email->recipient="firstname.lastname@example.org"; $new_email->trigger(); // show the email content //echo $new_email->get_content(); var_dump($new_email); ?>
Just run the above script and it'll send you a test email from Woocommerce - no order data will be filled out, but it does send from WordPress.