Most of the time the email leaves the store correctly - and dies on the way, because the receiving server has no reason to trust it. That distinction matters, because it changes where you look: instead of digging through WooCommerce settings, you check what the store sends with, and from which address.
The symptom is always similar. Orders come in, everything shows up in the admin panel, the money arrives - but the customer calls to say no confirmation reached them, and you find out about a new order only when you open the panel yourself. It is the most expensive silent failure in a store: it does not take the site down, it just eats trust and time.
Below is the diagnostic order I use myself when this lands on my desk. From the most common cause to the rarest, with specifics on where to click.
Step zero: pin down exactly what is broken
Before you change anything, narrow the problem. Three questions, three different diagnoses:
- Who is not getting the email - the customer, you, or both? If only you, it is usually trivial (wrong admin address or a filter in your own mailbox). If only the customer, the problem is deliverability. If both, the store is not sending at all.
- Which notification - all of them, or one specific one (for example “order processing” arrives but “order complete” does not)? One specific notification points at WooCommerce settings or at order status, not at sending.
- Since when - always, or from some particular moment? “Since last Wednesday” almost always means a plugin update, a change on the hosting side, or something expiring (an API key, a mailbox password).
Answering those three cuts the diagnosis in half. Write them down before you go further.
Cause number one: the store sends through PHP’s mail() function
By default WordPress sends mail with wp_mail(), which underneath uses PHP’s mail(). In practice that means the hosting server pushes the message out “on its own”, with no authentication, using a sender address nobody authorised it to use.
Ten years ago that worked. Today Gmail, Outlook and most business mail reject or spam-bin messages that carry no valid domain signature. The result: WooCommerce reports it sent, the host log confirms it sent - and the message is nowhere.
You will recognise it by two signs: mail to addresses on the same domain as the store arrives, and mail to Gmail does not; or it arrives, but always in spam, with a warning about an unverified sender.
What helps: sending over SMTP - connecting the store to a real mailbox, exactly the way you connect a mail client. The store then logs into the mail server and sends as an authenticated sender. This is what I set up on practically every store that passes through my hands - more on it below.
Cause number two: no SPF, DKIM or DMARC for the domain
This sits one layer above the sending method and is the most common reason for “the mail goes out but does not arrive”. Three DNS records on your domain tell receiving servers who is allowed to send on your behalf:
- SPF - the list of servers permitted to send mail from your domain
- DKIM - a cryptographic signature the sending server stamps on every message
- DMARC - the instruction telling the recipient what to do with a message that passed neither SPF nor DKIM
If the store sends from shop@yourcompany.com and the hosting server is not listed in the domain’s SPF, the recipient sees a message impersonating your company. And treats it exactly as it deserves.
What helps: setting SPF, DKIM and DMARC for the channel you actually send through. If you use Google Workspace for mail and the store sends through your host, those are two different channels and both have to be declared. You can check it by opening the headers of any message from the store in Gmail (“Show original”) and looking at three lines:
SPF,DKIM,DMARC. All three should readPASS.
Cause number three: the notification is switched off
Trivial, but it happens more often than it should - especially after a theme change or after somebody “was just checking something”.
In the panel: WooCommerce → Settings → Emails. You will see the list of every notification: new order, cancelled order, failed order, order on-hold, processing order, completed order, refunded order, invoice, password reset. Each has its own “Enable this email notification” switch.
While you are there, check two fields at the bottom of the same page: “From name” and “From address”. If that address is on a different domain than the store - the owner’s personal Gmail, say - it is a ready-made recipe for being rejected by filters. The sender address belongs on the store’s domain.
Cause number four: wrong recipient for admin notifications
This covers the “the customer gets it, I do not” case. In the same WooCommerce → Settings → Emails section, the “New order” notification has its own “Recipients” field. It does not automatically inherit the WordPress admin address after every change - it happily holds an old address from the build phase, or a former employee’s mailbox.
Put the current address in there. You can list several, separated by commas. Also check Settings → General → Administration email address - that is where WordPress system notifications go, including the ones about critical errors.
Cause number five: a plugin intercepts or blocks the sending
Several classes of plugin hook into mail sending and can stop it:
- Badly configured SMTP plugins - instead of fixing sending, they take it away from
wp_mail()and try to send through a server they do not have the right password for. The result is worse than having no plugin at all. - “Email log” plugins in test mode - some have a “log but do not send” option, switched on for testing once and never switched off.
- Performance and security plugins blocking outbound connections from the server on port 465 or 587.
- Invoicing and marketing plugins that swap out the WooCommerce email template and fall over on an error along the way, cutting the send off halfway.
What helps: bisection. Disable every plugin except WooCommerce, place a test order, check whether the mail arrived. If it did, switch plugins back on one at a time, checking after each. Do this on a copy or outside selling hours, and always after taking a backup.
Cause number six: the order status is not changing the way you think
WooCommerce does not send an email “because an order came in”. It sends because the order changed status. If payment does not confirm properly, the order gets stuck as “pending payment” - and that status has no customer notification attached. The order is visible in the panel, there is no email, and everything is working exactly as designed.
This is the most common false trail in the whole diagnosis. You can check it in half a minute: open the order in question and look at its status and at the notes on the right. If you see “pending payment”, or a note about a failed return from the gateway, the problem is not in email at all - it is in the conversation with your payment provider. Then look where it belongs: in the gateway configuration. I break that down in the piece on technical reasons carts get abandoned and in the payment gateway comparison.
Cause number seven: cron and the queue
WooCommerce sends some mail not immediately but through an internal job queue (Action Scheduler). That queue runs when somebody visits the site - and if wp-cron is disabled in wp-config.php and nobody set up a real server cron in its place, the jobs wait forever.
The characteristic symptom: emails do arrive, but hours late, or all at once in a batch.
You can check it in WooCommerce → Status → Scheduled Actions. If the “Pending” tab holds items dated several hours ago, the queue is stalled.
What helps: disabling
wp-cronin the config file and setting up a real cron in the hosting panel that fireswp-cron.phpevery five minutes. That is standard on any store with traffic, and it takes the overhead off every page view along the way.
The fix that holds: sending over SMTP
Causes one and two are dealt with in a single move, and it is what I set up by default in a store.
You need a mailbox on the store’s domain - it can live on the host, in Google Workspace, in Microsoft 365 or with a transactional email provider. From it you need: server, port, username, password. Then an SMTP plugin in WordPress and four fields to fill in.
Practical notes from actual builds:
- Do not use the plain mailbox password if the provider offers an app password. Google and Microsoft now require a separate app password when two-factor login is on. The plain password simply will not work.
- Port 465 with SSL, or 587 with TLS. If your host blocks one, try the other - that is the most common cause of “cannot connect to the SMTP server”.
- The sender address must be the same address you log in with. Sending as
contact@while logging in asshop@ends with the mail server itself rejecting the message. - Check the daily limits. A mailbox on shared hosting usually has a limit in the hundreds of messages per day. With a hundred orders a day - and each order generating several messages - that is not enough, and sending stops halfway through the day.
- Keep the password out of the database if the plugin allows it, in
wp-config.php. Databases leak more often than files.
How to confirm the fix works
Three tests, in this order, and I only close the ticket after the third:
- The SMTP plugin’s test send - every decent one has a “send a test email” button. It checks the connection to the mail server itself. Send it to an address on a different domain than the store, ideally Gmail.
- A test order end to end - going through payment for real (gateways have a test mode) and manually moving the status to “completed”. That way you check each message separately, not just the first one.
- The message headers in Gmail - open the mail from the store, the menu next to the reply arrow, “Show original”. Three
PASSresults on SPF, DKIM and DMARC mean the message is credible to any recipient, not just to your own mailbox.
Plus one thing permanently: an enabled log of outgoing mail. Then the next time somebody says “I did not get a confirmation”, you can see in a minute whether the message was ever created, at what time and to which address it went. Without a log, every one of those conversations starts with guesswork.
The diagnostic order in short
- Establish who is not getting which notifications, and since when
- Open the order and check its status - if it is “pending payment”, look at the gateway, not at email
- WooCommerce → Settings → Emails: notification enabled, what sender address, which recipients
- Send a test email and check whether it reaches Gmail and whether it lands in spam
- Open the headers: SPF, DKIM, DMARC - three
PASSresults or not - WooCommerce → Status → Scheduled Actions: is the queue stalled
- Disable plugins by bisection and find the one intercepting the send
- Set up SMTP and fill in the DNS records - that is the fix the problem does not come back from
The first five steps take fifteen minutes. If after them it is still unclear where the message dies, the problem is usually on the server or provider side, and that is where you have to read the logs.
When to hand it over
The line is fairly clear. Enabling a notification, correcting the sender address and wiring up SMTP are things to do yourself in an hour, with the mail provider’s instructions at hand.
DNS records, app passwords, sending limits and plugin conflicts are ground where it is easy to do more harm than good - a wrong SPF record can stop your ordinary company mail too, not just the store’s. If the store sells every day, paying someone works out cheaper than experimenting on the live system.
This is exactly the class of failure that should not happen twice - which is why for clients on ongoing care a mail log and send monitoring are part of the standard, not an extra.
FAQ
Why does the customer not get the email when I do? Because your mailboxes judge the message differently. Yours is usually on the same domain as the store and lets anything from its own server through. The customer’s mailbox - most often Gmail - checks SPF and DKIM, and with no signature it rejects the message or bins it as spam. This is not a WooCommerce problem, it is a sender credibility problem.
Is an SMTP plugin enough, or do I still have to touch DNS? The plugin alone solves authentication and that is usually enough for mail to start arriving. SPF and DKIM records in DNS take deliverability up another level and protect you from the spam folder at higher volumes. For a store both are worth doing - in this order: SMTP first, DNS second.
The store was sending email and stopped overnight. Where do I start? With the question of what changed that day: a plugin update, a mailbox password change, a hosting move, an expired certificate, an exceeded sending limit. The most common culprit in this scenario is a changed mailbox password - the SMTP plugin still holds the old one and quietly cannot log in. Second most common: an update that reset the settings. The checking order and how to update safely is written out in the safe update checklist.
Can the store send mail through an ordinary Gmail account? It can, and for a small store it works fine. The conditions: an app password instead of the plain password, a sender address identical to the login address, and awareness of the daily limit. With more traffic the limit starts getting in the way, and that is when you move to a transactional email provider.
Will the customer get an email if they paid by bank transfer? Yes, but a different one than with online payment. A bank transfer order lands in “on hold” status and the customer gets a message with the transfer details. The completion confirmation only goes out when you manually move the status to “processing” or “completed”. If nobody moves those statuses, the customer never gets a confirmation - and that is not a failure, it is a missing step in the process.
Would rather not watch over it every month yourself? I take sites and stores under ongoing care - backups, updates, monitoring, and priority when something breaks. Tell me what you run and I will send back scope and price.