Bento

Example: Abandon Cart Sequence

View on YouTube

Recover abandoned carts with a Bento flow-driven email sequence. Trigger on cart events, time follow-ups, and adapt the pattern to your store.

Hands-on time. You'll build a flow-driven abandon cart sequence that recovers people who start checkout and leave.

Follow along in the video. Pause when you need to catch up in Bento. By the end you'll have a reusable cart recovery system you can adapt to your store.

If a step feels unfamiliar, jump back to Flow-Driven Sequence Setup or Behavior-Based Emails & Segmentation.

Video transcript

So in this video, I will walk you through how I like to do abandoned carts in Bento. The main consideration when you're building an abandoned cart sequence is that you need to be able to remove somebody from it if they buy the thing that the sequence is trying to convert them to, and that they don't get placed into it twice since it's a flow. And if somebody re-triggers the flow event multiple times or the webhook from your cart system gets sent multiple times, they can technically coexist twice in that same flow. And so they'll receive the emails multiple times.

So I have two flows that handle my abandoned cart to conquer the multiple times thing, which you'll see in a moment. So I have one that's an initiator flow, and it's pretty dang simple. That's this one. Yeah.

So this one is just a new event called abandoned cart. And what this one does is it first kills the core flow and then starts the core flow again. And the only magic special thing is that we're passing in the product name from the event details that they abandoned the cart for. So the way I build mine, I use ThriveCart for DYF.

ThriveCart has an abandoned cart event that I catch in Zapier, but I could send a webhook directly to Bento. But since ThriveCart directly integrates with Zapier, it's a little bit easier to catch the abandoned cart in Zapier and then fire the Bento event from that Zapier chain than to try to set up the webhook in here and parse it. And then Zapier calls the Bento event with the product name as I show. And so once that gets hit, it kills any preexisting sessions in this abandoned cart flow.

And the way I have it right now, which I'm not sure I will have forever, but the way I have it right now is that all products have their abandoned carts in this one flow. Where this wouldn't work is if for some reason, theoretically, somebody could abandon cart for product A, and they could then abandon cart for product B, and we would want to not-- let's say they now abandon cart again for product A a second time. Right now, this would kill product B's abandoned cart sequence at the same time. But I can't really imagine a situation where I'd want somebody receiving two simultaneous concurrent abandoned cart sequences anyway.

So to me, this is fine. So the way it works is that when a specific product is abandoned, this is getting triggered. So in this case, the product is called 200KF, stands for 200K Freelancer from Double Your Freelancing. This is what is getting injected here.

So abandoned cart init and then 200KF. And so that triggers this flow. First thing that we do is we just wait a little bit of time. Right now, Bento, over the years, has had different delays that work.

I don't know what the current one is. So it says every 10 minutes right now. So 10 minutes is the current safe delay to add. So the first thing that I do is basically wait the time, wait 10 minutes, and then I check if somebody has bought the thing.

So in this case, I have a segment for 200KF customers. So if they abandon their cart, I wait 10 minutes, I check if they're a customer. If not, I send them an email. And I added this new one recently.

So in the case of 200KF, I open and close the doors for it. So it would be kind of silly for me to send abandoned cart emails to somebody after the doors have closed and it's impossible to purchase. But I think in the end, I decided I don't care that much because I think I'm linking to the cart directly. Yeah, I'm linking to the cart directly, and I think these days I'm not taking the cart offline and I'm only taking the sales page offline.

So if somebody gets a backdoor link to the cart and they join a day or two late, it's not the end of the world because the class is still onboarding and stuff anyway. But in any case, that's what this is. This is just making sure, are they eligible? I personally use environment variables to set that cart open and close date.

Let me pull those up real quick. So I love environment variables for this. I like to do it for seats remaining, cart open and close date, that kind of thing. So it's just very simple.

It's just only code here, and it's just the date time. So this was when the cart closed for the last one was. And this is useful for any date comparison, for some display, countdown timers could be used based on this, I think, et cetera. So that's what this is doing.

