In this post, we will check how to create custom shipping method based on a percentage of cart price.
You can find complete module on Github.
Step 1: Create a new module
Create folder inside app/code/Magelearn/PercentageShipping
Add registration.php file in it:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Magelearn_PercentageShipping',
__DIR__
);
Add composer.json file in it:{
"name": "magelearn/module-percentageshipping",
"description": "Shipping method based on a percentage of cart price.",
"type": "magento2-module",
"license": "OSL-3.0",
"authors": [
{
"email": "info@mage2gen.com",
"name": "Mage2Gen"
},
{
"email": "vijaymrami@gmail.com",
"name": "vijay rami"
}
],
"minimum-stability": "dev",
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Magelearn\\PercentageShipping\\": ""
}
}
}<?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="Magelearn_PercentageShipping" setup_version="1.0.0">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
<module name="Magento_SalesRule"/>
</sequence>
</module>
</config>Step 2: Add the module configuration
- Enabled
- Title
- Method Name
- Shipping Cost
- Ship to Applicable Countries
- Ship to Specific Countries
- Show Method if Not Applicable
- Sort Order
<?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" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="percentageshipping" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Percentage Shipping</label>
<field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" 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="0">
<label>Title</label>
</field>
<field id="name" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Method Name</label>
</field>
<field id="shipping_percentage" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0" >
<label>Shipping Percentage</label>
<validate>validate-number validate-zero-or-greater</validate>
</field>
<field id="sallowspecific" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0" 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="70" 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="80" showInDefault="1" showInWebsite="1" showInStore="0">
<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="90" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Sort Order</label>
</field>
</group>
</section>
</system>
</config>Create etc/config.xml file.
The config.xml file specifies default values for custom shipping module options and the shipping module model, Magelearn\PercentageShipping\Model\Carrier\PercentageShipping:
<?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>
<percentageshipping>
<active>0</active>
<title>Percentage Shipping</title>
<name>Percentage Shipping</name>
<shipping_percentage>7</shipping_percentage>
<sallowspecific>0</sallowspecific>
<sort_order>15</sort_order>
<specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
<model>Magelearn\PercentageShipping\Model\Carrier\PercentageShipping</model>
</percentageshipping>
</carriers>
</default>
</config>Step 3: Create the carrier model
<?php
declare(strict_types=1);
namespace Magelearn\PercentageShipping\Model\Carrier;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Rate\Result;
/**
* Class PercentageShipping
* @package Magelearn\PercentageShipping\Model\Carrier
*/
class PercentageShipping extends AbstractCarrier implements CarrierInterface
{
/**
* @var string
*/
protected $_code = 'percentageshipping';
/**
* @var bool
*/
protected $_isFixed = true;
/**
* @var \Magento\Shipping\Model\Rate\ResultFactory
*/
private $rateResultFactory;
/**
* @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
*/
private $rateMethodFactory;
/**
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
* @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
* @param array $data
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
\Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
array $data = []
) {
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
$this->rateResultFactory = $rateResultFactory;
$this->rateMethodFactory = $rateMethodFactory;
}
/**
* Percentage Shipping Rates Collector
*
* @param RateRequest $request
* @return Result
*/
public function collectRates(RateRequest $request) : Result
{
$result = $this->rateResultFactory->create();
if (!$this->getConfigFlag('active')) {
return $result;
}
$method = $this->rateMethodFactory->create();
$method->setCarrier($this->_code);
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod($this->_code);
$method->setMethodTitle($this->getConfigData('name'));
$shippingPercentage = (float)$this->getConfigData('shipping_percentage') / 100;
$shippingPercentage = $shippingPercentage > 1 ? 1 : $shippingPercentage;
$shippingCost = $request->getPackageValue() * $shippingPercentage;
$method->setPrice($shippingCost);
$method->setCost($shippingCost);
$result->append($method);
return $result;
}
/**
* @return array
*/
public function getAllowedMethods() : array
{
return [$this->_code => $this->getConfigData('name')];
}
}After adding above files, just run Magento commands:
php bin/magento set:upg
php bin/magento set:d:c
php bin/magento set:s:d en_US
php bin/magento c:c
php bin/magento c:f
Now, you can see new shipping method configuration will display at Store >> Configuration >> Sales >> Shipping Method
And also new shipping method will be display on checkout page as per the screenshot at above.


0 Comments On "Magento2 Create Custom Shipping Method Based On a Percentage of Cart Price"