The Hidden Cost of Fake Accounts: Why E-commerce Fraud Starts With Email
Every year, e-commerce businesses lose billions of dollars to fraud. Chargebacks, stolen merchandise, promo abuse, and fake reviews quietly drain margins while customer trust erodes. But here is what most merchants overlook: the vast majority of these attacks share a single point of entry — a fraudulent email address.
Fraudsters know that email is the weakest link in most onboarding flows. Create a throwaway address, sign up for an account, claim a welcome discount, submit a fake five-star review, and vanish before anyone notices. Repeat the process a hundred times and you have a scalable fraud operation that costs the merchant thousands of dollars while requiring almost no effort from the attacker.
The good news is that email verification closes this door before it opens. By validating every address at the moment it enters your system — signup, checkout, account recovery, or review submission — you can eliminate the vast majority of fraudulent activity without adding meaningful friction for legitimate customers.
This guide covers everything you need to know: the specific fraud patterns targeting e-commerce businesses, exactly where to integrate email verification in your stack, working code examples using the MailValid API, and a realistic ROI calculation that shows why verification pays for itself many times over.
The Scope of E-commerce Fraud: What You Are Really Dealing With
Before diving into solutions, it helps to understand the full landscape of email-driven fraud. These are not isolated incidents — they are systematic, repeatable attack patterns that scale effortlessly.
Promotional Abuse and Coupon Fraud
Welcome discounts, referral bonuses, and first-order coupons are powerful acquisition tools. They are also magnets for abuse. A fraudster who discovers that your platform offers a 20% discount to new accounts will simply create dozens of new accounts, each with a different disposable email address, and claim the discount repeatedly. This is sometimes called "multi-accounting" or "bonus abuse," and it is extraordinarily common.
According to a 2023 report by Signifyd, promotional abuse accounts for nearly 29% of all e-commerce fraud losses, making it the single largest category of fraud by volume. The margins on those discounted orders are already thin — when they are claimed by fraudsters, they become pure losses.
Fake Reviews and Rating Manipulation
Fake product reviews distort purchasing decisions and damage competitor rankings. Merchants operating on platforms like Amazon, Etsy, or their own storefronts may face coordinated review bombing from competitors, or conversely, may be tempted to generate fake positive reviews themselves. Either way, the mechanism is the same: bulk fake accounts, each with a disposable or synthetic email address, submitting reviews at scale.
The problem is significant. A 2022 study by the Transparency Company found that approximately 30% of reviews on major e-commerce platforms are potentially fraudulent, costing honest sellers meaningful ranking and revenue.
Account Takeover and Credential Stuffing
Account takeover (ATO) attacks involve fraudsters gaining access to legitimate customer accounts, typically by using leaked credential databases. Once inside, they change the email address, drain loyalty points, redirect pending shipments, or make unauthorized purchases using stored payment methods.
Email verification plays a defensive role here too. When a user attempts to change their account email, verifying that the new address is real and deliverable adds a meaningful barrier against takeover attempts. Fraudsters frequently switch accounts to disposable or synthetic addresses as part of the takeover process.
Chargeback Fraud and Friendly Fraud
Chargeback fraud — where a customer makes a legitimate purchase and then disputes the charge with their bank — is one of the most damaging forms of e-commerce fraud. Merchants not only lose the merchandise but also pay chargeback fees that typically range from $20 to $100 per incident. According to Chargebacks911, friendly fraud costs e-commerce merchants over $132 billion annually, with an average chargeback costing merchants 2.4 times the original transaction value when fees and overhead are included.
Fraudulent accounts created with fake email addresses are disproportionately likely to initiate chargebacks. A real customer with a verified, deliverable email address is far less likely to dispute a legitimate transaction than someone who registered with a throwaway address specifically to commit fraud.
Where to Integrate Email Verification in Your E-commerce Stack
Effective fraud prevention is not a single checkpoint — it is a series of gates. Each integration point catches a different class of fraudulent behavior.
Account Signup
This is the most obvious integration point and the most impactful. Verifying email addresses at registration prevents fake accounts from being created in the first place. Any address that fails deliverability checks, belongs to a known disposable provider, or shows signs of being synthetically generated should be flagged or blocked immediately.
It is worth noting that the problem is larger than most merchants assume. Research by Arkose Labs found that between 20% and 30% of new account registrations on some e-commerce platforms come from fake or fraudulent users. Catching these at the door eliminates downstream fraud before it begins.
Checkout for Guest Orders
Many e-commerce platforms allow guest checkout without creating an account. Fraudsters love this flow because it bypasses account-level controls. Verifying the email address entered at checkout — even for guest orders — adds a meaningful signal. A disposable email at checkout is a strong indicator of fraud risk and should trigger additional review or payment verification steps.
Account Recovery and Password Reset
Password reset flows are a common vector for account takeover. If an attacker can intercept or redirect a reset email, they gain full access to the account. Verifying that the email on file is still deliverable before sending a reset link reduces the risk of reset emails landing in attacker-controlled inboxes. This is particularly relevant when users have not logged in for extended periods.
Review and UGC Submissions
If your platform accepts product reviews, Q&A submissions, or other user-generated content, verifying the submitter's email address before publishing adds a layer of authenticity. Reviews submitted from disposable or role-based addresses (like admin@ or test@) warrant additional scrutiny before going live.
Loyalty Program Enrollment
Loyalty programs are high-value targets for multi-accounting fraud. Points can often be transferred or redeemed for real merchandise. Verifying email addresses at enrollment and periodically re-verifying the database prevents dormant fake accounts from accumulating points.
Specific Fraud Patterns and How Email Verification Disrupts Them
Understanding the mechanics of each attack pattern makes it easier to configure your verification logic appropriately.
The Referral Abuse Loop
Referral programs offer existing users a reward for bringing in new customers. The fraud pattern is straightforward: create Account A with a real or semi-real email, generate a referral link, then create Accounts B through Z using disposable addresses. Each fake signup triggers a referral reward for Account A.
Email verification disrupts this loop at the point of new account creation. If your verification flags disposable email providers — temporary mail services like Mailinator, Guerrilla Mail, 10 Minute Mail, and hundreds of others — the fake accounts never complete registration, and the referral reward is never triggered.
The MailValid API returns a disposable flag as part of its response payload, making it straightforward to reject or flag these addresses in your registration logic.
The Promo Code Farming Operation
Welcome discount codes are typically single-use and tied to a new account. A fraudster who wants to farm these codes will use a disposable email service that generates unlimited unique addresses under a single domain, or will use a "plus addressing" trick ([email protected], [email protected]) to generate variations of the same address.
Verification catches both vectors. Disposable provider detection blocks throwaway domains. Catch-all domain detection identifies domains that accept all incoming mail regardless of whether the specific address exists, which is a common characteristic of self-hosted disposable mail setups. Plus-addressing normalization can identify that [email protected] and [email protected] resolve to the same underlying inbox.
The Fake Review Network
Review farms typically operate by creating hundreds or thousands of accounts, each submitting a single review to avoid pattern detection. These accounts are created in bulk using disposable email addresses or synthetic addresses that pass basic format validation but are not actually deliverable.
SMTP-level verification — where the verification service actually checks whether the mailbox exists on the receiving mail server — is the most effective tool against synthetic addresses. An address like [email protected] might pass format and domain checks but fail SMTP verification because no such mailbox exists. MailValid performs this check as part of its standard verification process.
Python Integration: Verifying Emails at Checkout
The most impactful single integration point for most e-commerce merchants is checkout. Here is a complete Python example that calls the MailValid API when a customer submits their email at checkout, evaluates the risk level, and decides whether to proceed, flag for review, or block the order.
import requests
import json
from enum import Enum
MAILVALID_API_KEY = "your_api_key_here"
MAILVALID_API_URL = "https://api.mailvalid.io/v1/verify"
class CheckoutDecision(Enum):
ALLOW = "allow"
FLAG_FOR_REVIEW = "flag_for_review"
BLOCK = "block"
def verify_checkout_email(email: str) -> dict:
"""
Verify an email address using the MailValid API.
Returns the full verification result.
"""
headers = {
"Authorization": f"Bearer {MAILVALID_API_KEY}",
"Content-Type": "application/json"
}
payload = {"email": email}
try:
response = requests.post(
MAILVALID_API_URL,
headers=headers,
json=payload,
timeout=5
)
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
# Fail open on timeout to avoid blocking legitimate customers
return {"error": "timeout", "result": "unknown"}
except requests.exceptions.RequestException as e:
return {"error": str(e), "result": "unknown"}
def evaluate_checkout_risk(verification_result: dict) -> tuple[CheckoutDecision, str]:
"""
Evaluate the fraud risk of an email at checkout based on
MailValid verification results.
Returns a tuple of (decision, reason).
"""
# If verification failed due to network issues, allow with logging
if "error" in verification_result:
return CheckoutDecision.ALLOW, "verification_unavailable"
result = verification_result.get("result", "unknown")
is_disposable = verification_result.get("disposable", False)
is_role_based = verification_result.get("role", False)
is_catch_all = verification_result.get("catch_all", False)
is_free_provider = verification_result.get("free_provider", False)
# Hard block: disposable email addresses
# These are almost never used by legitimate customers for purchases
if is_disposable:
return CheckoutDecision.BLOCK, "disposable_email_detected"
# Hard block: invalid or undeliverable addresses
if result in ("invalid", "undeliverable"):
return CheckoutDecision.BLOCK, "email_not_deliverable"
# Flag for review: role-based addresses at checkout
# Legitimate customers rarely use admin@ or info@ for personal purchases
if is_role_based:
return CheckoutDecision.FLAG_FOR_REVIEW, "role_based_email"
# Flag for review: catch-all domains with unknown deliverability
if is_catch_all and result == "unknown":
return CheckoutDecision.FLAG_FOR_REVIEW, "catch_all_domain_unverified"
# Allow: valid, deliverable address
if result in ("valid", "deliverable"):
return CheckoutDecision.ALLOW, "email_verified"
# Default: flag unknown results for manual review
return CheckoutDecision.FLAG_FOR_REVIEW, "verification_inconclusive"
def process_checkout_email(email: str, order_value: float) -> dict:
"""
Main checkout email processing function.
Combines verification and risk evaluation with order-value-aware logic.
"""
print(f"Verifying email: {email} for order value: ${order_value:.2f}")
verification_result = verify_checkout_email(email)
decision, reason = evaluate_checkout_risk(verification_result)
# For high-value orders, escalate flag_for_review to stricter handling
HIGH_VALUE_THRESHOLD = 500.00
if order_value >= HIGH_VALUE_THRESHOLD and decision == CheckoutDecision.FLAG_FOR_REVIEW:
print(f"High-value order flagged — escalating review for {email}")
response = {
"email": email,
"decision": decision.value,
"reason": reason,
"order_value": order_value,
"verification_details": verification_result
}
print(f"Checkout decision: {decision.value} — Reason: {reason}")
return response
# Example usage
if __name__ == "__main__":
test_cases = [
("[email protected]", 89.99),
("[email protected]", 149.00),
("[email protected]", 299.99),
("[email protected]", 750.00),
]
for email, order_value in test_cases:
result = process_checkout_email(email, order_value)
print(json.dumps(result, indent=2, default=str))
print("---")
JavaScript Integration for Frontend Validation
For client-side validation during the checkout flow, here is a JavaScript implementation that calls the MailValid API and provides real-time feedback before form submission:
const MAILVALID_API_URL = "https://api.mailvalid.io/v1/verify";
const MAILVALID_API_KEY = "your_api_key_here";
async function verifyEmailAtCheckout(email) {
try {
const response = await fetch(MAILVALID_API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${MAILVALID_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
signal: AbortSignal.timeout(5000),
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return await response.json();
} catch (error) {
console.warn("Email verification unavailable:", error.message);
return { error: error.message, result: "unknown" };
}
}
function getCheckoutDecision(verificationResult) {
if (verificationResult.error) {
return { decision: "allow", reason: "verification_unavailable" };
}
const { result, disposable, role, catch_all } = verificationResult;
if (disposable) {
return {
decision: "block",
reason: "Please use a permanent email address to complete your order.",
};
}
if (result === "invalid" || result === "undeliverable") {
return {
decision: "block",
reason: "This email address appears to be invalid. Please check and try again.",
};
}
if (role) {
return {
decision: "flag",
reason: "We recommend using a personal email address for order confirmations.",
};
}
return { decision: "allow", reason: "email_verified" };
}
// Attach to checkout form
document.addEventListener("DOMContentLoaded", () => {
const checkoutForm = document.getElementById("checkout-form");
const emailInput = document.getElementById("email");
const emailFeedback = document.getElementById("email-feedback");
const submitButton = document.getElementById("submit-order");
let verificationDebounceTimer;
emailInput.addEventListener("input", () => {
clearTimeout(verificationDebounceTimer);
verificationDebounceTimer = setTimeout(async () => {
const email = emailInput.value.trim();
if (!email || !email.includes("@")) return;
emailFeedback.textContent = "Verifying...";
emailFeedback.className = "feedback-pending";
const result = await verifyEmailAtCheckout(email);
const { decision, reason } = getCheckoutDecision(result);
if (decision === "block") {
emailFeedback.textContent = reason;
emailFeedback.className = "feedback-error";
submitButton.disabled = true;
} else if (decision === "flag") {
emailFeedback.textContent = reason;
emailFeedback.className = "feedback-warning";
submitButton.disabled = false;
} else {
emailFeedback.textContent = "Email verified ✓";
emailFeedback.className = "feedback-success";
submitButton.disabled = false;
}
}, 600);
});
});
Important note on API key security: Never expose your MailValid API key in client-side JavaScript in production. Route verification requests through your own backend endpoint, which then calls the MailValid API with the key stored server-side.
The ROI Calculation: Verification vs. Fraud Losses
The business case for email verification is compelling when you run the numbers. Let us work through a realistic scenario for a mid-size e-commerce merchant.
The Cost of a Single Fraud Incident
A chargeback on a $150 order does not cost you $150. It costs you:
- Lost merchandise value: $150 (if goods were already shipped)
- Chargeback fee from payment processor: $25–$100 (typically $40–$75)
- Operational overhead: Staff time to respond to the dispute, typically 30–60 minutes at a fully-loaded labor cost of $35–$50/hour
- Chargeback ratio impact: If your chargeback ratio exceeds 1%, you may face elevated processing fees or lose your merchant account entirely
A conservative estimate puts the total cost of a single $150 chargeback at $220–$350. For merchants with higher average order values, the numbers scale accordingly.
Promo Abuse at Scale
Consider a welcome discount of 20% on first orders, with an average order value of $80. That is a $16 discount per new account. If a fraudster creates 200 fake accounts in a month (a trivial task with disposable email services), the direct discount loss is $3,200. Add in the cost of fulfilling any orders placed and the operational overhead, and the monthly loss from a single bad actor can easily exceed $5,000.
The Cost of Email Verification
MailValid pricing starts at fractions of a cent per verification. Even at a generous estimate of $0.005 per verification, verifying 10,000 new registrations per month costs $50. If that verification prevents even a single $300 fraud incident — the most conservative possible estimate — the ROI is 600%.
For a merchant processing 50,000 new registrations per month:
| Cost Category | Monthly Amount |
|---|---|
| Verification cost (50,000 × $0.005) | $250 |
| Chargebacks prevented (estimated 0.5% reduction on 50k signups) | 250 incidents |
| Average chargeback cost | $280 |
| Fraud loss prevented | $70,000 |
| Net ROI | 27,900% |
These numbers are conservative. They do not account for promo abuse prevention, fake review elimination, or the long-term brand value of maintaining a clean customer database.
Bulk Verification: Cleaning Your Existing User Database
Email verification is not only a real-time tool. If your platform has been operating without verification, your existing user database likely contains a significant percentage of invalid, disposable, or fraudulent addresses. Cleaning this database delivers immediate benefits: better email deliverability, reduced bounce rates, and identification of dormant fraud accounts.
Python Bulk Verification Script
import requests
import csv
import time
import json
from pathlib import Path
MAILVALID_API_KEY = "your_api_key_here"
MAILVALID_API_URL = "https://api.mailvalid.io/v1/verify"
def verify_email(email: str, session: requests.Session) -> dict:
"""Verify a single email using a persistent session for efficiency."""
headers = {
"Authorization": f"Bearer {MAILVALID_API_KEY}",
"Content-Type": "application/json"
}
try:
response = session.post(
MAILVALID_API_URL,
headers=headers,
json={"email": email},
timeout=10
)
response.raise_for_status()
result = response.json()
result["queried_email"] = email
return result
except requests.exceptions.RequestException as e:
return {"queried_email": email, "result": "error", "error": str(e)}
def bulk_verify_database(
input_csv: str,
output_csv: str,
email_column: str = "email",
rate_limit_per_second: int = 10,
batch_size: int = 100
) -> dict:
"""
Bulk verify all emails in a CSV file.
Args:
input_csv: Path to input CSV with user data
output_csv: Path to write results
email_column: Name of the column containing email addresses
rate_limit_per_second: Max API calls per second
batch_size: Number of records to process before writing to disk
Returns:
Summary statistics dictionary
"""
results = []
stats = {
"total": 0,
"valid": 0,
"invalid": 0,
"disposable": 0,
"catch_all": 0,
"unknown": 0,
"errors": 0
}
delay = 1.0 / rate_limit_per_second
with requests.Session() as session:
with open(input_csv, "r", newline="", encoding="utf-8") as infile:
reader = csv.DictReader(infile)
rows = list(reader)
print(f"Starting bulk verification of {len(rows)} email addresses...")
for i, row in enumerate(rows):
email = row.get(email_column, "").strip()
if not email:
continue
verification = verify_email(email, session)
result_status = verification.get("result", "unknown")
# Merge original row data with verification results
enriched_row = {
**row,
"verification_result": result_status,
"is_disposable": verification.get("disposable", False),
"is_role_based": verification.get("role", False),
"is_catch_all": verification.get("catch_all", False),
"fraud_risk": classify_fraud_risk(verification),
"recommended_action": get_recommended_action(verification)
}
results.append(enriched_row)
# Update stats
stats["total"] += 1
if result_status in ("valid", "deliverable"):
stats["valid"] += 1
elif result_status in ("invalid", "undeliverable"):
stats["invalid"] += 1
elif verification.get("disposable"):
stats["disposable"] += 1
elif verification.get("catch_all"):
stats["catch_all"] += 1
elif "error" in verification:
stats["errors"] += 1
else:
stats["unknown"] += 1
# Progress logging
if (i + 1) % batch_size == 0:
print(f"Processed {i + 1}/{len(rows)} records...")
# Write batch to disk to avoid memory issues on large datasets
write_results_to_csv(results, output_csv, append=(i >= batch_size))
results = []
time.sleep(delay)
# Write any remaining results
if results:
write_results_to_csv(results, output_csv, append=(stats["total"] > batch_size))
print(f"\nBulk verification complete.")
print(f"Results written to: {output_csv}")
print(json.dumps(stats, indent=2))
return stats
def classify_fraud_risk(verification: dict) -> str:
"""Assign a fraud risk level based on verification results."""
if verification.get("disposable"):
return "high"
if verification.get("result") in ("invalid", "undeliverable"):
return "high"
if verification.get("role") and verification.get("catch_all"):
return "medium"
if verification.get("catch_all") and verification.get("result") == "unknown":
return "medium"
if verification.get("result") in ("valid", "deliverable"):
return "low"
return "medium"
def get_recommended_action(verification: dict) -> str:
"""Recommend an action for each account based on verification results."""
risk = classify_fraud_risk(verification)
if risk == "high":
return "suspend_pending_review"
if risk == "medium":
return "require_reverification"
return "no_action_required"
def write_results_to_csv(results: list, output_path: str, append: bool = False) -> None:
"""Write results to CSV file."""
if not results:
return
mode = "a" if append else "w"
with open(output_path, mode, newline="", encoding="utf-8") as outfile:
writer = csv.DictWriter(outfile, fieldnames=results[0].keys())
if not append:
writer.writeheader()
writer.writerows(results)
# Example usage
if __name__ == "__main__":
stats = bulk_verify_database(
input_csv="users_export.csv",
output_csv="users_verified.csv",
email_column="email",
rate_limit_per_second=10
)
What to Do With the Results
Once you have your bulk verification results, segment your user base into three tiers:
-
High risk (disposable, invalid, undeliverable): Suspend these accounts pending identity verification. Send a re-verification email to the address on file. If it bounces, escalate to manual review or permanent suspension.
-
Medium risk (catch-all, unknown, role-based): Require these users to confirm their email address the next time they log in. Do not suspend them outright, but do not extend new promotions or increase purchase limits until they verify.
-
Low risk (valid, deliverable): No action required. These accounts can be used as a baseline for normal customer behavior modeling.
Building a Sustainable Fraud Prevention Posture
Email verification is not a one-time fix — it is an ongoing practice. Fraud techniques evolve, new disposable email providers emerge constantly, and your user base changes over time. Building a sustainable posture means treating verification as infrastructure rather than a feature.
Establish Verification at Every Entry Point
Work through your entire customer journey and identify every point where an email address enters your system. This typically includes registration, guest checkout, newsletter signup, loyalty enrollment, account updates, and review submissions. Each of these is a potential fraud entry point and should have verification in place.
Set Risk Thresholds That Match Your Business
Not every business should have the same blocking thresholds. A high-volume marketplace with thin margins and high fraud exposure should block aggressively. A B2B platform where customers use corporate email addresses might apply different rules to free provider addresses than a consumer retailer would.
The code examples above demonstrate how to make these decisions programmatically based on your specific risk tolerance. Tune the thresholds based on your actual fraud rates and customer demographics.
Monitor and Iterate
Track the percentage of blocked registrations over time. A sudden spike may indicate a coordinated attack. A gradual increase may indicate that fraudsters have discovered a weakness in your flow. Use your verification data as an early warning system, not just a gate.
Combine email verification signals with other fraud indicators — device fingerprinting, IP reputation, behavioral velocity checks — to build a multi-layered defense. Email verification is the most cost-effective first layer, but it works best as part of a broader fraud prevention stack.
Re-verify Your Database Periodically
Email addresses change. People abandon inboxes. Domains expire. An address that was valid eighteen months ago may be undeliverable today — or worse, may have been recycled to a new owner. Running periodic re-verification of your active user database (quarterly is a reasonable cadence for most merchants) keeps your data clean and your fraud signals accurate.
Conclusion: Email Verification Is the Highest-ROI Fraud Prevention Investment You Can Make
The math is straightforward. A single prevented chargeback pays for thousands of email verifications. The operational overhead of managing fraud — customer service tickets, dispute responses, manual reviews — is eliminated before it starts. Your promotions reach real customers instead of being farmed by bots. Your reviews reflect genuine buyer experiences instead of manufactured sentiment.
Email verification does not require a significant engineering investment. The MailValid API is straightforward to integrate, the response times are fast enough for real-time checkout flows, and the pricing is low enough that verification adds no meaningful cost to customer acquisition.
The merchants who are losing the most to e-commerce fraud are not losing because they lack sophisticated fraud tools. They are losing because they never verified the email address at the door.
Ready to verify your list? Get started free — 1,000 credits free.
MailValid Team
Email verification experts
Join developers who verify smarter
Stop letting bad emails hurt your deliverability
100 free credits. $0.001/email after. Credits never expire. No credit card required.