Reading list Switch to dark mode

    Create Custom Shipping Method in Magento 2

    Updated 11 July 2023

    How to create Shipping method in Magento 2 – In this dev doc article, we will learn about Magento 2 shipping 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
    /**
     * Webkul Software.
     *
     * @category  Webkul
     * @package   Webkul_Customshipping
     * @author    Webkul Software Private Limited
     * @copyright Webkul Software Private Limited (https://webkul.com)
     * @license   https://store.webkul.com/license.html
     */
    
    namespace Webkul\Customshipping\Model;
    
    use Magento\Quote\Model\Quote\Address\RateResult\Error;
    use Magento\Quote\Model\Quote\Address\RateRequest;
    use Magento\Shipping\Model\Carrier\AbstractCarrier;
    use Magento\Shipping\Model\Carrier\CarrierInterface;
    use Magento\Shipping\Model\Simplexml\Element;
    
    class Carrier extends AbstractCarrier implements CarrierInterface
    {
        const CODE = 'wkcustomshipping';
        protected $_code = self::CODE;
        
        public function __construct(
            protected \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
            protected \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
            protected \Psr\Log\LoggerInterface $logger,
            protected \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
            protected \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
            protected \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory,
            protected \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory,
            protected \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory,
            protected \Magento\Directory\Model\RegionFactory $regionFactory,
            protected \Magento\Directory\Model\CountryFactory $countryFactory,
            protected \Magento\Directory\Model\CurrencyFactory $currencyFactory,
            protected \Magento\Directory\Helper\Data $directoryData,
            protected \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
            protected \Magento\Framework\Locale\FormatInterface $localeFormat,
            array $data = []
        ) {
            parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
        }
    
        public function getAllowedMethods()
        {
        }
        
        /**
         * Collect and get rates
         *
         * @param RateRequest $request
         * @return Result|bool|null
         */
        public function collectRates(RateRequest $request)
        {   
            $result = $this->rateFactory->create();
            $method = $this->rateMethodFactory->create();
            $method->setCarrier($this->_code);
            $method->setCarrierTitle('Webkul custom Shipping');
            /* Set method name */
            $method->setMethod($this->_code);
            $method->setMethodTitle('Webkul Custom Shipping');
            $method->setCost(10);
            /* Set shipping charge */
            $method->setPrice(10);
            $result->append($method);
            return $result; 
        }
        
        /**
         * Processing additional validation to check is carrier applicable.
         *
         * @param \Magento\Framework\DataObject $request
         * @return $this|bool|\Magento\Framework\DataObject
         */
        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"?>
    <!--
    /**
     * Webkul Software.
     *
     * @category  Webkul
     * @package   Webkul_Customshipping
     * @author    Webkul Software Private Limited
     * @copyright Webkul Software Private Limited (https://webkul.com)
     * @license   https://store.webkul.com/license.html
     */
    -->
    <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

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home