E-commerce9 min read

WooCommerce emails in Spam: the admin fix

Out of the box, WooCommerce hands every order confirmation to PHP's mail() function and hopes for the best. Here is the concrete path to get those orders back in the inbox — plugin, DNS, template, test.

WooCommerce ships with a queue of transactional mail: new order, processing, completed, refunded, customer invoice, password reset. Every single one of those is routed through WordPress'swp_mail() wrapper, which falls back to PHPmail() unless you intercept it. That is where the trouble starts.

PHP mail() talks to the local MTA (sendmail/postfix on the hosting server). That MTA relays from the shared hosting IP, which is almost always on a consumer blocklist. Gmail sees no DKIM, Outlook sees a mismatched envelope, and Mail.ru rejects outright. Admins stare at the WooCommerce log seeing "sent" and wonder why customers email support asking where the confirmation is.

The 4-step fix

Install an SMTP plugin, route through an authenticated relay, add SPF and DKIM for the sender domain, and seed-test every status email across Gmail, Outlook, Yahoo and Mail.ru before you declare victory.

Why PHP mail() kills WooCommerce deliverability

On shared hosting — SiteGround, Bluehost, Hostinger, any cPanel environment — the outbound path from PHP mail() is identical for every tenant on the IP. Your order confirmation goes out alongside someone else's newsletter blast alongside a third tenant's password reset. The IP reputation is the lowest common denominator.

  • No DKIM signing: PHP mail() does not sign. Gmail requires DKIM for any volume, and WooCommerce at a few orders an hour already counts as volume.
  • Envelope mismatch: the MAIL FROM is usually the cPanel user (cpanel_user@server42.hostprovider.net), not orders@yourstore.com. That fails DMARC alignment the moment you publish a DMARC record.
  • Shared IP blocklisting: Spamhaus PBL, UCEPROTECT L3 and Sorbs routinely list shared hosting ranges. Your mail never reaches the filter — it bounces at the border.
  • No retry intelligence: PHP mail() returns true if the local MTA accepted the message. What happens after that is invisible to WooCommerce.

Step 1: install an SMTP plugin

The three reliable choices for WooCommerce are WP Mail SMTP, Post SMTP and Fluent SMTP. All three hook wp_mail() and route through an authenticated relay of your choice — SendGrid, Postmark, SES, Brevo, Mailgun, or plain authenticated SMTP against Google Workspace / Microsoft 365.

For a store doing under 10k emails a month, the pragmatic pick is WP Mail SMTP with Brevo (free 300/day) or SendLayer. For higher volume, split the transactional stream to Postmark and keep it separate from any marketing list.

WP Mail SMTP + SendGrid example

// wp-config.php — do NOT put raw creds here, use env vars
define( 'WPMS_ON', true );
define( 'WPMS_MAIL_FROM', 'orders@yourstore.com' );
define( 'WPMS_MAIL_FROM_NAME', 'Your Store' );
define( 'WPMS_MAILER', 'sendgrid' );
define( 'WPMS_SENDGRID_API_KEY', getenv('SENDGRID_API_KEY') );
define( 'WPMS_SENDGRID_DOMAIN', 'yourstore.com' );
Do not keep API keys in wp-config.php

Many tutorials paste the raw API key into wp-config.php. That file ships to git, ends up in backups, and leaks through plugin exploits. Use an env var via your host's panel or a secrets plugin. Rotate if a key was ever committed.

Step 2: authenticate the domain

An SMTP plugin without DNS authentication is a sticker on a broken window. You still need SPF, DKIM and DMARC on the domain in yourWPMS_MAIL_FROM. Every relay publishes the exact records — copy them into your DNS provider and wait for propagation.

DNS checklist

  1. SPF: one record at the apex. If you already use Google Workspace for corporate mail, merge the relay include into the existing SPF. Do not create a second TXT record at the root — SPF will fail permanent error.
  2. DKIM: the relay gives you a selector and CNAMEs. Publish exactly as shown. Verify with dig TXT selector._domainkey.yourstore.com.
  3. DMARC: start at v=DMARC1; p=none; rua=mailto:dmarc@yourstore.com;. Move to p=quarantine once you confirm alignment is clean.
  4. Return-Path / bounce domain: most relays require a CNAME so bounces align with your domain. This is what turns DMARC from green-with-one-yellow to green-green.
