In this article, we will review and compare promotions between Sitecore Experience Commerce and OrderCloud to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.
We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.
Note: This article is a little outdated with the release of Promotion Enhancements. Please see the official documentation for latest updates.
Conceptual Architecture and Features
Qualifications/Conditions vs Eligible Expressions
The Business Tools application in XC provides a basic wizard dialog for building up qualifications for a promotion. XC has over thirty promotion qualifications (or conditions) to construct common promotion scenarios without customisation.
For a complete list of available qualifications, see Promotions qualifications.
OrderCloud promotions provide an EligibleExpression
property, which accepts a free-text logic expression to qualify/validate a promotion as eligible against an order, using custom syntax outlined in Rule-Based Promotion Expressions.
Looking at table 1, we see the native support for utilising entities and objects in qualifications/eligible expressions for each platform. For qualification types that are not natively supported by the OrderCloud platform, it is possible that support can be achieved through customisation. For more details, see Extending Promotion Functionality > Custom Promotion Logic.
Qualification Type \ Platform | XC | OrderCloud |
---|---|---|
Product Inventory | Yes | No |
Cart Line/Line Item | Yes | Yes |
Cart/Order | Yes | Yes |
Customer | Yes | Yes |
Customer Order History | Yes | No |
Date and Time | Yes | Partial |
Benefits/Actions vs Value Expressions
Similar to qualifications, the benefits (or actions) in XC’s Business Tools also uses a wizard dialog to facilitate building out the promotion’s benefits, with over 10 pre-defined benefits available.
For a complete list of available benefits, see Promotion benefits.
OrderCloud promotions have a ValueExpression
property, which use the same Rule-Based Promotion Expressions as the EligibleExpression
property.
Is Exclusive vs Can Combine
Promotions in XC have an Is Exclusive flag, which is used in the Promotion Evaluation and Application Logic to determine eligible promotions and prioritisation over non-exclusive promotions.
In OrderCloud, promotions use a can combine flag with similar behaviour, however the single biggest difference is that exclusive promotions do not take priority over non-exclusive (can combine) promotions.
Order Level vs Line Item Level Promotions
Both XC and OrderCloud promotions allow promotions to apply discounts at the order level or line item level, however, in calculating the promotion’s qualifications against the order or line item total properties, XC’s calculations are dynamically updated with each promotion discount calculation, therefore leveraging the Engine’s Promotion Priority Rules.
OrderCloud calculates each promotion discount against static totals, therefore regardless of the order in which promotions are calculated, it will not impact the final discount calculations, as per Promotion Calculation Logic.
Promotion Prioritisation
As touched upon above in Order Level vs Line Item Level Promotions, XC has a set of Promotion Priority Rules that determine the order promotions are applied.
OrderCloud’s Promotion Prioritisation Logic does not prioritise the order of promotions applied to an order, which is effectively not required as is utilises static order and line item totals meaning that promotion discount values will always be calculated the same, regardless of the order they are processed.
Promotion Assignments
For promotions in XC to be available to customers in a storefront, the Commerce Engine groups promotions into promotion books, which are associated to catalogs. The catalog is then associated to a storefront, which will be associated to a security domain that contains customers, to complete the customer to promotion connection.
Promotion books can be associated to multiple catalogs to be utilised in other storefronts.
In OrderCloud, promotions have more explicit assignments, allowing direct assignments to the buyer.
OrderCloud promotions can also be configured to target buyer user groups for more refined promotion targeting. More information can be found in Personalized Shopping > Targeted Promotions.
Automatic vs Coupon-Triggered Promotions
The Commerce Engine’s promotions can be classified as automatic or coupon-triggered. Coupon-triggered promotions are evaluated as a preliminary qualifier during promotion qualification, which requires the coupon code to be applied to the cart, while the automatic promotions pass this qualifier gate and continue the promotion evaluation process, effectively allowing a promotion to be able to be applied to a cart based on the cart state and promotion qualifications alone and not via some explicit request to apply the promotion. For futher details, see Promotion Evaluation and Application Logic.
An XC promotion can be added to a cart even if it has yet to qualify for its benefit.
Currently, only coupon-triggered promotions are native to the OrderCloud platform. In a slightly different manner to XC, applying a promotion via a coupon code will be rejected by the platform if its currently not eligible, e.g. does not meet its eligible expression (qualification rule), falls outside the start or expiration date, does not adhere to the rules for the CanCombine
flag, etc.
Private vs Public Coupons
The Commerce Engine breaks down coupons into private and public coupons, where public coupons are those that anyone may use, while private coupons are generated as single use coupons that the business can distribute to customers as they see fit, yet has no restrictions in the Commerce Engine as to who can use the coupons, although some smarts can be configured in the promotion’s qualifications and customisations will allow specific business requirements to be met.
Figure 7 shows the general setup of promotions with public vs private coupons, where customers with the relevant promotion assignments can apply the promotions to their cart.
In OrderCloud, although promotions don’t have an explicit private/public flag against them, they can still be configured to behave in a similar fashion.
For “public” coupon promotions, this would simply depend on the promotion assignment created. For example, at a global level the AllowAllBuyers
flag will allow all users to apply the promotion to their order, or an explicit promotion assignment to one or more buyers and/or buyer user groups may fit the “public” coupon business requirement.
For “private” coupon promotion, defining the promotion assignments to target the subset of buyer users and leveraging the RedemptionLimitPerUser
property (covered in more detail in Redemption Limits), we can restrict the amount of redemptions the users have for the promotion.
Redemption Limits
As mentioned in Private vs Public Coupons, in XC private coupons have a single usage limit. Public coupons, on the other hand, have no redemption limit, although the UsageCount
is tracked against the coupon entity, which can be used in a customisation to limit promotion redemptions at a global level.
In OrderCloud, promotions have a RedemptionLimit
property to configure a global limit across all users and a RedemptionLimitPerUser
property to set a redemption limit per user (both with the relevant promotion assignments).
Approval Workflow
XC has approval workflow logic built into promotions, which requires a business user with the PromotionerManager role to approve a promotion prior to it being made available.
OrderCloud has no native approval workflow for promotions, however we could use the following approach to replicate the XC functionality in OrderCloud (with the additional retract action for business users who have submitted a promotion for approval prematurely and want to amend the promotion without intervention from the promotion manager).
xp.Status
will track the current promotion’s status. The Disabled state has been promoted to an explicit status.- Pre-hook webhooks would be utilised for all relevant promotion endpoints, for the middleware to validate the user’s custom
PromotionManager
role where applicable and also ensure that thexp.Status
transition is valid.
Disabling a Promotion in Non-Approved States
For non-Approved statuses, these are effectively inactive promotion states that we will need to safeguard against, i.e. inactive promotions cannot be applied to orders and should be invalidated for orders not in an Unsubmitted or AwaitingApproval state. The approach we will look to take is to override the promotion’s ExpirationDate
property.
For the Draft and ReadyForApproval states, the ExpirationDate
can be set with the StartDate
and the intended expiration date can be set on the xp
as ActualExpirationDate
. When the promotion is promoted to an approved state, the ExpirationDate
can be replaced with the ActualExpirationDate
.
With the StartDate
being the equivalent of the ExpirationDate
, the promotion can never be evaluated to being active.
For the Disabled state, we can set the ExpirationDate
to the current date/time, while the xp.ActualExpirationDate
still maintains the original expiration date for historical and reconciliation purposes.
For this approach, “inactive” promotions will throw a Promotion.Expired
error code, which in conjunction with the xp.Status
could be translated into a more user-friendly and promotion status-specific error message for front end applications, and/or allow for more appropriate error handling.
Triggering Promotion Evaluation
In XC, promotions were evaluated whenever the CalculateCartPipeline was called, which typically occurs when retrieving the cart or modifying the cart.
In OrderCloud, promotions are validated, calculated, and invalidated by the platform when certain endpoints are called. For detailed information, see Promotion Validation, Calculation, and Invalidation.
Extending Promotions
It is possible to fully customise Commerce Engine by adding, modifying and removing pipelines and pipelines and pipeline blocks to meet bespoke business requirements.
Extending promotions in OrderCloud requires a building the solution around the API rather than being able to customise the platform directly as per the Commerce Engine . Depending on business requirements a few approaches have been documented in Custom Promotion Logic.
XC to OrderCloud Promotion Cheatsheet
As a quick reference for re-writing XC promotion qualifications and benefits as eligible expressions and value expressions in OrderCloud, the following tables provide either the available OrderCloud expressions, or are flagged that customisation are required to achieve, with some instances providing sample approaches to how the customisation could be achieved.
Qualifications to Eligible Expressions
Product Inventory Qualifications
Line Level: true
Qualification/Condition | Eligible Expression |
---|---|
Inventory Item Stock Count In [specific] Location [compares] to [specific value]? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item In Stock? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item in Stock in [specific] Location? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item Out of Stock? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item Out of Stock in [specific] Location? | Inventory evaluation requires extending the API functionality via middleware. |
Is Cart Item Available? | Inventory evaluation requires extending the API functionality via middleware. |
Is Cart Item [specific] Quantity Available? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item Pre-orderable? | item.Product.xp.PreOrderable = true Although pre-order functionality is not native to the platform, a pre-order flag may be set on the product’s xp to achieve this promotion. |
Is Item Pre-orderable in [specific] Location? | Inventory evaluation requires extending the API functionality via middleware. |
Is Item Back-orderable? | item.Product.xp.Backorderable = true Although back-order functionality is not native to the platform, a back-order flag may be set on the product’s xp to achieve this promotion. |
Is Item Back-orderable in [specific] Location? | Inventory evaluation requires extending the API functionality via middleware. |
Cart Line Qualifications
Line Level: true
Qualification/Condition | Eligible Expression |
---|---|
Cart Item Quantity [compares] to [specific value]? | item.ProductID = <value> and item.Quantity <comparison operator> <value> |
Cart Item Quantity is in [min] [max] Range? | item.ProductID = <value> and item.Quantity >= <min value> and item.Quantity <= <max value> |
Cart Item Subtotal [compares] to [specific value]? | item.ProductID = <value> and item.LineSubtotal <comparison operator> <value> |
Cart Item is in [specific] category? | item.product.incategory(<category ID>) OR item.incategory(<category ID>) |
Cart Qualifications
Qualification/Condition | Eligible Expression |
---|---|
Cart Has included/excluded [specific] item(s)? (Items Collection) | items.Any(<value>) and not item.Any(<value>) |
Cart Has Items? | Order.LineItemCount > 0 |
Cart Has [count] Items? | Order.LineItemCount = <value> |
Cart Any Item Has [Tag]? | Arrays are not currently supported in OrderCloud, however this could be achieved via converting tags to flags or strings for direct evaluation. |
Cart Any Item Subtotal [compares] to [specific value]? | items.any(LineSubtotal <comparison operator> <value>) |
Cart Subtotal [compares] to [specific value]? | Order.Subtotal <comparison operator> <value> |
Cart Has Fulfillment? | Order.xp.SelectedShipMethodID <> null Requires maintaining a copy of the SelectedShipMethodID from the ShipEstimateResponse on the order’s xp . |
Is Context Currency [specific value]? | Order.Currency = <value> |
Customer Qualifications
Qualification/Condition | Eligible Expression |
---|---|
Is Cart Contact Currency [specific value]? | Order.FromUser.Locale.Currency = <value> |
Is Cart Contact Customer ID [specific value]? | Order.FromUser.ID = <value> |
Is Cart Contact Language [specific value]? | Order.FromUser.Locale.Language = <value> |
Is Cart Contact Registered? | Order.FromUser.ID = <Default Context User> |
Order History Qualifications
While the orders count and orders total may be able to be updated on the customers xp, keeping track of individual items purchased in the xp would be considered abuse as this can scale out of control and breach the maximum character length.
Qualification/Condition | Eligible Expression |
---|---|
Current Customer Has Purchased [specific] Item? | Evaluation requires extending the API functionality via middleware. |
Current Customer Has Purchased Item with [specific] Tag? | Evaluation requires extending the API functionality via middleware. |
Current Customer Orders Count [compares] to [specific value]? | Order.FromUser.xp.OrdersCount <comparison operator> <value> Requires maintaining the count of orders on the buyer user’s xp . |
Current Customer Orders Total [compares] to [specific value]? | Order.FromUser.xp.OrdersTotal <comparison operator> <value> Requires maintaining the sum of order totals on the buyer user’s xp . |
Shop Qualifications
Qualification/Condition | Eligible Expression |
---|---|
Is Shop Currency [specific value]? | Order.Currency = <value> |
Is Shop Language [specific value]? | Order.FromUser.Locale.Language = <value> |
Is Shop Name [specific value]? | Order.xp.Storefront = 'Storefront' Requires customising the storefront to apply the storefront name to the order’s xp . |
Date Qualifications
Qualification/Condition | Eligible Expression |
---|---|
Current Date Has Passed? | <value> > now(0) It is likely that the promotion’s StartDate should be sufficient. |
Is Current Day? | Evaluation requires extending the API functionality via middleware. |
Is Current Month? | Evaluation requires extending the API functionality via middleware. |
Benefits to Value Expressions
Cart Benefits
Benefits/Actions | Value Expression |
---|---|
Get Free Shipping | Order.ShippingCost |
Get Free Gift | Requires extending the API functionality via middleware. |
Get Cart Subtotal [specific] Amount Off | <value> |
Get Cart Subtotal [specific] Percent Off | Order.Subtotal * <percentage value> |
Cart Line Benefits
As can be seen below, a number of benefits can be converted into the same, more basic value expression in OrderCloud as it retains context of the line item for evaluation, whereas XC typically requires the condition to be re-evaluated in the benefit to be applied correctly.
Benefits/Actions | Value Expression |
---|---|
Get Cart Any Item Sell Price | item.UnitPrice - <value> |
Get [specific] Amount Off Item Subtotal | <value> |
Get Cart Any Item Subtotal [specific] Amount Off | See above. |
Get Cart Item in Category [specific] Amount Off | See above. |
Get Cart Item Subtotal [specific] Amount Off | See above. |
Get [specific] Percentage off Item Subtotal | item.LineSubtotal * <percentage value> |
Get Cart Any Item Subtotal [specific] Percent Off | See above. |
Get Cart Item in Category [specific] Percent Off | See above. |
Get Cart Item Subtotal [specific] Percent Off | See above. |
References
- OrderCloud: The Rules Engine Has Arrived
- OrderCloud: Rules-Based Promotion Expressions
- OrderCloud: Introducing Line Item-Level Promotions
- Sitecore OrderCloud: Working with Promotions
- Sitecore Experience Commerce: Promotion Evaluation and Application Logic in XC 10
- Sitecore XC: Promotions
- Sitecore XC: Promotions service
- Sitecore XC: Promotions qualifications
- Sitecore XC: Promotions benefits
Continue the Series
- Transitioning from Sitecore Experience Commerce to OrderCloud: Customers to Buyer Users
- Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access
- Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories
- Transitioning from Sitecore Experience Commerce to OrderCloud: Sellable Items To Products
- Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing
- Transitioning from Sitecore Experience Commerce to OrderCloud: Carts to Unsubmitted Orders and Carts
- Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping
- Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments
- Transitioning from Sitecore Experience Commerce to OrderCloud: Orders
- Transitioning from Sitecore Experience Commerce to OrderCloud: Order Workflow and Minions
- Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions