The available shipping methods can be found in Magento Admin Panel under the Shipping Methods section in System/Configuration/SalesFlat Rate, Table Rates, and Free Shipping methods fall under the category of static methods while others are dynamic. Dynamic means retrieval of rates from various shipping providers. Static means that shipping rates are based on a predefined set of rules. For the live production store you might be interested in obtaining the merchant account for one of the dynamic methods because they enable potentially more precise shipping cost calculation in regards to product weight.

Clean installation of Magento CE comes with the Flat Rate shipping method turned on, so be sure to turn it off in production if not required by setting the Enabled option in System/Configuration/Sales/Shipping Methods/Flat Rate to No. Setting up the dynamic methods is pretty easy; all you need to do is to obtain the access data from the shipping provider such as FedEx, then configure that access data under the proper shipping method configuration area, for example, System/Configuration/Sales/Shipping Methods/FedEx.

In this lesson of Magento Tutorial, we spend two hours on these sections:

  • How to configure the shipping method
  • How shipping method works
  • Add custom shipping method rates
  • Create Shipping Method Module

1. How to configure the shipping method

To configure the shipping method:

  • Log in to the Magento Admin Panel and go to System/Configuration/Sales/Shipping Methods.
  • Select an appropriate payment method, configure its options, and click on the Save Config button.

2. How shipping method works

Once a certain shipping method is turned on, it will be visible on the frontend to the customer during the checkout’s so-called Shipping Method step, as shown in the screenshot that follows. The shipping method’s price is based on the customer’s shipping address, products in cart, applied promo rules, and possibly other parameters.

shipping method

3. Add custom shipping method rates

Magento calculates Shipping rate through the Instance Model of each shipping method. So, shipping method is checked whether to be active or not. It will be estimated the fee by collectRates() of Instance model. You could follow one typical example with model Mage_Shipping_Model_Carrier_Flatrate. You can see the collectRates() method:

/**
* Enter description here...
*
* @param Mage_Shipping_Model_Rate_Request $data
* @return Mage_Shipping_Model_Rate_Result
*/
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->getProduct()->isVirtual() || $item->getParentItem()) {
continue;
}

if ($item->getHasChildren() && $item->isShipSeparately()) {
foreach ($item->getChildren() as $child) {
if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
$freeBoxes += $item->getQty() * $child->getQty();
}
}
} elseif ($item->getFreeShipping()) {
$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('flatrate');
$method->setCarrierTitle($this->getConfigData('title'));

$method->setMethod('flatrate');
$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;
}

4. Create Shipping Method Module

 4.1. Configuration

Create app/code/local/YourCompany/YourModule/etc/config.xml:
Now we have module Lesson25 and company is Magestore
The file create is app/code/local/Magestore/Lesson25/etc/config.xml

<?xml version="1.0"?>

<!--
/**
* Magestore
*
* Online Magento Course
*
*/
-->
<config>
<modules>
<!-- declare module's version information -->
<Magestore_Lesson25>
<!-- this version number will be used for database upgrades -->
<version>0.1.0</version>
</Magestore_Lesson25>
</modules>
<global>
<!-- declare model group for new module -->
<models>
<!-- model group alias to be used in Mage::getModel() -->
<lesson25>
<!-- base class name for the model group -->
<class>Magestore_Lesson25_Model</class>
</lesson25>
</models>

<!-- declare resource setup for new module -->
<resources>
<!-- resource identifier -->
<lesson25_setup>
<!-- specify that this resource is a setup resource and used for upgrades -->
<setup>
<!-- which module to look for install/upgrade files in -->
<module>Magestore_Lesson25</module>
</setup>
<!-- specify database connection for this resource -->
<connection>
<!-- do not create new connection, use predefined core setup connection -->
<use>core_setup</use>
</connection>
</lesson25_setup>
</resources>
</global>
<!-- set default for some filed of your shipping method-->
<default>
<carriers>
<lesson25>
<!—set model tocalculate shipping rate -->
<model>lesson25/carrier_shippingmethod</model>
<active>1</active>
<title>Lesson25</title>
<price>10</price>
</lesson25>
</carriers>
</default>
</config>

