Example - Creating a shipping carrier provider

The example on this page demonstrates how to create a custom shipping carrier provider. The sample carrier provider has the following features:

  • Shipping costs are determined based on the country to which the order is shipped. The costs are defined directly in the code, without a user interface for setting the values.

    If you want to have a user interface for configuring the shipping costs (or other options), you can create a configuration tab as described in Implementing custom shipping carrier providers or create a custom table and use the custom table API to load the shipping cost values from the given table. Do not forget to set caching (you can use the CacheHelper class).

  • Shipping options that use the sample shipping carrier are available only for orders whose shipping address is in the USA, Canada or Mexico.

  • Does NOT use a packageable module for distribution to other instances. See Example - Creating a packageable module to learn how to create a module package containing custom functionality (such as the shipping carrier provider).

For custom shipping carrier provider classes, the AssemblyDiscoverable attribute is not required (the Carrier provider selector in the administration interface can find the class even without the attribute). However, we recommend adding the attribute to your custom Class Library project to ensure that other possible types of customization work correctly for you (for example registration of custom modules, interface implementations or inherited providers).

For more information, see: Adding custom assemblies

Continue by implementing the shipping carrier provider:

  1. Add a new class to the custom project, implementing the ICarrierProvider interface. For example, name the class CountryCarrierProvider.

    
    
    
     using System;
     using System.Collections.Generic;
     using System.Linq;
    
     using CMS.Ecommerce;
     using CMS.Globalization;
    
     /// <summary>
     /// Sample carrier provider that sets shipping costs based on the delivery country.
     /// The carrier allows creation of shipping options that are available for addresses in the USA, Canada and Mexico.
     /// </summary>
     public sealed class CountryCarrierProvider : ICarrierProvider
     {
         private const string NAME = "Custom carrier provider";
         private List<KeyValuePair<string, string>> services;
         private Dictionary<string, decimal> countryCosts;
    
         /// <summary>
         /// Gets a dictionary of 3-letter country codes and shipping costs.
         /// The dictionary also defines all countries where delivery is available.
         /// </summary>
         private Dictionary<string, decimal> CountryCosts
         {
             get
             {
                 return countryCosts ?? (countryCosts = new Dictionary<string, decimal>
                     {
                         { "CAN", 12.99m },
                         { "MEX", 33.33m },
                         { "USA", 5.0m }
                     });
             }
         }
    
         /// <summary>
         /// Gets the name of the carrier provider.
         /// </summary>
         public string CarrierProviderName
         {
             get
             {
                 return NAME;
             }
         }
    
         /// <summary>
         /// Returns a list of service code names and display names.
         /// </summary>
         public List<KeyValuePair<string, string>> GetServices()
         {
             return services ?? (services = new List<KeyValuePair<string, string>>
             {
                 new KeyValuePair<string, string>("CostByCountry", "Shipping cost to USA, CAN and MEX")
             });
         }
    
         /// <summary>
         /// Calculates the shipping cost of the given delivery.
         /// </summary>
         /// <param name="delivery">The shipped delivery.</param>
         /// <param name="currencyCode">The code of the currency in which the shipping price should be calculated (e.g. USD or EUR).</param>
         /// <returns>The price in the currency specified by currencyCode.</returns>
         public decimal GetPrice(Delivery delivery, string currencyCode)
         {
             if (delivery.DeliveryAddress != null)
             {
                 // Gets the 3-letter country code of the delivery's target country
                 var country = CountryInfo.Provider.Get(delivery.DeliveryAddress.AddressCountryID);
                 string countryCode = country?.CountryThreeLetterCode;
    
                 // Checks whether the shipping option is available for the specified country code
                 if (CountryCosts.ContainsKey(countryCode))
                 {
                     // Returns the shipping price converted to the specified currency
                     return CurrencyConverter.Convert(CountryCosts[countryCode], "USD", currencyCode, delivery.ShippingOption.ShippingOptionSiteID);
                 }
             }    
    
             return 0;
         }
    
         /// <summary>
         /// Checks whether the shipping option is available for the specified shipping address.
         /// The only supported shipping addresses are to USA, Canada or Mexico.
         /// </summary>
         public bool CanDeliver(Delivery delivery)
         {
             // Checks whether a shipping option and delivery address is assigned to the delivery
             // and evaluates whether the shipping option is available for the specified shipping country
             if ((delivery.ShippingOption == null) || (delivery.DeliveryAddress == null) || !CanDeliverToCountry(delivery.DeliveryAddress))
             {
                 return false;
             }
    
             // Returns true if the carrier provider supports the shipping service
             return SupportsService(delivery.ShippingOption.ShippingOptionCarrierServiceName);
         }
    
         /// <summary>
         /// Returns Guid.Empty. This carrier does not have a configuration interface.
         /// </summary>
         public Guid GetConfigurationUIElementGUID()
         {
             return Guid.Empty;
         }
    
         /// <summary>
         /// Returns Guid.Empty. This carrier does not have a carrier service configuration interface.
         /// </summary>
         public Guid GetServiceConfigurationUIElementGUID(string serviceName)
         {
             return Guid.Empty;
         }
    
         /// <summary>
         /// Returns true if the carrier provider can handle the specified shipping service.
         /// </summary>
         private bool SupportsService(string serviceName)
         {
             return GetServices().Any(item => item.Key == serviceName);
         }
    
         /// <summary>
         /// Checks whether the package can be delivered to the selected country.
         /// </summary>
         private bool CanDeliverToCountry(AddressInfo address)
         {
             // Gets the 3-letter country code from the delivery address
             var country = CountryInfo.Provider.Get(address.AddressCountryID);
             string countryCode = country?.CountryThreeLetterCode;
    
             // Returns true if the country code is found among the codes supported by the carrier provider
             return CountryCosts.ContainsKey(countryCode);
         }
     }
    
    
     
  2. Save all changes and rebuild your solution.

Register the custom carrier in the Xperience administration interface:

  1. Open the Store configuration application (or Multistore configuration).
  2. Select the Shipping -> Carriers tab.
  3. Click New carrier.
  4. Type a Name for the carrier, and choose your custom assembly and ICarrierProvider class via the Carrier provider selector.
  5. Click Save.

You can now create shipping options that use the custom carrier and its “Shipping cost to USA, CAN and MEX” service. If customers create an order with products that need shipping, and their delivery address is in the USA, Canada or Mexico, the given shipping options are available for selection and their cost is calculated by the custom shipping carrier provider.