# Cart Abandonment

Whether you’re an e-commerce company or a product company, the techniques used for cart abandonment can help you increase completion rates in any flow where you have drop off. One of the most powerful concepts you’ll learn is how to store context on a profile for easy recall and personalization later.

## How it works[](#how-it-works)

For this recipe, we’ll send emails to customers who have abandoned their carts after a certain amount of time. We offer two methods through event-triggered or segment-triggered [campaignsCampaigns are automated workflows you set up to send people messages and perform other actions when they meet your criteria.](/journeys/campaigns-in-customerio/). We recommend using event-triggered campaigns when possible as you’ll have more flexibility for targeting information related to carts than if the information were stored on a person’s profile (segment-triggered campaign).

## Method (Recommended): Event-Triggered Campaign[](#method-recommended-event-triggered-campaign)

For this recipe, we’ll walk through how to send cart [eventSomething that a person in your workspace did. Events can trigger campaigns, add people to segments, etc, and you can use properties from events to personalize messages.](/events/) data to your workspace and create different pathways for your customers based on the actions they’ve taken and time that’s elapsed since updating their cart.

### Ingredients[](#ingredients)

*   Your [Track API credentials](https://fly.customer.io/env/last/settings/api_credentials) from your Customer.io workspace.
*   The ability to send event data when items are added and removed from a person’s cart.

### Send Event Data for Cart Updates[](#send-event-data-for-cart-updates)

To remind people about their abandoned carts, you’ll create an event that captures updates to cart items including adding, removing, and changing the attributes of an item, like quantity. Send this data with a name like `cart_updated` so it’s easy to find within your workspace.

You’ll either need to:

*   Send the contents of the cart with each event (shown in this recipe) or
*   Set up a [webhook](/journeys/webhooks-action/) in your campaign to retrieve the complete contents of the cart

Your cart event might look something like this:

```json
{
    "name": "cart_updated",
    "timestamp": 1677700459,
    "data": {
        "currency": "usd",
        "added": {
            "product": "something-else",
            "qty": 2,
            "price": 19.99
        },
        "already_in_cart": [
            {
                "product": "socks",
                "qty": 2,
                "price": 23.45
            },
            {
                "product": "sneakers",
                "qty": 1,
                "price": 99.99
            }
        ]
    }
}
```

For this recipe to work, you’ll send a person’s entire cart with the event. This should include all items currently in the cart as well as the timestamp of the event. Include any other information that you want to query with [liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable `{{customer.first_name}}`.](/using-liquid) within the reminder email, such as item price, color, or quantity.

### Set the Trigger for Your Campaign[](#set-the-trigger-for-your-campaign)

After sending your event, you’ll create an event-triggered campaign. Set the trigger as the event you just made: `cart_updated`.

[![Under the type of campaign, select cart_updated as the trigger.](https://docs.customer.io/images/cart-abandonment-trigger-1.png)](#7bbf97f6ea43242d4a58cc6969198570-lightbox)

### Create a Workflow Using Wait Until[](#create-a-workflow-using-wait-until)

Now you’re ready to create an event-based workflow for cart abandonment. While the goal of the workflow is to remind a person to purchase the items in their cart, you’ll also need to make sure a person does not receive too many reminder emails nor receive them too soon. To make sure you’re targeting the right users at the right time, let’s **use [Wait Until](/journeys/wait-until/) to create 3 different pathways for people who just updated their cart** (that is, just entered the campaign).

[![On the Workflow canvas, there is a Wait Until delay with three paths. There are two conditions and one path based on maximum time. Under maximum time is an email. The other conditions cause a person to exit.](https://docs.customer.io/images/cart-abandonment-workflow.png)](#a817363a253130ebf6a402730ba4be6d-lightbox)

1.  Set a **Condition** where the cart has updated since the trigger event.
    
    [![Within Path 1 of the Wait Until, select `cart_updated` is performed. Then add event data such that the time stamp of the cart update is greater than the timestamp of the trigger event.](https://docs.customer.io/images/cart-abandonment-condition-cartupdated.png)](#72ed4bc9b34806dcc72dcb17262a2649-lightbox)
    
2.  Next, set another **Condition** where a purchase has occurred since the cart was updated.
    
    [![Within Path 2 of the Wait Until, select `purchased` is performed. Then add event data such that the time stamp of the purchase event is greater than the timestamp of the trigger event.](https://docs.customer.io/images/cart-abandonment-condition-purchase.png)](#1442b778ec8461e8afd3041478c1cfb6-lightbox)
    
3.  Finally, select **Max Time** and enter a time period that the workflow should wait to send a person a reminder email. In this example, we use 45 minutes.
    
    [![Within Path 3 of the Wait Until, choose 45 for the counter and minutes from the dropdown for Max Time.](https://docs.customer.io/images/cart-abandonment-maxtime.png)](#056a7ab2c008c47bc8bc6bcdc2f42fdf-lightbox)
    

### Create Your Reminder Email[](#create-your-reminder-email)

Finally, under the Max Time path, add your reminder email. Use liquid to customize the email with each customer’s cart information.

When a person enters the workflow, the clock starts counting to 45 minutes. If people update their carts or purchase items after the event trigger, they exit the campaign. Otherwise, when the counter reaches 45 minutes, your customers will receive an email reminding them to purchase the items in their cart.

## Method: Segment-Triggered Campaign[](#method-segment-triggered-campaign)

For this recipe, we’ll walk through storing and updating cart data on your customers’ profiles so you can send messaging around cart abandonment.

At a high-level, you’ll set the following logic:

*   When a person has an item in their cart, you’ll populate their `cart` attribute.
*   When a person updates their cart, you’ll update their `cart` attribute.
*   When a person completes a purchase, you’ll clear their `cart` attribute.

Then you’ll create a [segmentA segment is a group of people in your workspace. Use segments to trigger campaigns, track membership over time, or fine-tune your audience. There are two types of segments: data-driven and manual. Data-driven segments automatically update when people start or stop matching criteria. Manual segments are static.](/journeys/segments/) for people who have the `cart` attribute which will trigger a campaign reminding them to checkout.

### Ingredients[](#ingredients-1)

*   Your [Track API credentials](https://fly.customer.io/env/last/settings/api_credentials) from your Customer.io workspace.
*   The ability to update profile data programmatically when items are added and removed from a person’s cart.

### Set Up Your Cart[](#set-up-your-cart)

#### Store Cart Data on People’s Profiles[](#store-cart-data-on-peoples-profiles)

To get started, store people’s cart data as an [attributeA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/). For this recipe, you’ll store this data in an attribute called `cart` using the following JSON:

```json
{
    "cart": [
        {
            "item_name": "Hat", 
            "item_price": "22"
        },
        {
            "item_name": "Scarf",
            "item_price": "11"
        }
    ]
}
```

#### Update Cart Data When a Person Adds or Removes Items[](#update-cart-data-when-a-person-adds-or-removes-items)

Next, you’ll set the “cart” attribute whenever a person adds or removes items using an [`identify` call](/integrations/api/cdp/#operation/identify). You can use your language of choice to update a person’s “cart” attribute, but we’ve added examples using our [JavaScript source integration](/integrations/data-in/connections/javascript) and our [Classic JavaScript SDK](/integrations/data-in/connections/javascript/legacy-js/getting-started/) below:

 JavaScript Source (recommended)

#### JavaScript Source (recommended)[](#JavaScript Source \(recommended\))

```javascript
cioanalytics.identify('1234', {
    cart: [
        {
            item_name: "hat",
            item_price: 22
        },
        {
            item_name: "scarf",
            item_price: 11
        }
    ]
});
```

 Classic JS SDK

#### Classic JS SDK[](#Classic JS SDK)

```javascript
_cio.identify(1234, {
    cart: [
        {
            item_name: "hat",
            item_price: 22
        },
        {
            item_name: "scarf",
            item_price: 11
        }
    ]
});
```

By storing the `cart` attribute on a person, you’ll be able to use [liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable `{{customer.first_name}}`.](/using-liquid) to personalize messages for your audience based on the items in their cart.

#### Clear Cart Data When a Person Completes a Purchase[](#clear-cart-data-when-a-person-completes-a-purchase)

If there’s nothing in a person’s cart, i.e. the person purchased, or otherwise emptied their cart, then you don’t want to send them an email reminding them to purchase. This step removes the cart attribute from a person to ensure you notify the correct people.

When you set the `cart` attribute to an empty string, you’ll remove it from a person’s profile.

 JavaScript Source (recommended)

#### JavaScript Source (recommended)[](#JavaScript Source \(recommended\))

```javascript
cioanalytics.identify('1234', {
    cart: ""
});
```

 Classic JS SDK

#### Classic JS SDK[](#Classic JS SDK)

```javascript
_cio.identify(1234, {
    cart: ""
});
```

### Create Your Segment[](#create-your-segment)

Now that you’re sending and storing cart data on people’s profiles, create a [segment](/journeys/data-driven-segments/) for people who have a `cart` attribute using the *exists* condition.

[![a segment for people who have a cart attribute](https://docs.customer.io/images/segment-abandoned-cart.png)](#149c48601093ee399077863443bd047e-lightbox)

### Create Your Campaign[](#create-your-campaign)

#### Set the Trigger for Your Campaign[](#set-the-trigger-for-your-campaign-1)

Create a campaign that targets the segment you just made – people whose cart attribute exists.

[![Under 'what triggers a campaign?' select 'when a person moves in or out of a segmenet.` Then define the trigger as the segment `Cart Exists.`](https://docs.customer.io/images/cart-abandon-trigger-segment-1.png)](#c014acd651b99de26fb2b2c73b8a0c82-lightbox)

 People will match this campaign immediately when they add an item to their cart. So make sure you add a delay in your workflow that gives customers enough time to check out.

Below the trigger segment, allow people to re-enter the campaign at a **Frequency** you specify. This ensures they enter the Cart Abandonment campaign for all future carts.

[![image.png](https://docs.customer.io/images/frequency-re-match.png)](#1d83972a0dda549eb9e9fcd958439543-lightbox)

#### Set Your Exit Conditions[](#set-your-exit-conditions)

By default, people will exit when they stop meeting the trigger condition. If a person’s cart is empty or does not exist, they will exit the campaign and will not receive a reminder email. This prevents your campaign from sending messages to your customers if they complete their purchase before the delay ends.

If you [set a goal](/journeys/campaign-conversions/) for the campaign, you can change the exit criteria such that [people exit when they meet the goal](/journeys/campaign-conversions/#exit-conditions) too.

#### Create Your Workflow Using a Delay[](#create-your-workflow-using-a-delay)

You’ll add a delay before your first email as well as between your first email and future messages related to cart abandonment. This prevents customers who intend to purchase from immediately receiving a reminder email anytime they change their carts.

[![image.png](https://docs.customer.io/images/image%28403%29.png)](#d6d09a96310114aff4f79455770d8ef8-lightbox)

#### Create Your Reminder Email[](#create-your-reminder-email-1)

Finally, drag an email into your workflow under your delay. This is the email you’ll send to anyone who continutes to meet the campaign trigger condition (cart exists) after 45 minutes.

Craft the email content with any relevant information. Use [liquid](/journeys/liquid-tag-list/) to reference the items in your customers’ carts, their prices, and more:

```fallback
Hi {{customer.first_name}}!

Your cart contains:
{% for item in customer.cart %}{{ item.item_name }} - {{ item.item_price }}{% endfor %}
```

In our simple example, this will render like the email below:

[![image.png](https://docs.customer.io/images/image%28404%29.png)](#0a7b53cef48f2416610ae34faf6a7c34-lightbox)

You can use this basic structure to store lots of data as customer attributes and merge in a picture of the item in the cart, a link to the item, and more.