How to add custom shipping validations Magento 2

Discover how Magento 2 allows you to implement shipping validations, ensuring transparency and accurate collection of the necessary shipping information for a seamless e-commerce experience

Shipping validation in Magento 2 serves the purpose of verifying and ensuring the accuracy of shipping information provided by customers during the checkout process. It helps to validate critical aspects such as addresses, shipping methods, and other related details. By implementing shipping validations, you can enhance the overall order fulfillment process, minimize errors, reduce shipping delays, and provide a seamless customer experience.

For developers, this shipping validator will trigger the checkout module to load (ajax) the shipping method details when users entering information.
This is an essential part of the bigger task of adding a custom shipping method to your Magento store.


Custom Checkout Fields

Custom Checkout Fields for Magento 2

Collect extra customer data at the checkout page to improve marketing strategy

Check it out!


In this article, we will take a look at Magento default/native carriers and then implement our own rules/validator.

Having issues with adding custom shipping validations in Magento 2? Don’t worry! This tutorial is all you need.

Customize shipping carrier validator.

You should know how to create a basic Magento 2 module. All of customized files will be inside this module.

Let’s begin.

Step 1: Understand TableRate validator.

Since the validator bases on the rules we will check the rules first.
Just bear with me a bit, we will know exactly what they are soon.

The code from the TableRate Rules js/model/shipping-rates-validation-rules/tablerate.js as below

/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
/*global define*/
define(
    [],
    function () {
        "use strict";
        return {
            getRules: function() {
                return {
                    'postcode': {
                        'required': true
                    },
                    'country_id': {
                        'required': true
                    },
                    'region_id': {
                        'required': true
                    },
                    'region_id_input': {
                        'required': true
                    }
                };
            }
        };
    }
);

Only one defined function getRules, this is where we define our rules.
For the tableRate, it requires country, state, postcode to be filled in before loading/triggering the Shipping method details.

This is the code from TableRate Validator /js/model/shipping-rates-validator/tablerate.js

/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
/*global define*/
define(
    [
        'jquery',
        'mageUtils',
        '../shipping-rates-validation-rules/tablerate',
        'mage/translate'
    ],
    function ($, utils, validationRules, $t) {
        'use strict';
        return {
            validationErrors: [],
            validate: function (address) {
                var self = this;
                this.validationErrors = [];
                $.each(validationRules.getRules(), function (field, rule) {
                    if (rule.required && utils.isEmpty(address[field])) {
                        var message = $t('Field ') + field + $t(' is required.');
                        var regionFields = ['region', 'region_id', 'region_id_input'];
                        if (
                            $.inArray(field, regionFields) === -1
                            || utils.isEmpty(address['region']) && utils.isEmpty(address['region_id'])
                        ) {
                            self.validationErrors.push(message);
                        }
                    }
                });
                return !Boolean(this.validationErrors.length);
            }
        };
    }
);

The main method here is the validate method, this method is required for every validator.
The code is simple, what it does is checking whether those required fields have been fulfilled.

Here is the price information bases on each country/region
tableRate information

To test this validator, you should use TableRates as the only Shipping Carrier. Read more about Shipping Settings here

First, I add a $45 item to the cart which will result in $15 shipping price, fill in all required information except for State/Province information. When I change the State to Alaska (abbr: AK), the shipping method will reload.
Here is the video that demonstrates step by step: https://www.screencast.com/t/PuK9hy5zYaP

Step 2: Create a custom rule/validator.

We need 3 files: 2 files to define getRules and validate functions. The last file is responsible for letting Magento knows the existence of our new code (Registering our validator).
Since we don’t have a new carrier, we will overwrite tablerate. Instead of using Magento’s table rate rules and validator, it will use our created rules and validator.

Step 2.1 Add Shipping rate validation rules

Create the tablerate.js file under Mageplaza/HelloWorld/view/frontend/web/js/model/shipping-rates-validation-rules directory.

define(
    [],
    function () {
        "use strict";
        return {
            getRules: function() {
                return {
                    'region_id': {
                        'required': true
                    },
                    'region_id_input': {
                        'required': true
                    },
                    'telephone': {
                        'required': true
                    }
                };
            }
        };
    }
);

