2014-01-15


  

In this tutorial, we will use Magento’s powerful shipping-method code abstraction to create a shipping carrier. We will create two shipping methods that provide a fixed shipping price, allow for free shipping promotions, define logic based on an item’s weight and, finally, make it all configurable in the admin panel.

We will cover the following:

Extend the abstract shipping class and implement the required methods.

Make the shipping method configurable in Magento’s admin panel.

Work with promotions to allow for free shipping.

Allow tracking codes to be set against an order.

Before We Start

This tutorial assumes that you are familiar with how to create a Magento module. If you are not, please first refer to an earlier tutorial in this series, “The Basics of Creating a Magento Module.” To begin, you will need a Community or Enterprise installation of Magento, either locally or on a server that you are able to access.

The logic we will implement in this tutorial could be client-specific, so we will implement our module as a “local module” and, therefore, create it in app/code/local. Let’s start by creating the following file structure:

Now we can create SmashingMagazine_MyCarrier.xml:

Notice the dependency on the shipping module. This ensures that our SmashingMagazine MyCarrier module will load after the Mage Shipping module, and it will throw an error if the Mage Shipping module has been disabled.

Carriers, Methods, Requests And Results

Before continuing, we should understand the terminology that Magento uses throughout its shipping abstraction. A “carrier” represents a shipping carrier in the sense you would expect (DPD, FedEx, etc.). Each carrier has one or many shipping methods, which contain the carrier code, the carrier title, the method code, the method title, a price to be paid by the customer and a cost of shipping to the retailer (optional).

During the checkout process, Magento creates a shipping-rate “request” object that contains all of the shipping information. The request can be used to determine which rates apply. For example, an “express” shipping method might not apply to orders under $10. All applicable rates are then “appended” to a shipping-rate “result” object, which generates a list of methods for the customer to choose from.

The following list names these concepts defined above, along with their representation as Magento classes:

Request
Mage_Shipping_Model_Rate_Request

Result
Mage_Shipping_Model_Rate_Result

Method
Mage_Shipping_Model_Rate_Result_Method

Carrier

Any class that extends the abstract class Mage_Shipping_Model_Carrier_Abstract and implements the interface Mage_Shipping_Model_Carrier_Interface

Extending The Shipping Abstract

To create our shipping carrier, we need to extend Mage_Shipping_Model_Carrier_Abstract, implement Mage_Shipping_Model_Carrier_Interface and add the required abstract methods.

The most important method is collectRates. This is the method that receives a shipping request, appends applicable shipping methods and returns a shipping result.

Copy the following code into app/code/local/SmashingMagazine/MyCarrier/Model/Carrier.php:

This is the skeleton for a shipping method class, but it is pretty useless because we have no shipping methods.

Let’s start by hardcoding a method. This method will be called “standard” and have a price of $9.99. For now, we will assume there is no cost to the retailer.

Now we are just one step away from a working shipping method — the module configuration file.

Module Configuration

The module configuration has the standard structure (as detailed in “The Basics of Creating a Magento Module”). Copy the following into app/code/local/SmashingMagazine/MyCarrier/etc/config.xml:

This default configuration “registers” the model we have just created as a shipping carrier. As you may know, Magento merges all of its configuration XML together and caches the result (if the cache is enabled). When a customer loads the shipping-method list, Magento loops through all of the carriers in the carriers node of the configuration and loads the shipping methods from the models determined by the “active” carriers.

We should now be able to see our shipping method in the checkout.

Making It Configurable

We have already specified the default configuration for this module. So, let’s make our module configurable in the admin panel by copying the following into app/code/local/SmashingMagazine/etc/system.xml:

These fields are visible in the admin panel by navigating to System → Configuration → Shipping Method → Smashing Magazine Carrier.

Using Multiple Shipping Methods

Express Shipping

So far, we have added a standard shipping method for the price of $9.99. However, the customer may wish to pay more to receive their order faster. The following code creates a shipping rate with a higher price and different shipping code:

To make this shipping rate appear next to the standard rate that we created earlier, we will need to modify the code in the collectRates method to append the new rate. Add the following before the return statement:

Finally, add the shipping method to the allowed methods array in getAllowedMethods:

Free Shipping

Many websites offer free shipping when a customer spends over a certain amount or satisfies certain conditions. We need to be able to do the same here. In Magento, you can set up a “Shopping Cart Rule.” With it, you can specify a set of conditions and define actions if those conditions are met; one of those actions is free shipping.

If free shipping is available for a customer, then the request object will populated with is_free_shipping set to 1. We need to check for and handle this possibility in our shipping method. Add the following before the return statement in the collectRates method:

Add the following code to app/code/local/SmashingMagazine/MyCarrier/Model/Carrier.php:

Remember to add the method to the allowed methods array:

Taking It A Bit Further

Tracking Deliveries

Tracking numbers may be added to shipments through either the admin panel or an API. But to make our shipping methods visible in the admin panel, we will have to overwrite the isTrackingAvailable method in the abstract to return true.

Add the following method to the end of SmashingMagazine_MyCarrier_Model_Carrier.

You should now see the shipping carriers and methods available in the delivery courier drop-down menu when you try to place a shipment in the admin panel.

Using the Weight

Earlier, we added a more expensive express shipping method. But heavier items that require complex shipping arrangements might not be available for next-day delivery. We can check for this using the weight attribute of the request object by wrapping the code that appends the shipping method to the shipping result:

Notice that we have added a reference to the configuration. To make this appear in the admin panel, we need to add the following XML to the app/code/local/SmashingMagazine/MyCarrier/etc/system.xml file in the fields node:

Summary

With a relatively small amount of code, we have been able to define our own shipping logic that integrates with checkout, the admin panel and even the shopping-cart promotions. You can learn much more about creating shipping modules in Magento by looking at the examples in the core files — namely, Mage_Usa and Mage_Shipping.

I welcome any questions and would love to hear your feedback in the comments area below.

(al, ea)

© Matthew Haworth for Smashing Magazine, 2014.

Show more