Abandoned cart recovery
Your storefront reports in-progress carts; litecommerce stores them, and a
recovery cron emails customers who left one behind. Examples reuse the
api() helper.
Capture a cart (public)
POST /api/v1/public/abandoned-carts — tenant header, no auth. Call it as the
cart changes; it upserts on sessionId, so repeated calls update one row
rather than piling up duplicates.
await api("/public/abandoned-carts", {
method: "POST",
body: JSON.stringify({
sessionId: "sess_…", // required, 8–200 — your storefront session id
snapshot: { // required — frozen cart state
items: [{ itemId: "…", variantId: "…", name: "Trail Pack 38L", quantity: 1, unitPriceInCents: 18900 }],
subtotalInCents: 18900,
totalInCents: 18900,
},
email: "dana@example.com", // optional — capture once you have it
}),
});
// → { ok: true, wasCreated: boolean } (deliberately returns no row id or email)email is optional so you can capture the cart before you know who it
belongs to, then fill it in once the shopper enters it. A cart with no email
can be stored but can't be emailed a recovery.
Review captures (merchant)
GET /api/v1/merchant/abandoned-carts?filter=pending — open to any member.
filter is pending (not yet recovered, the default), recovered, or all.
How recovery works
The recovery send is live and automated:
- A scheduled cron sweeps carts that have an email and aren't yet recovered
(
recoveredAt IS NULL). - It sends a recovery email via Resend and stamps
recoveryEmailSentAtandrecoveryEmailCount. The send is capped (an unconverted cart gets at most a couple of nudges spaced out over ~a day, never an indefinite stream).
You don't trigger any of this — capturing the cart (with an email) is all your storefront does; the platform handles the send cadence.
Conversion attribution isn't wired yet.
recoveredAtexists as a column and therecovered/allmerchant filters read it, but nothing stamps it when a captured cart turns into an order today — so in practice every captured cart stays in thependinglist, and the send cap (not a conversion signal) is what stops the emails. Closing that loop — matching a new order back to its cart and stampingrecoveredAt— is a planned follow-up that pairs naturally with order placement at hosted checkout.
Related
- Orders & fulfillment — what a recovered cart becomes
- Pricing rules — a recovery email can feature a coupon