Categories: Magento 2 Tutorials

How to Create Custom Magento 2 Shipping Method

Transporting an item from one place to another is called Shipping, and to deliver an ordered product through a medium to your customer is called the Shipping Method. Magento 2 already has built-in Shipping methods, but if you need custom Shipping Methods, then you need to create a custom Shipping Method. In this guide I am going to show you how to create a custom Magento 2 shipping method. If you are not familiar with a custom module, then first learn about it from this guide: Create a Module in Magento 2.

Registration and Configuration of Custom Magento 2 Shipping Module

First of all, configuration and registration of a custom module is required. Let’s first configure and then register the module.
Create module.xml in app/code/Magenticians/Moduleshipping/etc and add the following code in it to configure the module:
<?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="Magenticians_Moduleshipping" setup_version="1.0.1">
</module>
</config>
Create registration.php in app/code/Magenticians/Moduleshipping and add the following code in it to register the module:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magenticians_Moduleshipping',
__DIR__
);

Create New Fields in Admin Panel

Create system.xml in app/code/Magenticians/Moduleshipping/etc/adminhtml and add this code to it:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Magento/Config/etc/system_file.xsd">
<system>
<section id="carriers" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="magenticians_moduleshipping" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Magenticians Custom Shipping</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>Method Name</label>
</field>
<field id="price" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Shipping Cost</label>
<validate>validate-number validate-zero-or-greater</validate>
</field>
<field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Displayed Error Message</label>
</field>
<field id="sallowspecific" translate="label" type="select" sortOrder="90" 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="91" 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>
<field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Show Method if Not Applicable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Sort Order</label>
</field>
</group>
</section>
</system>
</config>

Define Shipping Model

Now define the shipping model by creating config.xml in app/code/Magenticians/Moduleshipping/etc, add this code to it:
<?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>
<magenticians_moduleshipping>
<active>0</active>
<sallowspecific>0</sallowspecific>
<price>0</price>
<model>Magenticians\Moduleshipping\Model\Carrier\Customshipping</model>
<name>Custom Shipping</name>
<title>Magenticians Custom Shipping</title>
<specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
</magenticians_moduleshipping>
</carriers>
</default>
</config>

Create Shipping Model Class

In the previous step I defined the Shipping Model class and now I am going to create it by creating Customshipping.php in app/code/Magenticians/Moduleshipping/Model/Carrier. Let’s add this code to it:
<?php

namespace Magenticians\Moduleshipping\Model\Carrier;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObject;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Config;
use Magento\Shipping\Model\Rate\ResultFactory;
use Magento\Store\Model\ScopeInterface;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Magento\Quote\Model\Quote\Address\RateResult\Method;
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Psr\Log\LoggerInterface;

class Customshipping extends AbstractCarrier implements CarrierInterface
{

/**

* Carrier's code
*
* @var string
*/
protected $_code = 'magenticians_moduleshipping';
/**
* Whether this carrier has fixed rates calculation
*
* @var bool
*/
protected $_isFixed = true;
/**
* @var ResultFactory
*/
protected $_rateResultFactory;
/**
* @var MethodFactory
*/
protected $_rateMethodFactory;
/**
* @param ScopeConfigInterface $scopeConfig
* @param ErrorFactory $rateErrorFactory
* @param LoggerInterface $logger
* @param ResultFactory $rateResultFactory
* @param MethodFactory $rateMethodFactory
* @param array $data
*/
public function __construct(
ScopeConfigInterface $scopeConfig,
ErrorFactory $rateErrorFactory,
LoggerInterface $logger,
ResultFactory $rateResultFactory,
MethodFactory $rateMethodFactory,
array $data = []
) {

$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}

/**
* Generates list of allowed carrier`s shipping methods
* Displays on cart price rules page
*
* @return array
* @api
*/
public function getAllowedMethods()
{
return [$this->getCarrierCode() => __($this->getConfigData('name'))];
}
/**
* Collect and get rates for storefront
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @param RateRequest $request
* @return DataObject|bool|null
* @api
*/
public function collectRates(RateRequest $request)
{
/**
* Make sure that Shipping method is enabled
*/
if (!$this->isActive()) {
return false;
}

/** @var \Magento\Shipping\Model\Rate\Result $result */$result = $this->_rateResultFactory->create();
$shippingPrice = $this->getConfigData('price');
$method = $this->_rateMethodFactory->create();
/**
* Set carrier's method data
*/$method->setCarrier($this->getCarrierCode());
$method->setCarrierTitle($this->getConfigData('title'));
/**
* Displayed as shipping method under Carrier
*/
$method->setMethod($this->getCarrierCode());
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
$result->append($method);
return $result;
}
}

