Using Custom Data to Include Extra Shipment Information


Shipping is an important part of any e-commerce site that sells physical items. Using shipping carriers and shipping options, you can integrate companies’ shipping options with your store. Some companies may return additional information about product shipments that you might want to display to customers, such as delivery date, package attributes, or the address the package will be shipped from. If there is a piece of information about the shipment that doesn't have a corresponding field in Kentico, you can still pass that data to the customer using the CustomData fields in many of the classes.

The following example, written for Kentico 11 and 12, shows how to use a shipping provider to display when each shopping cart item will be delivered. Please note that code provided in this article is a proof of concept, and should not be considered official. Make sure you have backups of your application and database before adding custom code.

The first step is to save some identifying data that can be used to find and alter the shopping cart items during the shipping calculation. To accomplish this, create a global event handler that writes a Shopping Cart Item’s GUID into its custom data. This may seem a bit redundant, but the custom data can be transferred between different object types. Later on, we’ll use this identifier to retrieve the shopping cart item from related objects.

[assembly: RegisterModule(typeof(ShippingLibrary.CustomCartItemHandler))] namespace ShippingLibrary { class CustomCartItemHandler : Module { public CustomCartItemHandler() : base("CustomCartItemHandler") { } protected override void OnInit() { base.OnInit(); ShoppingCartItemInfo.TYPEINFO.Events.Insert.Before += ShoppingCartItem_InsertBefore; } private void ShoppingCartItem_InsertBefore(object sender, ObjectEventArgs e) { ShoppingCartItemInfo cartItem = (ShoppingCartItemInfo)e.Object; cartItem.CartItemCustomData.SetValue("CartItemGUID", cartItem.CartItemGUID); } } }

The GUID in the custom data will be transferred to the CalculationRequestItem generated for this cart item automatically. However, to transfer it into the delivery items processed by our payment provider, we’ll need to add some code. Specifically, we’ll need to override the GetItemCustomDataContainers method of the DefaultDeliveryBuilder class, which is empty by default.

using System.Collections.Generic; using CMS; using CMS.Base; using CMS.Ecommerce; [assembly: RegisterImplementation(typeof(IDeliveryBuilder), typeof(ShippingLibrary.CustomDeliveryBuilder))] namespace ShippingLibrary { class CustomDeliveryBuilder : DefaultDeliveryBuilder { protected override void GetItemCustomDataContainers(List<IDataContainer> containers, CalculationRequestItem requestItem) { containers.Add(requestItem.ItemCustomData); } } }

Now, in our shipping provider implementation, we’ll be able to access the shopping cart items corresponding to the delivery items being shipped. We can parse through the response from the shipping provider’s API to find additional information aside from the price. The following code pulls the expected arrival date for each item from a dummy JSON response, and writes that information to the custom data.

public decimal GetPrice(Delivery delivery, string currencyCode) { if (CanDeliver(delivery) && delivery.DeliveryAddress != null) { JToken response = DummyShippingCompany.GetShippingResponse(delivery, currencyCode); foreach (JToken item in response["ShipmentItems"]) { /* Not all shipping APIs allow you to send some kind of external ID to identify * your items, so you may need to do something like this to figure out which * items are being referred to in the api's response.*/ DeliveryItem di = delivery.Items.Where(i => i.Product.SKUID == item["ItemSku"].ToInteger(0)).First(); //retreive the shopping cart and write it's expected delivery date to the custom data ShoppingCartItemInfo sci = ShoppingCartItemInfoProvider.GetShoppingCartItemInfo(di.CustomData.GetValue("CartItemGUID").ToGuid(Guid.Empty)); sci.CartItemCustomData.SetValue("DeliveryDate", item["ItemExpectedArrival"].ToString()); sci.Update(); } return Decimal.Parse(response["ShipmentCost"].ToString()); } return 0; }

Now that the expected delivery date is stored in the custom data, we can display it on the shopping cart review page before the user pays. The following screenshots will show a demonstration of this code from a simple MVC site, which is available on GitHub.

In the world of microservices, APIs, and specialized software, systems of all types are battling to give customers the smoothest experience possible in the online shopping process. One way you can do this is to give your customers peace of mind by providing extra information that Shipping APIs return about their packages using custom data in Kentico. Another article, going into a bit more detail about how custom data fields work, is coming soon!

Share this article on   LinkedIn

Matthew Sandstrom

Hello! I'm a Support Engineer here at Kentico, specializing in E-Commerce and Upgrades.