WooCommerce emails not sending: order emails and test emails
New-order emails never arrive, customers get no confirmation, or “send a test email” fails. In almost every case WooCommerce did its part and the mail was lost on the way out of the server. Here is how to tell which side failed, and the fix for each.
How a WooCommerce email is sent
WooCommerce does not send mail itself. When an order changes status it builds the email and hands it to wp_mail(), WordPress’s mail function. By default wp_mail() passes it to PHP’s mail(), which hands it to whatever mail program the server has. From there it goes to the recipient’s provider, which decides whether it is spam.
That gives three places for an email to disappear: WooCommerce never triggered it, the server never sent it, or the recipient’s provider rejected or filtered it. Each has a different fix, so find out which first.
Did WooCommerce trigger it?
- WooCommerce → Settings → Emails: is the email enabled, and is the recipient address right? “New order” goes to the address listed there, not to the admin email.
- Emails are triggered by status changes. “Processing order” fires when an order moves to processing — a paid card order. A bank transfer order goes to on-hold and sends “Order on-hold” instead. An order created in the admin by hand sends nothing until you change its status or use Order actions → Resend.
- Open the order: the notes at the side record status changes. No transition, no email.
- If transactional emails are deferred (woocommerce_defer_transactional_emails), they are sent by a background job; a stalled Action Scheduler queue delays them. Check WooCommerce → Status → Scheduled Actions for past-due actions.
Did the server send it?
Install an email log plugin (WP Mail Logging, or the log in most SMTP plugins) and trigger the email again. If the log shows the email with an error, the server refused to send it. If it shows it as sent but nobody received it, the problem is deliverability, below. If there is no entry at all, go back to the previous section — WooCommerce never called wp_mail().
Many hosts disable PHP mail() or limit it heavily, and cloud servers often block outgoing port 25 altogether. The reliable fix is to stop using mail() and send through a real mail service over SMTP or its API: your mailbox provider, or a transactional service such as Amazon SES, Postmark, Mailgun or Brevo. An SMTP plugin (WP Mail SMTP, FluentSMTP, Post SMTP) replaces wp_mail()’s transport without touching WooCommerce.
Sent, but not received
Gmail, Outlook and Yahoo now reject or bin mail that cannot prove it came from the domain in the From address. Mail sent by PHP from a web server almost never can. Three DNS records fix it:
| Record | What it proves | Where it comes from |
|---|---|---|
| SPF | This server or service may send for the domain | A TXT record listing your mail service |
| DKIM | The message was signed by the domain and not altered | A key your mail service gives you to publish |
| DMARC | What receivers should do when SPF or DKIM fail | A TXT record at _dmarc.yourdomain |
Set the From address under WooCommerce → Settings → Emails to an address on your own domain — not a gmail.com address, which your server is not allowed to send for — and make it match the domain your SMTP service is set up for.
When “send a test email” fails
A failed test from WooCommerce’s email settings, or from an SMTP plugin, means wp_mail() returned false — the transport refused the message. With an SMTP plugin, its test screen shows the actual error: wrong password, a port blocked by the host (try 587 with TLS, or 465 with SSL), or an account that requires an app password rather than the normal one. Without one, the PHP mail() function has failed, which is the cue to set up SMTP rather than debug mail().
The checklist
- The email is enabled and the recipient is right in WooCommerce → Settings → Emails.
- The order actually changed to the status that sends it — check the order notes.
- No past-due actions if emails are deferred.
- An email log shows whether wp_mail() was called and whether it succeeded.
- Send through SMTP or a transactional email service, not PHP mail().
- SPF, DKIM and DMARC published; From address on your own domain.
