Abandoned cart and browse recovery

An abandonment recovery program re-engages a customer who adds items to a cart and does not check out, or who browses products and leaves, while their intent is still fresh. This page shows how to configure the program from Amperity’s real-time objects: an event stream that receives cart, browse, and order events, a profile collection whose attributes describe each customer’s cart and browsing, real-time segments that hold the customers who have abandoned, and a real-time journey that sends the recovery messages.

The same pattern recovers any flow that a customer starts and does not finish, such as a booking, a reservation, or an application. Replace the cart events with the events that flow sends.

How abandonment recovery works

Abandonment is not an event. It is a state that depends on something happening and then something else not happening: the customer added to their cart, and then did not purchase within a window. Because no event marks the moment a cart becomes abandoned, the program models abandonment as a state on the customer’s profile:

  1. Cart and browse events update event attributes on the profile, such as the current cart and the time of the latest cart activity.

  2. A computed attribute combines those values with a time condition, such as “the cart has items and has not changed in 30 minutes.” A computed attribute that uses timestamp_in_last is recalculated shortly after its result changes, so the profile changes when the window passes even though no new event arrives.

  3. A real-time segment tests the computed attribute. The customer joins the segment when the attribute becomes true.

  4. A real-time journey uses the segment as its entry condition. Joining the segment starts the customer on the journey.

  5. An exit condition on the journey removes the customer when they purchase. Leaving the entry segment does not remove a traveler from a journey, so the exit condition is what stops the recovery messages.

Before you begin

This program needs:

  • An event stream that receives events from your website and app. Send events to the stream with POST /prof/events/{stream-id} in the Real-time API.

  • A profile collection that subscribes to that stream and is bound to your customer 360 database, so that it can carry database attributes and recognize customers by their stitched identifiers. See Identity recognition.

  • A real-time destination that sends the recovery message. A real-time journey activates only to real-time destinations. See Real-time destinations for the supported connectors.

Send cart and browse events

Define an event type on the stream for each kind of event the program uses, and assign a Keychain key to at least one of its properties, such as an email address or a loyalty ID, so that Amperity can match the event to a profile:

  • Cart events. Add to cart, remove from cart, and view cart. Model the cart as an Array property whose value type is a Struct with a field for each line-item value, such as product ID, quantity, and price, so that each event carries every line item in the cart after the change. An event that carries the whole cart lets the profile keep the current cart with a single Most recent attribute, instead of rebuilding it from additions and removals.

  • Browse events. Product views, with fields for the product and its category.

  • Order events. Purchases, if you send orders as events. See Bring in orders.

Bring in orders

The program needs to know when a customer purchases, so that it can stop treating them as abandoned. A profile collection can learn about orders in two ways, and many programs use both.

Orders as events

Send each order to the event stream as an order event type. An order event updates the profile as soon as it arrives:

  • An event attribute such as the time of the most recent order, or the count of orders in the last 24 hours, changes immediately, so the abandonment attributes and segments that use it update too.

  • A journey exit condition of type Event type removes a traveler the moment their order event arrives.

Orders as events reflect purchases from any channel that can send an event when the order is placed, such as your website, app, or point of sale.

Orders as batch

Add database attributes from a table in the collection’s database that has an amperity_id column, such as the date of each customer’s most recent order, their lifetime order count, or their value tier. Database attributes carry the full order history Amperity has stitched from every source, including channels that do not send events.

Database attributes update after each run of the collection’s database when Automatically refresh profiles after each database run? is selected on the collection. They are as current as the most recent database run, so a purchase made after that run is not reflected until the next one.

Choosing between them

  • Use orders as events to suppress and exit customers the moment they purchase.

  • Use orders as batch for history and context that do not need to change within minutes: value tier, lifetime orders, purchases from channels that only arrive in batch, and suppression of customers who bought recently through another channel.

  • Use both to exit customers the moment an online order arrives, and to tailor messages and offers with the customer’s full history.

Define profile attributes

Define these attributes on the profile collection. The names are examples.

Event attributes

  • current_cart – Most recent of the cart array field. Scope it to the event stream, or to every cart event type, so that add, remove, and view events all update it.

  • last_cart_activity – Most recent of event_timestamp, with the same scope.

  • last_product_view – Most recent of event_timestamp, scoped to the product view event type.

  • category_views_7d – Count of product view events with a Where condition on the category, with a Lookback window of Last 7 days. Define one attribute for each category you want to track.

  • last_order – Most recent of event_timestamp, scoped to the order event type, if you send orders as events.

  • orders_7d – Count of order events with a Lookback window of Last 7 days, if you send orders as events.

