Menu Close

    Create Custom Shipping Method in Magento 2

    In this dev doc article, we will learn about Magento 2 delivery method development. So to create a custom shipping method in Magento 2, you first need to define it in your config.xml file, which is located at:

    app/code/Webkul/Customshipping/etc/config.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
        <default>
            <carriers>
                <wkcustomshipping>
                    <active>1</active>
                    <allowed_methods>delivery</allowed_methods>
                    <methods>delivery</methods>
                    <sallowspecific>0</sallowspecific>
                    <model>Webkul\Customshipping\Model\Carrier</model>
                    <name>Webkul custom Shipping</name>
                    <title>Webkul custom Shipping</title>
                    <handling_type>F</handling_type>
                </wkcustomshipping>
            </carriers>
        </default>
    </config>

    In this file, we define the shipping method code, which should be unique for each method.

    Now, we need to define our model, which is already defined in config.xml under the <model> tag.

    In the model, we calculate our shipping cost.

    Searching for an experienced
    Magento 2 Company ?
    Read More

    app/code/Webkul/Customshipping/Model/Carrier.php

    <?php
    namespace Webkul\Customshipping\Model;
    
    use Magento\Quote\Model\Quote\Address\RateResult\Error;
    use Magento\Quote\Model\Quote\Address\RateRequest;
    use Magento\Shipping\Model\Carrier\AbstractCarrierOnline;
    use Magento\Shipping\Model\Carrier\CarrierInterface;
    use Magento\Shipping\Model\Rate\Result;
    use Magento\Shipping\Model\Simplexml\Element;
    use Magento\Ups\Helper\Config;
    use Magento\Framework\Xml\Security;
    
    
    class Carrier extends AbstractCarrierOnline implements CarrierInterface
    {
        const CODE = 'wkcustomshipping';
        protected $_code = self::CODE;
        protected $_request;
        protected $_result;
        protected $_baseCurrencyRate;
        protected $_xmlAccessRequest;
        protected $_localeFormat;
        protected $_logger;
        protected $configHelper;
        protected $_errors = [];
        protected $_isFixed = true;
        
        public function __construct(
            \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
            \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
            \Psr\Log\LoggerInterface $logger,
            Security $xmlSecurity,
            \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
            \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
            \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
            \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory,
            \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory,
            \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory,
            \Magento\Directory\Model\RegionFactory $regionFactory,
            \Magento\Directory\Model\CountryFactory $countryFactory,
            \Magento\Directory\Model\CurrencyFactory $currencyFactory,
            \Magento\Directory\Helper\Data $directoryData,
            \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
            \Magento\Framework\Locale\FormatInterface $localeFormat,
            Config $configHelper,
            array $data = []
        ) {
            $this->_localeFormat = $localeFormat;
            $this->configHelper = $configHelper;
            parent::__construct(
                $scopeConfig,
                $rateErrorFactory,
                $logger,
                $xmlSecurity,
                $xmlElFactory,
                $rateFactory,
                $rateMethodFactory,
                $trackFactory,
                $trackErrorFactory,
                $trackStatusFactory,
                $regionFactory,
                $countryFactory,
                $currencyFactory,
                $directoryData,
                $stockRegistry,
                $data
            );
        }
        protected function _doShipmentRequest(\Magento\Framework\DataObject $request)
        {
        }
    
        public function getAllowedMethods()
        {
        }
        
        public function collectRates(RateRequest $request)
        {   
            $result = $this->_rateFactory->create();
            
            /*store shipping in session*/
            $method = $this->_rateMethodFactory->create();
            $method->setCarrier($this->_code);
            $method->setCarrierTitle('Webkul custom Shipping');
            /* Use method name */
            $method->setMethod($this->_code);
            $method->setMethodTitle('Webkul Custom Shipping');
            $method->setCost(10);
            $method->setPrice(10);
            $result->append($method);
            return $result; 
        }
        
        public function proccessAdditionalValidation(\Magento\Framework\DataObject $request) {
            return true;
        }
    }

    After that, your shipping method will get displayed on front end.

    custom shipping method magento 2

    To define custom setting of shipping method, you need to create system.xml , which is at location:

    app/code/Webkul/Customshipping/etc/adminhtml/system.xml

    <?xml version="1.0"?>
    <!--
    /**
     * Copyright © 2015 Magento. All rights reserved.
     * See COPYING.txt for license details.
     */
    -->
    <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" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
                <group id="wkcustomshipping" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Webkul Custom Shipping Method</label>               
                    <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
                        <label>Enabled</label>
                        <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    </field>
                    <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                        <label>Title</label>
                    </field>
                    <field id="name" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
                        <label>Name</label>
                    </field>
                    <field id="sallowspecific" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="0">
                        <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" translate="label" type="multiselect" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="0">
                        <label>Ship to Specific Countries</label>
                        <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
                        <can_be_empty>1</can_be_empty>
                    </field>
                </group>
            </section>
        </system>
    </config>

    Thank you for reading this article on How to Create a Custom Shipping Method in Magento 2, we hope you liked it.

    You can also view our wide range of ready-to-use Magento 2 extensions. Such as custom delivery methods, third-party carriers Magento 2 shipping integrations, and more. Further for any more queries, please reach out to our team via support ticket.

    . . .
    Discuss on Helpdesk

    Leave a Comment

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


    6 comments

  • Ghulam Muhammad
    Really helpful material This is what I was looking 🙂 .
  • cole hafner
    This is great. Thank you! However, I’m trouble understanding how to get the data in the current cart/order, so I can pass it to my external shipping API. I expect I’m supposed to make the request in collectRates() function. Does the RateRequest param include information such as destination address, cart items, and weight? If no, where can I get that information? Any help would be much appreciated.
    • Piyush Dangre
      I have the same question ! Pls any help wud be appreciated ! 🙂
    • Piyush Dangre
      @cole_hafner:disqus Did you figure out how to do that, mate?
  • SHEHAN GOMES
    Thanx
  • Arsalan Ajmal
    Thank you for your post, very helpful. Keep on sharing your great work 🙂
  • Back to Top