Order confirmations, payment receipts, shipping notices and password resets are the emails a store cannot afford to lose — and WooCommerce sends every one of them through WordPress's wp_mail(), which by default goes nowhere useful. This guide points those emails at Postwing and sets the sender up so they pass DMARC.
WooCommerce has no mail transport of its own. Everything it sends goes through wp_mail(), so it inherits WordPress's default behaviour: hand the message to PHP's mail(), which on most modern hosting has no mail server behind it. The order completes, the customer sees a thank-you page, and the confirmation never arrives.
Where a local mail server does exist, the message goes out unsigned from an IP your SPF record does not list — and an unauthenticated receipt from a shop is exactly the shape of a phishing email, so it gets filtered.
Because WooCommerce uses wp_mail(), configuring SMTP once at the WordPress level covers the whole store. Follow the WordPress SMTP guide — WP Mail SMTP, FluentSMTP or the plugin-free phpmailer_init hook all work. There is no WooCommerce-specific plugin to install.
| Setting | Value |
|---|---|
| SMTP host | smtp.postwing.app |
| Port | 587 |
| Encryption | STARTTLS (the connection is upgraded to TLS before login) |
| Username | The login of an SMTP token for your domain |
| Password | The password of that token — shown once, when the token is created |
Go to WooCommerce → Settings → Emails and set "From" address to an address on the domain you verified — for example orders@your-domain.com. This is the single setting that decides whether your receipts pass DMARC.
From: on someone else's domain cannot align with them, DMARC fails, and order confirmations are filtered — the messages customers are most likely to complain about not receiving. If a theme or a third-party plugin keeps overriding the sender, pin it with a filter:
/**
* Force every WooCommerce email to send from your verified domain, whatever the
* store settings or a third-party plugin says.
*/
add_filter( 'woocommerce_email_from_address', fn() => 'orders@your-domain.com', 99 );
add_filter( 'woocommerce_email_from_name', fn() => 'Acme Store', 99 ); To let staff reply straight to the customer while keeping the From: aligned, set Reply-To instead of changing the sender:
// Keep the From on your own domain, but send replies to the customer.
add_filter( 'woocommerce_email_headers', function ( $headers, $email_id, $order ) {
if ( 'new_order' === $email_id && $order ) {
$headers .= 'Reply-To: ' . $order->get_billing_email() . "\r\n";
}
return $headers;
}, 10, 3 );Still under WooCommerce → Settings → Emails, each notification is toggled separately and several are off by default. The ones customers notice:
| Sent to | Trigger | |
|---|---|---|
| New order | Store admin | Order is placed |
| Processing order | Customer | Payment received |
| Completed order | Customer | Order marked complete |
| Refunded order | Customer | Refund issued |
| Customer invoice | Customer | Sent manually from the order screen |
| Reset password / New account | Customer | Account actions |
Place a real test order rather than relying on the SMTP plugin's test button — that only proves the connection works, not that WooCommerce's triggers fire. To re-send an email for an existing order, use the Order actions box on the order screen, or WP-CLI:
# Re-trigger the "processing order" email for one order
wp eval "WC()->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger( 4417 );"
# List every registered WooCommerce email class
wp eval "print_r( array_keys( WC()->mailer()->emails ) );"| Symptom | Cause and fix |
|---|---|
| No WooCommerce email at all | SMTP not configured. Set it up at the WordPress level first. |
| Admin gets "New order", customer gets nothing | The customer emails are disabled, or the order never left pending. |
| "Completed order" never sends | The gateway leaves orders in processing. Complete them, or enable the processing email. |
| Emails land in spam | The From address is not on your verified domain. |
| Emails are delayed by minutes | WooCommerce defers sends to WP-Cron. On a low-traffic store, trigger cron from a real scheduler. |
| Duplicate order emails | Two SMTP plugins active, or an order-status plugin re-triggering the same hook. |
WooCommerce sends through WordPress's wp_mail(), which by default hands the message to PHP's mail() function. On most hosting there is no local mail server behind it, so the email is silently discarded. Configuring an SMTP relay fixes it for WooCommerce and for every other WordPress notification at the same time.
Check WooCommerce → Settings → Emails: each notification is enabled independently, and several are off by default. Also remember that the customer 'Completed order' email only fires when the order actually reaches that status — a payment gateway that leaves orders in 'processing' will never trigger it.
An address on the domain you have verified for sending, such as orders@your-domain.com. Using a Gmail, Yandex or Mail.ru address means DKIM and SPF cannot align with the From domain, DMARC fails, and order confirmations land in spam.
Almost always sender alignment. If the store's From address is on a free mail provider, or the site sends unauthenticated through PHP mail(), receiving servers treat the message as forged. Send over an authenticated relay from your own verified domain and the problem usually disappears within a day.
Open the order in the admin and use the Order actions box — it lists each customer email you can resend. From the command line, WC()->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger( $order_id ) does the same thing.
No. WooCommerce has no mail transport of its own — it calls wp_mail(). Any WordPress SMTP plugin, or a small phpmailer_init hook, covers WooCommerce automatically.