You are here: Order System > Checkout Process > Shipping Options > Creating a Shipping Gateway

Creating a Shipping Gateway

Overview

Shipping gateways/providers are used to provide shipping rates for a cart. They're used in EPiServer Commerce to return the appropriate shipping charge for carts during checkout. EPiServer Commerce includes two shipping gateway/providers. One of them (Generic provider) returns a flat fee for all shipments. The other provider (Weight/Jurisdiction Gateway) allows shipping rates to be set based on the shipping destination jurisdiction and shipment weight.

EPiServer Commerce also supports the ability to add your own shipping gateway.

Key Classes and Files

IShippingGateway - Interface implemented in creating a shipping gateway

WeightJurisdictionGateway - Example implementation

GenericGateway - Example implementation

CurrencyAdmin - Provides a lookup for currency codes

ShippingMethodDto - Dto for shipping method configuration information

JurisdictionManager - Provides methods to retrieve jurisdictions

How It Works

To provide shipping options during the checkout process, you need to add Shipping Methods; each method must use a shipping provider. Here are the steps to create a custom shipping provider and method:

1. If you haven’t already, create a separate project in the solution to store custom business logic implementations for your application.

2. Create a class in this project that inherits from IShippingGateway. This interface only has one method, GetRate(). This method returns the rate for shipping associated with the LineItems from the shopping cart submitted for pricing. This method provides whatever interface is required to the actual shipping services/rate provider to determine the shipping cost. Here’s the signature for the method:

public ShippingRate GetRate(Guid methodId, LineItem[] items, ref string message)

The return value is a ShippingRate instance, which contains several properties:

ShippingMethodDto methods;
ShippingMethodDto.ShippingMethodRow row;
string name;
 
//Look up payment method
methods = ShippingManager.GetShippingMethods(Thread.CurrentThread.CurrentCulture.Name);
//the methodId was passed into the method as one of the method parameters_
row = methods.ShippingMethod.FindByShippingMethodId(methodId);
 
if (row != null)
  name = row.Name;
else
  name = "";

 

3. Copy the .dlls associated with the project where the shipping gateway is implemented into the bin folders of both the Commerce Manager and Public web sites.

4. In Commerce Manager, goto the Admin tab.
5. Goto the Order System/Shipping Providers navigation node.
6. Click on the New button.
7. Enter a name for the gateway and a system keyword. The system keyword has to be unique.
8. Select the gateway which implements IShippingGateway and that you just created in the previous step.
9. Press the OK button.
10. Goto the Order System/Shipping Methods/[applicable language] navigation node.
11. Click the New button.
12. Fill in the fields for the method, including the name of the provider created in the previous step. To make the shipping method available, set IsActive to “Yes”.
13. Press the OK button.

Adding a Configuration Tab

You can also create a configuration tab for your new shipping method. This will allow you to use multiple instances of a custom shipping provider you create and then set custom parameters for each instance. To do this, you need to create a user control that will render in Commerce Manager as the Parameters tab for a shipping method. The control you create will create/update/retrieve shipping scenario data about different circumstances based on weight, number of items, and jurisdiction that your custom shipping gateway will use to calculate the shipping rate.

1. Add a new control to your custom  shipping provider project. Call the control ConfigureShippingMethod.ascx.
2. Make sure the new control inherits from OrderBaseUserControl and implements the IGatewayControl interface.
3. Add references to your project for Mediachase.Commerce.dll and Mediachase.Webconsolelib.dll
4. The IGatewayControl interface has two methods and a property required:

public interface IGatewayControl
{
  void SaveChanges(object dto);
  void LoadObject(object dto);
 
  string ValidationGroup { get;set;}
}

 

