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

68
Top

Care to rate this post?

Author

Vedran Subotic

Ex. Inchooer

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

Other posts from this author

Discussion 68 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.

  6. Perfect ! Works like a charm !!

  7. Vivek

    Hi When i enable method from admin the method not showing in fronted and gives meg (Sorry, no quotes are available for this order at this time.)… please help

  8. Juan

    Does it work for Magento 1.7?

  9. bater

    when i submit an web service api request after get inchoocustom shipment method enabled in the admin panel,
    $shipment = array(‘shipmentIncrementId’ => ’100000039′, ‘carrier’ => ‘inchoocustom’, ‘title’ => ‘tracking title’, ‘track Number’ => ’123123′);
    $result = $client->call( $session, ‘sales_order_shipment.addTrack’, $shipment );

    I got the following message shown on the screen:
    “Invalid model for shipping method: inchoocustom”.

    how to get something like “dhl”?

  10. Vedran this is an amazing article, which guided me in creating custom shipping methods based on the flat rat shipping module.

    I do have a question which is not completely related to this but in essence it is. When order is created Magento stores Order Shipping Method which, in your example would be inchoocustom_inchoocustom. Our fulfillement center expects to get specific code in there per each method (they use this to map our methods to theirs), which is not a problem to do following your instructions above. How do I change Order Shipping Method from being stored as XXX_XXX to XXX?

  11. Jesse Hanson

    Special attention should be put on the model tag in the config.xml . This is where you specify the location of the model class. Obviously, this is an old example; but it’s still one of the top results in Google. Most people will want to use a local/community module rather than editing core.

  12. hello,
    Vedran Subotic, i read your blog. it is a very helpful blog me. i learn most of things from all inchoo team’s blogs. i want to thank from my heart to all of you.
    i have some query regarding shipping method module. i want multiple shipping methods on checkout in one custom module like ups, fedex, DHL, how can i do that?
    your replay is important to me.
    thank you,
    anil kasar

  13. Tom

    This should not be editing and adding files in core Magento folders! People reading this please don’t edit core files….there’s better ways of doing it.

  14. Jai

    Hello Guys…

    After adding this method, When i enable method from admin the method not showing in frontend and gives message
    (Sorry, no quotes are available for this order at this time.)… Please Help ASAP

  15. Taras

    Please correct sort order node in the system.xml file line 51. Looks like it should be

    <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>
    
  16. Taras

    And please fix comments )))

  17. Hi, Taras.
    Thanks for reporting this, closing part of the node was missing :)

    We’re working on a new implementation of the sourcecode snippet, we are aware it sometimes breaks the code.

  18. vikas

    Hi,

    How to add comment box and “submit button to connect to mail” under shipping method

    please visit http://steel.newtrendzonline.com/

    please “Add to cart” some products, after go for checkout . In checkout page, in 3rd step 3) Shipping Method,

    we added the comment box, but below “SUBMIT button” is not working.

    The same code for “submit button” , which we used in “Contact form page” is working.

    [mails are sending to contacts "e-mail"] . But the “submit” button code” is not working

    under 3)Shipping method in Checkout. [mails are not sending to contacts "e-mail"].

    please give me the solution.

    Thanks in Advance.

1 2

Add Your Comment

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