HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Shipping gateways and providers

Describes shipping gateways and providers that return the appropriate shipping charge for a cart during checkout in Optimizely Customized Commerce 13.

Two shipping gateways/providers are included by default.

  • Generic Gateway – Flat shipping rate.
  • Weight/Jurisdiction Gateway – Base price + additional fee depending on weight and shipping location.

You can add your own shipping gateway and provider. Under Shipping Providers, a Shipping Gateway is the specific class that you select (Generic Gateway or Weight/Jurisdiction Gateway).

Classes in this topic are available in the following namespaces:

  • Mediachase.Commerce.Orders. Contains IShippingGateway and IShippingPlugin.
  • Mediachase.Commerce.Catalog.Data. Contains CurrencyAdmin.
  • Mediachase.Commerce.Orders.Dto. Contains ShippingMethodDto.

See also Shipping methods.

Shipping gateways

You select a Shipping Gateway from the Shipping Provider view in the Customized Commerce Admin user interface. Configure the values for a gateway/provider in the Shipping Methods area.

  • Shipping Jurisdictions – Lets you define values for region-specific shipping rates; only used when you select the Weight/Jurisdiction Gateway, such as California.
  • Shipping Jurisdiction Groups – Group of jurisdictions; a required field when configuring Shipping Method parameters, such as Southwest region.

Shipping providers

Shipping provider classes retrieve shipping price information from one or more shipping services, such as USPS, UPS, or FedEX. Typically, a provider represents one service, for example, USPS. A provider also can represent a type of shipping situation, for example, overnight delivery. The provider can retrieve pricing for that service to determine the lowest price for a customer location. A provider can also represent other scenarios with one or more services, such as price by weight or ground shipping.

Key classes and files

  • IShippingGateway – Interface implemented in creating a shipping gateway.
  • IShippingPlugin – The same functionality as IShippingGateway but works only with the abstraction API instead of concrete classes.
  • WeightJurisdictionGateway – Example implementation.
  • GenericGateway – Example implementation.
  • CurrencyAdmin – Provides lookup for currency codes.
  • ShippingMethodDto – DTO for shipping method configuration information.
  • JurisdictionManager – Provides methods to retrieve jurisdictions.

📘

Note

IShippingPlugin is highly recommended. IShippingGateway remains to support backward compatibility.

Create shipping options

To provide shipping options during checkout, you need to add shipping methods, and each method must use a shipping provider. Follow these steps to create a custom shipping provider and method.

  1. In the solution, create a separate project to store custom business logic implementations for your application.

  2. In this project, create a class that implements from IShippingPlugin. This interface only has one method, GetRate().
    This method returns the rate for shipping associated with the IShipment 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.

    📘

    Note

    Remember to register the class with the service container as a service of IShippingPlugin.

    Example: the method's signature:

    public ShippingRate GetRate(Guid methodId, IShipment shipment, ref string message)
    

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

    • Id – For the associated shipping method. This value is passed to the method (first parameter).

    • Money – The price connected to the shipping company. It should correspond to one of the currencies associated with the application.
      To retrieve currency information from the database, use the CurrencyAdmin object.

    • Name – The name of the shipping method associated with the shipping method ID.

      Example: retrieving the shipping method ID

    // Look up payment method
     ShippingMethodDto methods = ShippingManager.GetShippingMethods(Thread.CurrentThread.CurrentCulture.Name); 
     // the methodId was passed into the method as one of the method parameters
     ShippingMethodDto.ShippingMethodRow row = methods.ShippingMethod.FindByShippingMethodId(methodId);
     
     string name; 
     if (row != null) 
       { 
        name = row.Name; 
       } 
     else 
       { 
        name = ""; 
       }
    
  3. Copy the .dlls associated with the project where the shipping gateway is implemented to the bin folders of the Commerce Manager and public web sites.

  4. In Commerce Manager, go to Admin > Order System > Shipping Providers.

  5. Click New.

  6. Enter a name for the gateway and a system keyword. The keyword must be unique.

  7. Select the gateway that implements IShippingPlugin, which  you created in the previous step.

  8. Click OK.

  9. Go to Order System > Shipping Methods > /[applicable language].

  10. Click New.

  11. 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.

  12. Click OK.

Add a configuration tab

You can create a configuration tab for your shipping method. This lets you use multiple instances of a custom shipping provider then set custom parameters for each instance. To do this, create a user control that renders in Commerce Manager as the Parameters tab for a shipping method.

The custom control creates/updates/retrieves shipping data about different circumstances based on weight, number of items, and jurisdiction that your custom shipping gateway uses to calculate shipping rate. Follow these steps to create a configuration tab.

  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 required property.

    Example: methods of IGatewayControl

    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 passed to 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 shipping rate scenarios that you store for the shipping method.

    The code in the control simply needs to update the ShippingMethodCase rows to reflect each scenario the user adds in Commerce Manager. Commerce Manager takes care of retrieving the data and saving it 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 is not used by the framework during the checkout.

    Each data row includes these fields:

    • Total – A number which can represent weight, item count, or another number indicator.

    • Charge – Represents the cost.

    • StartDate, EndDate – Lets you specify the date range of the rate validity.

    • JurisdictionGroupId – Maps to a jurisdiction group configured in the Jursidictions/Jurisdiction Groups section of Commerce Manager.

    • ShippingMethodId – The ID of the shipping method.

      You can retrieve jurisdiction groups using the JurisdictionManager.

      Example: retrieving jurisdiction groups

    // 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.

    Example: minimum code for SaveChanges() and LoadObject() methods

    _shippingMethodDto = dto as ShippingMethodDto;
    

    The _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.

    Example: adding and retrieving data from ShippingMethodDto

    // 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, which is used internally by the framework.

    Example: implementing ValidationGroup

    public string ValidationGroup { get; set; }
    

    a. Build your shipping provider project containing the configuration control. You may separate the shipping provider and the configuration control. There is no need for them to be in the same project except for convenience.
    b. Add a reference to your shipping provider method in the Commerce Manager project, if this has not been done.
    c. Copy ConfigurateShippingMethod.ascx to a new folder under the Shared folder location Apps/Order/Shipping/Plugins/Shipping Method Name. The shipping method name does not have to be the name of the shipping provider; it can be more informational, representing a shipping provider or shipping type, for example, FedEx24Hour.
    d. Build the site.
    e. Go to Commerce Manager > Administration > Order System > Shipping > Shipping Methods > Language.
    f. Click New.
    g. 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 and set it to active.
    h. Save the shipping method, re-open, and navigate to the parameters tab. You should see the new shipping provider.
    i. Enter parameter information and save the shipping method.

Access shipping provider information

The ShippingManager class lets you retrieve the appropriate case rows, depending on your scenario. This code is used in your GetRate method, or in a method called by GetRate().

Example: retrieving shipping provider information

// 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 information about using this DataTable, see the WeightJurisdictionGateway.cs GetRate() implementation.

Packages

You can create packages and associate them with shipping providers. In this way, you can define generic package sizes, associate them with a product, then map this generic package to a provider-specific package. For example, the generic "LARGE" package can map to a 25 Kg Large FedExbox and a USPS Large Flat Rate box.

You can associate packages 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 in Commerce Manager by changing the Package property on a SKU's Pricing/Inventory tab.

To retrieve package information for a shipping provider, use ShippingMethodDto. This contains two typed data tables with the package information:

  • ShippingPackage – Contains relationship information between shipping providers and packages.
  • Package – Contains all package information.

Example: 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
        }
      }