Step 2.2: Add Shipping Rates Validator

Create the tablerate.js file under Mageplaza/HelloWorld/view/frontend/web/js/model/shipping-rates-validator directory.

define(
    [
        'jquery',
        'mageUtils',
        '../shipping-rates-validation-rules/tablerate',
        'mage/translate'
    ],
    function ($, utils, validationRules, $t) {
        'use strict';
        return {
            validationErrors: [],
            validate: function (address) {
                var self = this;
                this.validationErrors = [];

                $.each(validationRules.getRules(), function (field, rule) {
                    if (rule.required && field === 'telephone' & address[field] !== '911') {
                        self.validationErrors.push(1);
                    }
                });
                return !!!(this.validationErrors.length);
            }
        };
    }
);

Step 2.3: Registering our validator

To register our new validator, we must add it to the pool of validators.
To do this, in the Mageplaza/HelloWorld/view/frontend/web/js/view directory create a new tablerate.js file with the following content:

define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/shipping-rates-validator',
        'Magento_Checkout/js/model/shipping-rates-validation-rules',
        '../model/shipping-rates-validator/tablerate',
        '../model/shipping-rates-validation-rules/tablerate'
    ],
    function (
        Component,
        defaultShippingRatesValidator,
        defaultShippingRatesValidationRules,
        shippingRatesValidator,
        shippingRatesValidationRules
    ) {
        'use strict';
        defaultShippingRatesValidator.registerValidator('tablerate', shippingRatesValidator);
        defaultShippingRatesValidationRules.registerRules('tablerate', shippingRatesValidationRules);
        return Component;
    }
);

Step 2.4 Add the validation to the checkout layout

Add the following code to Mageplaza/HelloWorld/view/frontend/layout/checkout_index_index.xml

 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceBlock name="checkout.root">
                 <arguments>
                     <argument name="jsLayout" xsi:type="array">
                         <item name="components" xsi:type="array">
                             <item name="checkout" xsi:type="array">
                                 <item name="children" xsi:type="array">
                                     <item name="steps" xsi:type="array">
                                         <item name="children" xsi:type="array">
                                             <item name="shipping-step" xsi:type="array">
                                                 <item name="children" xsi:type="array">
                                                     <!-- add a new validator-->
                                                     <item name="step-config" xsi:type="array">
                                                         <item name="children" xsi:type="array">
                                                             <item name="shipping-rates-validation" xsi:type="array">
                                                                 <item name="children" xsi:type="array">
                                                                     <item name="tablerate" xsi:type="array">
                                                                         <item name="component" xsi:type="string">Mageplaza_HelloWorld/js/view/tablerate</item>
                                                                     </item>
                                                                 </item>
                                                             </item>
                                                         </item>
                                                     </item>
                                                 </item>
                                             </item>
                                         </item>
                                     </item>
                                 </item>
                             </item>
                         </item>
                     </argument>
                 </arguments>
         </referenceBlock>
     </body>
 </page>

The code is simple, it only applies TableRate when the telephone field has the value of 911.

Step 3: Flush cache and test result

Now time to flush cache and test your result. If you have any issue, feel free to leave a comment below, Mageplaza and Magento community are willing to help.

Final words

That’s all about custom shipping validations in Magento 2. I hope this tutorial is helpful for you. If you have any questions, feel free to let me know in the comment section. Thanks for reading!

Table Rate Shipping

Table Rate Shipping for Magento 2

Create unlimited custom shipping methods and shipping rates for customers

Learn more


Enjoyed the tutorial? Spread it to your friends!

Vinh Jacker
Vinh Jacker

Hello, I’m the Chief Technology Officer of Mageplaza, and I am thrilled to share my story with you. My deep love and passion for technology have fueled my journey as a professional coder and an ultra-marathon runner. Over the past decade, I have accumulated extensive experience and honed my expertise in PHP development.

People also searched for

  • Customize shipping
  • shipping validate Magento 2
  • 2.2.x, 2.3.x, 2.4.x