These two methods are called by Commerce Manager. The dto object that is passed into both methods is, in the case of a shipping provider configuration tab, an instance of a ShippingMethodDto.cs. This DTO contains a table, ShippingMethodCase, which holds all of the shipping rate scenarios you store for your shipping method. Your code in the control simply needs to update the ShippingMethodCase rows to reflect each of the scenarios the user adds in Commerce Manager; Commerce Manager takes care of retrieving the data and saving the data back to the database. Each shipping scenario is a row of data. The framework provides this scenario storage for your implementation. In other words, the scenario data you store for a shipping method in the ShippingMethodCase table isn't going to be used by the framework during the checkout. In each row of date include the fields :

Jurisdiction groups can be retrieved using the JurisdictionManager. Here's an example of retrieving them:

//retrieve the data; get shipping jurisdictions, not tax jurisdictions
JurisdictionDto jDto = JurisdictionManager.GetJurisdictionGroups(JurisdictionType.Shipping);
//bind to a dropdownlist
ddlJurisdiction.DataSource = jDto.JurisdictionGroup;

5. Implement the SaveChanges() and LoadObject() methods. The SaveChanges() and LoadObject() methods need to contain a minimum of this line of code :

_ShippingMethodDto = dto as ShippingMethodDto;

where _ShippingMethodDto is a class member of type ShippingMethodDto. Either in the aforementioned methods or in other event handler methods, data entered by the customer needs to be retrieved/saved to this DTO. Here are examples of adding and retrieving data from this DTO:

//Adding a row of data
    if (_ShippingMethodDto != null && _ShippingMethodDto.ShippingMethod.Count > 0)
    {
        ShippingMethodDto.ShippingMethodCaseRow row = _ShippingMethodDto.ShippingMethodCase.NewShippingMethodCaseRow();
        row.Total = Double.Parse(Weight.Text, _NumberFormat);
        row.Charge = Double.Parse(Price.Text, _NumberFormat);
        row.StartDate = StartDate.Value;
        row.EndDate = EndDate.Value;
 
        //the ShippingMethodDto will only contain one row for the ShippingMethod row, which
        //represents the shipping method information stored on the first tab of the shipping method in
        //commerce manager
        row.ShippingMethodId = _ShippingMethodDto.ShippingMethod[0].ShippingMethodId;
        row.JurisdictionGroupId = Int32.Parse(JurisdictionGroupList.SelectedValue);
 
        // add the row to the dto
        if (row.RowState == DataRowState.Detached)
            _ShippingMethodDto.ShippingMethodCase.Rows.Add(row);
    }
 
    //retrieving a row of data to populate controls
    //set the properties of the controls in the configuration
    //tab
    if (_ShippingMethodDto.ShippingMethodCase.Count > 0)
    {
        //in this scenario, we're only supporting a single row
        //to serve as a simple example
        row = _ShippingMethodDto.ShippingMethodCase.Rows[0];
        txtRate.Text = row.Charge.ToString();
        txtWeight.Text = row.Total.ToString();
        ddlJurisdiction.SelectedValue = row.JurisdictionGroupId;
    }

 

6. Implement the ValidationGroup property. For this, you can simply implement it this way. This property is used internally by the framework:

public string ValidationGroup
    {
        get
        {
            return _ValidationGroup;
        }
        set
        {
            _ValidationGroup = value;
        }
    }

 

7. Build your shipping provider project (which contains the configuration control). You may separate the shipping provider and the configuration control; there's no need for them to be in the same project except for convenience.

8. If you haven't previously added a reference to your shipping provider method, add it now to the commerce manager project.

9. Copy the ConfigurateShippingMethod.ascx into a new folder under Shared folder locationApps/Order/Shipping/Plugins/Shipping Method Name. The shipping method name doesn't have to be the name of the shipping provider; it can be more informational, representing a shipping provider or shipping type (e.g. FedEx24Hour).

10. Build the site.

11. Goto Commerce Manager/Administration/Order System/Shipping/Shipping Methods/Language.

12. Click on New button.

13. Configure the new shipping method. Select your new shipping provider from the list of shipping providers, use the same system name as you named the folder in step 9, set it to active.