Lookback windows are Lifetime, Last 7 days, Last 24 hours, or a Custom duration in hours, days, or weeks. A window is made of whole hours, days, or weeks aligned to UTC, with weeks starting on Monday. It is not a sliding window measured to the second, so a minute-level threshold such as 30 minutes belongs in a computed attribute, not in a lookback window.

Computed attributes

  • cart_abandoned – the cart has items, has not changed in 30 minutes, and no order has arrived since the cart last changed:

    size(current_cart) > 0
      and not timestamp_in_last(30, 'minutes', last_cart_activity)
      and (last_order is null or last_order < last_cart_activity)
    
  • browse_abandoned – the customer viewed a product in the last 24 hours, not in the last hour, and has an empty cart:

    timestamp_in_last(24, 'hours', last_product_view)
      and not timestamp_in_last(1, 'hours', last_product_view)
      and (current_cart is null or size(current_cart) = 0)
    
  • repeat_browser_outdoor – the customer viewed a category four or more times in the last seven days and has not ordered:

    category_views_7d >= 4 and orders_7d = 0
    

Only timestamp_in_last, timestamp_in_next, date_in_last, and date_in_next are recalculated as time passes. A computed attribute built on another function, such as timestamp_diff, changes only when the profile changes, so it never becomes true while the customer is inactive. For the full set of functions, see Expressions.

Build the segments

Create a real-time segment on the profile collection for each pattern the program recovers. Each segment’s query tests one computed attribute, and can add conditions on database attributes:

  • Cart abandoners – cart_abandoned = true

  • Browse abandoners – browse_abandoned = true

  • Repeat browsers – repeat_browser_outdoor = true

A customer joins a segment the moment its query becomes true for their profile, and leaves it the moment the query becomes false.

To keep customers out of the program, such as customers who have not consented to marketing, create a segment for them as well and use it as an exclusion on the journey.

Build the journey

Create a real-time journey for each segment, or one journey that splits on the segment the traveler is in. For how to configure each part of a real-time journey, see Build a real-time journey.

Configure the journey with:

  • Entry conditions. Include the abandoners segment. Exclude any segment of customers who must not receive the program. A customer enters when they join the segment, so customers who were already in it when the journey started enter only after they leave and join again.

  • Delay and quiet hours. A Delay step waits before the first message, and between messages. Delays in real-time journeys can be minutes, hours, days, weeks, or months. A Quiet Hours step holds travelers until a quiet window ends, so that messages are not sent overnight.

  • Conditional splits. Send different treatment to different customers. A Conditional Split path matches a real-time segment, or Custom criteria: an expression over the profile’s attributes, such as a value tier from a database attribute. Travelers go down the first path they match, and travelers who match none go down No match. For example, send high-value customers a reminder first and reserve an incentive for later in the journey, and send first-time visitors a reminder only.

  • Activations. An Activate step sends the traveler to a real-time destination, with the profile attributes the message needs, such as current_cart.

  • Exit conditions. Add an exit condition for every reason a traveler should stop receiving messages:

    • Event type – the order event type, to exit travelers the moment they purchase.

    • Real-time segment – a segment of customers who purchased, by order events or by database attributes.

    • Real-time journey – another journey that takes priority, such as an order confirmation journey.

  • Re-entry. Allow re-entry lets a customer who abandons again enter the journey again, after they finish their previous path. A Cooldown period sets how long they must wait first, and Linked journeys also keeps a customer out while they are in a related journey, such as a browse abandonment journey, or within that journey’s cooldown, so that one customer doesn’t receive both programs at once.

Measure results

Add a Percent Split with Include control at the start of the journey to hold out a Control Group path that receives no messages. The journey’s travel log records the path each traveler took through the percent split, and whether that path is the control. Export the travel log by choosing a JTL Destination and a Recurrence in the journey’s settings; the travel log goes to a destination for journeys and campaigns, not to a real-time destination. Then compare the order rate of travelers on each path with the control path to measure what the program recovers. See Holdout and A/B testing and Exporting the travel log.