How to Create a Shipping Method in Magento 2?

Magento 2 shipping extensions can be used for the delivery of the products. It determines the shipping charges and shipping methods for the purchases on ecommerce stores. Some online stores charge a flat rate for orders while some others calculate the shipping costs dynamically using real-time shipping services. The shipping cost depends on several factors such as weight of package, origin, destination, time of delivery, and more.

Magento 2 comes with in-built shipping methods, but if you want to create a custom Magento shipping method, you would need to hire expert Magento developers for customizing the existing extensions or building new ones from the scratch. An experienced and reliable Magento Development Services provider company can help you get the best custom solutions for shipping methods for your online stores.

Related: Build Magento Mobile App for your eCommerce Store

Magento 2 Create Shipping Method provides details about the steps with code snippets to add shipping methods for Magento 2 online store? This guide can help you understand the step-by-step process to create new shipping methods. The shipping methods can be stored in Magento Admin Panel.

This blog post will help you develop your own custom shipping method exactly as per your requirements and choices.

Magento 2 already has certain default shipping methods. But we might need to develop our own shipping methods in Magento 2 in some cases. This blog will helps you to develop your own custom shipping method by just performing following steps.

Steps to create a simple custom shipping method in Magento 2

  • Create a new module
  • Create new fields in admin panel
  • Define shipping model
  • Create a shipping model class
  • Run Commands

Step #1 – Create a new module

To register a new module, create a registration.php file in the below file path and add the given code.

File path: <Magento2_Root>/app/code/Iverve/Customshipping/registration.php


Next, for define the module by creating a module.xml file in the below file path and add the below code.

File path: <Magento2_Root>/app/code/Iverve/Customshipping/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Iverve_Customshipping" setup_version="1.0.0" />

Step #2 – Create New Fields in Admin Panel

In Magento 2, the admin panel should have configuration options for each shipping method. Through the system.xml file, we can generate configuration options for custom shipping method.
File path: <Magento2_Root>/app/code/Iverve/Customshipping/etc/adminhtml/system.xml

[xml]<?xml version=”1.0″?>
<config xmlns_xsi=”” xsi_noNamespaceSchemaLocation=”urn:magento:module:Magento_Config:etc/system_file.xsd”>

<section id=”carriers” translate=”label” type=”text” sortOrder=”320″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″>
<group id=”customshipping” translate=”label” type=”text” sortOrder=”0″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″>
<label>Iverve Custom Shipping Method</label>
<field id=”active” translate=”label” type=”select” sortOrder=”1″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″ canRestore=”1″>
<field id=”name” translate=”label” type=”text” sortOrder=”3″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″ canRestore=”1″>
<label>Method Name</label>
<field id=”price” translate=”label” type=”text” sortOrder=”5″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″ canRestore=”1″>
<validate>validate-number validate-zero-or-greater</validate>
<field id=”handling_type” translate=”label” type=”select” sortOrder=”7″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″ canRestore=”1″>
<label>Calculate Handling Fee</label>
<field id=”handling_fee” translate=”label” type=”text” sortOrder=”8″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″>
<label>Handling Fee</label>
<validate>validate-number validate-zero-or-greater</validate>
<field id=”sort_order” translate=”label” type=”text” sortOrder=”100″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″>
<label>Sort Order</label>
<field id=”title” translate=”label” type=”text” sortOrder=”2″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″ canRestore=”1″>
<field id=”sallowspecific” translate=”label” type=”select” sortOrder=”90″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″ canRestore=”1″>
<label>Ship to Applicable Countries</label>
<field id=”specificcountry” translate=”label” type=”multiselect” sortOrder=”91″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″>
<label>Ship to Specific Countries</label>
<field id=”showmethod” translate=”label” type=”select” sortOrder=”92″ showInDefault=”1″ showInWebsite=”1″ showInStore=”0″>
<label>Show Method if Not Applicable</label>
<field id=”specificerrmsg” translate=”label” type=”textarea” sortOrder=”80″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″ canRestore=”1″>
<label>Displayed Error Message</label>


Step #3 – Define Shipping Model

