Smart Coupons for Sitecore Experience Commerce How to Add Conditions

In my search and crusade to make Smarter E-commerce Storefronts, I wanted to take a closer look at our favorite promotional item – the beloved coupon. With the right set of alphanumeric text and the right conditions, the lowly coupon will do its magic like no other and elevate customer experience. From a static $5 discount to a mighty percentage based one (or a 100% BOGO), the coupon is the both the customer and marketer’s favorite.

In this article, we will investigate how we can make Sitecore Experience Commerce coupons smarter by adding conditions to its usage increment action.

How It Works

When a cart is checked out and paid for, it triggers the ICreateOrderPipeline. This pipeline contains and triggers the necessary blocks to process the order including updating the coupon usage. See below default pipeline configuration on Figure 1.

Figure 1: UpdateCouponUsageBlock processor in ICreateOrderPipeline

On Figure 2, using our favorite decompiler, we see what the block code looks like. Marked with a red arrow is the actual line of code that increments the coupon usage count. So basically, it works like this:

  1. Get all coupons in the order
  2. For each coupon
    1. increment the usage count
    2. Save the coupon

Figure 2: Plugin.Coupon.UpdateCouponUsageBlock

The Problem

Based on the chapter above, one thing stood out. And that is if a valid coupon was added to the cart, the usage count will be incremented whether it had any effect. Not having any effect means that the conditions for the coupon have not been met so the benefits were not applied.

In a project of mine where coupons are pretty much cherished and monitored, they only wanted the coupon usage to increment when it affected the order.

In short, they wanted to make sure that each coupon usage translated to an actual sale.

This is not supported out of the box.

The Solution

In order to make these coupons smarter and implement our conditions, we will need to swap that block with our improved and smarter one.

Overview of Steps:

  1. Create our own implementation of UpdateCouponUsageBlock
  2. Configure the ICreateOrderPipeline to swap the OOTB UpdateCouponUsageBlock with our own
  3. Test it out

Note: Code taken from actual project files. Some names have been covered for privacy purposes.

Create our own implementation of UpdateCouponUsageBlock

In the figure below, we modified the out-of-the-box (OOTB) code and added our own that implements our chosen conditions. These business rules and conditions are:

  1. Only line item level discounts will be used. Basically, coupons affect products only and not the whole cart. (1)
  2. in the code, you will see some trimming and blanks space replacements for names. This was needed since I found out that matching the coupon names can be tricky since they can have spaces on some objects but not on others. (1)
  3. A coupon is considered used if at least one item received a discount from it. Discount here means a negative amount was awarded. (2)
  4. If a coupon was not used, do not increment its usage count. This makes sure that each usage translates to an actual sale (2)

Figure 3: Our own implementation of the UpdateCouponUsageBlock

Configure the ICreateOrderPipeline to swap the OOTB UpdateCouponUsageBlock with our own

Figure 4: ICreateOrderPipeline configuration

Figure 5: Shows our pipeline configuration's effect


Making coupons smarter by improving out of the box functionality is as easy as 1-2-3 thanks to the great extensibility of Sitecore Experience Commerce. Not only were we able to accomplish the business requirements of the client, but we were also able to create a reusable pattern for upcoming improvements.