Skip to main content

Overview

Abandoned carts are one of the highest-impact opportunities to recover lost revenue. Most users who abandon a cart still intend to purchase — they just need a timely reminder. This guide shows you how to build an automated abandoned cart Journey in OneSignal that:
  • Detects cart activity
  • Waits for a short period of inactivity
  • Sends a personalized reminder
  • Stops messaging immediately after purchase or cart removal
You can implement this using either:
  • Custom Events (recommended for most implementations)
  • Tags (simpler, limited use cases)
The right choice depends on the data you want to show in the message and where that data comes from.

What you will build

By the end of this guide, you will have:
  • Cart activity sent to OneSignal (via Tags or Custom Events)
  • A clear, code-defined abandonment signal
  • Message templates that personalize cart data
  • A Journey that:
    • Starts when an abandonment signal is received
    • Waits before sending
    • Sends an abandoned cart message
    • Exits immediately when the cart is emptied or purchased
  • Analytics to measure message and revenue performance

Choose your tracking method

You can track cart activity using either Custom Events or Tags.
  • Use Custom Events if you:
    • Can detect abandonment after a period of inactivity
    • Want rich cart data (items, images, prices)
    • Are comfortable ensuring events fire once per abandonment
  • Use Tags if you:
    • Want state-based safety by default
    • Only need simple cart data
    • Prefer segment-controlled entry and exit
This guide shows both approaches. Custom Events offer more flexibility, but require more care.

How abandoned carts are modeled

OneSignal does not automatically determine when a cart is abandoned.You decide when a cart becomes abandoned in your own code or system, and then notify OneSignal.
What cart_abandoned means The cart_abandoned event should represent a state transition - The cart was active → the user stopped engaging → the cart is now considered abandoned. This event should be sent:
  • After a meaningful period of inactivity (e.g. 1 hour)
  • Only if the cart still contains items
Do not send cart_abandoned on every cart update.Sending this event repeatedly will cause users to re-enter the Journey multiple times and may spam them.

How Journeys use abandonment signals

Once OneSignal receives cart_abandoned:
  • The user becomes eligible to enter the Journey
  • A wait period gives them time to return naturally
  • A message is sent only if they do not exit
  • The user exits immediately when cart_emptied is received
Journeys control timing and repetition — they do not determine abandonment.

Setup

Step 1. Plan your cart data and source

Decide what cart information you want to show and where that data comes from. Common cart data includes:
  • Product name, image, price, and quantity
  • Number of items in the cart
  • A deep link back to the cart
Your data source determines how you send events:
Data sourceRecommended method
App or websiteOneSignal Frontend SDK
Backend or databaseOneSignal REST API
Third-party platformIntegration-based Custom Events
By the end of this step, you know what data you will send and how you will send it.

Step 2. Send cart state signals to OneSignal

You must send signals that represent cart state changes.
SignalPurpose
cart_abandonedCart activity detected and not resolved
cart_updatedCart contents change
cart_emptiedCart cleared or purchase completed
Event and tag names must match exactly across SDK/API calls, Segments, Journey rules, and Liquid templates.
Use the OneSignal Web or Mobile SDKs to send Custom Events or Tags.
SDK MethodDescription
trackEventSend a Custom Event (Mobile SDK, Web SDK)
addTagsAdd a Tag (Mobile SDK, Web SDK)
removeTagsRemove a Tag (Mobile SDK, Web SDK)
Custom Event example
The cart_abandoned event should be sent after a period of cart inactivity, not when the user enters or updates their cart.The cart_emptied event should be sent immediately when the cart is emptied or a purchase is completed.
OneSignal.User.trackEvent("cart_abandoned", {
  product_name: "24 Pack of Acorns",
  product_image: "https://i.imgur.com/ssPCfbC.png",
  product_price: 12.99,
  product_quantity: 1,
  cart_url: "https://yourdomain.com/cart"
});
Tag example
This example sets the cart_updated tag to a Unix timestamp (in seconds) representing when the cart was last updated. You can also use a boolean value (true/false), but a timestamp provides more flexibility with Time Operators.
OneSignal.User.addTags({
  cart_updated: unix_timestamp_seconds,
  product_name: "24 Pack of Acorns", 
  product_image: "https://i.imgur.com/ssPCfbC.png",
  product_price: "$12.99",
  product_quantity: "1",
  cart_url: "https://yourdomain.com/username/cart"
})
If you do not send a cart_emptied signal, users may continue receiving abandoned cart messages after purchasing.

Step 3. Create abandoned cart message templates

Create message templates that reference cart data dynamically. For more details on the concepts used in this section, see:
Reference event properties using liquid syntax format:
Liquid
{{journey.event.name.properties.property_name | default: "fallback_value"}}
Message:
Liquid
You left {{journey.event.cart_abandoned.properties.product_name | default: "items"}} in your cart.
Image:
Liquid
{{journey.event.cart_abandoned.properties.product_image | default: "https://i.imgur.com/ssPCfbC.png"}}
Launch URL:
Liquid
{{journey.event.cart_abandoned.properties.cart_url | default: "https://yourdomain.com/cart"}}
The image will not display if product_image is not a direct, publicly accessible image URL.If your product_image is the name of an image file available online, you can reference the image using the following format: https://yourdomain.com/images/{{journey.event.cart_abandoned.properties.product_image | default: "stock_image"}}.png
Abandoned cart template example with Custom Events
Need email examples, help, or just more inspiration?

Step 4. Create abandoned cart Segment (Tags only)

