Lead Capture
StorePilot can capture lead information from WooCommerce checkout forms — even before the customer completes the purchase. This lets you follow up with visitors who abandoned their cart. It also captures the contact forms on the rest of your site, in the browser and — for three form plugins — on the server.
How It Works
The plugin listens for blur and change events on WooCommerce checkout fields. As the visitor leaves each field, the values are buffered and sent to the Platform.
Capturing happens in two phases:
- Client-side (JavaScript) — Captures name, email, phone number as the visitor fills in the form
- Server-side enrichment (PHP) — After the JavaScript payload is received by the WordPress proxy, PHP adds:
wp_user_id— WordPress user ID if the visitor is logged in- Cart contents from WooCommerce (
WC()->cart) - Cart total value
The enriched lead is then forwarded to the Platform.
One shopper is one checkout, across several visits
A visit ends and a new one begins for reasons that have nothing to do with the purchase: the shopper signs in, opens a second tab, or comes back after half an hour away. Each of those starts a fresh browser session, and each used to produce a separate lead — so the same basket appeared twice, and a cart somebody bought an hour later went on being listed as abandoned.
StorePilot now recognises the returning shopper and keeps filling in the same lead. Three things identify them, in order: WooCommerce's own identifier for the visit, the email address on the form, and the browser. The window is 48 hours, which is how long WooCommerce itself keeps a guest cart — inside it, the basket a shopper returns to is the same basket the shop still holds.
What follows from that:
- The lead is announced once, counted once against your plan, and enrolled in cart recovery once.
- The lead page lists every visit the checkout was filled in over, with the session recording for each where one exists.
- A checkout begun after an order was paid is a new purchase attempt, never a continuation.
- Once an order confirms what was actually bought, a later visit never overwrites those lines.
Checkouts captured before this shipped can be collapsed by an operator running the merge tool; two orders from one shopper are always left as two.
Captured Fields
| Field | Source |
|---|---|
| First name | Checkout billing form |
| Last name | Checkout billing form |
| Checkout billing form | |
| Phone | Checkout billing form |
| Cart items | WooCommerce (server-side) |
| Cart total | WooCommerce (server-side) |
| WordPress user ID | WordPress session (server-side) |
| Page URL at capture time | JavaScript |
Which forms are captured
Two collectors, and they overlap on purpose — a form seen by both lands on one lead.
On the server, three form plugins report a submission after their own validation ran, whatever JavaScript did or did not do on the page:
| Plugin | Hook |
|---|---|
| Contact Form 7 | wpcf7_before_send_mail |
| WPForms | wpforms_process_complete |
| Gravity Forms | gform_after_submission |
In the browser, the generic form tracker watches every <form> on every page:
- It listens for the
submitevent on the document in the capture phase, so a form whose handler callspreventDefault()and posts by AJAX, a form rendered by React or Vue, a form injected after the page loaded, andrequestSubmit()are all seen — before the page's own handler can reset the fields. form.submit()fires no event at all, so the tracker also observes the method itself and reads the form before the page leaves.- A form is a contact form when one of its controls names a contact detail — by
name,id, placeholder,aria-labelor its<label>(email, phone, name, message, subject, company) — or says what it is throughtype="email",type="tel"or a standardautocompletetoken (email,tel,name,given-name,family-name,organization). Controls attached from outside the element withform="id"count. - Login, registration, search, password-reset, comment and cart forms are skipped, and so is
anything posting to
wp-login.phpor a checkout address (the checkout tracker owns those). - Password fields, hidden inputs and payment-shaped fields (
autocomplete="cc-*") never leave the page; credential-shaped names and street/postcode fields are sent as[hidden]. - A submit with no recognisable contact detail sends nothing and remembers nothing, so a visitor whose first attempt failed validation is still captured on the second.
Not captured, deliberately: a button that sends the data with its own script and never
submits a form — <button type="button"> with a click handler that calls fetch. Seeing that
would mean inspecting the body of every request your site makes, which StorePilot does not do.
If a form on your site is built that way, its plugin's server-side hook (above) is the path.
Lead Statuses
| Status | Meaning |
|---|---|
in_progress | Captured, and nothing has happened to it yet |
reached_out | A team member has contacted this person |
payment_pending | An order was placed and the money has not arrived |
cancelled | Every order this checkout produced was cancelled by the shop |
ordered | The order was paid |
You can update lead statuses in the Dashboard and add internal notes.
payment_pending is set by the shop, not by hand: WooCommerce creates the order row before
the payment gateway answers, so an order that fails, is abandoned at the payment step, or
waits on a bank transfer sits here. It is not counted as revenue, it is not a funnel
conversion, and cart-recovery sequences keep running for it — which is the point, because a
shopper whose card was declined is exactly the person a reminder is for. When the payment
completes, the same lead becomes ordered.
cancelled is derived the same way: it is what the lead reads once every order it produced has
been cancelled in the shop, whether by a merchant clearing stale quotes or by WooCommerce's own
unpaid-order timeout. It changes nothing about how the lead is treated — it is still open, so the
shopper's next attempt continues the same checkout, and cart-recovery sequences keep running,
because an unpaid order the shop cancelled is exactly the abandoned cart they exist for. A lead
with one paid order and any number of cancelled ones reads ordered: a person who bought is a
customer, whatever else they walked away from.
Acting on leads automatically
Every new lead can fire a signed webhook (n8n_leads_webhook) when it is captured — or, for an
abandoned checkout on a site that has set a delay, when that delay is up and the basket still
qualifies. See Notifications for the two controls and
Webhooks for the payload and signature. For ready-made
automations — an abandoned-cart email with a delay, a CRM card, a Slack alert for high-value
carts — import one of the n8n recipes as-is and connect your
own accounts.
Privacy
Lead capture requires your Privacy Policy to clearly disclose that you collect form data before checkout completion. StorePilot's own Privacy Policy and Terms of Service describe what the Platform does with the data; they are not a substitute for your own notice to your customers, which is your obligation as the Data Controller.
Consider adding a notice near the checkout form:
"Your information may be saved to allow us to follow up if your order is not completed. See our Privacy Policy."
(Link that to your privacy policy, not to ours — the disclosure has to come from the business the customer is buying from.)
This is considered best practice and is required in most jurisdictions.
GDPR / Opt-in Consideration
In EU/EEA jurisdictions, capturing personal data before explicit consent may require a cookie consent mechanism or an explicit opt-in checkbox near the checkout form.
See GDPR Compliance for detailed guidance.
WooCommerce Requirement
Lead capture requires WooCommerce 7.0+. If WooCommerce is not active, this feature is silently disabled.