Back to Top

Create Custom Shipping Method in Magento 2

Updated 23 February 2024

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 ?
Find out 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.

. . .

Leave a Comment

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


6 comments

  • Ghulam Muhammad
  • cole hafner
    • Piyush Dangre
    • Piyush Dangre
  • SHEHAN GOMES
  • Arsalan Ajmal
  • Back to Top

    Message Sent!

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

    Back to Home