Press ESC to close

How to Restrict Shipping Method for Specific Product in Magento 2

If you’re running an eCommerce store with Magento 2, offering flexible shipping options is essential—but so is control. In certain scenarios, you may need to restrict a shipping method for a specific product. An example is that you may wish to exclude Free Shipping on high-weight or low-margin products. This tutorial will walk you through how to restrict shipping method for specific product in Magento 2 using a custom module. This method leverages Magento’s plugin architecture and is ideal for store owners or developers looking to implement Magento 2 restrict shipping method or define custom Magento 2 shipping rules programmatically.

Now, let us get into the implementation step by step.

Why Restrict Shipping Methods in Magento 2?

Magento 2 is robust and flexible, making it easy to define business-specific shipping policies. Restricting shipping methods allows you to:

  • Avoid losses on low margin products
  • Manage fragile or bulky products logistics
  • Offer region or product-specific shipping logic
  • Enhance checkout experience with valid options only

Step-by-Step Guide to Restrict Shipping Method for Specific Product

Follow these steps to create a custom module that disables Free Shipping for a product with a specific SKU.

Step 1: Create registration.php

First, you need to create the registration.php file to register your custom module with Magento. Place this file in the app/code/Vendor/Module directory.

<?php

\Magento\Framework\Component\ComponentRegistrar::register(

    \Magento\Framework\Component\ComponentRegistrar::MODULE,

    'Vendor_Module',

    __DIR__

);

Step 2: Create module.xml

Next, create the module.xml file in the etc folder to define the module configuration. This file should be placed at app/code/Vendor/Module/etc.

<?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="Vendor_Module" setup_version="1.0.0">

    </module>

</config>

Step 3: Create di.xml

Now, create the di.xml file to configure the plugin for the shipping model.

File Path: app/code/Vendor/Module/etc/di.xml

<?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\Shipping\Model\Shipping">

        <plugin disabled="false" name="Vendor_Module_Plugin_Magento_Shipping_Model_Shipping" sortOrder="10" type="Vendor\Module\Plugin\Model\Shipping"/>

    </type>

</config>

Step 4:Create Shipping.php

Now, create the plugin Shipping.php to restrict the free shipping method based on the product SKU.

File Path: app/code/Vendor/Module/Plugin/Model/Shipping.php

<?php

namespace Vendor\Module\Plugin\Model;

use Magento\Catalog\Model\ProductFactory;

use Magento\Shipping\Model\Shipping as ShippingModel;

use Closure;

class Shipping

{

    /**

     * @var ProductFactory

     */

    protected $productFactory;

    /**

     * Shipping constructor.

     *

     * @param ProductFactory $productFactory

     */

    public function __construct(ProductFactory $productFactory)

    {

        $this->productFactory = $productFactory;

    }

    /**

     * Around plugin for collectCarrierRates method.

     *

     * @param ShippingModel $subject

     * @param Closure $proceed

     * @param string $carrierCode

     * @param \Magento\Shipping\Model\Carrier\Request $request

     * @return mixed

     */

    public function aroundCollectCarrierRates(

        ShippingModel $subject,

        Closure $proceed,

        string $carrierCode,

        $request

    ) {

        $noFreeShipping = false;

        $allItems = $request->getAllItems();

        foreach ($allItems as $item) {

            $productId = $item->getProduct()->getId();

            $product = $this->productFactory->create()->load($productId);

            // Check if the SKU matches the specified product

            if ($product->getSku() === "cd-test-product") {

                // Set the flag to true if the product is found

                $noFreeShipping = true;

                break;

            }

        }

        // If free shipping is not allowed and the carrier is free shipping, return false

        if ($noFreeShipping && $carrierCode === 'freeshipping') {

            return false;

        }

        return $proceed($carrierCode, $request);

    }

}

Step 5: Run Magento Commands

After creating the necessary files, run the following Magento commands to upgrade, compile, and deploy the changes:

php bin/magento setup:upgrade

 php bin/magento setup:di:compile

 php bin/magento setup:static-content:deploy -f

 php bin/magento cache:clean

 php bin/magento cache:flush

When a customer adds the product with SKU cd-test-product to their cart, the Free Shipping option will no longer appear at checkout.

Product Restriction in magento 2

Now that you know how to restrict shipping method for specific product in Magento 2, you can confidently tailor shipping options to fit your store’s needs. Whether you’re applying advanced Magento 2 shipping rules or just trying to Magento 2 restrict shipping method for select items, this approach gives you full control with clean, maintainable code.

For more advanced customization or assistance with Magento 2 conditional shipping rules, feel free to reach out to us in the comments or contact our team for expert guidance. We’re here to help you optimize your eCommerce store’s shipping strategy!

Share Post

CodeDecorator

We are a prominent worldwide provider of Magento Extensions and a pioneer in web development solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *