All posts
WooCommerce order emails: fix deliverability with MailKite SMTP
Gabe 4 min read

WooCommerce order emails: fix deliverability with MailKite SMTP

WooCommerce sends 12+ email types through WordPress's wp_mail() — and most store owners have no idea they're going to spam. This tutorial shows how to route every WooCommerce email through MailKite's SMTP relay: order confirmations, shipping notifications, refund emails, all DKIM-signed from your own domain.

Your WooCommerce store sends 12+ different email types. Order confirmation, processing, completed, refunded, failed, cancelled, customer note, new order (admin), low stock, out of stock, backorder, password reset. Every one of them goes through wp_mail(). And if you haven’t configured an SMTP relay, every one of them is at risk of landing in spam.

Store owners fix the SMTP once and forget about it. But “once” often means never — or it means using a free SMTP service with daily limits that silently throttle your high-volume days. When a $500 order confirmation doesn’t arrive, the customer thinks you took their money and vanished.

MailKite fixes this with four DNS records and two settings. Here’s the full setup.

What WooCommerce’s default actually does

WooCommerce hooks into WordPress’s wp_mail() function. That function calls PHP’s mail(), which hands the message to whatever MTA your server runs — typically Postfix or Sendmail, with no DKIM signing, no SPF alignment, and a shared IP.

For a store, this is worse than a blog. Order confirmations are time-sensitive. A delayed or missing shipping notification damages trust more than a blog comment notification ever could. And WooCommerce doesn’t retry failed emails — if the MTA rejects it, the email is gone.

The fix: 4 records + 2 settings

1. Add your domain to MailKite

In the dashboard, add your store’s domain (e.g., yourstore.com). MailKite returns DNS records:

MX    yourstore.com           mx.mailkite.dev    (priority 10)
TXT   yourstore.com           v=spf1 include:mailkite.dev ~all
TXT   mailkite._domainkey.yourstore.com   v=DKIM1; k=rsa; p=…
TXT   _dmarc.yourstore.com    v=DMARC1; p=none;

Add them to your DNS provider. The MX propagates in under 5 minutes.

2. Install WP Mail SMTP

WP Mail SMTP overrides wp_mail() to route through your chosen SMTP server. Install it from the WordPress plugin directory.

3. Configure the connection

Go to WP Mail SMTP → Settings:

SettingValue
From Emailorders@yourstore.com (on your verified domain)
From NameYour store name
MailerOther SMTP
SMTP Hostsmtp.mailkite.dev
EncryptionTLS
SMTP Port587
Usernamemailkite
PasswordYour API key (mk_live_…)

4. Verify which emails are covered

WP Mail SMTP intercepts every wp_mail() call on the site. That includes:

WooCommerce emailTrigger
New orderCustomer places an order
Processing orderPayment confirmed
Completed orderOrder marked complete
Refunded orderRefund processed
Failed orderPayment failed
Customer noteAdmin adds a note
Reset passwordCustomer requests password reset
Email address changedCustomer changes email

Plus any WordPress core emails (user registration, comment notifications) and plugin emails (WPForms submissions, Yoast alerts, etc.).

5. Test it

WP Mail SMTP has a Email Test tab. Send a test to your Gmail or Outlook address and check the headers:

Authentication-Results: mx.google.com;
  dkim=pass header.d=yourstore.com
  spf=pass (google.com: domain of orders@yourstore.com designates ... as permitted sender)
  dmarc=pass

All three should pass. If DKIM or SPF fails, double-check your DNS records.

Customize WooCommerce email templates

WooCommerce lets you customize email templates in WooCommerce → Settings → Emails. You can change colors, header text, and footer — but not the SMTP server. That’s handled by WP Mail SMTP, which runs before WooCommerce’s template engine.

To set a reply-to address on order emails (so customers reply to your support inbox, not the no-reply address), add this to functions.php:

add_action('woocommerce_email_headers', function ($headers, $email_id, $order) {
    if (in_array($email_id, ['customer_processing_order', 'customer_completed_order'])) {
        $headers .= 'Reply-To: support@yourstore.com' . "\r\n";
    }
    return $headers;
}, 10, 3);

Receiving customer replies

When a customer replies to an order confirmation, MailKite can POST the reply to your webhook as clean JSON. Add a webhook handler that extracts the order number from the subject and creates a WooCommerce order note:

<?php
// webhook-replies.php — receives MailKite inbound webhook
$payload = json_decode(file_get_contents('php://input'), true);

$sig     = $_SERVER['HTTP_X_MAILKITE_SIGNATURE'] ?? '';
$secret  = getenv('MK_WEBHOOK_SECRET');
$computed = hash_hmac('sha256', json_encode($payload), $secret);
if (!hash_equals($computed, $sig)) {
    http_response_code(401);
    exit;
}

if (preg_match('/Order #(\d+)/', $payload['subject'], $m)) {
    $order = wc_get_order((int) $m[1]);
    if ($order) {
        $order->add_order_note(
            "Customer reply from {$payload['from']}:\n\n{$payload['text']}"
        );
    }
}

http_response_code(200);
echo '{"ok":true}';

Customer replies appear directly in WooCommerce’s order notes — visible in the admin panel, tied to the right order.

How it compares

WP mail() defaultWP Mail SMTP + MailKite
DKIM signingNoneAutomatic, per-domain
SPF alignmentFails (shared server IP)Passes (your domain)
Inbox placement~40–60%~95%+
Retry on failureNoneMailKite retries
Delivery logsServer mail.log onlyDashboard + API
Inbound repliesNot supportedWebhook → order notes
Daily send limitsServer capacityFree tier scales

FAQ

Will this affect WooCommerce email templates? No. WP Mail SMTP only changes how email is sent, not what WooCommerce puts in it. Templates, branding, and content stay the same.

What about bulk marketing emails? MailKite is for transactional email. Don’t use it for newsletters or marketing campaigns — that’s what Mailchimp, Klaviyo, or Brevo are for. Order confirmations, shipping updates, and password resets are transactional and belong on MailKite.

I’m using WooCommerce MailChimp/Klaviyo — will this conflict? These plugins hook wp_mail() for marketing emails. WP Mail SMTP hooks it for transactional. As long as MailChimp/Klaviyo send to their own list (not wp_mail()), there’s no conflict. If they use wp_mail(), one hook wins — deactivate the one you don’t need.

Can I use this with multiple domains? Yes. Add each domain to MailKite, publish its DNS records, and use the same API key. MailKite handles DKIM signing per domain automatically.


Four DNS records, two settings, and your WooCommerce emails stop going to spam. Start free — unlimited domains, no credit card.

Related: Fix WordPress email deliverability — the general WordPress fix · Shopify email from your own domain — for Shopify stores · Set up email once, reuse every project — the architecture behind it

Discuss this post: Hacker News Share on X Share on LinkedIn

Related posts