; example zone file additions for yourstore.com
yourstore.com.              TXT   "v=spf1 include:sendgrid.net include:_spf.google.com ~all"
s1._domainkey.yourstore.com CNAME s1.domainkey.u1234567.wl.sendgrid.net.
s2._domainkey.yourstore.com CNAME s2.domainkey.u1234567.wl.sendgrid.net.
_dmarc.yourstore.com        TXT   "v=DMARC1; p=none; rua=mailto:dmarc@yourstore.com; fo=1"
em.yourstore.com            CNAME u1234567.wl.sendgrid.net.

Step 3: clean up the WooCommerce template

The default WooCommerce email template is fine for a small store, but a few tweaks under WooCommerce > Settings > Emails tip the balance in your favour.

  • Disable the header image for New Order and Customer Invoice — or keep it under 10 KB. Heavy banners push confirmations into Gmail Promotions.
  • From name + from address: match your store brand. orders@yourstore.com is better thanwordpress@yourstore.com.
  • Plain-text alternative: WooCommerce generates one automatically but many third-party plugins break it. Send a test and view source to confirm a text/plain part exists.
  • Footer: remove the "Powered by WooCommerce" default string. Replace with a support email and a physical address — that alone lifts trust signals.

Step 4: seed-test every status email

WooCommerce has a dozen trigger points. Each one uses a slightly different template and a different subject line. Testing only "New order" tells you nothing about whether "Refunded" or "Failed payment" will land. Walk through all of them.

  1. Place a real test order against a set of seed mailboxes covering Gmail, Outlook, Yahoo, iCloud, Mail.ru and Yandex.
  2. Mark it Processing. Check placement of the processing email.
  3. Mark it Completed. Check again.
  4. Refund. Check again.
  5. Trigger a password reset for one of the seed accounts. That uses the core WordPress template, not WooCommerce's — often a different failure mode.
Free WooCommerce deliverability test

Run an inbox placement test across 20+ seed mailboxes — see which WooCommerce emails hit inbox, which go to Promotions, and which get silently dropped. No signup.

→ Run Free Test · → Join the WordPress plugin beta

Common traps after the fix

  • Caching plugins: WP Rocket or LiteSpeed Cache can cache admin-ajax responses and break SMTP plugin debug logs. Exclude /wp-admin/ from cache.
  • Multisite: network activation of WP Mail SMTP is different from per-site activation. In multisite stores, set the relay at network level and let each site override from/name.
  • Order action emails: third-party plugins (Order Delivery Date, Subscriptions, Bookings) often bypass wp_mail(). They call PHP mail() directly. Audit each plugin.

FAQ

Do I still need SPF and DKIM if I use WP Mail SMTP with Gmail?

Yes. Gmail as a relay still requires the sender domain to authenticate. Without DKIM on yourstore.com, Gmail signs as gmail.com and DMARC alignment fails.

Which SMTP relay is best for a small WooCommerce store?

For under 10k/month, Brevo (free tier) or SendLayer are painless. For transactional-only, Postmark gives the cleanest placement. SES is cheapest at scale but needs more setup.

Can I use Gmail SMTP for WooCommerce?

Yes, via WP Mail SMTP's Google Workspace mailer. OAuth auth, 2000/day limit. Fine for small stores, overkill on setup vs a dedicated transactional relay.

Why are new-order emails to the admin still missing?

The admin notification is a separate template and often a separate From. Check the to-address is not an internal wildcard that your mailbox filters to trash, and test it through the seed list too.
Related reading

Check your deliverability across 20+ providers

Gmail, Outlook, Yahoo, Mail.ru, Yandex, GMX, ProtonMail and more. Real inbox screenshots, SPF/DKIM/DMARC, spam engine verdicts. Free, no signup.

Run Free Test →

Unlimited tests · 20+ seed mailboxes · Live results · No account required