and runs during HTML parse, but hubspotutk is set by
js.hs-analytics.net, measured loading at ~834ms. On a first visit the cookie
does not exist yet, so a single read returns nothing and the visitor gets no
external ID at all — and a first visit is exactly what an ad click is. So
poll briefly until HubSpot sets it. The SDK loads lazily (~4.5s) and replays
a queue, so an init queued a second or two in still lands before any events
are transmitted. */
(function attachExternalId() {
var attempts = 0;
var MAX_ATTEMPTS = 40; /* 40 x 200ms = 8s, then give up quietly */
var timer = null;
function tryAttach() {
var raw = getExternalId();
if (!raw) {
if (++attempts >= MAX_ATTEMPTS && timer) clearInterval(timer);
return;
}
if (timer) clearInterval(timer);
sha256Hex(raw).then(function (hash) {
oaiq("init", { user: { external_id_sha256: hash } });
}).catch(function () {});
}
tryAttach(); /* returning visitor: immediate */
if (!getExternalId()) timer = setInterval(tryAttach, 200);
})();
/* ---------------------------------------------------------------------------
2. Load the SDK off the critical path
Whichever comes first: the main thread going idle after load, or the first
sign of real user intent. No preconnect on purpose — a TLS handshake during
LCP for a script we deliberately deferred is a net loss.
Measured on clickpost.ai: load event 3614ms, SDK fetched 4508ms.
------------------------------------------------------------------------ */
var loaded = false;
var INTENT = ["pointerdown", "keydown", "scroll"];
function loadSdk() {
if (loaded) return;
loaded = true;
INTENT.forEach(function (t) { removeEventListener(t, loadSdk, { passive: true }); });
var s = document.createElement("script");
s.src = SDK;
s.async = true;
s.fetchPriority = "low";
document.head.appendChild(s);
}
INTENT.forEach(function (t) {
addEventListener(t, loadSdk, { passive: true, once: true });
});
addEventListener("load", function () {
window.requestIdleCallback
? requestIdleCallback(loadSdk, { timeout: 2500 })
: setTimeout(loadSdk, 1500);
}, { once: true });
/* ---------------------------------------------------------------------------
3. Conversion id
sha256(lowercase(email) + "|" + formId + "|" + ISO-hour), first 20 hex,
"lead_" prefix.
- email lowercased/trimmed so casing does not fork the id
- formId keeps two different forms in the same hour from colliding
- the hour bucket is only the server's fallback; the id computed here is
sent to the relay verbatim, so the two paths cannot disagree even when
a submit straddles an hour boundary
Ads Manager's own sample omits event_id. We send it so the pixel event and
the relay event collapse into one conversion instead of counting twice.
------------------------------------------------------------------------ */
function buildEventId(email, formId) {
var seed = [
String(email || "").trim().toLowerCase(),
String(formId || ""),
new Date().toISOString().slice(0, 13)
].join("|");
return crypto.subtle.digest("SHA-256", new TextEncoder().encode(seed)).then(function (buf) {
var hex = Array.prototype.map.call(new Uint8Array(buf), function (b) {
return b.toString(16).padStart(2, "0");
}).join("");
return "lead_" + hex.slice(0, 20);
});
}
/* Guards a re-fire from the history.pushState that book-a-demo-core.js runs
after submit, and from back-navigation onto the same state. */
function firedOnce(id) {
try {
if (sessionStorage.getItem("oaiq_" + id)) return true;
sessionStorage.setItem("oaiq_" + id, "1");
return false;
} catch (e) {
return false; /* private mode / blocked storage: fire rather than lose it */
}
}
/* Path 2. keepalive lets the request finish even if the page navigates away.
Failures are swallowed deliberately: a reporting call must never surface an
error to someone who just submitted a form.
The relay hashes the email server-side into user.emails_sha256 and adds the
caller's IP and user agent, so this event carries the same match signals the
pixel gets for free. */
function sendToRelay(email, formId, eventType, eventId) {
try {
var payload = {
token: RELAY_TOKEN,
email: email,
form_id: formId || "",
event_type: eventType,
event_id: eventId, /* verbatim, so both paths always match */
source_url: location.href
};
var oppref = getOppref();
if (oppref) payload.oppref = oppref;
var externalId = getExternalId();
if (externalId) payload.external_id = externalId;
fetch(RELAY_URL, {
method: "POST",
keepalive: true,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
}).catch(function () {});
} catch (e) {}
}
/* Capture the email while the form is still on the page. onFormSubmitted does
not reliably carry submissionValues, and by then the form may be removed. */
var lastEmail = "";
document.addEventListener("submit", function (e) {
var f = e.target;
if (!f || !f.querySelector) return;
var i = f.querySelector('input[name="email"], input[type="email"]');
if (i && i.value) lastEmail = i.value;
}, true);
/* Every HubSpot form on the site reports through this one message event, so no
module or theme JS needs editing to add coverage. */
window.addEventListener("message", function (e) {
var d = e.data;
if (!d || d.type !== "hsFormCallback" || d.eventName !== "onFormSubmitted") return;
var email = (d.data && d.data.submissionValues && d.data.submissionValues.email) || lastEmail;
if (!email) return; /* without an email there is no stable id to dedupe on */
var eventType = EVENT_BY_FORM[d.id] || EVENT_DEFAULT;
buildEventId(email, d.id).then(function (id) {
if (firedOnce(id)) return;
oaiq("measure", eventType, { type: DATA_TYPE }, { event_id: id }); /* path 1 */
sendToRelay(email, d.id, eventType, id); /* path 2 */
});
});
})();
Beauty lives or dies on the second order, not the first.
Serums, shampoos, and cosmetics get bought again and again. So a single bad delivery or a clumsy return doesn't cost you one sale. It costs you the whole customer.
A bad delivery ends the relationship
A leaking bottle or a melted balm does more than trigger a refund. It ends a repeat relationship worth far more than one order, and the review usually follows.
Launches and drops spike WISMO
Beauty runs on limited launches, influencer drops, and sampling. Each one floods support with "where is my order" tickets, right when your team has the least room.
~10%
of beauty and health orders are returned, lower than apparel but harder to resell.
30–40%
of customers reorder from beauty brands, one of the highest repeat rates in ecommerce.
20–30%
of an item's value gets eaten by processing a single return.
50%+
of US shoppers say a damaged or leaking delivery would stop them reordering.
Sourced from National Retail Federation reports and industry benchmarks on ecommerce return costs and repeat-purchase rates.
HOW CLICKPOST HELPS
Own the whole journey, from doorstep to the way back
ClickPost runs tracking, returns, exchanges, and carrier decisions from one platform, so every post-purchase moment builds retention instead of eroding it.
Keep shoppers on your brand, not the carrier's site
Proactive updates by email and SMS at every milestone, on a branded tracking page that looks like your store. Fewer "where is my order" tickets during launches and drops.
Mobile-first branded tracking page
Milestone alerts by email, SMS, and push
Estimated delivery dates that set expectations
Use case
A skincare brand sends proactive SMS at each milestone during an influencer drop, keeping shoppers on a branded page instead of the carrier's site.
Business impact
Fewer WISMO tickets and more engagement on the brand's own domain.
Turn a return into an exchange or credit, not a loss
A self-service portal applies hygiene and eligibility rules, then offers a shade swap, an exchange, or store credit, so revenue stays inside the brand.
Branded self-service returns portal
Rule-based exchange and store-credit prompts
Return tracking so shoppers stop chasing status
Use case
A shopper wants to return an opened serum. The portal applies policy and offers store credit toward a better-fit product instead of a refund.
Business impact
More returns kept as exchanges or credit, protecting margin on items you can't resell.
Catch delayed and mishandled parcels before they leak revenue
Beauty ships fragile, sometimes temperature-sensitive parcels across UPS, USPS, FedEx, and regional carriers. ClickPost tracks every parcel in one place and flags stuck shipments early.
Unified tracking across US carriers
Early alerts on delayed and stuck shipments
Accurate delivery dates that hold up at peak
Use case
During a summer launch, a brand catches heat-delayed shipments in the control tower and reships before customers report melted product.
Business impact
Fewer damaged-delivery complaints and stronger repeat rates.
Feed return and reorder data back into product and merchandising
See why items come back by SKU and reason, and where repeat orders come from, then act on it. Post-purchase data becomes a signal for your product pages and buying decisions.
Return reason and exchange reporting
Repeat-order and carrier performance visibility
Signals your merchandising team can use
Use case
Analytics show a foundation shade has high returns for "wrong tone." The team improves the shade finder and returns fall.
Business impact
Higher repeat rate and clear data for product and buying decisions.
BEYOND TRACKING AND RETURNS
Keep more of every order, and grow it.
Beauty shoppers reorder, subscribe, and keep opening the order page. ClickPost adds three revenue moves built for exactly that behavior.
BEFORE IT SHIPS · ORDER EDITING
Let shoppers fix the order before the box leaves
Customers edit shade, variant, quantity, and address themselves from the order page, inside a window you set, so a wrong shade gets fixed instead of returned and written off.
Self-serve shade, variant, and address edits
Address validation pre-dispatch
Merchant-set edit window with 3PL sync
30%fewer order-change tickets
PROTECT REVENUE · RETURNS PROTECTION
Protect margin on returns you can't resell
ClickPost segments high-risk shoppers and applies eligibility rules by customer, region, or SKU, so hygiene-limited items are handled by policy instead of case by case.
AI segments serial returners
Eligibility enforcement by customer or SKU
Package protection for lost or damaged orders
30%of returns revenue protected
GROW AOV · POST-PURCHASE UPSELL
Prompt the reorder while attention is high
ClickPost surfaces AI-picked replenishment and routine add-ons on tracking and order pages and inside the returns flow, so one order becomes the next one.
AI reorder prompts on tracking pages
Routine add-ons during returns flow
Upsell and replenishment that lift AOV
+AOVfrom post-purchase recommendations
GETTING STARTED
Go live on ClickPost without rebuilding your stack
Connect your store and carriers
Plug ClickPost into Shopify or your commerce platform and link your US carriers through a single API.
Brand tracking and returns
Match the tracking page, returns portal, and notifications to your look and voice. Set exchange rules once.
Watch WISMO and refunds drop
Proactive updates cut support load and exchange prompts hold revenue. Analytics show what is working.
THE LEADER IN POST-PURCHASE
Powering 600+ leading retail brands
From the first tracking scan to the final return, ClickPost powers everything that happens after checkout.
We’ve been using Clickpost and it’s genuinely been super helpful. The post-purchase upsells have been a solid bonus for incremental revenue.
Samarth Sindhi
Chief Executive Officer, MarsGHC
ClickPost’s team were experts in their systems and integrated seamlessly with ours. They proactively resolved every issue, ensuring a smooth experience.
Sonali Das
D2C Tech and Product Head, Birkenstock
Great experience and fantastic support from ClickPost. This immediately cut our top post-purchase support tickets, making ROI easy to quantify. Plus, the customization features and upsell tools help increase AOV. Highly recommend.
Paul Fulton
VanillaPura
ClickPost helped us create a return experience that fit our business instead of forcing us to fit the platform. They customized our workflows without additional costs or developer support. The automation they built for our returns, freed up 5 hours a week.
Rated 4.8 on G2. Named a Leader in returns. Enterprise-grade security.
Enterprise-grade certifications
ISO 27001
SOC 2 Type II
GDPR Compliant
CCPA Compliant
4.8
4.4
Make Every Delivery the Start of the Next Reorder
High-repeat beauty brands turn the tracking page into the next reorder and stop fielding where-is-my-order tickets. See it on your catalog in 30 minutes.