Now, users can set the default configuration for custom shipping method in the config.xml file in the below path and add the code.
File path: <Magento2_Root>/app/code/Iverve/Customshipping/etc/config.xml

[xml]<?xml version=”1.0″?>
<config xmlns_xsi=”” xsi_noNamespaceSchemaLocation=”urn:magento:module:Magento_Store:etc/config.xsd”>
<name>Iverve Custom Shipping Method</name>
<title>Iverve Custom Shipping Method</title>
<specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>

Here, <default> is a parent node and is its child node, and <customshipping> is the shipping method code. Developers should define the shipping model class with tag.

Step #4 – Create a Shipping Model Class

Once the shipping model class is defined, developers can create a shipping model class in Shipping.php file as shown below:

File path: <Magento2_Root>/app/code/Iverve/Customshipping/Model/Carrier/Shipping.php

[xml]<?php namespace IverveCustomshippingModelCarrier; use MagentoQuoteModelQuoteAddressRateRequest; use MagentoShippingModelRateResult; class Shipping extends MagentoShippingModelCarrierAbstractCarrier implements MagentoShippingModelCarrierCarrierInterface { /** * @var string */ protected $_code = ‘customshipping’; /** * @var MagentoShippingModelRateResultFactory */ protected $_rateResultFactory; /** * @var MagentoQuoteModelQuoteAddressRateResultMethodFactory */ protected $_rateMethodFactory; /** Shipping constructor * @param ScopeConfigInterface $scopeConfig * @param ErrorFactory $rateErrorFactory * @param LoggerInterface $logger * @param ResultFactory $rateResultFactory * @param MethodFactory $rateMethodFactory * @param array $data */ public function __construct( MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig, MagentoQuoteModelQuoteAddressRateResultErrorFactory $rateErrorFactory, PsrLogLoggerInterface $logger, MagentoShippingModelRateResultFactory $rateResultFactory, MagentoQuoteModelQuoteAddressRateResultMethodFactory $rateMethodFactory, array $data = [] ) { $this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);

* get allowed methods
* @return array
public function getAllowedMethods()
return [$this->_code => $this->getConfigData(‘name’)];

* @return float
private function getShippingPrice()
$configPrice = $this->getConfigData(‘price’);

$shippingPrice = $this->getFinalPriceWithHandlingFee($configPrice);

return $shippingPrice;

* @param RateRequest $request
* @return bool|Result
public function collectRates(RateRequest $request)
if (!$this->getConfigFlag(‘active’)) {
return false;

/** @var MagentoShippingModelRateResult $result */
$result = $this->_rateResultFactory->create();

/** @var MagentoQuoteModelQuoteAddressRateResultMethod $method */
$method = $this->_rateMethodFactory->create();



$amount = $this->getShippingPrice();



return $result;


  • Each shipping class in Magento 2 should extend MagentoShippingModelCarrierAbstractCarrier and the MagentoShippingModelCarrierCarrierInterface class should be implemented.
  • The $_code value should be the same name as the system.xml group id.
  • The abstract class and interface requires the two functions getAllowedMethods and collectRates.
  • We need to implement all the logic for our custom shipping calculation in the collectRates function.

Step #5 – Run Commands

After all the above steps are completed, developers should enable custom Magento 2 extensions and install it. For the same, in the CLI go to [magento2_root]/bin directory and run the below command.

php magento module:enable Iverve_Customshipping

After that, in the CLI run below command for upgrade the setup.

php magento setup:upgrade

Now, using the below command in CLI clear the cache.

php magento cache:flush

Log in to Magento 2 admin panel. Go to Stores -> Configuration -> Sales -> click Shipping Methods. You can check custom shipping method configuration.

From the backend, you can enable custom shipping method and also set the configuration values according the needs.
Also Read – How to Configure Shipping Methods in Magento 2
After completing the custom shipping method configuration, the shipping calculation will be displayed on the checkout page.

Helpful reading – How much does a Magento website development cost

It can be a good idea to hire Magento 2 developers to build custom extension for your ecommerce store. There are several ways in which you can add customized shipping methods for your Magento 2 store. Talk to a few experts and get suggestions before you decide upon what features are needed in the extension.