Creating a New Shipping Method In Magento 2
Configuring shipping methods is crucial for any ecommerce business that sells physical products.
Shipping methods determine how products are delivered to customers and directly impact the customer’s shopping experience.
<?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="Hikmadh_Shipping" setup_version="1.0.0"/>
</config>
2.Create the registration file “registration.php” where ‘app/code/Hikmadh/Shipping”.Use the following code.
<?php
\Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Hikmadh_Shipping', __DIR__);
3.Enable the module by typing the following command into your terminal
php bin/magento module:enable Hikmadh_Shipping
Step 2: Create The Configuration File.
- Create a configuration file system.xml at app/code/Hikmadh/Pay/etc/adminhtml/system.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2023 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="hmcustomshipping" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Hikmadh 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>

Step 3: Create config.xml
- Create config.xml file in app/code/Hikmadh/Shipping/etc/ folder as follows :
<?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>
<custom>
<active>1</active>
<sallowspecific>0</sallowspecific>
<model>Hikmadh\Shipping\Model\Carrier\Custom</model>
<name>Custom Shipping</name>
<handling_type>F</handling_type>
<price>15.00</price>
<title>Custom Method</title>
<type>I</type>
<specificerrmsg>This shipping method is not available right now.</specificerrmsg>
</custom>
</carriers>
</default>
</config>
Step 4: Create shipping model
- Create Custom.php file at app/code/Hikmadh/Shipping/Model/Carrier/Custom.php and add below code to this
<?php
namespace Hikmadh\Shipping\Model\Carrier;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Psr\Log\LoggerInterface;
use Magento\Shipping\Model\Rate\ResultFactory;
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
class Custom extends AbstractCarrier implements CarrierInterface
{
protected $_code = 'custom';
protected $rateResultFactory;
protected $rateMethodFactory;
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);
}
public function getAllowedMethods()
{
return ['custom' => $this->getConfigData('name')];
}
public function collectRates(RateRequest $request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
/** @var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->rateResultFactory->create();
/** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
$method = $this->rateMethodFactory->create();
$method->setCarrier('custom');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('custom');
$method->setMethodTitle($this->getConfigData('name'));
/*you can fetch shipping price from different sources over some APIs, we used price from config.xml - xml node price*/
$amount = $this->getConfigData('price');
$shippingPrice = $this->getFinalPriceWithHandlingFee($amount);
$method->setPrice($shippingPrice);
$method->setCost($amount);
$result->append($method);
return $result;
}
}