Custom shipping method in Magento
23 Comments 26th JUL 2009 | Posted by Vedran Subotic 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.
To post code in comments, place your code inside [code] and [/code] tags.


















July 27th, 2009 at 15:23
Can this be made into a local module so as to not get overridden during upgrades?
July 27th, 2009 at 15:53
I keep getting an error on this
July 28th, 2009 at 7:26
@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?
July 28th, 2009 at 7:28
@Tobeyt23
“Can this be made into a local module so as to not get overridden during upgrades?” => Yes it can.
July 28th, 2009 at 14:34
@Branko Ajzele
I found the error:
Sort order
text
100
1
1
0
should be:
Sort order
text
100
1
1
0
July 28th, 2009 at 14:43
@Tobeyt23 Vedran is the author of this post
I guess this one goes to him.
July 28th, 2009 at 15:22
@ 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.
July 28th, 2009 at 23:20
Well done Tobeyt23,
ceep tracing Magento code!!
July 29th, 2009 at 0:25
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
July 29th, 2009 at 23:20
@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.
August 28th, 2009 at 12:28
Hi, you have shown how to add shipping module in Core/Mage. Is there any way I can add shipping module in Local/
November 6th, 2009 at 7:37
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
November 9th, 2009 at 3:12
I found the error:
Sort order
text
100
1
1
0
should be:
Sort order
text
100
1
1
0
November 9th, 2009 at 3:15
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.
November 9th, 2009 at 3:17
i found error at line 054
January 27th, 2010 at 16:53
Can you offer opensource EMS shipment model?
March 7th, 2010 at 15:30
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
April 9th, 2010 at 7:12
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
April 9th, 2010 at 10:14
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.
April 20th, 2010 at 17:42
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.
April 29th, 2010 at 23:42
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!
May 19th, 2010 at 1:16
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
June 14th, 2010 at 11:13
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->setMethod($method['code']);
$method->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