Example - Creating a shipping carrier provider with costs based on the country

In this example, you can learn how to create a custom shipping carrier provider which calculates the shipping cost based on the country to which the package is shipped. This shipping carrier provider:

If you place the Customer address web part (where the customer enters the shipping address) and the Shipping option selection web part (where the customer selects the desired shipping option) on the same page, you need to select the Propagate changes on postback field while editing the Customer address web part. This ensures that when the customer changes the shipping country, the shipping options that the Shipping option selection web part offers are recalculated and the web part then offers the shipping options available in the currently selected country.

To implement the shipping carrier provider example:

  1. Open your web project in Visual Studio.

  2. Create a new class in the App_Code folder (or Old_App_Code on web application installations). For example, name the class CountryCarrierProvider.cs.

    
    
    
     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using CMS;
     using CMS.Ecommerce;
    
     [assembly: RegisterCustomClass("CountryCarrierProvider", typeof(CountryCarrierProvider))]
    
     /// <summary>
     /// Sample carrier provider providing shipping costs based on the delivery country.
     /// The cost is charged for deliveries to USA, Canada and Mexico.
     /// </summary>
     public sealed class CountryCarrierProvider : ICarrierProvider
     {
         private const string NAME = "{$com.countrycarrierprovider.name$}";
         private List<KeyValuePair<string, string>> mServices;
         private Dictionary<string, decimal> mCountryCosts;
    
         /// <summary>
         /// Gets a dictionary of 3-letter country codes and shipping costs. 
         /// The dictionary contains all countries where the delivery is possible.
         /// </summary>
         private Dictionary<string, decimal> CountryCosts
         {
             get
             {
                 return mCountryCosts ?? (mCountryCosts = 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 mServices ?? (mServices = 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)
         {
             // Gets the 3-letter country code of the target country of the delivery.
             var countryCode = delivery.DeliveryAddress.GetCountryThreeLetterCode();
    
             // 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>
         /// <param name="delivery">The shipped delivery.</param>
         public bool CanDeliver(Delivery delivery)
         {
             // Checks whether a shipping option and a delivery address is assigned to the delivery
             // and checks 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 or need any configuration tab.
         /// </summary>
         public Guid GetConfigurationUIElementGUID()
         {
             return Guid.Empty;
         }
    
         /// <summary>
         /// Returns Guid.Empty. Service configuration is not required.
         /// </summary>
         /// <param name="serviceName">Service name.</param>
         public Guid GetServiceConfigurationUIElementGUID(string serviceName)
         {
             return Guid.Empty;
         }
    
         /// <summary>
         /// Returns true if the carrier provider can handle the selected shipping service.
         /// </summary>
         /// <param name="serviceName">The name of the used shipping service.</param>
         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>
         /// <param name="address">The delivery address.</param>
         private bool CanDeliverToCountry(IAddress address)
         {
             // Gets the 3-letter country code from the delivery address.
             var countryCode = address.GetCountryThreeLetterCode();
    
             // Returns true if the country code is found among country codes supported by the carrier provider.
             return CountryCosts.ContainsKey(countryCode);
         }
     }
    
    
     
  3. Save the CountryCarrierProvider.cs file.

If customers now order a product that needs shipping and their delivery address is in the USA, Canada or Mexico, the customers are able to select the shipping option based on this shipping carrier provider.