Create app/etc/modules/Magestore_Lesson25.xml:

<?xml version="1.0"?>

<!--
/**
* Magestore
*
* Online Magento Course
*
*/
-->
<config>
<modules>
<!-- declare Magestore_Lesson25 module -->
<Magestore_Lesson25>
<active>true</active>
<codePool>local</codePool>
</Magestore_Lesson25>
</modules>
</config>

4.2. Adapter model

Note: ShippingMethod name is arbitrary and is up to your decision.
Create app/code/local/Magestore/Lesson25/Model/Carrier/ShippingMethod.php:

<?php

/**
* Magestore
*
* Online Magento Course
*
*/

/**
* Carrier ShippingMethod Model
*
* @category Magestore
* @package Magestore_Lesson25
* @author Magestore Developer
*/
class Magestore_Lesson25_Model_Carrier_ShippingMethod extends Mage_Shipping_Model_Carrier_Abstract
{
/**
* unique internal shipping method identifier
*
* @var string [a-z0-9_]
*/
protected $_code = 'lesson25';

/**
* Collect rates for this shipping method based on information in $request
*
* @param Mage_Shipping_Model_Rate_Request $data
* @return Mage_Shipping_Model_Rate_Result
*/
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
// skip if not enabled
if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
return false;
}

/**
* here we are retrieving shipping rates from external service
* or using internal logic to calculate the rate from $request
* you can see an example in Mage_Usa_Model_Shipping_Carrier_Ups::setRequest()
*/

// get necessary configuration values
$handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');

// this object will be returned as result of this method
// containing all the shipping rates of this method
$result = Mage::getModel('shipping/rate_result');

// create new instance of method rate
$method = Mage::getModel('shipping/rate_result_method');

// record carrier information
$method->setCarrier($this->_code);
$method->setCarrierTitle(Mage::getStoreConfig('carriers/'.$this->_code.'/title'));

// record method information
$method->setMethod('lesson25');
$method->setMethodTitle(Mage::getStoreConfig('carriers/'.$this->_code.'/title'));

// rate cost is optional property to record how much it costs to vendor to ship
// this case I set cost = 10
$cost = 10;
$method->setCost($cost);

// in our example handling is fixed amount that is added to cost
// to receive price the customer will pay for shipping method.

$method->setPrice($cost+$handling);

// add this rate to the result
$result->append($method);

return $result;
}

/**
* This method is used when viewing / listing Shipping Methods with Codes programmatically
*/
public function getAllowedMethods()
{
return array($this->_code => $this->getConfigData('name'));
}
}

Now, we have the model, give admin a way to configure it and also make checkout process aware of this method.

4.3. Admin Configuration Implementation

In this step, we need to tell Magento how to display our module in the Configuration section of the administrative panel. In order to do so, we must create app/code/local/Magestore/Lesson25/etc/system.xml and make it look something like this.

<?xml version="1.0"?>
<!--
/**
* Magestore
*
* Online Magento Course
*
*/
-->
<config>
<sections>
<carriers>
<groups>
<lesson25 translate="label" module="shipping">
<label>Lesson 25</label>
<frontend_type>text</frontend_type>
<sort_order>13</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>1</show_in_store>
</active>
<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>
<price translate="label">
<label>Price</label>
<frontend_type>text</frontend_type>
<validate>validate-number validate-zero-or-greater</validate>
<sort_order>5</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</price>
<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>1</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>1</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>1</show_in_store>
</showmethod>
<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>1</show_in_store>
</sort_order>
</fields>
</lesson25>
</groups>
</carriers>
</sections>
</config>

Go to System => Configuration => Shipping Methods and see the shipping method you have created:

magento shipping method

In Frontend, when customers checkout, your shipping method will be shown:

shipping

So, we have learned the final parts of lesson 25: Shipping Method. Now, you should have answer to two questions:

  • How to configure and how Shipping Method works in Magento
  • How to add a new Shipping Method

Enjoy coding and see you later. Follow us in Magento Open Course for Magento Tutorial.

Author

Why Magestore? We believe in building a meaningful & long-term relationship with you.

Write A Comment