If WordPress password-reset emails, contact form submissions, or WooCommerce order confirmations are landing in spam — or not arriving at all — the cause is almost always the same: WordPress's default wp_mail() sends through PHP's built-in mail() function, which most receiving mail servers treat with deep suspicion by default. This is a solvable problem, and the fix is the same regardless of what plugin triggered the email.
Why PHP's default mail sending fails
mail() hands the message to the server's local mail transfer agent, which typically sends it directly without proper authentication. Modern email providers (Gmail, Outlook, Yahoo) heavily weight three authentication mechanisms when deciding whether to deliver, flag, or reject a message — and PHP's default sending path satisfies none of them by default:
- SPF (Sender Policy Framework) — verifies the sending server is authorized to send mail for the domain
- DKIM (DomainKeys Identified Mail) — cryptographically signs the message to prove it wasn't altered and genuinely came from the claimed domain
- DMARC — tells receiving servers what to do when SPF/DKIM fail, and is increasingly required outright by major providers (Gmail and Yahoo both now require it for bulk senders)
Without these, mail from a generic hosting server's IP — often shared with hundreds of other sites, some of which may have bad sending reputations — gets flagged as spam or rejected outright.
The actual fix: send through a real SMTP provider
Route WordPress's outgoing mail through a dedicated transactional email provider (rather than the server's local mail function) using an SMTP plugin. This does two things: it authenticates properly against SPF/DKIM/DMARC because you're sending from infrastructure built for deliverability, and it gives you actual visibility (delivery/bounce/open tracking) instead of firing emails into a void.
Steps:
- Choose a transactional email provider appropriate to your volume (they range from free tiers for low-volume sites to dedicated infrastructure for high-volume stores).
- Verify your sending domain with that provider — this is where SPF and DKIM DNS records get set up, proving to receiving servers that the provider is authorized to send on your domain's behalf.
- Configure an SMTP plugin in WordPress with that provider's credentials, so
wp_mail()routes through their authenticated servers instead of PHP's localmail(). - Set up a DMARC record for your domain if you don't already have one, even a permissive
p=nonepolicy — its presence alone improves how major providers treat your mail, and it gives you visibility into spoofing attempts against your domain.
Send from a real, matching domain — not a mismatched "from" address
Sending "from" [email protected] when your SPF/DKIM records don't cover that exact sending pattern, or sending from a free webmail address ([email protected]) through your server, both hurt deliverability. The from-address domain needs to match what you actually authenticated in step 2.
Test deliverability, don't assume it
After setup, send a real test email to a mail-tester-style tool that scores SPF/DKIM/DMARC alignment and spam-trigger content, rather than just checking that an email arrived in your own inbox — your own address may have relationship history with your domain that a first-time recipient wouldn't.
WooCommerce-specific consideration
Order confirmations and shipping notifications are transactional emails customers actively expect and often need (receipts, tracking numbers) — deliverability failures here are a direct customer-experience and support-ticket problem, not just a marketing metric. It's worth verifying this specifically after any hosting or plugin change, not just at initial setup.
The takeaway
WordPress email problems are almost never a WordPress bug — they're a missing authentication layer. Route mail through a real SMTP provider with SPF, DKIM, and DMARC properly configured for your domain, and the vast majority of deliverability issues disappear.
