Custom shipping method in Magento

Featured Image

In this article I will demonstrate how to write custom shipping method in Magento commerce.
First we need to write our shipping method, it’s a class in folder app/code/core/Mage/Shipping/Model/Carrier/.
I called it Inchoocustom.php and it’s based on Flat rate shipping method but you can developed your own class.

< ?php
class Mage_Shipping_Model_Carrier_Inchoocustom
    extends Mage_Shipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface
{
    protected $_code = 'inchoocustom';
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }
        $freeBoxes = 0;
        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getFreeShipping() && !$item->getProduct()->isVirtual()) {
                    $freeBoxes+=$item->getQty();
                }
            }
        }
        $this->setFreeBoxes($freeBoxes);
        $result = Mage::getModel('shipping/rate_result');
        if ($this->getConfigData('type') == 'O') { // per order
            $shippingPrice = $this->getConfigData('price');
        } elseif ($this->getConfigData('type') == 'I') { // per item
            $shippingPrice = ($request->getPackageQty() * $this->getConfigData('price')) - ($this->getFreeBoxes() * $this->getConfigData('price'));
        } else {
            $shippingPrice = false;
        }
        $shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);
        if ($shippingPrice !== false) {
            $method = Mage::getModel('shipping/rate_result_method');
            $method->setCarrier('inchoocustom');
            $method->setCarrierTitle($this->getConfigData('title'));
            $method->setMethod('inchoocustom');
            $method->setMethodTitle($this->getConfigData('name'));
            if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
                $shippingPrice = '0.00';
            }
            $method->setPrice($shippingPrice);
            $method->setCost($shippingPrice);
            $result->append($method);
        }
        return $result;
    }
    public function getAllowedMethods()
    {
        return array('inchoocustom'=>$this->getConfigData('name'));
    }
}

Pay attention on following lines:

$method->setCarrier('inchoocustom');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('inchoocustom');
$method->setMethodTitle($this->getConfigData('name'));

They determine how we will set up our method. Keyword is ‘inchoocustom’.
In folder app/code/core/Mage/Shipping/etc/ we need to edit
system.xml and config.xml in order to enable our new shipping method.

system.xml:

                <inchoocustom translate="label">
                    <label>Inchoo Custom Shipping Method</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>Price</label>
                            <frontend_type>text</frontend_type>
                            <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>
                        <handling_type translate="label">
                            <label>Calculate Handling Fee</label>
                            <frontend_type>select</frontend_type>
                            <source_model>shipping/source_handlingType</source_model>
                            <sort_order>7</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </handling_type>
                        <handling_fee translate="label">
                            <label>Handling Fee</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>8</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </handling_fee>
                        <sort_order translate="label">
                            <label>Sort order</label>
                            <frontend_type>text</frontend_type>
                            </sort_order><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>
                        <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>
                        <type translate="label">
                            <label>Type</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_shipping_flatrate</source_model>
                            <sort_order>4</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </type>
                        <sallowspecific translate="label">
                            <label>Ship to applicable countries</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>90</sort_order>
                            <frontend_class>shipping-applicable-country</frontend_class>
                            <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </sallowspecific>
                        <specificcountry translate="label">
                            <label>Ship to Specific countries</label>
                            <frontend_type>multiselect</frontend_type>
                            <sort_order>91</sort_order>
                            <source_model>adminhtml/system_config_source_country</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </specificcountry>
                        <showmethod translate="label">
                            <label>Show method if not applicable</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>92</sort_order>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </showmethod>
                        <specificerrmsg translate="label">
                            <label>Displayed Error Message</label>
                            <frontend_type>textarea</frontend_type>
                            <sort_order>80</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </specificerrmsg>
                    </fields>
                </inchoocustom>

config.xml:

	<inchoocustom>
                <active>0</active>
                <sallowspecific>0</sallowspecific>
                <model>shipping/carrier_inchoocustom</model>
                <name>Inchoo Custom Shipping Method</name>
                <price>5.00</price>
                <title>Inchoo Custom Shipping Method</title>
                <type>I</type>
                <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
                <handling_type>F</handling_type>
        </inchoocustom>

Now we need to enable our new shipping method in admin panel (System->Configuration->Shipping Methods)
And we have our custom shipping method.
Enjoy coding.

55
Top

Enjoyed this post?

Subscribe to our RSS Feed, Follow us on Twitter and spread it to your friends!

Author

Vedran Subotic

Ex. Inchooer

Vedran worked in Inchoo from 2009 to 2012 as a backend developer.

Other posts from this author

Discussion 55 Comments

1 2
Add Comment
  1. Nitin

    Is it possible to create a shipping method that works per product and not per order?? Any help appreciated…

  2. Is it possible to integrate “UPS Ground” shipping rate with this custom shipping method?

  3. OnePack

    Hey Inchoo, Thanks for the great example. I might setup an own shipping method very soon but for now I’m stuck on something very annoying in that Magento shipping price vs destination. I don’t know why but Magento doesn’t provide an option to use the table rates with “including vat” prices. It’s all based on excluded vat and that makes it pretty weird. When you make a table with data like 20 euro -> cost 4 euro a client actually has to buy for more that 20 euros to have this rule applied. “Because the table rates are prices excluded vat”. When you have one vat rate it’s ok and you can have a workaround by calculating back the vat on the prices in the table but we have 3 vat rates… (21, 6 and 0).
    Is there a know work around because I’m completely stuck on how to fix this.

  4. Hey Guys, I was wondering if this could be updated to have a secondary how-to for extending this and making it possible to add LTL Freight carriers to it.

    Meaning if lets say RoadRunner gives us the API information to access their quoting system that we can plug in the necessary information to access quotes through using this module.

    Just a thought, we made a custom module, used part of this and part of the free module from FreightQuote.com but I would like to add a couple more LTL Carriers to the list.

    thanks,
    Bradley

  5. Emmanuel

    There is a problem on

    Sort order
    text
    100
    1
    1
    0
    Your closes it too early.

1 2

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top