Apr/10
29
Custom shipping method in Magento
3 Comments · Posted by leo in development, magento, module
This article will show you 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/.
You can create a new one which codes as below, I named it as newflatcustom.php (you can copy from Flatrate.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <?php class Mage_Shipping_Model_Carrier_newflatcustom extends Mage_Shipping_Model_Carrier_Abstract implements Mage_Shipping_Model_Carrier_Interface { protected $_code = 'newflatcustom'; 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('newflatcustom'); $method->setCarrierTitle($this->getConfigData('title')); $method->setMethod('newflatcustom'); $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('newflatcustom'=>$this->getConfigData('name')); } } |
Pay attention on following lines:
1 2 3 4 5 | $method->setCarrier('newflatcustom');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('newflatcustom');
$method->setMethodTitle($this->getConfigData('name')); |
‘newflatcustom’ determine how we will set up our method.
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | <newflatcustom translate="label"> <label>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> </newflatcustom> |
config.xml:
1 2 3 4 5 6 7 8 9 10 11 | <newflatcustom> <active>0</active> <sallowspecific>0</sallowspecific> <model>shipping/newflatcustom</model> <name>Custom Shipping Method</name> <price>5.00</price> <title>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> </newflatcustom> |
Then we need to enable this new shipping method in admin panel (System->Configuration->Shipping Methods). Well done!

Roger Willis · 15/05/2010 at 06:21
This was truly a life saver! Thank you for this!
Jaime Stuardo · 19/05/2010 at 01:10
Placing the new files where core files are stored? I think it’s a bad idea.
a.neo · 24/06/2010 at 17:41
Hi,
I have implemented as your guidance. but its showing error. the error is:
=============================================
Trying to get property of non-object in /home/user/public_html/app/code/core/Mage/Adminhtml/Block/System/Config/Form.php on line 301
Trace:
#0 /home/user/public_html/app/code/core/Mage/Adminhtml/Block/System/Config/Form.php(301): mageCoreErrorHandler(8, ‘Trying to get p…’, ‘/home/user/…’, 301, Array)
#1 /home/user/public_html/app/code/core/Mage/Adminhtml/Block/System/Config/Form.php(215): Mage_Adminhtml_Block_System_Config_Form->_sortForm(‘1′, Object(Mage_Core_Model_Config_Element))
#2 /home/user/public_html/app/code/core/Mage/Adminhtml/Block/System/Config/Form.php(180): Mage_Adminhtml_Block_System_Config_Form->initFields(Array, Array)
#3 /home/user/public_html/app/code/core/Mage/Adminhtml/Block/System/Config/Edit.php(91): Mage_Adminhtml_Block_System_Config_Form->initForm(Object(Varien_Data_Form_Element_Fieldset), Object(Mage_Core_Model_Config_Element), Object(Mage_Core_Model_Config_Element))
#4 /home/user/public_html/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php(87): Mage_Adminhtml_Block_System_Config_Edit->initForm()
#5 /home/user/public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(376): Mage_Adminhtml_System_ConfigController->editAction()
#6 /home/user/public_html/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(248): Mage_Core_Controller_Varien_Action->dispatch()
#7 /home/user/public_html/app/code/core/Mage/Core/Controller/Varien/Front.php(158): Mage_Core_Controller_Varien_Router_Standard->match(‘edit’)
#8 /home/user/public_html/app/Mage.php(459): Mage_Core_Controller_Varien_Front->dispatch(Object(Mage_Core_Controller_Request_Http))
#9 /home/user/public_html/index.php(65): Mage::run()
#10 {main}
=========================================
can you please tell me whats wrong with it.
Thanks.