Run Commands

Great, you’re all done! Launch your SSH terminal and connect it to your store, and run the following commands in the root directory of your store:
php bin/magento module:status
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento cache:clean
php bin/magento cache:flush
Now let’s check out the result! First, go to STORES → Configuration from the admin panel of your store. Then click on Shipping Methods under the SALES tab. Here, you will see the new shipping Method section: Magenticians Custom Shipping. Enable the Custom Shipping method and set its values according to your need. Now go to the checkout page of your Magento 2 store and you will see the Magenticians Custom Shipping Method. The above result means that the custom Magento 2 shipping method has been successfully created.

Wrapping Up

After following this guide, you should be able to create a custom Magento 2 shipping method. Hopefully, all the steps mentioned above were easy to follow and you didn’t have any hiccups along the way. However, if you still have any issues or confusions, just leave your thoughts below!

Frequently Asked Questions

Q1. Why create a custom Magento 2 shipping method in place of default built in shipping methods? If the built-in Magento 2 shipping methods are not fulfilling your requirements then you have to create a custom one. Q2. How can a Magento 2 custom shipping module improve delivery of ordered products to the customer? Since the purpose of a custom Magento 2 shipping module is to give a better ordering experience to your customers, it will improve delivery of ordered products.
Syed Muneeb Ul Hasan

Syed Muneeb Ul Hasan is an expert in PHP and Magento, he prefers to educate users in implementing and learning Magento. When not working, he loves to watch cricket.

View Comments

  • Hi there. I am trying to recreate the shipping module according to your instructions for my M2 website. I am confused in this step: Define Shipping Model

    Haven't we created the config.xml on the first step? Do I just ammend the code or are they 2 separate config.xml files?
    Looking forward to your reply, really interested in making this work.

    • Hello,

      Thanks for highlighting.Well, in the first step module.xml have to be created. I have updated it.

  • I want to print shipping labels ? for an order can I do this with this module if not what is the write way to follow for that

  • i want to add 3 logistics partners/shipping method i.e spoton, safexpress, rivigo. Please tell me what to do that. I am new in this. Am using magento 2 with the paid theme

Share
Published by
Syed Muneeb Ul Hasan

Recent Posts

Building Employee Trust and Dedication – A Complete Guide

In the highly competitive modern workplace, trust, and employee loyalty are crucial factors for long-term… Read More

3 months ago

12 Winning Strategies for Small Businesses Marketing

In the ever-evolving world of small business developing and implementing effective marketing strategies is critical to… Read More

3 months ago

Top 10 App Development Companies in Dubai 2024

With one of the highest internet penetration rates, the UAE has set out to revolutionize… Read More

3 months ago

Transforming Industries: How Amazons GPT44X is Revolutionizing AI Technology

Artificial Intelligence (AI) has been continually evolving, leading to remarkable advancements in various industries. Among… Read More

8 months ago

Top Magento 2 Extensions for 2023

Extensions, extensions and lots of extensions. We all love extensions, don’t we? After all, extensions… Read More

11 months ago

Unleashing the Power of Software Testing: Cooperating with a Testing Firm

Software quality is crucial to a firm's success across industries in the quickly changing digital… Read More

11 months ago