Description
Casa Mail intercepts wp_mail() and delivers each message through the Casa Mail transactional email service operated by CodeCasa Studios on the OnlineStoreNotifications infrastructure (api.onlinestorenotifications.com).
If your WordPress site doesn’t send emails yet, Casa Mail is the perfect solution to start sending with no technical experience or SMTP API keys. Already send mail? Switch to Casa Mail, save money and improve deliverability.
The plugin is intended for sites that want an easy, hassle free wp_mail setup! Improve deliverability of order confirmations, password resets, account-verification emails, and similar transactional traffic with our built-in SMTP server. It does not change anything about how WordPress queues mail; it only changes how the SMTP step is performed.
How it works
pre_wp_mailis hooked at priority 1. Each call is converted to a JSON payload and POSTed to the gateway.- If the gateway accepts on the first POST,
wp_mail()returns true and the message is durably enqueued upstream. - If the gateway is unreachable on the first POST, the payload is written to a durable outbox table (
<prefix>casamail_outbox) and a cron tick retries with 30s, 2m, 10m backoff. - A separate transmit log table (
<prefix>casamail_sends) records every attempt for visibility on the plugin dashboard. Rows older than 30 days are pruned automatically.
Onboarding
After activation, an in-WordPress wizard collects:
- Site name, site URL, contact email address.
- A 6-digit code emailed by the gateway to confirm the address.
- Plan selection (one free plan today; paid tiers planned).
- Optional: authenticate a sender domain so customer email goes out from your domain with aligned DKIM.
Trademark note
This plugin is not affiliated with or endorsed by WooCommerce, Automattic, or any third party. The WooCommerce name appears only as a compatibility note (when WooCommerce is detected, the plugin’s admin menu attaches under it for convenience; otherwise it lands under Settings).
External services
This plugin transmits data to a third-party SMTP gateway. WordPress.org policy requires this be disclosed.
Endpoints contacted
The plugin makes HTTPS requests to:
https://api.onlinestorenotifications.com/v1/onboard/request— during onboarding, to send your verification email.https://api.onlinestorenotifications.com/v1/onboard/verify— during onboarding, to confirm the code and provision an account.https://api.onlinestorenotifications.com/v1/send— for everywp_mail()call once the plugin is onboarded.https://api.onlinestorenotifications.com/v1/email/domain(GET / add / verify) — when the site administrator interacts with the Sender Domain page.
The gateway is operated by CodeCasa Studios under the Casa Mail brand and runs on the OnlineStoreNotifications infrastructure. Casa Mail and OnlineStoreNotifications are sister brands of the same company; the API hostname reflects the shared backbone rather than a third-party dependency.
Data sent
During onboarding (one-time, before any send): site administrator email address, site name, site URL.
For each wp_mail() call once onboarded: sender email address, sender name, recipient email address(es), subject, message body, message headers (after stripping From/To/Subject/Date/Message-ID/MIME-Version/Content-Type/Content-Transfer-Encoding).
Terms and privacy
- Terms of service: https://sendemailtoday.io/terms.html
- Privacy policy: https://sendemailtoday.io/privacy.html
Privacy
When activated, this plugin transmits email content (recipient, sender, subject, body, headers) to a third-party SMTP gateway for delivery. This is the plugin’s only purpose. The data lifecycle is described above under “External services” and on the linked privacy policy.
The plugin also writes a wp_add_privacy_policy_content() block describing what is transmitted; this lets site administrators include the disclosure in the WordPress-managed privacy policy page (Settings -> Privacy).
Account deletion: a “Request account deletion” button on the plugin’s Settings page emails the gateway operator. Upon confirmation, the tenant record, API key(s), domain-authentication records, and recent sending history are removed from the gateway side. The plugin uninstall additionally removes the plugin’s WordPress-side options + tables.
Screenshots
Installation
- Upload the plugin zip via Plugins -> Add New -> Upload Plugin, or extract
casa-mailintowp-content/plugins/. - Activate.
- WooCommerce -> Casa Mail (or Settings -> Casa Mail if WooCommerce is not installed) launches the onboarding wizard.
The plugin requires PHP 7.4 or newer and WordPress 6.0 or newer.
FAQ
-
Does this replace existing SMTP plugins?
-
Yes. The plugin hooks
pre_wp_mailat priority 1, which runs before most SMTP plugins. For predictable behaviour, disable other mail routers (FluentSMTP, WP Mail SMTP, etc) when this plugin is active. -
What happens if the gateway is unreachable?
-
Calls land in a durable retry outbox and a 60-second cron drains them with 30s / 2m / 10m backoff. After three failed retries the row is marked failed and preserved for diagnosis.
wp_mail()always returns true (the plugin guarantees zero-loss + zero-blocking). -
How is the From: address handled?
-
If the site has verified a sender domain through the plugin’s Sender Domain page, the plugin rewrites the From address to
noreply@<verified-domain>so DKIM aligns. If the caller (WooCommerce, WordPress core, etc) already supplies a From address inside the verified domain, that address is honored. A “Default From” override is also available on the Settings page. -
Where can I see what was sent?
-
The dashboard’s “Recent sends” panel lists the most recent 10 wp_mail() calls intercepted by the plugin. The Logs page extends this to the last 200. Rows older than 30 days are pruned automatically.
-
How do I delete my account?
-
Settings -> Delete my account -> Request account deletion. This emails the gateway operator who removes the tenant + API key + history within 48 hours and replies to the contact email on completion. The plugin uninstall (Plugins -> Delete) handles the WordPress-side cleanup.
-
Is this affiliated with WooCommerce?
-
No. WooCommerce is an Automattic trademark and this plugin is not endorsed by or affiliated with Automattic. The plugin only mentions WooCommerce as a compatibility note (the admin menu nests under WooCommerce when present, for ergonomic reasons).
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Casa Mail” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Casa Mail” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
1.4.0
Renamed the plugin to Casa Mail (display name and slug). No functional change to mail handling – the same CodeCasa-operated transactional gateway on the OnlineStoreNotifications backbone. WordPress option keys, the outbox table, and the sends-log table now use the casamail_ prefix; the admin menu pages, AJAX actions, cron hooks, script handles, and PHP namespace were prefixed to match. Existing installs re-run onboarding once after upgrade because the stored option keys changed prefix.
1.3.5
Sender Domain page no longer shows the yellow “Using Cloudflare?” advice boxes once a record is OK. They were setup hints meant for users who hadn’t added the entries yet; sitting next to a green VERIFIED pill they made it look like something was wrong. Now hidden per-record: the apex “trim the dot” hint hides once overall status is verified, the Return-Path “set to DNS only” hint hides once that individual record’s status is OK.
1.3.4
WordPress.org Plugin Check pass. All ERROR-level findings resolved: translators: comments added on the two placeholder-bearing translation strings; output escaped in the dashboard stat cards (esc_html(number_format_i18n(...))); parse_url() replaced with wp_parse_url(); $wpdb->prepare() brought to the OUTBOX_TABLE INSERT; Tested up to bumped to 7.0. Removed load_plugin_textdomain() (auto-loaded on WP.org since 4.6). Added phpcs:disable blocks with documented rationale for the false-positive WARNING-level findings: NonceVerification on AJAX handlers (the nonce IS verified – in ajax_guard(), just not inline), DirectDatabaseQuery + InterpolatedNotPrepared on the plugin’s own custom tables (table names are hard-coded class constants, no user input, no object-cache layer for transmit logs), and PrefixAllGlobals on template files whose locals come from extract(). Bootstrap rewritten to use a closure so no $set_gateway global leaks into the WordPress namespace.
1.3.3
Dashboard banner (“Sending from the shared sender”) no longer hardcodes noreply@onlinestorenotifications.com – it now shows the tenant’s actual <slug>@onlinestorenotifications.com address (the inbox they picked at Step 3), matching what customers actually see in the From line. Fallback is the legacy noreply@ for tenants on installs older than 1.1 who don’t have a mailbox_slug yet.
1.3.2
Step 3 (“Your inbox”) no longer pre-locks the domain in the customer’s mental model. The preview now reads slug@... (with a literal ellipsis after the @), and a short helper line tells them Step 5 is where they pick the actual domain (the shared one, or their own). The host hint next to the rename input is also @.... Step 5 “Use this address” button no longer pops a confirmation modal – the card already explains the trade-offs, the second confirmation was pure friction; the click now fires the AJAX straight away. Stale “noreply@” copy in the populated Sender Domain page banner and the success notice is gone; both now use the tenant’s actual slug address. Translated into all 8 bundled locales.
1.3.1
Step 5 (the sender-domain choice) now shows the user’s actual inbox slug + addresses instead of generic placeholders. The page leads with “Your inbox name is acmestore. Where would you like to use it?” and each choice card previews the literal address customers will see (acmestore@onlinestorenotifications.com or acmestore@yourstore.com). Inline domain-input form’s example also uses the user’s slug. SG.mailboxSlug + SG.mailboxEmail stay in sync through OTP verify + rename so step 5 always reflects the chosen slug, even if the user renamed in step 3.
1.3
Wizard step 5 (“Sender domain”) rewritten for non-technical users:
* Step heading is now “Where should your emails come from?” instead of “Authenticate your sender domain”.
* Two equal-weight side-by-side cards present the choice as either/or, not as “do this complex thing OR skip it”. One card is “Use the Casa Mail address” (easiest), the other is “Use your own domain” (on-brand). On phones the cards stack.
* Domain input field is hidden until the user picks “Set up my own domain” – clicking the card’s button reveals a small inline form. Keeps the choice screen uncluttered.
* DNS-records copy after provisioning uses plain English: “Add these 3 entries to your domain settings” instead of “Publish these 3 DNS records”. Mentions Cloudflare / GoDaddy / Namecheap / Google Domains by name so users recognise where they’re going. “Verify DNS” button relabelled “Check my domain”.
* SPF helper text explains the “merge into existing v=spf1 record” instruction in plain English.
* Cloudflare grey-cloud tip explains why (not just “set to DNS only”) – replies coming back from your customers depend on it.
* The duplicate “Use shared sender” button in the wizard footer is gone – the shared-sender path is now one of the two main cards. The footer now shows only “I will decide later” + the post-verify “Finish” CTA.
1.2
- Use the tenant’s chosen
mailbox_slugas the From local-part on their own verified domain too, not just on the OSN side. Onboarding picks (or the user renames)acmestoreas the inbox handle, and from then on customer-facing emails go fromacmestore@theirdomain.com(after domain verification) ANDacmestore@onlinestorenotifications.com(Reply-To target, where replies route through). One consistent identity across both addresses; no morenoreply@in the customer-facing From. - Gateway’s
activateTenantSendernow overwrites any@onlinestorenotifications.comsender_email when a tenant verifies their own domain — previously it only matched the legacy sharednoreply@osnvalue, leaving v1.1 per-tenant slug addresses stuck on OSN after domain verification. - Operator-configured
default_fromon the Settings page still wins over the slug-based default.
1.1
Per-tenant inbox feature (foundation for the paid webmail tier):
* Every onboarded tenant now gets their own inbox at <slug>@onlinestorenotifications.com. The slug is derived from the site URL host (strips common subdomain noise like www., shop., sms.) with a fallback to store-xxxxxx for collisions.
* New wizard step between OTP verification and plan selection lets the user accept the suggested inbox name or rename it inline with live availability checking.
* When the tenant is on the shared sender, every wp_mail() now goes from <slug>@onlinestorenotifications.com instead of the generic noreply@onlinestorenotifications.com. Replies route directly to the tenant’s inbox.
* When the tenant has authenticated their own domain, From stays on their domain but a Reply-To: <slug>@onlinestorenotifications.com header is injected so replies still arrive in the OSN inbox.
* Free tier auto-forwards inbox mail to the tenant’s contact email via a Postfix virtual-alias map backed by a MariaDB view. The view is regenerated every 60s by a host systemd timer; no manual sync needed when tenants onboard or rename.
* New gateway endpoints: GET /v1/email/mailbox (read current inbox state), POST /v1/email/mailbox/check (live slug validation without mutating), POST /v1/email/mailbox/rename (atomic rename with UNIQUE-index protection).
* A webmail_enabled flag exists on tenants for the future paid tier; when flipped on, the alias destination changes from “forward to contact_email” to “store in Maildir” — Roundcube auto-login + IMAP provisioning will arrive in a follow-up release.
1.0
First stable public release. Consolidates the 0.4.x WordPress.org compliance work and the 0.5.0 shared-sender feature, plus two correctness fixes shipped during end-to-end testing:
* Onboarding submenu is now registered even when the plugin is already onboarded – the wizard URL gracefully renders the “Setup is already complete – Open dashboard” branch instead of WP’s bare “not allowed” page when the admin_init redirect races a page-cache or back-button.
* Stale-clone fix on the standalone Sender Domain page: the verified-state celebration banner (cloned from a template with the hidden HTML attribute) was being forced visible by display: flex in CSS, leaking a green “verified” banner onto the pending-records view. CSS now uses :not([hidden]) so the attribute wins.
* activateTenantSender() on the gateway now overwrites the shared-sender address when a tenant who previously opted into the shared path verifies their own domain. Previously the COALESCE guard kept sender_email pinned to noreply@onlinestorenotifications.com forever, so verification succeeded but sends never moved over to the customer’s domain.
0.5.0
- Add the “Use shared sender” option to the onboarding wizard’s step 4 and the standalone Sender Domain page. Tenants who don’t want to authenticate their own domain can route every wp_mail() from
noreply@onlinestorenotifications.cominstead – DKIM + SPF + Return-Path are already configured for that domain on the gateway side, so mail arrives signed and aligned (cost: Gmail shows “via onlinestorenotifications.com” in the sender chrome). - New gateway endpoint:
POST /v1/email/domain/skip– setstenants.sender_emailto the shared address so Transport’sfromFor()picks it up on every send. - Plugin’s
from_email()now short-circuits to the shared address whendomain_status === 'shared', so the WP-sidewp_casamail_sendslog reflects the actual From the recipient will see (no drift between plugin log and Postal envelope). - Inject a
Reply-Toheader whenever the plugin rewrites the From, so customer replies still reach the original mailbox (caller-supplied From, or the tenant’s contact email as fallback). Skipped when the caller already set Reply-To. - Dashboard banner gains a blue informational variant for the shared-sender state (vs. the existing orange warning for “authenticate your domain”).
0.4.2
- Switch the account-deletion + error-message support address from
support@sendemailtoday.iotosupport@onlinestorenotifications.com. The OSN mailbox already exists on the gateway’s role-mailbox stack and is the same support address the onboarding OTP email body has always referenced.
0.4.1
- Replace the inline
<script>block inshow_onboarding_noticewith a separately-enqueuedassets/js/notice-dismiss.js, loaded only when the notice would render. - Remove dead URL-based notice-dismiss code path (was unreachable from the UI – everything went via the AJAX path).
- Route the account-deletion request email through the gateway instead of bypassing it – the previous
X-SET-Outbox: 1shortcut relied on the host’s PHPmail()being functional, which most managed WordPress hosts disable. - Drop unused
set_gateway_get_dashboardandset_gateway_get_logsAJAX endpoints that were scaffolded for a polling feature never implemented. - Replace the
woocommercereadme tag withdeliverabilityto sidestep the trademark concern when listing on WordPress.org.
0.4.0
- Add
readme.txtand WP.org submission compliance. - Add
wp_add_privacy_policy_content()registration for Settings -> Privacy. - Add data-disclosure paragraph on the onboarding wizard’s first step.
- Add Settings -> Delete my account flow that emails the gateway operator.
- Make the persistent onboarding notice dismissible per-user, resurfaces on plugin upgrade.
- Replace
window.prompt()calls with an accessible in-page modal. - Move every user-facing JS string through
wp_localize_scriptso the plugin is fully translatable. - Add
load_plugin_textdomainand ship translations forde_DE,es_ES,fr_FR,it_IT,ja,nl_NL,pl_PL,pt_BR. - Replace
wp_unschedule_eventwithwp_clear_scheduled_hookin deactivate to defend against duplicate-scheduled hooks. - Annotate intentional unprepared
$wpdbqueries withphpcs:ignorecomments + justifications. - Replace inline
style=""attributes with CSS classes (set-gw-notice-cta,set-logs-section-heading,set-danger-zone,set-gw-modal). - Move sales copy out of the plugin header into the Description section here.
0.3.2
- Add
Sent (24h)stat card on the dashboard.
0.3.1
- Add post-verify celebration banner with Send Test Email and Open Dashboard CTAs.
- Patch the verifier to bypass
systemd-resolvedand query DNS viadig @1.1.1.1directly so a freshly-flipped Cloudflare proxy switch is reflected immediately.
0.3.0
- Auto-rewrite From to
noreply@<verified-domain>when the WC-supplied From is outside the verified domain. - Add
wp_casamail_sendstransmit-log table + Recent sends dashboard panel. - On plugin reinstall, rotate the API key and surface any existing sender-domain record so missing DNS records are visible immediately.
0.2.0
- In-WordPress onboarding wizard.
- Durable retry outbox.