This step is only required if you are using Tags to track cart activity. If you are using Custom Events, you can skip this step.
The Segment will determine who can enter the Journey. See Segments for more details. Select the User Tag filter to track users where the cart_updated tag exists AND select the Last Session filter is less than 7 days ago
Abandoned Cart Segment with Tag Filter where the cart_updated tag exists and the last session is less than 7 days ago
We can now track users that update their cart and have visited the app or website in the last 7 days.Users will be automatically removed from the segment when either of the following conditions are met:
  • After 7 days have passed since they last visited the app/website
  • When the cart_updated tag is removed

Step 5. Create the abandoned cart Journey

Create a Journey that reacts to cart activity. See Journeys for more details.
New Abandoned Cart Journey create screen

Journey settings

Review the Journey Settings guide for more details on Entry, Exit, and Re-entry rules. Entry Rules:
  • Select Custom Event
  • Custom Event Name: cart_abandoned
Users enter the Journey every time the cart_abandoned event is sent. Only send this event after a meaningful inactivity period.
Abandoned Cart Journey Custom Event Entry Rules
Exit Rules:
  • Select Meet a certain condition
  • Check Exit when custom event condition occurs
  • Custom Event Name: cart_emptied
Abandoned Cart Journey Custom Event Exit Rules
Users will exit the Journey when either:
  • The cart_emptied event (from step 3) is performed.
  • They complete the Journey.
Re-entry Rules (Tags only):
  • Select Yes, after a certain amount of time
  • Set the re-entry time to 1 day
Abandoned Cart Journey Re-entry Rules
If you have followed this guide completely so far, then users will:
  1. Enter the Journey when they abandon/update their cart
  2. Exit the Journey when they empty their cart or complete the Journey.
  3. Be eligible to re-enter the Journey:
    • Custom Events: Each time the cart_abandoned event is performed
    • Tags: After 1 day has passed since they last exited the Journey and are in the segment.
Save the Journey Settings.

Journey steps

Users will enter the Journey when they match the Segment. This typically happens within a few minutes after the event/tag is received. Users will flow through the Journey step by step until they reach the end or an exit rule is met. For a basic abandoned cart Journey, we want to do 2 things:
  1. Give the user enough time to empty their cart (make a purchase or empty their cart manually)
  2. If they do not empty their cart, send them a message reminding them about the items in their cart
Achieve this by first adding a Wait step to the Journey.
  • Set the wait time to be as long as you want. We recommend setting it to 1 hour so you can message them while they still have the intent to purchase.
Add a Message step.
  • Select the Abandoned Cart Push Notification template you created in Step 4.
Basic Abandoned Cart Journey Steps
Basic Abandoned Cart Journey is now configured.When a user enters the Journey, they will wait for 1 hour. If they do not exit the Journey, they will receive the abandoned cart push notification.

Advanced Journey Setup

Using the knowledge you have gained from this guide, you can now extend the Journey to send more messages over time.

Message Sequence

A best practice timing sequence for a very common high-performing cadence is:
  1. Send the first message after 1 hour (completed in this guide).
  2. Add another Wait step for 1 day and send a second message (~24 hours since they updated their cart).
  3. Add another Wait step for 2 days and send a third message (~72 hours since they updated their cart).
Message Types and Content: Depending on which channels you setup with OneSignal, you will achive better results using an omnichannel approach.
  1. This guide shows how to send a push notification message after the first hour. This is used as a helpful reminder to try capturing the sale while the user may still be online.
  2. Consider using both a push and email for your 2nd message. Use this second message to highlight benefits and social proof with light urgency to encourage them to purchase.
  3. For the final message of the sequence, use an email or maybe an SMS (depending on the use case) as a “last call”. Consider using a discount code or other incentive to encourage them to purchase.

Fallback Messages

OneSignal’s Journeys provide Wait Until branching logic that you can use to check if a message was confirmed delivered, clicked or opened and if not performed within a certain time period, send a fallback message. This is extremely helpful for users who may have unsubscribed from a specific message channel. More details on how to setup fallback messages can be found in our Fallback Messages guide.

Track performance

Journey analytics can be used to track how the Journey as a whole is performing. You can also track each message performance using Template analytics.

Track revenue with Outcomes

To track revenue from this Journey, you can use Custom Outcomes. When a purchase is made, you can send the event as a “Custom Outcome” to track the revenue associated with the specific message sent. Custom Outcomes can be sent via the Mobile SDK or Web SDK.
Example: Send purchase outcome via frontend SDK
// Example: capture total price and item count at checkout
const checkoutPriceTotal = document.querySelector(".checkout-price-total").innerText;
const checkoutItemsTotal = document.querySelector(".checkout-items-total").innerText;

function updateOSOnCartPurchase(checkoutPriceTotal, checkoutItemsTotal) {
  const purchasePriceTotal = parseFloat(checkoutPriceTotal);
  const purchasedItemCount = parseInt(checkoutItemsTotal);

  OneSignalDeferred.push(function (OneSignal) {
    OneSignal.Session.sendOutcome("Purchase", purchasePriceTotal);
    OneSignal.Session.sendOutcome("Purchased Item Count", purchasedItemCount);
  });
}

const submitPurchaseButton = document.querySelector(".submit-payment");
if (submitPurchaseButton) {
  submitPurchaseButton.addEventListener("click", () => {
    updateOSOnCartPurchase(checkoutPriceTotal, checkoutItemsTotal);
  });
}
Outcomes can attribute revenue to messages users clicked or were influenced by within a defined attribution window.
You have successfully implemented an abandoned cart Journey. When you are ready to start sending messages, select Set Live.
Need help?Chat with our Support team or email support@onesignal.comPlease include:
  • Details of the issue you’re experiencing and steps to reproduce if available
  • Your OneSignal App ID
  • The External ID or Subscription ID if applicable
  • The URL to the message you tested in the OneSignal Dashboard if applicable
  • Any relevant logs or error messages
We’re happy to help!