{"id":737,"date":"2019-12-27T11:52:10","date_gmt":"2019-12-27T11:52:10","guid":{"rendered":"https:\/\/meetanshi.com\/blog\/2019\/12\/27\/magento-2-create-shipping-method\/"},"modified":"2025-07-24T15:12:32","modified_gmt":"2025-07-24T09:42:32","slug":"magento-2-create-shipping-method","status":"publish","type":"post","link":"https:\/\/meetanshi.com\/blog\/magento-2-create-shipping-method\/","title":{"rendered":"Try Our Programmatic Shipping Method In Magento 2"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">E-commerce is all about customer convenience. Offering a convenient shipping method is an inevitable part of customer experience in an online store. By default, there are 7 Magento 2 shipping methods:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Free Shipping<\/li>\n\n\n\n<li>Flat Rates<\/li>\n\n\n\n<li>Table Rates<\/li>\n\n\n\n<li>UPS<\/li>\n\n\n\n<li>USPS<\/li>\n\n\n\n<li>FedEx<\/li>\n\n\n\n<li>DHL<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">You can also learn how to <a href=\"https:\/\/meetanshi.com\/blog\/configure-magento-2-shipping-methods\/\" target=\"_blank\" rel=\"noreferrer noopener\">configure Magento 2 shipping methods<\/a> easily.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, as E-commerce popularity increases, more and more types of businesses opt for an online shopping platform, particularly Magento, owing to its features and performance. But, these default shipping methods are not enough for all the types of businesses these days.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, I&#8217;ve come up with a programmatic method to create shipping method in Magento 2 store.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A custom shipping method implemented keeping in mind the business requirement is a feasible option. A shipping strategy must be such that it does not end in the cost of order fulfillment more than the profit from that order.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An ideal shipping method must be manageable, quick, as well as affordable. It is not necessary that every store owner can find such a shipping method from the default Magento 2 shipping methods for his\/her business.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Programmatically creating a custom shipping method in Magento 2 store that suits your business requirements and is feasible is the most optimized solution for having the correct shipping system. Also if you want to enhance the user experience by providing real time cost calculation, transparency and essential shipping information then <a href=\"https:\/\/meetanshi.com\/blog\/update-checkout-summary-on-selecting-shipping-method-in-magento-2\/\">update checkout summary on selecting shipping method in Magento 2<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Why am I stressing so much about having an optimized shipping strategy?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The below statistics explains why:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>61% shoppers report leaving a transaction due to an extra cost such as shipping fees &#8211; <a href=\"https:\/\/99firms.com\/blog\/ecommerce-statistics\/#gref\" target=\"_blank\" rel=\"noreferrer noopener\">99firms<\/a><\/li>\n\n\n\n<li>79% of US consumers said that free shipping would make them more likely to shop online. &#8211; <a href=\"https:\/\/www.walkersands.com\/wp-content\/uploads\/2018\/07\/Walker-Sands_2018-Future-of-Retail-Report.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">Walkersands<\/a><\/li>\n\n\n\n<li>46.5% of small to mid-sized businesses say that offering free shipping increases their profits. &#8211; <a href=\"https:\/\/multichannelmerchant.com\/operations\/shopping-cart-abandonment-is-your-shipping-approach-hurting-your-conversions\/\" target=\"_blank\" rel=\"noreferrer noopener\">MCM<\/a><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Steps to Create Shipping Method In Magento 2:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">1. Create <strong>registration.php<\/strong> file at <strong>app\/code\/Meetanshi\/CustomShipping\/registration.php<\/strong>&nbsp;and add below code to this file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> &lt;?php\n\\Magento\\Framework\\Component\\ComponentRegistrar::register(\n    \\Magento\\Framework\\Component\\ComponentRegistrar::MODULE,\n    'Meetanshi_CustomShipping',\n    __DIR__\n);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Create&nbsp;<strong>module.xml<\/strong>&nbsp;file at&nbsp;<strong>app\/code\/Meetanshi\/CustomShipping\/etc\/module.xml&nbsp;<\/strong>and add below code to this file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?xml version=\"1.0\"?>\n&lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:Module\/etc\/module.xsd\">\n    &lt;module name=\"Meetanshi_CustomShipping\" setup_version=\"1.0.0\">\n    &lt;\/module>\n&lt;\/config><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Create&nbsp;<strong>system.xml<\/strong>&nbsp;file at&nbsp;<strong>app\/code\/Meetanshi\/CustomShipping\/etc\/adminhtml\/system.xml<\/strong>&nbsp;and add below code to this file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?xml version=\"1.0\"?>\n&lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:module:Magento_Config:etc\/system_file.xsd\">\n    &lt;system>\n        &lt;section id=\"carriers\" translate=\"label\" type=\"text\" sortOrder=\"320\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">\n            &lt;group id=\"custom\" translate=\"label\" type=\"text\" sortOrder=\"0\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">\n                &lt;label>Custom Shipping&lt;\/label>\n                &lt;field id=\"active\" translate=\"label\" type=\"select\" sortOrder=\"1\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Enabled&lt;\/label>\n                    &lt;source_model>Magento\\Config\\Model\\Config\\Source\\Yesno&lt;\/source_model>\n                &lt;\/field>\n                &lt;field id=\"name\" translate=\"label\" type=\"text\" sortOrder=\"3\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">\n                    &lt;label>Method Name&lt;\/label>\n                &lt;\/field>\n                &lt;field id=\"price\" translate=\"label\" type=\"text\" sortOrder=\"5\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Price&lt;\/label>\n                    &lt;validate>validate-number validate-zero-or-greater&lt;\/validate>\n                &lt;\/field>\n                &lt;field id=\"handling_type\" translate=\"label\" type=\"select\" sortOrder=\"7\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Calculate Handling Fee&lt;\/label>\n                    &lt;source_model>Magento\\Shipping\\Model\\Source\\HandlingType&lt;\/source_model>\n                &lt;\/field>\n                &lt;field id=\"handling_fee\" translate=\"label\" type=\"text\" sortOrder=\"8\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Handling Fee&lt;\/label>\n                    &lt;validate>validate-number validate-zero-or-greater&lt;\/validate>\n                &lt;\/field>\n                &lt;field id=\"sort_order\" translate=\"label\" type=\"text\" sortOrder=\"100\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Sort Order&lt;\/label>\n                &lt;\/field>\n                &lt;field id=\"title\" translate=\"label\" type=\"text\" sortOrder=\"2\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">\n                    &lt;label>Title&lt;\/label>\n                &lt;\/field>\n                &lt;field id=\"sallowspecific\" translate=\"label\" type=\"select\" sortOrder=\"90\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Ship to Applicable Countries&lt;\/label>\n                    &lt;frontend_class>shipping-applicable-country&lt;\/frontend_class>\n                    &lt;source_model>Magento\\Shipping\\Model\\Config\\Source\\Allspecificcountries&lt;\/source_model>\n                &lt;\/field>\n                &lt;field id=\"specificcountry\" translate=\"label\" type=\"multiselect\" sortOrder=\"91\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Ship to Specific Countries&lt;\/label>\n                    &lt;source_model>Magento\\Directory\\Model\\Config\\Source\\Country&lt;\/source_model>\n                    &lt;can_be_empty>1&lt;\/can_be_empty>\n                &lt;\/field>\n                &lt;field id=\"showmethod\" translate=\"label\" type=\"select\" sortOrder=\"92\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">\n                    &lt;label>Show Method if Not Applicable&lt;\/label>\n                    &lt;source_model>Magento\\Config\\Model\\Config\\Source\\Yesno&lt;\/source_model>\n                &lt;\/field>\n                &lt;field id=\"specificerrmsg\" translate=\"label\" type=\"textarea\" sortOrder=\"80\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">\n                    &lt;label>Displayed Error Message&lt;\/label>\n                &lt;\/field>\n            &lt;\/group>\n        &lt;\/section>\n    &lt;\/system>\n&lt;\/config><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Create&nbsp;<strong>config.xml<\/strong>&nbsp;file at&nbsp;<strong>app\/code\/Meetanshi\/CustomShipping\/etc\/config.xml&nbsp;<\/strong>and add below code to this file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?xml version=\"1.0\"?>\n&lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n        xsi:noNamespaceSchemaLocation=\"urn:magento:module:Magento_Store:etc\/config.xsd\">\n    &lt;default>\n        &lt;carriers>\n            &lt;custom>\n                &lt;active>1&lt;\/active>\n                &lt;sallowspecific>0&lt;\/sallowspecific>\n                &lt;model>Meetanshi\\CustomShipping\\Model\\Carrier\\Custom&lt;\/model>\n                &lt;name>Custom Shipping&lt;\/name>\n                &lt;handling_type>F&lt;\/handling_type>\n                &lt;price>15.00&lt;\/price>\n                &lt;title>Custom Method&lt;\/title>\n                &lt;type>I&lt;\/type>\n                &lt;specificerrmsg>This shipping method is not available right now.&lt;\/specificerrmsg>\n            &lt;\/custom>\n        &lt;\/carriers>\n    &lt;\/default>\n&lt;\/config><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">5. Create&nbsp;<strong>Custom.php<\/strong>&nbsp;file at&nbsp;<strong>app\/code\/Meetanshi\/CustomShipping\/Model\/Carrier\/Custom.php&nbsp;<\/strong>and add below code to this file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n \nnamespace Meetanshi\\CustomShipping\\Model\\Carrier;\n \nuse Magento\\Quote\\Model\\Quote\\Address\\RateRequest;\nuse Magento\\Shipping\\Model\\Rate\\Result;\nuse Magento\\Shipping\\Model\\Carrier\\AbstractCarrier;\nuse Magento\\Shipping\\Model\\Carrier\\CarrierInterface;\nuse Magento\\Framework\\App\\Config\\ScopeConfigInterface;\nuse Magento\\Quote\\Model\\Quote\\Address\\RateResult\\ErrorFactory;\nuse Psr\\Log\\LoggerInterface;\nuse Magento\\Shipping\\Model\\Rate\\ResultFactory;\nuse Magento\\Quote\\Model\\Quote\\Address\\RateResult\\MethodFactory;\n \nclass Custom extends AbstractCarrier implements CarrierInterface\n{\n \n    protected $_code = 'custom';\n \n    protected $rateResultFactory;\n \n    protected $rateMethodFactory;\n \n    public function __construct(\n        ScopeConfigInterface $scopeConfig,\n        ErrorFactory $rateErrorFactory,\n        LoggerInterface $logger,\n        ResultFactory $rateResultFactory,\n        MethodFactory $rateMethodFactory,\n        array $data = []\n    )\n    {\n        $this->rateResultFactory = $rateResultFactory;\n        $this->rateMethodFactory = $rateMethodFactory;\n        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);\n    }\n \n    public function getAllowedMethods()\n    {\n        return ['custom' => $this->getConfigData('name')];\n    }\n \n    public function collectRates(RateRequest $request)\n    {\n        if (!$this->getConfigFlag('active')) {\n            return false;\n        }\n \n        \/** @var \\Magento\\Shipping\\Model\\Rate\\Result $result *\/\n        $result = $this->rateResultFactory->create();\n \n        \/** @var \\Magento\\Quote\\Model\\Quote\\Address\\RateResult\\Method $method *\/\n        $method = $this->rateMethodFactory->create();\n \n        $method->setCarrier('custom');\n        $method->setCarrierTitle($this->getConfigData('title'));\n \n        $method->setMethod('custom');\n        $method->setMethodTitle($this->getConfigData('name'));\n \n        \/*you can fetch shipping price from different sources over some APIs, we used price from config.xml - xml node price*\/\n        $amount = $this->getConfigData('price');\n        $shippingPrice = $this->getFinalPriceWithHandlingFee($amount);\n        $method->setPrice($shippingPrice);\n        $method->setCost($amount);\n \n        $result->append($method);\n \n        return $result;\n    }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s all to create a custom shipping method in Magento 2. Once you have created Magento 2 custom shipping method, it\u2019s configuration is shown in the backend:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/meetanshi.com\/blog\/wp-content\/uploads\/2019\/12\/shipping-method-configuration-1024x480.png\" alt=\"custom shipping method configuration\" class=\"wp-image-7186\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once the custom shipping method is configured and enabled, it\u2019s shown in the frontend:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/meetanshi.com\/blog\/wp-content\/uploads\/2019\/12\/shipping-method-in-frontend.png\" alt=\"custom shipping method in frontend\" class=\"wp-image-7187\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Showing multiple shipping methods to customers, learn&nbsp;<a href=\"https:\/\/meetanshi.com\/blog\/auto-select-shipping-method-in-magento-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">auto select shipping method in Magento 2<\/a>&nbsp;and offer a convenient experience to the customers. You may directly use the&nbsp;<a href=\"https:\/\/meetanshi.com\/magento-2-shipping-table-rates.html\" target=\"_blank\" rel=\"noreferrer noopener\">Magento 2 Shipping Table Rates<\/a>&nbsp;extension instead of implementing the above solution yourself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have a look at the range of&nbsp;<a href=\"https:\/\/meetanshi.com\/magento-2-shipping-extensions.html\" target=\"_blank\" rel=\"noreferrer noopener\">Magento 2 Shipping Extensions<\/a>&nbsp;to enhance the shipping system of your Magento 2 store!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Please share the post with the Magento community via social media.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thank you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>E-commerce is all about customer convenience. Offering a convenient shipping method is an inevitable part of customer experience in an online store. By default, there&#8230;<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[34],"tags":[],"class_list":["post-737","post","type-post","status-publish","format-standard","hentry","category-magento"],"acf":[],"_links":{"self":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/comments?post=737"}],"version-history":[{"count":4,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/737\/revisions"}],"predecessor-version":[{"id":15135,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/737\/revisions\/15135"}],"wp:attachment":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/media?parent=737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/categories?post=737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/tags?post=737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}