Custom shipping method in Magento

23 Comments 26th JUL 2009 | Posted by Vedran Subotic in Magento

Custom shipping method in Magento

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.

If you like what you read, please share it.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Yahoo! Bookmarks
  • Reddit
  • Technorati
  • Twitter
  • StumbleUpon
  • LinkedIn
  • Netvibes
  • NewsVine
  • Sphinn
  • Tumblr
  • Posterous

To post code in comments, place your code inside [code] and [/code] tags.

There are 23 comments (Add Yours +)

  • Tobeyt23 Says

    Can this be made into a local module so as to not get overridden during upgrades?

  • Tobeyt23 Says

    I keep getting an error on this

  • @Tobeyt23

    Not much info provided on your side!

    What is the error you are getting? Check the SmallCaps cases in config.xmlf files. Our color syntax app has the tendency to lowercase attribute names in XML files so you might be getting some config errors?

  • @Tobeyt23

    “Can this be made into a local module so as to not get overridden during upgrades?” => Yes it can.

  • Tobeyt23 Says

    @Branko Ajzele

    I found the error:

    Sort order
    text
    100
    1
    1
    0

    should be:

    Sort order
    text
    100
    1
    1
    0

  • @Tobeyt23 Vedran is the author of this post :) I guess this one goes to him.

  • Tobeyt23 Says

    @ Branko Ajzele

    Woops didn’t see that the code got messed up. In the system.xml on line 54 the sortorder is closed before it should be once I fixed that it worked.

  • Vedran Subotic Says

    Well done Tobeyt23,
    ceep tracing Magento code!!

  • It does not work in the newest version of Magento … it is visible in System->Configuration->Shipping Methods, but if it is active shopping chart drops errors, and the checkout does not let to pass to shipping methods. or did I missed something in
    Pay attention on following lines:

    1. $method->setCarrier(‘inchoocustom’);
    2.$method->setCarrierTitle($this->getConfigData(‘title’));
    3.
    4.$method->setMethod(‘inchoocustom’);
    5.$method->setMethodTitle($this->getConfigData(‘name’));

    gimme more info to what should I pay attention to

    thanx best wishes

    Jozef

  • Vedran Subotic Says

    @Jozef

    I’m sorry, I should highlight that the code above is tested in Magento version 1.3.2.1.
    But if you followed the instructions (not just copy-paste) and tried to make your own shipping method with new magento version I belive that you would achieve your goal.

  • Hi, you have shown how to add shipping module in Core/Mage. Is there any way I can add shipping module in Local/

  • Sirvash Sharma Says

    try this one, hopefully working.

    Inchoo Custom Shipping Method
    text
    5
    1
    1
    1

    Enabled
    select
    adminhtml/system_config_source_yesno
    1
    1
    1
    0

    Method name
    text
    3
    1
    1
    1

    Price
    text
    5
    1
    1
    0

    Calculate Handling Fee
    select
    shipping/source_handlingType
    7
    1
    1
    0

    Handling Fee
    text
    8
    1
    1
    0

    Sort order
    text
    100
    1
    1
    0

    Title
    text
    2
    1
    1
    1

    Type
    select
    adminhtml/system_config_source_shipping_flatrate
    4
    1
    1
    0

    Ship to applicable countries
    select
    90
    shipping-applicable-country
    adminhtml/system_config_source_shipping_allspecificcountries
    1
    1
    0

    Ship to Specific countries
    multiselect
    91
    adminhtml/system_config_source_country
    1
    1
    0

    Show method if not applicable
    select
    92
    adminhtml/system_config_source_yesno
    1
    1
    0

    Displayed Error Message
    textarea
    80
    1
    1
    1

  • I found the error:

    Sort order
    text
    100
    1
    1
    0
    should be:

    Sort order
    text
    100
    1
    1
    0

  • i found error:

    052. Sort order
    053. text
    054. 100
    055. 1
    056. 1
    057. 0
    should be:

    052. Sort order
    053. text
    054. 100
    055. 1
    056. 1
    057. 0
    058.

  • i found error at line 054

  • Can you offer opensource EMS shipment model?

  • Great! Our store is based in one currency and displays in another ($). That works fine. The problem is with shipping. You see we want to have a flat fixed shipping rate in $ – but it gets converted from our base currency. Any ideas?

    Thanks

  • Gurvinder singh Says

    Hey please correct the section
    Sort order
    text
    100
    1
    1
    0

    Instead of blindly copy paste this in system.xml:

    Sort order
    text
    100
    1
    1
    0

  • Error was in line: 54
    Xml tag wasn’t properly closed.

    Please check the link provided:

    fixed solution

    Point was that You spend some time to trace the error so you can get that feeling how is like to be Magento developer.

  • Great tutorial! You should be namespacing this code into /local, especially if it is a tutorial, and you are telling others best practices in Magento programming.

  • How can I add a minimum shipping amount to the flat rate %. For example:

    I want to charge $6.50 or 8% depending on which is greater.

    Thanks!

  • Hello… I have made it local, but I saw thay the model class is never called. the system insists in calle Mage_Shipping model class.

    My module is called Newshipping, and the carrier is regionfreeshipping. Can you show me how to configure system.xml and config.xml files?

    Thanks
    Jaime

  • MagentoPycho Says

    HI,
    I tried to make the following fields dynamic so that it’s data come from some table.

    for example


    foreach($multiple_methods as $method){
    ...
    $method-&gt;setMethod($method['code']);
    $method-&gt;setMethodTitle($method[''name]);
    ..

    }

    But in the frontend i get the methods but with ‘US’ title and all divs ids were same.

    Can anybody has some idea

Leave a Comment

Please wrap all source codes with [code][/code] tags.
Magento Design and Development | Magento SEO | iPhone Application Development Web Application Development with ZEND | WordPress Ecommerce | WordPress development
Sitemap

Inchoo - webappsolutions | 2009