How to filter the shipping method in one-page checkout in Magento?

Introduction

You may want to filter the shipping method in one-page checkout for one of the following cases:

  • Filter shipping method based on Customer Group
  • Filter Shipping method based on Country, State, Zipcode, etc
  • Filter Shipping method based on products
  • etc.

Unlike event: payment_method_is_active for payment method filtration, we don’t have similar event: shipping_method_is_active available for shipping method. Maybe Magento team forgot to implement it or it was too hard to implement due to the structure.
Whatever may be the reason we still can filter by overriding:

Mage_Shipping_Model_Shipping::collectCarrierRates()

Solution

Suppose a skeleton module(MagePsycho_Shipmentfilter) has already been created. And for example purpose, we will be hiding flat rate shipping for non-logged in the customer.
1> Rewrite the shipping model class: ‘Mage_Shipping_Model_Shipping’
File: app/code/local/MagePsycho/Shipmentfilter/etc/config.xml
Code:

...
<global>
	...
	<models>
		<shipping>
			<rewrite>
				<shipping>MagePsycho_Shipmentfilter_Model_Shipping</shipping>
			</rewrite>
		</shipping>
	</models>
	...
</global>

2> Override the method: collectCarrierRates()
File: app/code/local/MagePsycho/Shipmentfilter/Model/Shipping.php
Code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Shipmentfilter
 * @author     magepsycho@gmail.com
 * @website    https://www.magepsycho.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 	*/
class MagePsycho_Shipmentfilter_Model_Shipping extends Mage_Shipping_Model_Shipping
{
    public function collectCarrierRates($carrierCode, $request)
    {
        if (!$this->_checkCarrierAvailability($carrierCode, $request)) {
            return $this;
        }
        return parent::collectCarrierRates($carrierCode, $request);
    }

	protected function _checkCarrierAvailability($carrierCode, $request = null)
	{
		$isLoggedIn	 = Mage::getSingleton('customer/session')->isLoggedIn();
		if(!$isLoggedIn){
			if($carrierCode == 'flatrate'){ #Hide Flat Rate for non logged in customers
				return false;
			}
		}
		return true;
	}
}

3> That’s all.

Please share any other ideas you have.

3 thoughts on “How to filter the shipping method in one-page checkout in Magento?”

  1. Does anybody know how i could hide some shipping methods depending on a product attribute. We would only show store pickup by some products.

  2. How to disable by code and not by name, currently flatrate code is flatrate_flatrate, im using matrixrate and it comes with a lot of id, i cannot use matrixrate or i will remove all, any ideas?

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.