Magento, Magento 2

How to Create Custom Shipping Method in Magento 2

How to Create Custom Shipping Method in Magento 2

In this tutorial, Today I will explain to how to create custom shipping method in Magento 2. Magento is big ecommerce platform. There are few shipping methods by default provided by Magento 2. But, still it’s not full fill requirement to merchant. At that time, We need to create custom shipping method in our store.

With simple explaination, I will create shipping method steps-by-steps.

You may also like this :

Steps to Create Custom Shipping Method in Magento 2

1) First of all, To register module create registration.php file at app/code/RH/CustomShipping/ and paste the below code :

<?php

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Created By : Rohan Hapani
 */
use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'RH_CustomShipping', __DIR__);

2) After that, To configure module create module.xml file at app/code/RH/CustomShipping/etc/ and paste the below code :

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Created By : Rohan Hapani
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="RH_CustomShipping" schema_version="1.0.0" setup_version="1.0.0"/>
</config>

3) Then, To define shipping module create config.xml file at app/code/RH/CustomShipping/etc/ and paste the below code :

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Created By : Rohan Hapani
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <carriers>
            <rohanshipping>
                <active>1</active>
                <sallowspecific>0</sallowspecific>
                <model>RH\CustomShipping\Model\Carrier\Shipping</model>
                <name>RH Custom Shipping Method</name>
                <title>RH Custom Shipping Method</title>
                <specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
                <handling_type>F</handling_type>
            </rohanshipping>
        </carriers>
    </default>
</config>

4) After that, To add shipping method config options create system.xml file at app/code/RH/CustomShipping/etc/adminhtml and paste the below code :

<?xml version="1.0" ?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Created By : Rohan Hapani
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="carriers" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="1000" translate="label">
            <group id="rohanshipping" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label">
                <label>Rohan Custom Shipping Method Group</label>
                <field id="active" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="select">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="name" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="20" translate="label" type="text">
                    <label>Method Name</label>
                </field>
                <field id="price" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="30" translate="label" type="text">
                    <label>Price</label>
                    <validate>validate-number</validate>
                </field>
                <field id="sort_order" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="40" translate="label" type="text">
                    <label>Sort Order</label>
                </field>
                <field id="title" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="50" translate="label" type="text">
                    <label>Title</label>
                </field>
                <field id="sallowspecific" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="60" translate="label" type="select">
                    <label>Ship to Applicable Countries</label>
                    <frontend_class>shipping-applicable-country</frontend_class>
                    <source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
                </field>
                <field id="specificcountry" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="70" translate="label" type="multiselect">
                    <label>Ship to Specific Countries</label>
                    <can_be_empty>1</can_be_empty>
                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
                </field>
                <field id="specificerrmsg" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="80" translate="label" type="textarea">
                    <label>Displayed Error Message</label>
                </field>
            </group>
        </section>
    </system>
</config>

5) Then, To create shipping model carrier file create Shipping.php at app/code/RH/CustomShipping/Model/Carrier/ and paste the below code :

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Created By : Rohan Hapani
 */
namespace RH\CustomShipping\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Rate\Result;
use Magento\Ups\Helper\Config;
use Magento\Shipping\Model\Carrier\AbstractCarrier;

class Shipping extends AbstractCarrier implements CarrierInterface
{
    const CODE = 'rohanshipping';

    protected $_code = self::CODE;

    protected $_isFixed = true;

    /**
     * @var \Magento\Shipping\Model\Rate\ResultFactory
     */
    protected $rateResultFactory;

    /**
     * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
     */
    protected $rateMethodFactory;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @param \Magento\Framework\App\Config\ScopeConfigInterface          $scopeConfig
     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory  $rateErrorFactory
     * @param \Psr\Log\LoggerInterface                                    $logger
     * @param \Magento\Shipping\Model\Rate\ResultFactory                  $rateResultFactory
     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
     * @param \Magento\Store\Model\StoreManagerInterface                  $storeManager
     * @param array                                                       $data
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        array $data = []
    ) {
        $this->rateResultFactory = $rateResultFactory;
        $this->rateMethodFactory = $rateMethodFactory;
        $this->storeManager = $storeManager;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }
    /**
     * @param RateRequest $request
     * @return Result|bool
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->rateResultFactory->create();
        $storeId = $this->storeManager->getStore()->getId();
        $price = $this->getConfigData('price');
        if ($price == "") {
            $price = 10; // By default price if price value is blank
        }

        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->rateMethodFactory->create();
        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));
        /* Use method name */
        $method->setMethod($this->_code);
        $method->setMethodTitle($this->getConfigData('name'));
        $method->setCost($price);
        $method->setPrice($price);
        $result->append($method);
        return $result;
    }

    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        return [$this->_code => __($this->getConfigData('name'))];
    }
}

Now, Just execute these below commands to install module :

php bin/magento s:up
php bin/magento s:s:d -f
php bin/magento c:c

That’s it !!

You can now see your custom shipping method at Stores -> Settings -> Configuration -> Sales -> Shipping Methods as like I attached these below screenshots.

Frontend Output :

RH Custom Shipping Method -1

Backend Output :

RH Custom Shipping Method -2

 

I hope this blog is easy to understand about how to create custom shipping method in Magento 2. In case, I missed anything or need to add some information, always feel free to leave a comment in this blog, I’ll get back with proper solution.

Keep liking and sharing !!

Tagged ,