154 lines
4.7 KiB
Markdown
154 lines
4.7 KiB
Markdown
# WPForms Email Delivery Debugging
|
|
|
|
6-step chain for diagnosing WPForms email delivery failures. Entries exist in the database, notification settings look correct, but emails never arrive.
|
|
|
|
## 1. Check entries in the database
|
|
|
|
```sql
|
|
SELECT entry_id, form_id, status, type, date, LEFT(fields, 200)
|
|
FROM wp_wpforms_entries
|
|
WHERE form_id = <FORM_ID>
|
|
ORDER BY entry_id DESC LIMIT 10;
|
|
```
|
|
|
|
If entries exist, the form is submitting correctly. Move to notifications.
|
|
|
|
## 2. Inspect notification settings
|
|
|
|
The notification JSON is stored in `wp_posts.post_content` under `settings.notifications`:
|
|
|
|
```sql
|
|
SELECT ID, post_title, LEFT(post_content, 500)
|
|
FROM wp_posts WHERE ID = <FORM_ID>;
|
|
```
|
|
|
|
Check for:
|
|
- `"paypal_commerce": "1"` in the notification — this gates email until PayPal confirms payment. Remove it.
|
|
- `email` field — is the recipient correct? Does the address actually exist?
|
|
- `enable` is `"1"`
|
|
|
|
**PayPal gate fix:** The flag `"paypal_commerce": "1"` is embedded in the notification JSON inside `wp_posts.post_content`:
|
|
```sql
|
|
UPDATE wp_posts
|
|
SET post_content = REPLACE(post_content, '"paypal_commerce":"1"', '')
|
|
WHERE ID = <FORM_ID>;
|
|
```
|
|
|
|
## 3. Direct SMTP test
|
|
|
|
Test the actual SMTP credentials directly (bypasses WordPress):
|
|
|
|
```python
|
|
import smtplib
|
|
s = smtplib.SMTP("c1113726.sgvps.net", 2525, timeout=15)
|
|
s.starttls()
|
|
s.login("contact@apextrackexperience.com", "apex.track!!")
|
|
msg = "From: contact@...\r\nTo: contact@...\r\nSubject: Test\r\n\r\nBody"
|
|
s.sendmail("from@domain.com", ["to@domain.com"], msg)
|
|
s.quit()
|
|
```
|
|
|
|
If this succeeds, the credentials and relay work. If it fails, check:
|
|
- Relay hostname resolves (`dig +short c1113726.sgvps.net`)
|
|
- Port 2525 (netcup VPS blocks 25/465/587)
|
|
- Credentials
|
|
|
|
## 4. wp_mail test
|
|
|
|
Test via WordPress's mail function (runs through WP Mail SMTP plugin):
|
|
|
|
```bash
|
|
cd /path/to/wordpress
|
|
php -r '
|
|
require_once "wp-config.php";
|
|
require_once "wp-includes/pluggable.php";
|
|
$sent = wp_mail("test@example.com", "Subject", "Body", ["From: sender@domain.com"]);
|
|
echo "wp_mail returned: " . ($sent ? "TRUE" : "FALSE");
|
|
'
|
|
```
|
|
|
|
If `wp_mail()` returns `TRUE` but email never arrives, the issue is downstream (SPF, MX, or mailbox).
|
|
|
|
## 5. SPF check — most common silent-failure cause
|
|
|
|
The SMTP relay IP must be authorized in the domain's SPF record. If not, the receiving server (MXroute's spam filter, etc.) silently drops the email even though the relay reports "250 OK id=...".
|
|
|
|
### Check SPF
|
|
|
|
```bash
|
|
dig +short TXT domain.com | grep spf
|
|
```
|
|
|
|
### Common SPF patterns
|
|
|
|
**SiteGround-hosted sites** that use `c1113726.sgvps.net:2525` as SMTP relay:
|
|
|
|
Current: `v=spf1 +a +mx include:domain.com.spf.auto.dnssmarthost.net ~all`
|
|
Fixed: `v=spf1 +a +mx ip4:35.212.86.161 include:domain.com.spf.auto.dnssmarthost.net ~all`
|
|
|
|
Where `35.212.86.161` = `c1113726.sgvps.net`.
|
|
|
|
### Understanding the include chain pitfall
|
|
|
|
`include:domain.com.spf.auto.dnssmarthost.net` resolves through multiple levels:
|
|
|
|
1. `domain.com.spf.auto.dnssmarthost.net` → `_30d8870...spf.dnssmarthost.net` → `include:_spf.mailspamprotection.com`
|
|
2. `_spf.mailspamprotection.com` → authorizes only MXroute's own IP ranges (`185.56.84.0/24`, etc.)
|
|
|
|
This chain authorizes the **mailbox server** (MXroute), NOT the **outbound SMTP relay** (SiteGround's `c1113726.sgvps.net`). They are different IP ranges. Adding `ip4:35.212.86.161` fixes this gap.
|
|
|
|
### Checking DNS provider
|
|
|
|
```bash
|
|
dig +short NS domain.com
|
|
```
|
|
|
|
- `ns1/ns2.siteground.net` → edit at SiteGround Dashboard → Websites → domain → DNS Zone Editor
|
|
- Cloudflare IPs (188.114.x.x) → edit via Cloudflare API or dashboard
|
|
|
|
## 6. MX verification
|
|
|
|
```bash
|
|
dig +short MX domain.com
|
|
```
|
|
|
|
**PITFALL — MXroute in front of SiteGround email:** SiteGround email customers have MX from `antispam.mailspamprotection.com` (MXroute's spam filter) but the actual mailbox is on SiteGround's servers. Mail flow:
|
|
|
|
```
|
|
WordPress → c1113726.sgvps.net (relay) → SPF check → MXroute spam filter → SiteGround mailbox
|
|
```
|
|
|
|
If SPF fails, MXroute drops before SiteGround ever sees it.
|
|
|
|
## Prevention — add CC backup
|
|
|
|
Once the SPF is fixed, add yourself as a secondary notification recipient so future issues don't blindside you:
|
|
|
|
```sql
|
|
UPDATE wp_posts
|
|
SET post_content = REPLACE(
|
|
post_content,
|
|
'"email":"contact@domain.com"',
|
|
'"email":"contact@domain.com, g@germainebrown.com"'
|
|
)
|
|
WHERE ID IN (<FORM_IDS>) AND post_content NOT LIKE '%g@germainebrown.com%';
|
|
```
|
|
|
|
## Quick Reference: dig commands
|
|
|
|
```bash
|
|
# SPF record
|
|
dig +short TXT <domain> | grep spf
|
|
# Full include chain
|
|
dig +short TXT <domain>.spf.auto.dnssmarthost.net
|
|
dig +short TXT _spf.mailspamprotection.com
|
|
# DKIM
|
|
dig +short TXT mail._domainkey.<domain>
|
|
# DMARC
|
|
dig +short TXT _dmarc.<domain>
|
|
# MX records
|
|
dig +short MX <domain>
|
|
# Nameservers (who hosts DNS)
|
|
dig +short NS <domain>
|
|
```
|