Strict Form Validation: Phone, Email, Passwords & Double-Submit
E-COMMERCE AUDITOR CURRICULUM14 Master Lessons

Learn the Good Patterns

Real-world engineering guide on how top e-commerce websites achieve sub-1.0s LCP, zero layout shifts, impenetrable checkout security, and effortless scale.

UX, Forms & Styling5 min read

Strict Form Validation: Phone, Email, Passwords & Double-Submit

Validating shopping inputs (E.164 phone numbers, RFC email, strong passwords), preventing double-submit charges with disabled states, and accessible error handling.

Production Benchmark (E-Commerce Standard)

Masked Inputs, Robust Regex & Anti-Double-Charge Guards

Production checkout forms validate customer input immediately in the browser while guaranteeing duplicate validation on the server. Phone fields enforce international E.164 standards with numeric keypads, emails are normalized and validated, and the "Pay Now" button is disabled with a loading spinner upon first click to prevent shoppers from being double-charged.

Production Implementation Reference
// Accessible Checkout Form with Anti-Double-Submit Guard (React / Next.js)
import { useState } from 'react';

export function CheckoutForm() {
  const [phone, setPhone] = useState('');
  const [email, setEmail] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errorMsg, setErrorMsg] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (isSubmitting) return; // Prevent double click

    // 1. Phone validation: E.164 (10 to 15 digits)
    const phoneRegex = /^\+?[1-9]\d{9,14}$/;
    if (!phoneRegex.test(phone.replace(/\s+/g, ''))) {
      setErrorMsg('Please enter a valid 10-digit phone number with country code');
      return;
    }

    // 2. Email normalization
    const cleanEmail = email.trim().toLowerCase();

    setIsSubmitting(true);
    try {
      await processOrderPayment({ email: cleanEmail, phone });
    } catch (err) {
      setErrorMsg(err.message);
      setIsSubmitting(false); // Re-enable on error
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <label htmlFor="customer-phone" className="block text-xs font-bold text-slate-700">
          Mobile Number (for Order SMS Tracking)
        </label>
        <input
          id="customer-phone"
          type="tel"
          inputMode="tel"
          required
          placeholder="+1 555 019 2834"
          value={phone}
          onChange={(e) => setPhone(e.target.value)}
          className="w-full rounded-lg border border-slate-300 p-2 text-sm"
        />
      </div>

      <button
        type="submit"
        disabled={isSubmitting}
        className="w-full rounded-xl bg-emerald-600 py-3 text-sm font-bold text-white hover:bg-emerald-500 disabled:opacity-50 flex items-center justify-center gap-2"
      >
        {isSubmitting ? (
          <>
            <span className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
            <span>Processing Payment... Do Not Refresh</span>
          </>
        ) : (
          <span>Pay $129.00 Securely</span>
        )}
      </button>
    </form>
  );
}

Key Engineering & Business Benefits:

  • Eliminates duplicate credit card authorization charges from impatient customer double-clicks.
  • Triggers the native telephone keypad on iOS and Android devices via inputmode="tel".
  • Reduces delivery failures caused by malformed phone numbers or mistyped delivery emails.
The Bad Site Anti-Pattern

The Horror Site: Zero Validation & 5x Double Charge Bug

High (Severity 8/10)

The bad site accepted random letters ("abcde") for phone numbers, allowed negative quantities ("-5 pairs of shoes"), and left the "Pay" button clickable indefinitely. Rapid clicking submitted multiple requests to the payment processor, charging customers multiple times!

<input type="text" name="phone" placeholder="Enter anything" /> <!-- Zero disabled state on click: --> <button onclick="payOrder()">Pay Now (Click 5 times for 5 charges!)</button>

How to Implement / Fix in 3 Practical Steps

1

Use inputmode="tel" and regex /^\+?[1-9]\d{9,14}$/ to validate phone numbers accurately.

2

Disable the payment submission button immediately upon click and render an accessible processing spinner.

3

Sanitize text inputs to eliminate cross-site scripting (XSS) in delivery instructions and review comments.

Auditor DevTools Inspection Tip:

Fill in checkout fields with invalid characters ("abcd" in phone) and click the Pay button rapidly. Verify validation blocks submission and button enters disabled state.

Finished reading this lesson?

Mark it as mastered below, or click Next Lesson to auto-complete.

Strict Form Validation: Phone, Email, Password… · DataArena