2

We need to get location and user-specific prices in the SXA Storefront. These prices should also be available when calling the Commerce Engine directly for headless scenarios.

We add XDB facets to the contact on the Storefront side with location and a user specific id. We can retrieve these facets in custom versions of the list price and sell price calculation blocks in the Commer Engine project:

.ConfigurePipeline<ICalculateSellableItemListPricePipeline>(builder => builder.Replace<CalculateSellableItemListPriceBlock, ExternalSellableItemListPriceBlock>())
.ConfigurePipeline<ICalculateSellableItemSellPricePipeline>(builder => builder.Replace<CalculateSellableItemSellPriceBlock, ExternalSellableItemSellPriceBlock>())
.ConfigurePipeline<ICalculateVariationsListPricePipeline>(builder => builder.Replace<CalculateVariationsListPriceBlock, ExternalVariationsListPriceBlock>())
.ConfigurePipeline<ICalculateVariationsSellPricePipeline>(builder => builder.Replace<CalculateVariationsSellPriceBlock, ExternalVariationsSellPriceBlock>())

If we try to retrieve customer-specific information from the commerce context, that it is empty in the above blocks. CommerceContext.ContactId is empty...

After some investigation into for example ShopperId on the Storefront side we see the following:

ShopperId

Looking at usage:

ShopperId usage

So only the following Storefront side pipeline blocks do set the ShopperId (and ContactId):

Sitecore.Commerce.Engine.Connect.Pipelines.Orders.GetVisitorOrders
Sitecore.Commerce.Engine.Connect.Pipelines.Orders.TranslateOrderToEntity
Sitecore.Commerce.Engine.Connect.Pipelines.Carts.TranslateCartToEntity

So these headers (described in https://doc.sitecore.com/developers/100/sitecore-experience-commerce/en/service-api-headers.html) are NOT set by the pipelines used in showing products or product details.

Is there a way to add these headers ourselves (like is done in the above pipeline blocks) in for example the processSearchItems pipeline as used for processing the SXA search result items in the case of a product search (used for the product lister pages)?

If we look at pipeline Sitecore.Commerce.Engine.Connect.Pipelines.Orders.GetVisitorOrders we see:

GetVisitorOrders

And in the method TranslateOrderHeaders we see:

CommerceOrderHeader commerceOrderHeader = EntityFactory.Create<CommerceOrderHeader>("OrderHeader");
commerceOrderHeader.ExternalId = item.Id;
commerceOrderHeader.ShopName = item.ShopName;
commerceOrderHeader.Name = item.Name;
commerceOrderHeader.OrderID = item.OrderConfirmationId;
commerceOrderHeader.TrackingNumber = item.OrderConfirmationId;
commerceOrderHeader.Status = item.Status;
commerceOrderHeader.OrderDate = item.OrderPlacedDate.DateTime;

Don't know if this translates to HTTP headers in Commerce Engine requests, but seems to be in the right direction...

1
  • We are a bit further in the meantime... product overview pages use SXA search, with a block in the processSearchItems pipeline to retrieve prices. Call is a XHR (AJAX) call from Storefront page. In this call the Tracker is disabled (and returns null), so the ShopperId (retrieved from the Tracker) is not available. This results in no ShopperId header placed on call to the commerce engine. We think this is a bug, but could fix it with an extra block in the pipeline to start the Tracker. Next problem is that ShopperId from SXA Search pipeline is different from product details page... (other bug?) Jan 28, 2021 at 22:22

1 Answer 1

0

As described in the comment the solution is to inject a pipeline processor in the ProcessSearchItems pipeline in Sitecore XP side:

EnableTracker.cs:

using Sitecore.Analytics;
using Sitecore.XA.Feature.Search.Pipelines.ProcessSearchItems;

namespace Feature.SCP.CommerceCatalog.Pipelines.ProcessSearchItems
{
    /// <summary>
    /// The Tracker must be started to enable the communication of the ShopperId header
    /// to the commerce engine. The Tracker is not started in the case of the SXA product search
    /// executed as an AJAX call from Storefront. During the SXA product search the 
    /// ProcessSearchItems pipeline is executed, and before the 
    /// Sitecore.Commerce.XA.Feature.Catalog.Pipelines.Search.PrepareSearchItems processor
    /// the Tracker must be started.
    /// </summary>
    public class EnableTracker : ProcessSearchItemsProcessor
    {
        public override void Process(ProcessSearchItemsArgs args)
        {
            if (Tracker.Current == null && Tracker.Enabled)
            {
                Tracker.StartTracking();
            }
        }
    }
}

And register it BEFORE Sitecore.Commerce.XA.Feature.Catalog.Pipelines.Search.PrepareSearchItems where the prices for found products are retrieved:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <pipelines>
            <group groupName="experienceAccelerator">
                <pipelines>
                    <processSearchItems>
                        <processor type="Feature.SCP.CommerceCatalog.Pipelines.ProcessSearchItems.EnableTracker, Feature.SCP.CommerceCatalog" patch:before="processor[@type='Sitecore.Commerce.XA.Feature.Catalog.Pipelines.Search.PrepareSearchItems, Sitecore.Commerce.XA.Feature.Catalog']" resolve="true"/>

                    </processSearchItems>
                </pipelines>
            </group>
        </pipelines>
    </sitecore>
</configuration>

The question is: is this a bug or a feature? In the default price calculation the ShopperId (which equals the contact ID) is not needed...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.