Customers get their order confirmations fine, but I have never once received the New order email, and it is not in my spam folder either
The admin notification is your store's domain mailing your store's own domain. WooCommerce sends it as orders@yourstore.com to a recipient at yourstore.com, over PHP on the web server, with no DKIM signature and from an IP that your SPF record does not authorize. An unauthenticated message claiming to be an internal sender is treated far more harshly than the same message arriving at an unrelated domain, and some providers hold it at the gateway rather than filing it to Junk, which is why you cannot find it anywhere. Customer mail scrapes through, admin mail does not.
The fix
Put an authenticated SMTP sender in front of wp_mail(), complete the provider's domain verification, publish the DKIM selector records and add its include to your single SPF TXT record. As a stopgap while you set that up, change the Recipient(s) field under WooCommerce > Settings > Emails > New order to an address on a different domain so you can at least see orders arriving. Then place a real test order to an Unspam seed address, confirm the DKIM d= value is your store domain, and switch the recipient back.
Gmail customers get everything. Outlook and Hotmail customers get nothing at all, and I never see a bounce
Because PHP hands the message to a local mail server and WooCommerce's log records only that it handed the email to the mail system successfully, your log reads Sent and there is no bounce anywhere to read.
The fix
Get off the PHP mail path entirely. Route wp_mail() through an authenticated SMTP provider, finish domain verification so the message carries a DKIM signature on your store domain, and add the provider's SPF include. The second thing the provider buys you is a bounce and suppression record, so silent drops stop being invisible. Then run an inbox placement test and confirm the message actually reaches an Outlook seed mailbox, not just a Gmail one.
Password reset emails never arrive, so customers who forget their password just give up and I lose the sale
Reset password is one of the notifications listed under WooCommerce > Settings > Emails, which means it can be switched off like any other, and it travels the same unauthenticated route as everything else. It is also the worst one to lose, because it is the only email the customer is actively waiting for and there is no order in your admin to tell you it failed. A disabled notification, a missing recipient and a filtered message all look identical from the storefront.
The fix
Open WooCommerce > Status > Logs and filter the transactional-emails source. Disabled means the notification is off under WooCommerce > Settings > Emails > Reset password, Skipped means a precondition such as a recipient was missing, Failed means the mail service returned an error, and Sent means WooCommerce handed it off and it was filtered downstream. If nothing is logged at all, check where the reset was requested: WooCommerce warns that WordPress password reset emails and other WordPress admin emails might not appear in that log, and points you to your SMTP provider's logs instead. Fix the route first with an SMTP sender that signs for your domain, then re-test by requesting a reset for an account whose email address is an Unspam seed address.
I installed an SMTP plugin like every guide told me to, and the emails still go to spam
SMTP solved the sending problem, not the identity problem. The provider now relays your mail from a reputable IP under its own Return-Path, so SPF passes against the provider's domain. Until you finish domain verification, the message is DKIM-signed with the provider's domain rather than yours. Your From header still says yourstore.com, nothing aligns to it, and DMARC fails exactly as it did before, just from better infrastructure.
The fix
In the provider's dashboard, verify the domain rather than a single sender address, and publish every DKIM record it issues. Send one real order email to a seed address and read the DKIM d= value: if it is still the provider's domain, verification is incomplete. Keep a single SPF TXT record with the provider's include added, for example v=spf1 include:_spf.google.com include:sendgrid.net ~all, rather than publishing a second SPF record, which invalidates both.
Order emails arrive hours late, sometimes not until the next morning, and checkout was crawling before that
This is the deferred email queue. WooCommerce can move transactional emails out of the checkout request so the customer is not waiting on the mail server: it is the Deferred emails feature at WooCommerce > Settings > Advanced > Features, off by default, and code can also force it with the woocommerce_defer_transactional_emails filter. The queue runs on Action Scheduler, and WooCommerce documents Action Scheduler as relying on WP-Cron, which is dependent on site traffic. A store with a quiet night has no visitor to trigger the queue, so the receipt waits for the next one.
The fix
Open WooCommerce > Status > Scheduled Actions and look for past-due actions; a pile of them more than a day old confirms it. WooCommerce's own guidance is to set up a custom server-side cron job to run WP-Cron independently and bypass the traffic dependency, which fixes timing for every scheduled job in the store, not just email. If checkout was already slow before the deferral, the cause is usually the mail hop happening inside the request, and moving to an SMTP provider removes that too.