Shipping method hide

Shipping methods are important for an eCommerce store and in many cases it’s required that we don’t want to show shipping method for some specific products. Today we will show how we can restrict the shipping method for specific products.

First we will setup a new module. Create registration.php inside app/code/WebbyTroops/Shipping

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'WebbyTroops_Shipping',
    __DIR__
);

Now we need to create module.xml file inside module’s etc folder.

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="WebbyTroops_Shipping" setup_version="1.0.0">
         
    </module>
</config>

Now we need to create di.xml file inside etc folder. Please use following code.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Api\ShipmentEstimationInterface">
        <plugin name="shipping_method_hide" type="WebbyTroops\Shipping\Plugin\ShippingPlugin" />
    </type>
    <type name="Magento\Quote\Api\ShipmentEstimationInterface">
        <plugin name="shipping_method_hide_using_address_id" type="WebbyTroops\Shipping\Plugin\ShippingPluginWithId" />
    </type>
</config>

We would need to create plugin file named as ShippingPlugin inside Plugin folder of module.

<?php
namespace WebbyTroops\Shipping\Plugin;


class ShippingPlugin
{
    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */   
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->checkoutSession = $checkoutSession;
    }

    /**
     * Hide FlatRate shipping method
     *
     * @param \Magento\Quote\Api\ShipmentEstimationInterface $subject
     * @param \Magento\Quote\Api\Data\ShippingMethodInterface[] $methods
     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] $methods
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function afterEstimateByExtendedAddress(\Magento\Quote\Api\ShipmentEstimationInterface $subject, $methods) 
    {
        foreach($methods as $key => &$method) {

            if($method->getMethodCode() == 'flatrate_flatrate') {
                if(!$this->checkShippingMethod()) {
                   unset($methods[$key]);
                   break;
                }
            }
        }
        return $methods;

    }

    private function checkShippingMethod()
    {
        $items = $this->checkoutSession->getQuote()->getAllVisibleItems();
        $showShippingMethod = true;
        foreach($items as $item)
        {
          if(in_array($item->getSku(), ['sku1', 'sku2'])) {
             $showShippingMethod = false;
             break;
          }
        }
        return $showShippingMethod; 

    }


}

We need to create another plugin which will work when shipping methods estimated from address id as it happens for logged in customers when they already have address added.

<?php
namespace WebbyTroops\Shipping\Plugin;


class ShippingPluginWithId
{
    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */   
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->checkoutSession = $checkoutSession;
    }

    /**
     * Hide FlatRate shipping method
     *
     * @param \Magento\Quote\Api\ShippingMethodManagementInterface $subject
     * @param \Magento\Quote\Api\Data\ShippingMethodInterface[] $methods
     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] $methods
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function afterEstimateByAddressId(\Magento\Quote\Api\ShippingMethodManagementInterface $subject, $methods) 
    {
        foreach($methods as $key => &$method) {

            if($method->getMethodCode() == 'flatrate_flatrate') {
                if(!$this->checkShippingMethod()) {
                   unset($methods[$key]);
                   break;
                }
            }
        }
        return $methods;

    }

    private function checkShippingMethod()
    {
        $items = $this->checkoutSession->getQuote()->getAllVisibleItems();
        $showShippingMethod = true;
        foreach($items as $item)
        {
          if(in_array($item->getSku(), ['sku1', 'sku2'])) {
             $showShippingMethod = false;
             break;
          }
        }
        return $showShippingMethod; 

    }


}

That’s it !! If you have followed all the steps then it will hide defined shipping method for SKUs you have provided. Even you can provide an option in store config to define which SKUs should be hidden for which shipping method. Happy Coding !!

  • Tags:

Leave A Comment

Go To Top