All posts
Take control of Shopify email: send order notifications from your own domain
Gabe 4 min read

Take control of Shopify email: send order notifications from your own domain

Shopify owns your transactional email. You can't change the SMTP settings, you can't sign with your own DKIM key, and your order confirmations come from shopify.com. This tutorial shows how to send Shopify order emails through MailKite's SMTP relay — DKIM-signed from your domain, with full deliverability control.

Shopify handles your transactional email. Order confirmations, shipping updates, password resets — they all go out through Shopify’s email infrastructure, from Shopify’s domain, with Shopify’s DKIM signature. Your brand is a From name, nothing more. You can’t change the SMTP server, you can’t sign with your own key, and if Shopify’s IP reputation takes a hit, your deliverability goes with it.

For most stores, this works fine. But the moment you want to send from your own domain — genuinely yours, DKIM-signed under your key, with deliverability you can measure — Shopify’s default email can’t do it.

MailKite can. Here’s how to take back control.

What Shopify’s email actually does

When a customer places an order, Shopify sends a confirmation email. Behind the scenes:

  1. The From address is set to your store’s email (e.g., orders@yourstore.com)
  2. The email is sent from Shopify’s mail servers, with Shopify’s DKIM signature
  3. The Return-Path bounces back to Shopify’s domain
  4. You have no visibility into delivery, bounces, or complaints

The result: your domain’s SPF record doesn’t cover Shopify’s sending IP, so SPF fails. The DKIM signature is Shopify’s, not yours, so DKIM alignment fails. Gmail sees this and may route your order confirmations to spam — especially for new stores without established sender reputation.

Two paths to your own email

Path A: SMTP app (10 minutes)

Several Shopify apps add SMTP configuration. Install one, point it at MailKite:

SettingValue
SMTP Serversmtp.mailkite.dev
Port587
Usernamemailkite
PasswordYour API key (mk_live_…)
EncryptionSTARTTLS

The app sends order notifications, shipping updates, and other transactional emails through MailKite instead of Shopify’s default. Your DKIM key, your domain, your reputation.

Limitation: Shopify apps can override some email types but not all. Shopify’s core transactional emails (order confirmation, shipping confirmation) are controlled by Shopify’s system. For full control, use Path B.

Path B: Webhook → MailKite API (full control)

Use Shopify’s order webhook and send via the MailKite API. This gives you templates, threading, attachments, and delivery logs — without fighting Shopify’s email limits.

  1. In Shopify admin, go to Settings → Notifications → Webhooks
  2. Create a webhook for Order creation
  3. Point it at a small serverless function:
// shopify-bridge.js — Cloudflare Worker, Vercel, or any serverless platform
export default {
  async fetch(request, env) {
    if (request.method !== "POST") return new Response("OK");

    const order = await request.json();
    const { email, first_name, order_number, total_price } = order;

    const resp = await fetch("https://api.mailkite.dev/v1/send", {
      method: "POST",
      headers: {
        "Authorization": "Bearer " + env.MAILKITE_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        from: "orders@yourdomain.com",
        to: email,
        subject: "Order #" + order_number + " confirmed",
        html: "<p>Hi " + first_name + ",</p>"
            + "<p>Your order #" + order_number + " for $" + total_price
            + " is confirmed. We'll notify you when it ships.</p>",
        text: "Hi " + first_name + ",\n\nYour order #" + order_number
            + " for $" + total_price + " is confirmed.",
      }),
    });

    return new Response(JSON.stringify({ sent: resp.ok }), { status: 200 });
  },
};

This fires for every new order. The customer gets an email from your domain, DKIM-signed by MailKite, with full deliverability tracking in the dashboard.

The deliverability difference

Shopify’s email infrastructure is shared across millions of stores. That means:

  • Shared reputation. Your store’s deliverability is tied to every other Shopify store on the same IP.
  • No DKIM alignment. The signature is Shopify’s, not yours. DMARC checks fail alignment.
  • Limited visibility. You can’t see delivery rates, bounces, or complaints in real time.

With MailKite, each message is:

  • DKIM-signed with your key. Gmail sees your domain’s signature, passes DMARC alignment.
  • Sent from a clean IP. No shared reputation — MailKite’s sending infrastructure is dedicated to MailKite customers.
  • Logged and trackable. Delivery, opens, bounces — all visible in the MailKite dashboard and API.

Receiving customer replies

When a customer replies to an order email, MailKite can POST the reply to your webhook. Create a Cloudflare Worker that:

  1. Parses the reply
  2. Matches it to the order (by subject line or thread ID)
  3. Adds it as a note in Shopify’s admin via the Shopify Admin API
// reply-handler.js — receives inbound email, creates Shopify order note
export default {
  async fetch(request, env) {
    const payload = await request.json();
    const { from, subject, text } = payload;

    // Match "Re: Order #1234 confirmed" to order number
    const match = subject.match(/Order #(\d+)/);
    if (!match) return new Response('{"ok":true}', { status: 200 });

    // Shopify Admin API — add note to order
    await fetch(
      "https://" + env.SHOP_DOMAIN + "/admin/api/2024-01/orders/" + match[1] + ".json",
      {
        method: "PUT",
        headers: {
          "X-Shopify-Access-Token": env.SHOP_API_TOKEN,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          note: "Customer reply from " + from + ":\n" + text,
        }),
      }
    );

    return new Response('{"ok":true}', { status: 200 });
  },
};

Now customer replies show up directly on the order in Shopify’s admin — no manual forwarding, no lost context.

How it compares

Shopify default emailMailKite via app or API
DKIM signatureShopify’s keyYour key
SPF alignmentFails (Shopify’s IP)Passes (your domain)
DMARC alignmentFailsPasses
Sending reputationShared (millions of stores)Dedicated (MailKite infra)
Delivery logsNot availableDashboard + API
Inbound repliesNot supportedWebhook → your endpoint
CostIncluded in Shopify planFree tier, scales with sends

FAQ

Will this replace all Shopify emails? Path A (SMTP app) replaces most transactional emails. Path B (webhook → API) gives you full control over which emails you send. Some Shopify system emails (like account creation) may still use Shopify’s default — check your notification settings.

Do I need to disable Shopify’s default email? No. You can run both in parallel while testing. Once you’re confident MailKite is delivering, disable Shopify’s notifications for the email types you’re handling.

What about Shopify Flow email actions? Shopify Flow can trigger email sends. If the Flow uses an SMTP action, point it at MailKite. If it uses Shopify’s built-in email, you’ll need to replace it with a webhook → MailKite API call.


Take back control of your Shopify email. Point an order webhook at MailKite and send from your own DKIM-signed domain. Start free — unlimited domains, no credit card.

Related: Fix WordPress email deliverability — the same problem on a different platform · WooCommerce order emails — if your store runs on WordPress · What is programmable email? — the category this belongs to

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

Related posts