It's just checking if right now is before cart close. And then assuming they're eligible and they haven't bought, that's what this check was, then we'll send them one email. So we just send them [clears throat] first email. If your cat threw up on the keyboard and you forgot to buy it, go buy it.

Normal stuff. Add a delay as normal, and then importantly, all of those same checks of eligibility. So they haven't bought the thing yet. The cart's still open, et cetera.

They have to happen before the next email. Because if, let's say, they received abandoned cart email one on the final day of cart, and then they bought the thing. We would not want to send them another abandoned cart email. Or they bought it on the final-- or sorry, they received it on the final day of cart, and they didn't buy the thing, and now it's been 24 hours, now cart's already closed.

We also wouldn't want to send them the email. So that's how abandoned cart sequences work here is just whenever you're sending a new email, if it's a flow-based thing, you would want to just make sure they're still eligible to receive the next one. In this case, it's a little bit of a fail-safe because I am pretty dang sure that when somebody purchases, I am canceling the abandoned cart sequence anyway. I'm not 100% sure because in this case, I'm sharing it with all of them.

But what I would do if I wanted to just kill the abandoned cart sequence when they bought the thing is In my They Just Bought the Thing sequence, I would fire off the cancellation one. And it looks like I already do that. So I have a flow in here called All Products Purchase Refund, et cetera, and this is my master flow for all products purchase refund, et cetera. [chuckles] So on the left side of this, I have some kind of generic events and generic chains that are called for any product where we pass in the product slug as an event parameter, and that affects what happens downstream. So for example, 200KF last purchased date time is right now.

This would get fired the moment it was purchased, or double your frequenting rate, last product purchase, et cetera, last action happened right now. These are essentially just little logs to help me keep track of what's happened over time. Supposing somebody buys something, refunds, buys it again, just having a nice little paper trail. And in this case, setting 200KFs_status to customer.

Whereas if they were to refund, which is this one, it would set 200KF status to refunded. So this is how I personally like to know if somebody is a customer or not, rather than just doing a tag for it. Because for certain things like a subscription, it's hard to know if they canceled, if they expired, if they refunded, if they're active, things like that with just tags, because it's these four potential values of the same thing. But in any case, what I wanted to show you here was just the abandoned cart thing, which is that in this main flow, someone either purchases it or un-cancels a canceled subscription.

In both cases, we end that abandoned cart flow anyway. So the whole check that they're still eligible thing that I showed you, wherever it is, is mostly a fail-safe because it should never happen anyway that they're still in here if they've purchased. But I reckon better be safe than sorry. One thing you could do if you wanted to simplify this, though, is you could have an abandoned cart sequence that's just a regular ass sequence in Bento, and then you can remove somebody from it when they receive a certain tag or whatever.

So when you're creating a new sequence, you can stop and mark successful when someone's tagged with something. So you could say, "Customer 200KF, remove." Or you could make a simpler flow than what I have where the abandoned cart... Gosh, where am I? You're not actually sending emails in the flow.

You just add or remove to a sequence. But I believe the reason I didn't do that here is that people on my email list are present for multiple promotions. And so if I built it as a proper sequence, what it would mean is that if in January they think about joining, they abandon their cart, and they get added to the sequence, and let's think of how we would end early. Well, maybe that was one of the issues, because I paused for a minute and I can't think of how we would end it early once the promo window ends, like the equivalent of this check here.

So maybe that's one reason that drove me to a flow. But maybe we could go into the sequence and set the emails to draft, or set it to the snooze or suppress email setting or whatever. But in any case, supposing we did find a solution for that, the other issue is that next promo rolls around, they've already received those first two emails in the sequence, quote, quote, and they won't receive them again. So in promo two, when they abandon cart, they won't get anything.

Unless I duplicate that sequence, make a new sequence. But I don't believe there's currently a way in Bento to re-add somebody to a sequence they've been in before and start from the top. So this is my little workaround for that, basically.