We all know that it’s necessary for Magento 2 create custom shipping method. Especially, when eCommerce becomes popular, the market needs more advanced features in shipping methods. Thus, in this Magento tutorial series for beginner, we write this article to give you instructions on how to create custom shipping method in Magento 2. Don’t worry too much if your tech knowledge is limited, we will provide you with an optimal solution in the last part.
Magento 2 Create Custom Shipping Method Programmatically
Table of Contents
Step 1: Create a New Module
To Magento 2 create custom shipping method, we need to create a new module.
Create a registration.php file in the following address – app/code/BSS/CustomShipping/registration.php
<?php declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'BSS_CustomShipping', __DIR__ );
Then, create composer.json in app/code/BSS/CustomShipping/composer.json with the following code:
{ "name": "BSS/module-custom-shipping", "description": "Custom shipping module", "require": { "php": "~7.4.0||~8.1.0", "magento/framework": "102.0.*", "magento/module-backend": "101.0.*", "magento/module-catalog": "103.0.*", "magento/module-config": "101.1.*", "magento/module-directory": "100.3.*", "magento/module-quote": "101.1.*", "magento/module-sales": "102.0.*", "magento/module-sales-rule": "101.1.*", "magento/module-shipping": "100.3.*", "magento/module-store": "101.0.*" }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], "autoload": { "files": [ "registration.php" ], "psr-4": { "BSS\\CustomShipping\\": "" } } }
In the next step to complete create a new module, we must create the module.xml file in app/code/BSS/CustomShipping/etc/module.xml
<?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="BSS_CustomShipping"/> </config> <?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="BSS_CustomShipping"/> </config>
Step 2: Add the Carrier Configuration
After having the folders, we need to set the configuration for our module. And to add a module configuration use the following code snippets.
Firstly, we need to create system.xml file to declare custom shipping module options (Enabled, Title, Method Name, Shipping Cost, Ship to Applicable Countries, Ship to Specific Countries, Show Method if Not Applicable, Sort Order).
In app/code/BSS/CustomShipping/etc/adminhtml/system.xml, use the following code to create system.xml file:
<?xml version="1.0"?> <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"> <group id="customshipping" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Custom Shipping Module</label> <field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Enabled</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> <field id="title" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Title</label> </field> <field id="name" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Method Name</label> </field> <field id="shipping_cost" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Shipping Cost</label> <validate>validate-number validate-zero-or-greater</validate> </field> <field id="sallowspecific" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <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="60" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <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="70" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Show Method if not applicable</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <frontend_class>shipping-skip-hide</frontend_class> </field> <field id="sort_order" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Sort Order</label> </field> </group> </section> </system> </config>
In the source app/code/BSS/CustomShipping/etc/config.xml, we have to create a config.xml file that specifies default values for custom shipping module options and the shipping module model, BSS\CustomShipping\Model\Carrier\Customshipping:
<?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> <customshipping> <active>0</active> <title>Custom Shipping Title</title> <name>Custom Shipping Method Name</name> <shipping_cost>10</shipping_cost> <sallowspecific>0</sallowspecific> <sort_order>15</sort_order> <model>BSS\CustomShipping\Model\Carrier\Customshipping</model> </customshipping> </carriers> </default> </config>
Step 3: Create the Carrier Model
Next step, it’s necessary to create the carrier model. In this example, the BSS\CustomShipping\Model\Carrier\Customshipping class is a skeleton of a carrier model. You can also extend it to fit your needs.
The carrier-class implements the CarrierInterface interface and retrieves all available shipping methods in the getAllowedMethods function. If the carrier method is available on checkout, the collectRates function returns the \Magento\Shipping\Model\Rate\Result object. On the other hand, when the carrier method does not apply to the shopping cart, it returns false.
Use the following command in app/code/BSS/CustomShipping/Model/Carrier/Customshipping.php
<?php declare(strict_types=1); namespace BSS\CustomShipping\Model\Carrier; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Quote\Model\Quote\Address\RateRequest; use Magento\Quote\Model\Quote\Address\RateResult\Method; use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory; use Magento\Shipping\Model\Carrier\AbstractCarrier; use Magento\Shipping\Model\Carrier\CarrierInterface; use Magento\Shipping\Model\Rate\Result; use Magento\Shipping\Model\Rate\ResultFactory; use Psr\Log\LoggerInterface; class Customshipping extends AbstractCarrier implements CarrierInterface { protected string $_code = 'customshipping'; protected bool $_isFixed = true; private ResultFactory $rateResultFactory; private MethodFactory $rateMethodFactory; public function __construct( ScopeConfigInterface $scopeConfig, ErrorFactory $rateErrorFactory, LoggerInterface $logger, ResultFactory $rateResultFactory, MethodFactory $rateMethodFactory, array $data = [] ) { parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data); $this->rateResultFactory = $rateResultFactory; $this->rateMethodFactory = $rateMethodFactory; } /** * Custom Shipping Rates Collector * * @param RateRequest $request * @return \Magento\Shipping\Model\Rate\Result|bool */ public function collectRates(RateRequest $request) { if (!$this->getConfigFlag('active')) { return false; } /** @var Method $method */ $method = $this->rateMethodFactory->create(); $method->setCarrier($this->_code); $method->setCarrierTitle($this->getConfigData('title')); $method->setMethod($this->_code); $method->setMethodTitle($this->getConfigData('name')); $shippingCost = (float) $this->getConfigData('shipping_cost'); $method->setPrice($shippingCost); $method->setCost($shippingCost); /** @var Result $result */ $result = $this->rateResultFactory->create(); $result->append($method); return $result; } public function getAllowedMethods(): array { return [$this->_code => $this->getConfigData('name')]; } }
If the carrier method is unavailable, it returns false; streamline your checkout with Magento 2 One Step Checkout for better conversions.
Step 4: Enable the Module
We are almost complete Magento 2 create custom shipping method. To enable the module, run this command:
bin/magento module:enable BSS_CustomShipping
Now, check your change in backend.
>>> Transform Your E-Commerce Business Today with Magento eCommerce development services
Magento 2 Create Shipping Method using Magento Extension
As I revealed at the beginning, besides the custom shipping method in Magento 2 solution programmatically, I introduce to you the Magento 2 Custom Shipping Method extension. With this extension, you can easily add new shipping method in Magento 2 stores to manage and control all custom methods wherever your country and region. Besides, not only developing the default features that Magento provides, our extensions can also customize advanced features to better support the shipping process.
With affordable price and comprehensive support, we believe that this extension is the best solution for your Magento store‘s shipping issues.
Additionally, we also provide the top 7 best Magento 2 Shipping extensions free & premium to enhance online shopping experience for your customers.
>>> LEARN MORE: How To Install Magento Extension: The Comprehensive Guide
Wrap-up
Above are detailed instructions on Magento 2 create custom shipping method in 2 ways. Hopefully, with our instructions, you can easily add a custom shipping method in Magento 2 backend. Besides, BSS Commerce also brings a collection of plugins for Magento stores. Please explore and contact us at any time to receive the best support.