In this article, we will review how we can redirect traffic from OrderCloud’s integration events and webhooks to our local web server to assist debugging efforts in local development.
The OrderCloud Headstart application will be referenced in this example, which may differ slightly from your integration service/middleware application.
Introduction
As OrderCloud’s integration events and webhooks require public urls to be available for testing and having complete functionality available, the question quickly arises as to how developers will be able to develop and debug the respective middleware endpoints in a local environment. One solution we will review is to use ngrok, a free service, which allows us to expose a web server running on our local machine to the internet.
Installation, Configuration, and Testing
High-level steps are provided below, however steps may vary based on operating systems and command tools. See ngrok: Getting Started > Setup & Installation, and register or log in to a free account, for alternative setup steps.
Now we can start HTTP tunnel forwarding to our local middleware.
ngrok http https://localhost:<port number>
The tunnel will then be created with a random URL, which we need to take note of for our OrderCloud configurations.
Configuring OrderCloud’s Integration Events
In OrderCloud, we can create or update an integration event using the generated URL from ngrok as the CustomImplementationUrl. The HashKey will also need to be configured to match the OrderCloudSettings:WebhookHashKey appsettings in HeadStart.
As ngrok does generate a random URL each time when using free accounts, the CustomImplementationUrl will need to be patched each time you expose the local web server.
If the integration event has been newly created, don’t forget to assign it to the API client’s OrderCheckoutIntegrationEventID so that the integration event can trigger the endpoints of the middleware.
When configuring webhooks, the Url will require the complete application service/middleware application endpoint to be defined, along with the HashKey, which should be configured to match the OrderCloudSettings:WebhookHashKey appsettings in HeadStart.
Webhooks also require the ApiClientIDs to be assigned on the resource itself rather that the API client and the WebhooksRoutes need to be specified in order for the OrderCloud API to trigger the webhook, which should then be redirected from ngrok through to the local web server.
With Visual Studio’s debugger attached to the local IIS site or is being debugged directly, when an integration event or webhook endpoint is requested via an appropriate API client, ngrok will redirect the request to the local web server and the debugger will be able to capture the traffic for local debugging.
Troubleshooting
An attempt was made to access a socket in a way forbidden by its access permissions
When attempting to run ngrok, if the response “An attempt was made to access a socket in a way forbidden by its access permissions” is received, restarting the Host Network Services Windows service should resolve this issue.
In this article, we will review and compare Sitecore Experience Commerce sellable items and OrderCloud products 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.
Conceptual Architecture and Features
Physical vs Digital Sellable Items
In XC, a sellable item is considered digital if it contains a tag that is also registered to the DigitalItemTagsPolicy. Digital products will not track inventory and will modify the delivery step of the checkout flow to collect information relevant to digital items, such as an email address and custom messaging, rather than a delivery address and shipping provider information, which is relevant for physical items.
As OrderCloud is impartial to the nature of the products, using existing platform functionality and extended properties xp, a solution can opt into tracking product types and apply custom behaviour the achieve bespoke business requirements. For example, to model products as digital as per XC, we can disable inventory tracking at the product level and copy the tags to the product’s extended properties. The middleware and storefront applications can then identify products with this information as representing digital items and provide custom behaviour throughout the storefront to match that of the SXA storefront.
In XC, sellable items can be represented as standalone products, which are sellable items without variations, or as a product family, which consists of a number of item variations each representing an individual product that share mostly similar properties to the other item variations.
OrderCloud can also represent products as both standalone product or a product with variants.
Item Variations vs Variants
In XC, the item variations are created within a sellable item entity, each representing its own unique product.
Variation properties are defined in the environment role configuration under VariationPropertyPolicy and sellable item families are expected to use a subset of these properties to create unique combinations.
In OrderCloud, the architecture of product families have the same intention, however there is enforcement around creating only unique variations using specs and spec options. A spec closely relates to the VariationPropertyPolicy in that it specifies the property that will break down the product into a variant, while the spec option specifies all of the values that will be assigned to the spec. A product can have multiple specs assigned, e.g. the first spec could represent colors while the second could represent sizes.
While specs can then be assigned to more than one product, there’s more control in creating specs that are unique to products even if they do represent the same property type, such as size, as this will reduce the long term maintenance.
OrderCloud then provides the endpoint, POST /products/{productID}/variants/generate, to generate variants from all possible combinations of the assigned specs. Referencing figure 3 it can be noted that when migrating sellable items from XC there will be instances where not all combinations are required, however any unwanted variants can be disabled.
Item Variation Corruption
While the SXA storefront and commerce data provider will utilise the VariationPropertyPolicy configuration for the item variation controls on the product details page in the storefront, there is no validation during item variation creation. This means that is is possible to corrupt sellable item families in the following ways:
Two or more varations share the same values across all of their variation properties. In figure 4, the product family utilises variation properties color and size, however item variations C and D are both configured with same color and size. In this instance, duplication may have been unintentional or a third variation property is missing that could make the variation unique. The Style property could be added in this instance to all item variations assuming the values between item variations C and D would be different.
The subset of variation properties are not all populated with values. In figure 4, the Color and Size properties are filled out for all item variations, except for item variation E which has a null value for Size.
In figure 4, the Style property is null for all item variations.
Folding Sellable Items with Variations into Standalone Products
During sellable item migration there are two more scenarios that may come up, specifically in relation to sellable items with a single item variation. The first is in noting point 2 of the item variation corruption, a sellable item is flagged as corrupted as no variation properties of the item variation have values, which can be easily folded into a standalone sellable item.
The second scenario is where the single item variation does contain values for one or more variation properties. Here, is where further consideration may be required as to whether this item variation should be folded back into a standalone sellable item. The reason for this consideration is because the Commerce Engine sets a global set of variation properties, however this may not necessary apply to the sellable item in question, but was designed this way because the global configuration in the VariationPropertyPolicy.
Static and Dynamic Bundles
XC has special product types called static bundles and dynamic bundles, which are configurations of sellable items that are sold together. These bundles can either represent a fixed group of sellable items or a list of sellable items with alternate sellable items, which can be substituted out by the user, and/or be an optional extra into the bundle.
OrderCloud currently does not currently support product bundling natively, however by leveraging the product’s xp it is possible to model product bundles and have functionality be controlled by middleware and buyer and seller applications.
Workshopping product bundle models and behaviour is outside of the scope of this analysis.
Extended Properties
In XC, a sellable item can have its properties extended via composer templates or programatically with custom components, while item variations only be extended programatically. These can be generally be translated over to OrderCloud using its eXtended Properties (xp), however considerations will be required around non-standard data types.
Images
XC leverages Sitecore’s media library for hosting images and stores the Sitecore Id of the image on the ImagesComponent of the sellable item or variant it’s associated to.
Over in OrderCloud, products don’t have an explicit property for images as it relies on external systems, such as DAMs or CDNs, to host imagery instead. In addition, the OrderCloud philosphy is that as there is no one-size-fits-all solution when it comes to working with product images, so the absence of a dedicated property provides the flexibility of allowing a bespoke data model to be added to the product’s xp to best represent the client’s business requirements. Examples of potential requirements include, a single array of images (image urls), image sets representing different views or components of a product, image sets representing varying quaility or sizing for omni-channel optimisation. etc.
Relationship Definitions
XC has a concept of relationship definitions, which allows sellable items to have a relation to another sellable item with a given context. For example, the Habitat catalog relationship definitions for associated sellable items for installation, training, warranty, and most notably related sellable items.
The Commerce Engine and BizFx application provides an interface for creating these relationships and applies validation to ensure that the related products exist and are not duplicated. The Commerce Engine also includes smarts to filter out invalid sellable items for a given context, e.g. inactive sellable items, sellable items that are not associated to the current catalog, etc.
In OrderCloud, custom product to product assignments are not native in the platform, however a list of associated products can be added to the product’s xp, e.g. xp.RelatedProducts, to represent the relationship. To retrieve the products, a filtered product search, under the me resource, can be queried using the product’s IDs, which will automatically exclude products that don’t exist, are inactive, or are not assigned to the user, e.g. /me/products?ID=<Product B>|<Product C>|<Product D>.
As OrderCloud has no concept of entity versioning, one approach towards migration is to only migrate the latest published versions of sellable items. In a similar manner the publishing workflow that applies to sellable items may see a project consider the latest entity version as the source of truth regardless of its published state. Considerations would need to be made on project by project basis, which may entail a level of data cleansing prior to migration.
Property Localisation
XC allows entity properties to be localisable for content that can be displayed in multiple languages. OrderCloud does not explicitly support property localisation, however localisation can be achieved by creating locale-specific entities as documented in How to Globalize your eCommerce.
Data Mapping
With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.
In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.
OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.
Products
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
OwnerID
string
No
N/A
N/A
N/A
DefaultPriceScheduleID
string
No
SellableItem
ListPrice
Money
PriceSchedule will be created from the SellableItem’s ListPrice, using the Product.ID as the Price Schedule’s ID.
AutoForward
bool
No
N/A
N/A
N/A
ID
string
No
SellableItem
FriendlyId
string
Name
string
Yes
SellableItem
DisplayName
string
Description
string
No
N/A
N/A
N/A
QuantityMultiplier
int
No
N/A
N/A
N/A
ShipWeight
float
No
[ItemSpecificationsComponent]
Weight
double
ShipHeight
float
No
[ItemSpecificationsComponent]
Height
double
ShipWidth
float
No
[ItemSpecificationsComponent]
Width
double
ShipLength
float
No
[ItemSpecificationsComponent]
Length
double
Active
boolean
No
SellableItem
Published
boolean
This assumes only the latest published entity version is being migrated.
ShipFromAddressID
string
No
N/A
N/A
N/A
Inventory.Enabled
boolean
No
N/A
N/A
N/A
Virtual products won’t have inventory in either XC or OrderCloud. This should be set to disabled if any of the XC tags contain a value representing an XC virtual product.
Inventory.NotificationPoint
int
No
N/A
N/A
N/A
Inventory.VariantLevelTracking
boolean
No
N/A
N/A
N/A
Inventory.OrderCanExceed
boolean
No
N/A
N/A
N/A
Inventory.QuantityAvailable
int
No
InventoryInformation
Quantity
int
If transitioning a single inventory set/ record per product.
DefaultSupplierID
string
No
N/A
N/A
N/A
AllSuppliersCanSell
boolean
No
N/A
N/A
N/A
xp
object
No
N/A
N/A
N/A
XC composer views and programatic components can be added to xp as needed.
xp.Brand
string
No
SellableItem
Brand
string
xp.Manufacturer
string
No
SellableItem
Manufacturer
string
xp.TypeOfGood
string
No
SellableItem
TypeOfGood
string
xp.Tags
list
No
SellableItem
Tags
list
Convert to list of string using name property only.
xp.ItemDefinitions
list
No
[CatalogsComponent].[CatalogComponent]
ItemDefinition
string
The ItemDefinition of each CatalogComponent should be added to the list, excluding duplicate values.
xp.RelatedProducts
list
No
Relationship (Commerce List)
Id
string
The relationships are stored in lists, not entities. All Ids will need to be parsed to their friendly ids.
Specs
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
ID
string
No
SellableItem ItemVariationComponent
FriendlyId <variation property>
string
Recommended using ‘{SellableItem.FriendlyId}_<variation property name>’ to create unique name.
ListOrder
integer
No
N/A
N/A
N/A
Name
string
Yes
ItemVariationComponent
<variation property>
string
The name of the variation property, not the value of the variation property.
DefaultValue
string
No
N/A
N/A
N/A
Required
boolean
No
N/A
N/A
N/A
Set to true.
AllowOpenText
boolean
No
N/A
N/A
N/A
false by default.
DefaultOptionID
string
No
N/A
N/A
N/A
DefinesVariant
boolean
No
N/A
N/A
N/A
Set to true.
xp
object
No
N/A
N/A
N/A
Spec Options
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
specID
string
Yes
SellableItem ItemVariationComponent
FriendlyId <variation property>
string
See Spec Data Mapping ID property.
ID
string
No
ItemVariationComponent
<variation property>
string
The value of the variation property.
Value
string
Yes
ItemVariationComponent
<variation property>
string
The value of the variation property.
ListOrder
integer
No
N/A
N/A
N/A
IsOpenText
boolean
No
N/A
N/A
N/A
false by default.
PriceMarkupType
string
No
N/A
N/A
N/A
PriceMarkup
number
No
N/A
N/A
N/A
xp
object
No
N/A
N/A
N/A
Spec Product Assignments
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
SpecID
string
Yes
SellableItem ItemVariationComponent
FriendlyId <variation property>
string
See Spec Data Mapping ID property.
ProductID
string
Yes
SellableItem
FriendlyId
string
DefaultValue
string
No
N/A
N/A
N/A
DefaultOptionID
string
No
N/A
N/A
N/A
Variants
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
productID
string
Yes
SellableItem
N/A
N/A
variantID
string
Yes
ItemVariationComponent
Id
string
ID
string
No
ItemVariationComponent
Id
string
Name
string
Yes
ItemVariationComponent
DisplayName
string
Description
string
No
ItemVariationComponent
N/A
N/A
Active
boolean
No
ItemVariationComponent
Disabled
boolean
Value to be inverted. Set to false if not a valid variant.
ShipWeight
float
No
[ItemSpecificationsComponent]
Weight
double
ShipHeight
float
No
[ItemSpecificationsComponent]
Height
double
ShipWidth
float
No
[ItemSpecificationsComponent]
Width
double
ShipLength
float
No
[ItemSpecificationsComponent]
Length
double
Inventory.QuantityAvailable
int
No
InventoryInformation
Quantity
int
If transitioning a single inventory set/ record per product.
xp
object
No
N/A
N/A
N/A
XC composer views and programatic components can be added to xp as needed.
xp.Tags
list
No
SellableItem
Tags
list
Convert to list of string using name property only.
In this article, we will review and compare API Access for Sitecore Experience Commerce customers and OrderCloud buyer users 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.
Conceptual Architecture and Features
Storefront API Access to the Commerce Systems
One aspect that developers tend to glaze over is how an SXA storefront interacts with the Commerce Engine. This is because the installation scripts apply the necessary configurations for the installed topology without the need for further manual intervention.
In an OrderCloud solution, the storefront will be configured to interact with the OrderCloud API server for the relevant region and environment, as documented in OrderCloud Supported Regions and Environments, that hosts the marketplace instance.
Resources
In the Commerce Engine, the CommerceODataController actions are registered to either the /api or /commerceops route, which creates the API under these two primary resources. The api route typically hosts actions that a storefront or the Commerce Business Tools (BizFx) would request, while the commerceops route hosts actions for dev ops interactions by dev ops users and the commerce data provider.
In OrderCloud, resources are not grouped up into resource buckets, however in the OrderCloud portal there is logical grouping within the UI to help navigate between related resources, as seen in figure 1.
For storefront users, the /me and /order resources will cover account management and creation of orders respectively.
Authentication
The Sitecore Identity Server provides bearer token authentication for SXA storefront requests made to the Commerce Engine using the Commerce Engine Connect client, which is configured across Sitecore, Sitecore Identity Server, and Commerce Engine applications.
SXA customer registration and login functionality is accomplished using the SQL authorization provider, instead of the Sitecore Identify Server. This also segregates customer authentication data stored in the security database from commerce data stored in the commerce database.
The related commerce customer entity is created in the commerce database during account creation and the commerce customer reference is stored against the customer account in the security database.
In an OrderCloud storefront implementation, authentication is handled within OrderCloud itself using API clients, in a similar fashion to Sitecore Identity Server’s clients, returning limited lifetime bearer tokens.
Storefront user data is stored under a single object and users are typically authenticated directly with all subsequent requests containing the context of a storefront user.
Roles and Authorisation
Requests to the Commerce Engine will see the bearer token validated, which will determine the roles of the authenticated user and compare them to the roles of the API resource, which is configured in the Commerce Engine under the ControllerMethodRolesPolicy in Global.json.
Requests not containing an authorized role will be rejected by the Commerce Engine with the exception of the Commerce Engine Connect client being a special case in that the Commerce Engine identifies this user and appends the commerce\runtime role to the request context to effectively brute force authorisation for its requests.
In contrast, OrderCloud has predefined roles for the various resources, which is detailed further in Understanding Security Profiles, providing more granular control over the resources a user has access to.
During the authentication process the roles are resolved from the user being authenticated, based on security profile assignments at the company, user group, and user levels.
To replicate the behaviour from XC, while having considerations for the necessary restrictions to API resources that wouldn’t be utilised by a storefront user, the following roles would be assigned to a security profile for storefront users.
In the SXA storefront, the customer id of anonymous/guest users and registered customers are passed in as a request header, which the Commerce Engine then resolves to the anonymous or registered user.
In OrderCloud, the user context needs to be resolved at the time of authentication, which will then be passed on to subsequent requests via the access token. Registered users are authenticated with username and password, while anonymous users are authenticated against an API client configured with an IsAnonBuyer flag and the default context user, which is used for resolving roles and not a user context when interacting with the OrderCloud API.
In figure 5, we see an API client configured with the IsAnonBuyer set as true and the DefaultContextUserName set to BUYER USER A. The roles configured to Security Profile A, which is assigned to Buyer A will be resolved when attempting to authenticate a registered buyer user or an anonymous user.
BUYER USER A is created for the specific purpose of being the anonymous user template as using a real user that can be modified or deleted at any time can have adverse effects on the anonymous user behaviour.
Service Proxy vs SDKs and Catalyst
The SXA storefront solution, including custom code, typically communicates with the Commerce Engine via the Service Proxy – an SDK containing Commerce Engine data models and strongly typed wrappers for the API. The Service Proxy simplifies custom development effort and complexity, which can also be regenerated after modifying the Commerce Engine to ensure the integrity of the library.
OrderCloud also provides a JavaScript and .Net SDK for the OrderCloud data models and strongly typed wrappers for all public endpoints. The JavaScript SDK allows requests to be made directly from the client browser rather than passed through middleware, whereas the .Net SDK is intended for the middleware for requests that typically require wrapped logic or even placeholder wrappers to insert logic at a later date.
The OrderCloud catalyst is another .Net library which provides additional helpers for authentication, performant bulk requests, error handling, jobs, project setup, etc.
Data Mapping
With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.
In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.
OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.
Security Profile
The security profile mapped below represents storefront users only. The BizFx Business Tools users would have a different configuration, most notably for roles.
Sitecore’s default value is 6, while OrderCloud has a minimum value of 10.
Security Profile Assignment
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
SecurityProfileID
string
Yes
Site (Sitecore)
Domain
string
BuyerID
string
No
Site (Sitecore)
Domain
string
SupplierID
string
No
N/A
N/A
N/A
UserID
string
No
N/A
N/A
N/A
UserGroupID
string
No
N/A
N/A
N/A
Buyer User (Anonymous User)
The anonymous buyer user is created to represent an instance of an anonymous user. This user is fleshed out with hard-coded values for mandatory properties.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
buyerID
string
Yes
Site (Sitecore)
Domain
string
Is a resource parameter, not body property.
ID
string
No
N/A
N/A
string
“anonymous-user”
Username
string
Yes
N/A
N/A
string
“{buyerId}-anonymous-user”
Password
string
No
N/A
N/A
N/A
FirstName
string
Yes
N/A
N/A
N/A
“Anonymous”
LastName
string
Yes
N/A
N/A
N/A
“User”
Email
string
Yes
N/A
N/A
N/A
“anonymous@user.com”
Phone
string
No
N/A
N/A
N/A
TermsAccepted
string
No
N/A
N/A
N/A
Active
boolean
Yes
N/A
N/A
N/A
Set to true
xp
object
No
N/A
N/A
N/A
API Client
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
ClientSecret
string
No
N/A
N/A
N/A
AccessTokenDuration
integer
Yes
N/A
N/A
N/A
Set to 600 (maximum)
Active
boolean
No
N/A
N/A
N/A
Set to true
AppName
string
Yes
Site (Sitecore)
Domain
string
RefreshTokenDuration
integer
No
N/A
N/A
N/A
DefaultContextUserName
string
No
Anonymous Buyer User (OrderCloud)
Username
string
AllowAnyBuyer
boolean
No
N/A
N/A
N/A
AllowAnySupplier
boolean
No
N/A
N/A
N/A
AllowSeller
boolean
No
N/A
N/A
N/A
IsAnonBuyer
boolean
No
N/A
N/A
N/A
Set to true
OrderCheckoutIntegrationEventID
string
No
N/A
N/A
N/A
MinimumRequiredRoles
array
No
N/A
N/A
N/A
MinimumRequiredCustomRoles
array
No
N/A
N/A
N/A
MaximumGrantedRoles
array
No
N/A
N/A
N/A
MaximumGrantedCustomRoles
array
No
N/A
N/A
N/A
xp
object
No
N/A
N/A
N/A
API Client Assignment
Technically, the API client assignment can be skipped and the AllowAnyBuyer property on the API client can be set to true instead, however this example creates an API client per storefront, which may be preferrable to allow the API client configuration to be modified later without affecting the other storefronts.
In this article, we will review and compare catalogs and categories 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.
Conceptual Architecture and Features
Catalogs and Categories
In XC, the structure of catalogs, categories, and sellable items/products can be recreated in OrderCloud. In a nutshell, categories are tied to their catalogs and can only have one parent, either another category or the catalog itself, while sellable items or products are separate to the catalog and can be assigned to one or more catalogs and/or categories.
In earlier versions of XC categories were allowed to have multiple parents, but support was subsequently removed. If an XC solution still contains categories with multiple parents this would be a consideration for pre-migration cleansing.
The Storefront to Catalog Association
In Customer to Buyer Users we discussed that in XC, a storefront was required in order to associate a customer to a catalog. while OrderCloud has a direct assignment between buyers and catalogs. We will now revisit this to complete the context for catalogs.
In the SXA storefront, only a single catalog can be associated to the storefront, which is configured in the Content Editor under /sitecore/content/<tenant>/<site>/Home/Catalogs.
Over in OrderCloud, a catalog assignment creates a link between a catalog and a buyer, bypassing the need for a storefront.
The catalog assignment also contains two additional boolean properties in ViewAllCategories and ViewAllProducts, which as the names suggest allow all categories and products to be viewed by buyer users via the /me/products resource. These properties are important when understanding how XC customers can view sellable items vs OrderCloud buyers viewing products, which we cover in the next section SXA Scope Query vs Product Visibility.
SXA Scope Query vs Product Visibility
Now that we have established that the catalog structure can be identical between XC and OrderCloud, how do both systems handle product search functionality?
In an SXA storefront, there are two primary search scopes that are used for searching sellable items; the catalog scope and the category scope. These scopes are defined in the Content Editor under /sitecore/content/<tenant>/<site>/Settings/Scopes.
Catalog Scope
The catalog scope is used by the global site search component, and will perform a search query returning all active sellable items associated to the catalog. An optional search term can be provided by the storefront user to further filter the results.
Referencing OrderCloud’s documentation, Product Visibility Requirements, we see Scenario 3 replicates the XC and the SXA storefront visibility rules for the catalog scope, excluding the search term filter. “When I assign a catalog to a buyer organization, I just want everybody in that organization to see everything in the catalog.” In short the ViewAllCategories and ViewAllProducts of a catalog assignment should be set to true.
Category Scope
The category scope is used for the category search results page and is just a more refined scope than the catalog scope in that it will return all active sellable items associated to a specific defined category. Again, an optional search term is available for further filtering.
The Search Term Filter
For the search term filter, the SXA query builder appends a comparison between the search term appends a fuzzy query against the sxacontent index field, which is an array consisting of the following sellable item properties:
Tags
ProductId
Name
DisplayName
ItemDefinition
Brand
The resulting query for a global search will look something like the following, with the highlighted section representing the example search term of “Spectra”.
7512 07:28:09 INFO Solr Query - ?q=((((((((commercesearchitemtype_t:("sellableitem") AND _latestversion:("True"))
AND excludefromwebsitesearchresults_b:("False")) AND parentcataloglist_sm:("59ddadc19b88727e9e143f6cf321ae0f"))
AND (_path:("ccd5fda3aaba4f46b4f9b8bb7938bae5") AND searchable_b:("True")))
AND (sxacontent_txm:(*Spectra*) OR sxacontent_txm:("Spectra")))
AND _language:("en")) AND _latestversion:("True"))
AND ((_displayname:(*Furry*))^1000 OR (-_name:("") _name:[* TO *]))) AND _val_:__boost&amp;amp;amp;start=0&amp;amp;amp;rows=0&amp;amp;amp;fq=_indexname:(sitecore_web_index)&amp;amp;amp;wt=xml
In OrderCloud, we can achieve an equivalent query using the /me/products resource and applying a filter that allows us to filter on multiple fields with logical “OR” syntax to query each of the raw OrderCloud properties that make up the XC sxacontent index field.
As we will review in an upcoming article, the Name property tends to be a duplicate of the DisplayName, so we won’t bloat the product’s xp in OrderCloud with redundant data, however you can choose to include the Name property and amend the /me/products queries as necessary.
Catalog – Item Definitions
Item definitions allow composer templates to be associated with sellable items to create extended properties on the sellable items. The name of the item definition is also used in storefront search indexes for search components
From an OrderCloud perspective, extended properties (XP) can be used to represent an equivalent result. As represented in figure 6, all item definition properties are merged into a consistent xp schema along with the item definitions as its own xp, which will be indexed and available for search queries, product facets, etc.
Other Considerations
Entity Versioning and Workflow
In lieu of entity versioning in OrderCloud, one approach towards migration is to only migrate the latest published versions of catalogs and categories. In a similar manner the publishing workflow that applies to catalogs and categories may see a project consider the latest entity version as the source of truth regardless of its published state. Considerations would need to be made on project by project basis, which may entail a level of data cleansing.
Catalogs and Categories Pending Purge
A gotcha in migrating catalogs and categories is that the entities can still exist if they are pending purge, which is represented on the entity with an instance of PurgeCatalogsComponent or PurgeCategoriesComponent. These entities can be safely ignored during migration.
Property Localisation
XC provides entity properties to be localisable for content that can be displayed in multiple languages. OrderCloud does not explicitly support property localisation, however localisation can be achieved by creating locale-specific entities as documented in How to Globalize your eCommerce.
Data Mapping
With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.
In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.
OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.
Catalogs
Catalog mapping is fairly basic as there aren’t many properties on the catalogs of either system
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
ID
string
Yes
Catalog
FriendlyId
string
OwnerID
string
No
N/A
N/A
N/A
Name
string
Yes
Catalog
DisplayName
string
Description
string
No
N/A
N/A
N/A
Active
boolean
No
Catalog
Published
boolean
This assumes only the latest published entity version is being migrated.
xp
object
No
N/A
N/A
N/A
XC composer views and programatic components can be added to xp as needed.
Catalog Assignments
Catalog assignments are simply a relational mapping with the added control over category and product visibility.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
CatalogID
string
Yes
Catalog
FriendlyId
string
BuyerID
string
No
N/A
N/A
N/A
The Sitecore Domain taken from the Storefront with the associated catalog.
ViewAllCategories
boolean
No
N/A
N/A
N/A
Set to true.
ViewAllProducts
boolean
No
N/A
N/A
N/A
Set to true.
Categories
XC orders categories alphabetically using list ids, while OrderCloud generates the ListOrder property, so this may result in different ordering between the two systems.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
catalogID
string
Yes
Category
FriendlyId
string
Is a resource parameter, not body property.
ID
string
No
Category
FriendlyId
string
Name
string
Yes
Category
DisplayName
string
Description
string
No
Category
Description
N/A
ListOrder
string
No
N/A
N/A
N/A
ListOrder will be generated (auto-increment) when creating categories.
Active
boolean
No
Category
Published
boolean
This assumes only the latest published entity version is being migrated.
xp
object
No
N/A
N/A
N/A
XC composer views and programatic components can be added to xp as needed.
In this article, we will review and compare Sitecore Experience Commerce inventory and pricing entities against OrderCloud’s inventory and pricing 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 the closest path to parity as possible in OrderCloud, using the Habitat catalog and SXA Storefront.
Conceptual Architecture and Features
Inventory
Single Inventory Approach
When it comes to inventory management, in its most basic form, a sellable item or item variation will contain inventory information on an associated entity within an inventory set. To be able to resolve the inventory, the sellable item must be associated to a catalog (or category within a catalog) and the catalog must be associated to the inventory set.
In a more simplified comparison, OrderCloud also has a separate underlying inventory object assigned to a product or variant, however it’s represented and managed as a sub-object of the product/variant. No relationship to a catalog or inventory set equivalent is required.
Multi-Inventory Approach
When it comes to dealing with multiple catalogs in XC, the approach has a new layer of complexity; catalogs may have different associated inventory sets, which means that the inventory information entity the commerce engine resolves to is based on catalog-inventory set association.
In OrderCloud, it is also possible to store multiple sets of inventory data using inventory records, providing two paths for inventory management. For implementations where single sets of inventory data will only ever be required, the traditional inventory management approach in figure 2 can be used. Where multi-inventory management is required, inventory records can be leveraged.
In OrderCloud’s multi-inventory management approach, admin addresses are effectively the inventory set equivalent in creating a logical grouping of inventory records; catalog assignments are still not required to resolve inventory.
Multiple inventory records can be assigned to an address, and although it’s not required in the XC to OrderCloud migration, it’s mentioned simply for a more complete understanding of the OrderCloud architecture.
The most notable difference between the two systems is the Commerce Engine controls the logic to resolve the appropriate inventory information entity, while the middleware application of an OrderCloud implementation would be responsible for resolving applicable inventory records.
Inventory sets can represent the grouping of inventory information entities, typically for source or purpose, e.g. warehouse stock or reserved inventory for online sales. These are used in common customisations, such as click and collect, where more than one inventory set is utilised in a storefront. Using inventory records in OrderCloud can achieve the same result.
Inventory Properties
Apart from the expected quantity property, XC’s inventory information also contains information such as invoice unit price and currency, preorderable and backorderable details. While the commerce engine does perform some logic for decrementing backorder and preorder inventory quantities, the implementation is not complete, therefore we won’t treat this as a functional gap between the two systems and simply adding them to OrderCloud’s extended properties (xp) will suffice from the data migration perspective.
Inventory records have the additional benefit of owning their xp. This means that additional properties such as preorderable and backorderable details better fit the context in the inventory record xp, over the product xp, which would be required when using the traditional product inventory approach.
Pricing
When directly comparing the pricing architecture of XC and OrderCloud, there are some notable differences in how pricing is resolved for at both the sellable item/product level and the item variation/variant level.
List Pricing Approach – Sellable Item Level
Starting with the most basic approach to pricing migration, sellable items have a list price policy that stores a list of multi-currency pricing. Note that item variations do not have list pricing in this example and will inherit from the sellable item. Also leaving the price card architecture out of the equation, the list pricing approach is represented in figure 5.
In OrderCloud, pricing is managed via price schedule objects that are assigned to products. In order to replicate the XC architecture, individual price schedules will represent the list price for each currency, then a product assignment is used to create the relationship between the product, the price schedule, and a buyer user group. Locale assignments between locale and buyer user group are used to resolve the currency when creating orders.
To switch between active currencies, the buyer user will need to be moved to the respective buyer group representing the desired currency configuration.
Multi-currency can also be achieved for anonymous/guest shoppers via multiple API clients configured appropriately. See OrderCloud: How to Globalize your eCommerce for more information.
If we only need to support a single currency then we can take advantage of a more simplified approach using just the product and price schedule, using the DefaultPriceScheduleID.
List Pricing Approach – Item Variation Level
XC also allows for list prices to be set at the item variation level, which includes fallback to the sellable item list pricing if not supplied. Excluding the fallback pricing, we see the following representation of a sellable item with list pricing configured against the item variations in figure 8.
To replicate XC price resolution at the variant level in OrderCloud, the variant’s xp could be used to host price schedule assignments, while the middleware solution can resolve the price schedule as needed. For example, during the order calculate integration event the order’s line item UnitPrice property can be overridden via LineItemOverrides model.
{
"LineItemOverrides": [
{
"LineItemID": "LineItemWithVariantA", // Line Item ID containing variant A
"UnitPrice": 6.00 // Price resolved from Price Schedule A
}
]
}
Price Card Approach
Associations
In XC, a price book can be associated to multiple catalogs, which represents the price book that the catalog will attempt to resolve price cards from for a given sellable item.
Price cards can be resolved, by name or by tag association, to more than one price card across multiple price books. The Commerce Engine contains some additional logic to identify the eligible price cards, prioritise them, and determine the winning price card.
Scheduled Pricing
Taking a step back to look at the minimal configuration of a single price card associated to a sellable item, the price snapshots on the price card represent scheduled pricing. Each snapshot supports multi-currency tiered pricing, and also has approval workflow to prevent new pricing from accidently going live.
In OrderCloud, the price schedule contains PriceBreaks, allowing for tier pricing for a single currency. The SaleStart and SaleEnd date/time properties dictate the timeframe when the SalePrice values are active, which is also flagged by the calculated property IsOnSale.
PriceSchedule assignments support price scheduling without needing to differ from the assignment architecture shown in figure 6 and figure 7.
In migrating from XC’s price card architecture to OrderCloud’s price schedule architecture, the following table highlights additional aspects of XC with high level approaches to implementing them in an OrderCloud solution.
XC
OrderCloud
A sellable item can resolve to multiple price cards, which has logic to prioritise and resolve a single price card.
OrderCloud supports multiple price schedule assignments to products via assignments allowing for dynamic resolution of a price schedule relevant to the customer. For more complex scenarios, the product’s xp can be utilised to have the middleware resolve the price schedule using custom logic and can override the unit price for calculating orders via the order calculate integration event. For more information, see OrderCloud: Same Product, Multiple Price Schedules and Order Checkout Integration Event > Implementation > /OrderCalculate
Price cards are grouped into price books, which can be resolved by the price book association of the catalog.
Price schedules can be assigned to a specific buyers or buyer groups, which is typically sufficient for resolving price schedules for the majority of business requirements. For more information, see OrderCloud: Same Product, Multiple Price Schedules.
Price cards may contain multiple price snapshots for scheduled pricing support.
Price schedules allow for sale pricing, based on a specific date and time, while future sale pricing can be achieved through creating scheduled tasks, e.g. a timer triggered function app in Azure, to update price schedules accordingly.
Using price cards without list pricing allows standard pricing to be scheduled.
Standard pricing can be achieved through creating scheduled tasks, e.g. a timer triggered function app in Azure, to update price schedules accordingly.
XC Price Snapshots have approval workflow.
Approval workflow can be implemented via middleware customisation.
Data Mapping
With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.
In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.
OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.
Admin Addresses
While admin addresses are a representation of inventory sets, there are a number of mandatory fields for address details that do not exist in XC. These fields can either be filled out with dummy data or enriched with the appropriate values.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
ID
string
No
InventorySet
FriendlyId
string
CompanyName
string
No
N/A
N/A
N/A
FirstName
string
Yes
N/A
N/A
N/A
LastName
string
No
N/A
N/A
N/A
Street1
string
Yes
N/A
N/A
N/A
Sample data will need to be supplied.
Street2
string
No
N/A
N/A
N/A
City
string
Yes
N/A
N/A
N/A
Sample data will need to be supplied.
State
string
Yes
N/A
N/A
N/A
Sample data will need to be supplied.
Zip
string
Yes
N/A
N/A
N/A
Sample data will need to be supplied.
Country
string
Yes
N/A
N/A
N/A
Sample data will need to be supplied.
Phone
string
No
N/A
N/A
N/A
AddressName
string
No
InventorySet
DisplayName
string
xp
object
No
N/A
N/A
N/A
xp.Description
string
No
InventorySet
Description
string
Inventory Records
The xp in inventory records should only be mapped if they are being used in the XC implementation to avoid unnecessary bloating of the xp. The xp mapping can also be used on the product for the traditional inventory management approach.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
productID
string
Yes
SellableItem
FriendlyId
string
ID
string
No
InventoryInformation
FriendlyId
string
OwnerID
string
No
N/A
N/A
N/A
AddressID
string
No
InventorySet
FriendlyId
string
OrderCanExceed
boolean
No
N/A
N/A
N/A
QuantityAvailable
integer
No
InventoryInformation
Quantity
integer
xp
object
No
N/A
N/A
N/A
xp.InvoiceUnitAmount
decimal
No
InventoryInformation
InvoiceUnitPrice.Amount
decimal
xp.InvoiceUnitCurrency
string
No
InventoryInformation
InvoiceUnitPrice.CurrencyCode
string
xp.Preorderable
boolean
No
[PreorderableComponent]
Preorderable
boolean
xp.PreorderAvailabilityDate
datetimeoffset
No
[PreorderableComponent]
PreorderAvailabilityDate
datetimeoffset
xp.PreorderedQuantity
integer
No
[PreorderableComponent]
PreorderedQuantity
integer
xp.PreorderLimit
integer
No
[PreorderableComponent]
PreorderLimit
integer
xp.Backorderable
boolean
No
[BackorderableComponent]
Backorderable
boolean
xp.BackorderAvailabilityDate
datetimeoffset
No
[BackorderableComponent]
BackorderAvailabilityDate
datetimeoffset
xp.BackorderedQuantity
integer
No
[BackorderableComponent]
BackorderedQuantity
integer
xp.BackorderLimit
integer
No
[BackorderableComponent]
BackorderLimit
integer
Price Schedules
As price schedules only support the equivalent of static list pricing of XC’s sellable items, this data mapping only covers this scenario.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
OwnerID
string
No
N/A
N/A
N/A
ID
string
No
SellableItem [ListPricePolicy].Prices
FriendlyId CurrencyCode
string string
Name
string
Yes
SellableItem [ListPricePolicy].Prices
FriendlyId CurrencyCode
string string
ApplyTax
string
No
N/A
N/A
N/A
ApplyShipping
boolean
No
N/A
N/A
N/A
MinQuantity
integer
No
N/A
N/A
N/A
MaxQuantity
integer
No
~[LineQuantityPolicy]
Maximum
decimal
XC stores this in the environment policies.
UseCumulativeQuantity
boolean
No
~[RollupCartLinesPolicy]
Rollup
boolean
XC stores this in the environment policies.
RestrictedQuantity
boolean
No
N/A
N/A
N/A
PriceBreaks
array
No
N/A
N/A
N/A
PriceBreaks.Quantity
integer
No
N/A
N/A
N/A
Set to 1.
PriceBreaks.Price
float
No
[ListPricePolicy].Prices
Amount
decimal
For a given price in the [ListPricePolicy].Prices array.
Currency
string
No
[ListPricePolicy].Prices
CurrencyCode
string
For a given price in the [ListPricePolicy].Prices array.
In this article, we will review and compare Sitecore Experience Commerce customers and OrderCloud buyer users 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.
Customers
The Customer to Storefront Association
In an XC SXA implementation, customer accounts are registered under a security domain, which can be configured in the Content Editor on the /sitecore/Content/<tenant>/<site>/Settings/Site Grouping/<storefront> item.
Customers can only be registered to a single security domain and will not be accessible in storefronts configured to a different domain. A separate customer account would need to be created under the other security domains, but it would have no knowledge or relationship to accounts across domains. However, a security domain can be registered to multiple storefronts allowing a customer to share an account across storefronts.
In OrderCloud, customers can be represented as buyer users, which are registered under buyer companies, and can only belong to a single buyer company. This can be compared directly to the relationship between security domains and customers.
The relationship of a buyer to an OrderCloud storefront is not tightly coupled like the SXA storefront. Access to an OrderCloud storefront is managed through API clients, security profiles and their assignments to buyers. See Getting Started > Establishing API Access for more information.
The Customer to Catalog Association
Buyers also contain a DefaultCatalogID property, which will create an associated catalog with an ID matching the buyer ID if not specified during the creation of a buyer. While it may seem like this limits Buyer A to a single catalog (Catalog A), multiple catalogs can be assigned via OrderCloud’s catalog assignments, which matches XC’s equivalent in supporting both Catalog A and Catalog C associations to Security Domain A via storefronts (figure 4).
The DefaultCatalogID property will be utilised in certain APIs when a catalogID is not supplied in their request, however this can be overridden. For now, it is only important to understand that this is not a limiting factor in OrderCloud functionality for migration of data or functionality.
OrderCloud User Groups
OrderCloud also allows buyer users to be assigned to one or more buyer user groups, which can be used to supersede assignments to buyer users in bulk, e.g. provide access to special pricing for VIP buyer users.
Over in XC, a common customisation is an implementation of customer groups to assign customers in order to provide customer-group specific pricing, promotions, etc. While the implementation details may have the customer group represented as a separate custom entity or a property on a customer, conceptually both approaches achieve the same outcome (figure 6) and are on par with OrderCloud’s architecture (figure 5), allowing a seamless transition path to OrderCloud.
Customer Addresses
In XC, customers have explicit addresses associations as the address component lives on the customer entity. The IsPrimary flag is used to allow a default address selection in implementations.
To bring across customer addresses into OrderCloud, figure 8 shows that we can create buyer user addresses, via the /me/addresses resource, creating a custom IsPrimary flag in the buyer address xp.
Buyer user addresses, also contain Shipping and Billing properties, which can facilitate filtering addresses for the purpose of being retrieving and setting for an order’s shipping address or billing address respectively. As the SXA Storefront allows customer addresses to be used for both of these addresses, these flags should also be set to true.
Data Mapping
With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.
In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.
OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.
Buyers
The DefaultCatalogID property will be reviewed further during the catalog analysis article.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
ID
string
No
Customer
Domain
string
Active
string
Yes
N/A
N/A
N/A
Set to true by default.
Name
string
No
Customer
Domain
string
DefaultCatalogID
string
Yes
N/A
N/A
N/A
Assign to an existing catalog or PATCH later.
xp
object
No
N/A
N/A
N/A
Any custom fields can be mapped to xp.
Buyer Users
There are a few properties in OrderCloud are required while not mandatory in the SXA Storefront, so considerations for handling these properties will need to be made in these instances, e.g. applying fallback values.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
buyerID
string
Yes
Customer
Domain
string
Is a resource parameter, not body property.
ID
string
No
Customer
FriendlyId
string
Username
string
Yes
Customer
LoginName
string
Password
string
No
N/A
N/A
N/A
Password should not be migrated.
FirstName
string
Yes
Customer
FirstName
string
Not a mandatory field in SXA, so a fallback value will need to be populated.
LastName
string
Yes
Customer
LastName
string
Not a mandatory field in SXA, so a fallback value will need to be populated.
Email
string
Yes
Customer
Email
string
Phone
string
No
CustomerDetailsComponent
PhoneNumber
string
The XC PhoneNumber exists under an entity view of the CustomerDetailsComponent, so consider this a rough mapping.
TermsAccepted
string
No
N/A
N/A
N/A
Active
boolean
Yes
Customer
AccountStatus
string
Set to true where AccountStatus == "ActiveAccount"
xp
object
No
N/A
N/A
N/A
Any custom fields can be mapped to xp.
Buyer User Addresses
OrderCloud only stores the ISO 3166-1 alpha-2 2-letter country code. Retrieving additional country details, such as country name, would best be handled by custom middleware, outside of OrderCloud.
OC Property
Data Type
Required
XC Entity/Component
XC Property
Data Type
Notes
Shipping
boolean
No
N/A
N/A
N/A
Set to true
Billing
boolean
No
N/A
N/A
N/A
Set to true
FirstName
string
No
AddressComponent
FirstName
string
SXA Storefront does not capture FirstName. May wish to use Customer.FirstName instead.
LastName
string
Yes
AddressComponent
LastName
string
SXA Storefront does not capture LastName. May wish to use Customer.LastName instead.
Street1
string
Yes
AddressComponent
Party.Address1
string
Street2
string
No
AddressComponent
Party.Address2
string
City
string
Yes
AddressComponent
Party.City
string
State
string
Yes
AddressComponent
Party.StateCode
string
Can also use Party.State for full state name, depending on requirement.
Zip
string
Yes
AddressComponent
Party.ZipPostalCode
string
Country
string
Yes
AddressComponent
Party.CountryCode
string
Phone
string
No
AddressComponent
Party.PhoneNumber
string
Will be empty in SXA Storefront default implementation. May wish to use Customer.[CustomerDetailsComponent].PhoneNumber instead.