Part 2 – Extending EPiServer Tracking API for In-Store orders

In the previous post in this series, we walked through EPiServer Tracking API and how we can customise the data tracked.

In this post we’re going to explore techniques for extending the Tracking API to customers interacting with our brand in store.

Sourcing In-Store data

Retailers will typically record in-store and online orders in their ERP (Enterprise Resource Planning) system of choice. For many retailers customer loyalty schemes will be the common denominator in identifying orders across in-store and online channels.

Typically a brand will either have ERP customisation capabilities in house or with a trusted partner. The ERP partners role in this integration will be to export in store orders so that we can track that data in the EPiServer Profile Store.

The capabilities of the ERP in question will likely dictate the nature of the in-store order integration but where possible it’s advisable to use some type of service bus to manage message synchronisation between systems.

Azure Service Bus Topics

An Azure Topic is similar to a standard service bus queue but it can have a number of independent receiving subscriptions.

Service-Bus-Topic

The reason i recommend a Topic over a queue for this particular scenario is to keep the solution as scalable as possible. You will find in-store order data can be extremely useful in a number of places. For example how useful would it be for your email marketing platform for know a customers last in store location and purchase date.

You can easily create an Azure Function to subscribe to an Order Topic and send the order data to the profile store. The following code is a very basic example of an Azure Function that read messages from the Topic and processing using an implementation of an IOrderService interface.


public static class OrdersFunction
{
    [FunctionName("OrdersFunction")]
     public static void Run(

        [ServiceBusTrigger("orders", "orderprocessing", AccessRights.Manage, Connection = "SBConn")]string myQueueItem,
        [Inject]IOrderService orderService,
        ExecutionContext context)

        {
            var orderDto = JsonConvert.DeserializeObject(myQueueItem);

            orderProcessor.ProcessOrder(orderDto);
        }
    }
}

Order Processor

The order processor will need to retrieve relevant data from the loyalty card providers API, process and send to the profile store as a Tracking event. The following sequence diagram reflects a simplistic flow.

Blog Post - Order To Profile Store

Often loyalty card provider API’s will expose a GetCustomerByLoyaltyCard type method that you can use to retrieve data like email address as this will typically be on the original registration form the customer fills out when joining the program.

In this case we can send the tracking event knowing that we can use the customers email address to associate the tracking event with the customer. Otherwise if the loyalty card number is saved against the Customer Contact in EPiServer, we can simply retrieve the customer data from there.

Sending the Tracking Event to Profile Store

First create a TrackingEvent DTO as follows to match the EPiServer object:


  public class TrackingEventDto
    {
        public User user { get; set; }
        public object payload { get; set; }
        public string deviceId { get; set; }
        public string eventType { get; set; }
        public string value { get; set; }
        public DateTime eventTime { get; set; }
        public string scope { get; set; }
    }

    public class User
    {
        public string name { get; set; }
        public string email { get; set; }
    }

When populating the TrackingEventDto, ensure that scope is set to the same value as TrackingEvent on the website. This is essential so that one customer profile is created for in store and online interactions. You can get this value in the EPi Visitor Intelligence UI or else ask EPiServer to confirm

The TrackingEvent object might be populated as below:


  var trackingEvent = new TrackingEventDto
  {
     deviceId = "InStoreDevice",
     eventTime = orderDto.Date,
     user = new User { email = orderDto.EmailAddress },
     eventType = "StorePurchase",
     value = "StorePurchase",
     payload = orderDto,
     scope = "Default"
}; 

Once the TrackingEvent is created, you can send to the Profile Store API:

 public void SendTrackingEvent(TrackingEventDto trackingEventDto)
 {
    if (!_settings.EnableTrackEvents)
    {
       return;
    }

    var restClient = new RestClient("https://track-emea01.profilestore.episerver.net/api/v1.0/Track");
    var request = new RestRequest(Method.POST);
    var json = JsonConvert.SerializeObject(trackingEventDto);

    request.AddHeader("Ocp-Apim-Subscription-Key", _settings.EpiserverTrackingEventsKey);
            request.AddParameter("application/json", json, ParameterType.RequestBody);
    var response = restClient.Execute(request);

    if (!response.IsSuccessful)
    {
        throw new ApplicationException($"Tracking API response: {response.Content} {response.ErrorMessage}");
     }
 }

Next Post

In the next and final post in the series, we’ll use the in-store and online data we are collecting in Profile Store.

We will write a KQL (Kusto Query Language) query to create an example Filter Definition against the Profile Store ADX database that enables marketers using EPiServer Visitor Intelligence to create Segments of customers who have viewed products online and proceeded to buy in-store.

Very powerfully these Segments can then be used to target customers with personalised web experiences and marketing campaigns.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s