WooCommerce staging email testing has one rule above all others: no test order should ever land in a real customer's inbox. The problem is that WooCommerce fires a lot of mail automatically. Order confirmations, processing updates, completed-order notices, new-account messages, admin alerts. Clone your production store into staging with real order data still in the database, run a quick checkout to verify a template change, and WooCommerce will happily email the actual person who placed order #4812 three weeks ago. This guide shows you how to stop that from happening and inspect every message your staging site sends instead.
Why WooCommerce staging is riskier than a normal WordPress site
A plain WordPress site sends the occasional password reset or comment notification. WooCommerce turns your install into a transactional email machine. Every status change on an order can trigger a message, and those triggers run whether you're on production or a staging copy. If your staging environment was cloned from live, it's carrying real customer names, real addresses, and real email addresses in wp_posts and the orders tables.
The default WordPress mailer, wp_mail(), doesn't know the difference between staging and production. It just hands the message to whatever's configured to send. So the moment you place a test order, or bulk-edit order statuses to check a workflow, or let a plugin re-trigger notifications, WooCommerce can email people who bought from you weeks ago. That's confusing at best and a trust problem at worst.
The approaches people usually try (and where they fall short)
Before the clean solution, it helps to know the common workarounds and why they leak.
- Disabling email in code. Dropping a filter that short-circuits wp_mail() stops sends, but you also can't see what would have gone out, so you're testing blind.
- Scrubbing the database. Anonymising every customer email in staging works until the next time someone re-clones production and forgets to run the script.
- A no-op SMTP host. Pointing at a dead SMTP server throws errors and clutters your logs, and some plugins retry or fall back to PHP mail() anyway.
- Just being careful. This holds right up until a colleague runs a bulk action or a cron job fires order emails while you're at lunch.
What you actually want is to keep WooCommerce sending normally, so the whole flow is exercised, while guaranteeing those messages go somewhere safe where you can open and inspect them. That's what a sandbox does.
How a sandbox catches WooCommerce mail
MailSandbox gives you an SMTP inbox that captures outgoing email instead of delivering it. You point WooCommerce at the sandbox's SMTP credentials, and from then on every order confirmation, admin notification, and account email your store generates lands in a web inbox you control. Nothing is delivered onward, so a test order for order #4812 stays in the sandbox rather than reaching that customer.
Because the mail genuinely gets sent over SMTP, you're testing the real path. You can open each captured message, view the rendered HTML, check headers, read the raw source, and confirm the spam score before anything ever ships to production. That covers WooCommerce order confirmation email testing end to end without a single real recipient involved.
The fast way: the MailSandbox WordPress plugin
You can wire SMTP settings in by hand, and we'll show that below, but the quickest route is our WordPress plugin. It exists specifically so you don't have to touch wp-config.php or juggle SMTP constants across environments. Install it on your staging site, drop in your sandbox credentials, and it reroutes everything WordPress and WooCommerce send into your MailSandbox inbox.
- Install and activate the MailSandbox plugin on your staging WordPress site.
- Open your MailSandbox inbox and copy the SMTP host, port, username, and password shown for that inbox.
- Paste those credentials into the plugin settings and save.
- Place a test order in WooCommerce, then check your sandbox inbox. The confirmation and admin emails will be sitting there instead of in a customer inbox.
The reason this is worth it over manual config: the plugin owns the mailer, so it doesn't matter whether an email originates from WooCommerce core, a shipping plugin, a subscriptions add-on, or a custom hook you wrote. If it goes through wp_mail(), it gets caught. There's no per-plugin SMTP setup to chase down.
The manual way: SMTP credentials by hand
If you'd rather not add a plugin, or you're managing config through environment variables in a containerised setup, you can point WordPress at the sandbox directly. WooCommerce uses the WordPress mailer, so configuring SMTP at the WordPress level catches WooCommerce mail too. A small mu-plugin that hooks phpmailer_init is the cleanest approach:
<?php// wp-content/mu-plugins/mailsandbox.phpadd_action( 'phpmailer_init', function ( $phpmailer ) { $phpmailer->isSMTP(); $phpmailer->Host = 'smtp.mailsandbox.com'; $phpmailer->Port = 2525; $phpmailer->SMTPAuth = true; $phpmailer->Username = getenv( 'MAILSANDBOX_USER' ); $phpmailer->Password = getenv( 'MAILSANDBOX_PASS' ); $phpmailer->SMTPSecure = 'tls';} );Store the username and password as environment variables so they never get committed and never leak into production. If you deploy staging with a .env file, it looks like this:
MAILSANDBOX_USER=your_inbox_usernameMAILSANDBOX_PASS=your_inbox_passwordOnce that's live, run a checkout. The order confirmation should appear in your sandbox inbox within a second or two. If it doesn't, check that no other SMTP plugin is already claiming phpmailer_init, since two mailers fighting over the same hook is the usual cause of a missing message.
What to actually check once emails are landing
Catching the mail is step one. The point of testing WooCommerce emails without sending them is to inspect what you're producing. A few things worth looking at on each captured message:
- Rendering. WooCommerce email templates lean on inlined CSS and table layouts. Open the HTML preview and confirm the order table, totals, and any custom branding hold together.
- The order data. Check that line items, quantities, totals, tax, and shipping render correctly for a real order, not just placeholder values.
- Headers. Confirm the From name and address, Reply-To, and subject line are what you expect for each notification type.
- Spam score. A high score on a transactional email is a warning sign for production deliverability, so fix it in staging while it's cheap.
- Every trigger. Walk an order through pending, processing, completed, and refunded, and confirm the right email fires at each transition and nothing double-sends.
Fitting this into a CI or team workflow
If more than one person touches the staging store, a shared sandbox inbox beats a local mail catcher that only exists on one machine. A developer changing an email template, a QA engineer running through checkout, and whoever's reviewing the design can all open the same captured messages. And because the plugin catches mail from anything using wp_mail(), you don't need to re-verify coverage every time you add a new WooCommerce extension. Set it once on staging and every future email is caught automatically.
Will this catch emails from WooCommerce extensions too, or just core?
Both. As long as an extension sends through the standard WordPress mailer (wp_mail), which the vast majority do, the plugin catches its mail along with WooCommerce core emails. There's no per-extension setup.
Can WooCommerce still accidentally send to a real customer with this set up?
No. Once staging is pointed at the sandbox, every message is captured by the SMTP inbox and none is delivered onward. That's the whole point of routing at the mailer level rather than relying on care.
Do I need to strip real customer emails out of my staging database?
It's still good hygiene, but it's no longer the thing standing between you and an accidental send. With the sandbox catching all outgoing mail, even real addresses in the database can't receive anything.
Does the plugin work without WooCommerce?
Yes. It catches anything WordPress sends through wp_mail, so password resets, form notifications, and other plugin emails are caught too. WooCommerce just happens to be one of the heaviest senders.
How is this different from disabling email on staging?
Disabling email stops sends but leaves you blind. A sandbox lets the mail send normally over SMTP and captures it, so you can open, inspect, and debug every message instead of guessing what would have gone out.