Creating custom shipping method in magento

This tutorial is dedicated to Magento Certification. Let’s start.

NameSpace : MyPackage and Module: CustomShipping

Register the module

<!-- app/etc/modules/MyPackage_CustomShipping.xml -->
<?xml version="1.0"?>
<config>
    <modules>
        <MyPackage_CustomShipping>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Shipping />
            </depends>
        </MyPackage_CustomShipping>
    </modules>
</config>


Create the config

<!-- app/code/local/MyPackage/CustomShipping/etc/config.xml -->
<?xml version="1.0"?>
<config>
    <modules>
        <MyPackage_CustomShipping>
            <version>0.0.0.1</version>
        </MyPackage_CustomShipping>
    </modules>
    <global>
        <models>
            <customshipping>
                <class>MyPackage_CustomShipping_Model</class>
            </customshipping>
        </models>
    </global>
    <!-- Default configuration -->
    <default>
        <carriers>
            <customshipping>
                <active>0</active>
                <title>Custom Shipping</title>
                <name>Standard</name>
                <price>9</price>
                <!-- this model hold all logic of custom module -->
                <model>customshipping/carrier_customshipping</model>
                <sallowspecific>0</sallowspecific>
                <sort_order>0</sort_order>
            </customshipping>
        </carriers>
    </default>
</config>

Adapter model
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 and getAllowedMethods. collectRates is the method that receives a shipping request, appends applicable shipping methods and returns a shipping result.

<?php
//app/code/local/MyPackage/CustomShipping/Model/Carrier/Customshipping.php
class MyPackage_CustomShipping_Model_Carrier_Customshipping
    extends Mage_Shipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface
{
    protected $_code = 'customshipping';

    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {

        return Mage::getModel('shipping/rate_result');
    }

    public function getAllowedMethods()
    {
        return array('custom_shipping'=>$this->getConfigData('name'));
    }
}

This is the skeleton for a shipping method class, it has no meaning if it has no shipping method.

Now creating meaningful of this method, suppose we use configure price from admin. Default method “Standard” and price is “9”.

<?php
//app/code/local/MyPackage/CustomShipping/Model/Carrier/Customshipping.php
class MyPackage_CustomShipping_Model_Carrier_Customshipping
    extends Mage_Shipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface
{
    protected $_code = 'customshipping';

    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        $result = Mage::getModel('shipping/rate_result');
        $method = Mage::getModel('shipping/rate_result_method');

        $method->setCarrier('customshipping');
        $method->setCarrierTitle($this->getConfigData('title'));

        $method->setMethod('custom_shipping');
        $method->setMethodTitle($this->getConfigData('name'));

        $method->setPrice($this->getConfigData('price'));
        $method->setCost($this->getConfigData('price'));

        $result->append($method);

        return $result;
    }

    public function getAllowedMethods()
    {
        return array('custom_shipping'=>$this->getConfigData('name'));
    }
}

System Configuration

<!-- app/code/local/MyPackage/CustomShipping/etc/system.xml -->
<?xml version="1.0"?>
<config>
    <sections>
        <carriers>
            <groups>
                <customshipping translate="label">
                    <label>Custom Configurable Shipping</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>2</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <active translate="label">
                            <label>Enabled</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>1</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </active>
                        <name translate="label">
                            <label>Method Name</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>3</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </name>
                        <price translate="label">
                            <label>Fixed Price</label>
                            <frontend_type>text</frontend_type>
                            <validate>validate-number validate-zero-or-greater</validate>
                            <sort_order>5</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </price>
                        <sort_order translate="label">
                            <label>Sort Order</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>100</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </sort_order>
                        <title translate="label">
                            <label>Title</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>2</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </title>
                    </fields>
                </customshipping>
            </groups>
        </carriers>
    </sections>
</config>

This is simple shipping method module creation.
N.B: Inside shipping method model class, you should take care of following condition

1. $item->getHasChildren() && $item->isShipSeparately()
2. $item->getProduct()->isVirtual() == true
3. $item->getProduct()->isVirtual() || $item->getParentItem()
4. $item->getFreeShipping() == true

Happy Coding!

One thought on “Creating custom shipping method in magento

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s