14. Save the shipping method, re-open, and navigate to the parameters tab. You should see your new shipping provider.

15. Enter parameter information and save the shipping method.

Now, how do you access this information in your shipping provider? The ShippingManager class allows you retrieve the appropriate case rows, depending on your scenario. This code would be used in your GetRate method (or in a method which is called by GetRate()). Here's a code example:

//the methodId is passed into the GetRate method
DataTable casesTable = ShippingManager.GetShippingMethodCases(methodId, shippingAddress.CountryCode,
shippingAddress.State, shippingAddress.PostalCode, shippingAddress.RegionCode,
null, shippingAddress.City, weight);

For more information about how to use this DataTable, see the WeightJurisdictionGateway.cs GetRate() implementation.

Packages

You can create packages and associate them with shipping providers. That way you can have a generic package sizes defined and associated with product and then map this generic package to a provider specific package. For example generic "LARGE" package can map to 25Kg Large FedEx box and USPS Large Flat Rate box. You can associate them with shipping providers by opening a shipping provider in Commerce Manager, clicking on the Packages tab, and selecting "Add Item". You can also associate packages with SKUs by changing the "Package" property on the Pricing/Inventory tab of a SKU in Commerce Manager.

You can retrieve package information for a shipping provider by retrieving the ShippingMethodDto. The ShippingMethodDto contains two typed datatables with the package information: ShippingPackage and Package. Package contains all of the package information; ShippingPackage contains the relationship information between shipping options (AKA providers) and packages.

Here's an example of retrieving package information for a shipping provider.

Mediachase.Commerce.Orders.Dto.ShippingMethodDto shippingMethods =
  Mediachase.Commerce.Orders.Managers.ShippingManager.GetShippingMethods("en-us");
 
foreach(System.Data.DataRow row in shippingMethods.ShippingOption.Rows)
{
  //A shipping option is a shipping provider
  Mediachase.Commerce.Orders.Dto.ShippingMethodDto.ShippingOptionRow shippingProviderRow =
    (Mediachase.Commerce.Orders.Dto.ShippingMethodDto.ShippingOptionRow)row;
 
  //now you have access to packages associated with the shipping provider
  Mediachase.Commerce.Orders.Dto.ShippingMethodDto.ShippingPackageRow[] packageRows =
    shippingProviderRow.GetShippingPackageRows();
 
  //now you have access to the packages' names and id's
  //packageRows[0].ShippingPackageId
  //packageRows[0].PackageName
 
  //now you can retrieve the individual Package row with additional information
  Mediachase.Commerce.Orders.Dto.ShippingMethodDto method =
    Mediachase.Commerce.Orders.Managers.ShippingManager.GetShippingPackage(packageRows[0].PackageId);
 
  //the GetShippingPackage method just populates the Package table with the applicable shipping package
  if (method.Package.Rows.Count > 0)
  {
    Mediachase.Commerce.Orders.Dto.ShippingMethodDto.PackageRow packageRow =
      (Mediachase.Commerce.Orders.Dto.ShippingMethodDto.PackageRow)method.Package.Rows[0];
 
  //here we can retrieve the package properties
  //packageRow.Length
  //packageRow.Height
  //packageRow.Width
  //packageRow.Description
  }
 
}

 

Namespaces

Mediachase.Commerce.Orders - contains IShippingGateway
Mediachase.Commerce.Catalog.Data - contains CurrencyAdmin
Mediachase.Commerce.Plugins.Shipping - contains WeightJurisdictionGateway 
Mediachase.Commerce.Plugins.Shipping.Generic - contains GenericGateway
Mediachase.Web.Console.Interfaces - contains IGatewayControl
Mediachase.Commerce.Orders.Dto - contains ShippingMethodDto

 


Version: EPiServer Commerce 1 R2 SP2| Last updated: 2012-06-29 | Copyright © EPiServer AB | Send feedback to us