Abandoned cart emails module
Module id: abandoned_cart. Dependencies: checkout.
A shopper who leaves items in their cart gets one email some hours later, listing what is in it, with a button that puts the cart back.
The module is off on every website until it is switched on in the Modules tab. The sidebar item (Abandoned carts, Commerce section, next to Review requests) opens its settings.
Who gets a reminder
Only shoppers whose address the shop already has:
- Customers who are logged in. Their cart is kept with their account, so the reminder goes to the account's address, in the account's language.
- Guests who went to the payment page and did not pay. Their order was cancelled (payment failed, cancelled or expired) and the cart is still there. The reminder goes to the address on that order, in the order's language.
A guest who leaves before pressing the order button cannot be reached: the email field is not saved until the order is placed. That is deliberate.
Not reminded:
- A cart that was ordered from after its last change: paid, shipped, or still awaiting payment (a bank transfer, for instance).
- An emptied cart.
- Shoppers who unsubscribed from cart reminders on this website.
- Shoppers reminded recently: someone who got a reminder within Remind the same shopper again after days does not get another for a new cart. 0 reminds about every cart.
- A deleted or disabled customer account.
When
Every 15 minutes the platform looks for carts whose last activity is at least Hours after the cart was left ago. The last activity is the later of the last change to the cart and the moment a guest went to pay.
Each abandonment gets at most one reminder. A shopper who comes back, changes the cart and leaves again has abandoned it again, and can get a new reminder, subject to the repeat rule above.
A cart more than 48 hours past due is let go. That stops switching the module on from emailing every cart on record, and it also means a missed run, or a website that fixes its sender address, still reminds this morning's shoppers.
What operators set
| Setting | Default | What it does |
|---|---|---|
| Hours after the cart was left | 3 | 1 to 72. |
| Remind the same shopper again after | 7 days | 0 to 90. 0 = remind about every cart. |
| Email text (per language) | built-in text | Subject and opening paragraph. Blank = the built-in text in that language. %shop% and %name% (first name) are filled in. |
Nothing is sent while the website has no sender address. The settings screen says so in red.
A discount code to win the shopper back goes in the opening text ("Use code WELCOMEBACK for 10% off"). Create the code under Discounts first; the mail does not apply it, the shopper types it at checkout.
The link back to the cart
The button opens /cart/recover/{token}. It adds what the reminded cart
holds to the cart of whoever opens it, and shows the cart:
- It works on another device than the one the cart was filled on.
- Prices are today's, stock and minimum quantities are checked again, and a product unpublished or restricted since is left out. The shopper is told when something could not come back.
- A product already in the cart is topped up to the reminded quantity, never added on top, so opening the link twice does not double anything.
The mail itself shows no prices, for the same reason: the cart may no longer say what yesterday's mail would.
The law
Treat a cart reminder as a marketing email. The safe route under Dutch and EU rules: tell shoppers near the email field at checkout, and in the privacy statement, that they may get a reminder about an unfinished order, and let every mail carry a working opt-out (it does, see below). Whether that is enough for a given shop is the shop's call; the module does not ask for consent itself.
Unsubscribe
Every reminder carries an unsubscribe link and a one-click
List-Unsubscribe header (RFC 8058). Unsubscribing stops cart reminders
from this website to that address, nothing else: order mails, review
requests and the newsletter are not affected. The link keeps working after
the module is switched off.
Where to see what was sent
The settings screen shows how many reminders went out in the last 30 days, and in how many of those the cart link was opened. A link checker in the shopper's mail (some company mail scans every link) counts as an opening.
A reminder is not part of an order, so it is not in any order's Emails tab. If a send fails (the mail server was down) it is recorded as failed and not retried: one reminder too few is better than two.
Public routes
| Route | Method | What |
|---|---|---|
/cart/recover/{token} |
GET | The button in the email: puts the cart back, then shows /cart. 404 while the cart module is off. |
/cart/reminders/unsubscribe/{token} |
GET, POST | Opt-out link from the email; POST is the one-click unsubscribe from mail providers. |
Overridable templates
| Template | What |
|---|---|
abandoned_cart/email/abandoned_cart.html.twig (+ .txt.twig) |
The email. Inputs: website, subject, locale, customer_name, message (the shop's own text or null), items (list of name, quantity), cart_url, unsubscribe_url. |
abandoned_cart/unsubscribe.html.twig |
The page after unsubscribing. Inputs: website, result (done or invalid). |
Scheduled job
cms-cron-abandoned-cart-remind in cms-k8s runs
app:schedule:dispatch abandoned-cart:remind every 15 minutes. It only
queues the work; cms-worker sends the mails on the analytics queue.