WooCommerce does not deliver mail. It calls wp_mail(). WordPress then uses PHP mail() from the hosting IP unless an SMTP or HTTP mailer overrides that transport. The hosting IP will not pass SPF/DKIM alignment for your store domain. Fix the transport, set a stable orders@ From on a sending-active custom domain, keep marketing off the receipt stream, and treat provider events—not the WooCommerce log—as delivery truth.
Why the order screen lied
The merchant sees “Order received.” The customer never gets the receipt. WooCommerce logged success because wp_mail() returned true after handing the message to PHP mail on a $9 shared host. That is acceptance by the local MTA, not inbox placement at Gmail or Outlook.
Typical failure modes:
- New-order and processing emails vanish because outbound port 25 is blocked.
- Password-reset mail leaves as
[email protected], which cannot align withstore.com. - A sale weekend burns a 3,000-send Free cap because forwarded mailbox copies also count.
How we analyzed this
This checklist is constrained by ArawaMail documentation: receiving must be enabled before sending; the HTTP API from must be a registered, sending-active domain allowed by the API key; the Cloudflare zone name must match the domain exactly. There is no first-party WordPress or WooCommerce plugin. Connect Device documents IMAP 993 and SMTP 465 with placeholder hosts—copy live SMTP values from Domain / Connect Device in-app. Do not publish example hostnames. Outgoing webhooks report delivery after a documented API send; plugin “test email sent” is not placement.
The checklist
1. Stop PHP mail() and the hosting IP
Shared-host IPs are shared reputation. They are not in your SPF. They cannot sign DKIM for your domain. Install one mailer that overrides wp_mail() for the whole site: WP Mail SMTP, FluentSMTP, Post SMTP, or Easy WP SMTP are the common options. Do not configure SMTP on each WooCommerce template. Order, processing, completed, refund, and customer-note emails inherit the same transport.
2. Put the store domain on Cloudflare, then enable sending
Connect the Cloudflare domain, activate receiving, then enable sending. Review the MX, SPF, DKIM, and DMARC records ArawaMail writes. Confirm SPF, DKIM, and DMARC and that alignment holds for the From domain.
3. Set WooCommerce From to a real address on that domain
Use orders@ or receipts@ on the sending-active domain. Not gmail.com. Not wordpress@serverhostname. Not noreply@ if customers need to reply. Receipts should come from an address people can reply to. Keep From, Reply-To, and Return-Path consistent so DMARC alignment survives.
4. Point the mailer at live SMTP or the documented API
Copy SMTP host, port, and credentials from Domain / Connect Device in the product. Prefer implicit TLS on 465 when the host allows it; confirm the host before assuming 465 is open—some shared hosts block 25 and 465. See ports 25, 465, and 587 and STARTTLS vs implicit TLS. Alternatively, a custom plugin may call the documented HTTP Send Email API or a Resend-compatible connector only if compatibility is confirmed. ArawaMail does not ship an official WooCommerce plugin.
5. Place a test order to three inboxes
Send to Gmail, Outlook, and a catch-all you control. Read the failure: authentication, TLS, blocked port, or DMARC fail. WooCommerce “email sent” is not the result. Use a placement check that inspects headers, as in how to test inbox placement.
6. Keep marketing off the receipt stream
Abandoned-cart and promo mail belong on a separate subdomain and ESP. Order confirmations must not share reputation with bulk campaigns. That split is documented in why marketing and transactional email should use separate subdomains. Marketing still needs Gmail and Yahoo bulk-sender requirements (SPF, DKIM, DMARC, one-click unsubscribe). Transactional order mail needs authentication even below bulk thresholds.
7. Watch bounces and complaints; do not retry hard bounces from checkout
If you send through the documented API, subscribe to outgoing webhooks. Give support the log instead of a Slack ping to engineering: support should see what the API sent. Retrieve Email last_event is not a finance or placement metric. Hard bounces from checkout should suppress, not retry.
8. Confirm volume fits the plan, including forwarded copies
Plan caps apply. Forwarded mailbox copies count toward the transactional allowance. Free includes 3,000 sends and has no overage—a sale weekend can exhaust it. Check pricing and the cost model in what email actually costs.
What support should look at when a customer says they never got the receipt
- WooCommerce email log (did
wp_mail()return?). - Mailer plugin log (did the SMTP/API session succeed?).
- Provider event (accepted, delayed, bounced, complained).
- Message headers at the destination (SPF/DKIM/DMARC alignment).
Password-reset mail is the same transport problem with a tighter latency budget; that topic is covered separately and should not be copied into this checklist.
FAQ
Why did WooCommerce say the order email was sent?
Because wp_mail() returned true. That is handoff to PHP mail or the mailer plugin, not proof the message reached the customer.
Does each WooCommerce template need its own SMTP settings?
No. Override wp_mail() once. Templates inherit the transport.
Which From address should receipts use?
A mailbox on the sending-active store domain, such as orders@ or receipts@, that a human can answer.
Should marketing and order mail share one domain?
No. Put campaigns on a separate subdomain and ESP so a list problem cannot sink receipts.
Is there an official ArawaMail WooCommerce plugin?
No. Use a generic wp_mail() mailer with live SMTP from the product, or a custom API integration against the documented Send Email API.