Limit Shopify orders to local zip codes

I have recently been working on a Shopify e-commerce projet. My client needed to restrict shipping to a small range of zip codes : he wanted to focus on local delivery before expanding in other cities in France.

This is impossible to achieve with native functionalities of Shopify, but I came up with a workaround, using pure javascript.

Prerequisite

The technique is to add javascript on the checkout process of Shopify. On the contact informations form submit, the javascript code checks that the zip code is valid. If you don’t know how to add javascript into checkout pages, please read my article : How to add custom javascript into checkout pages.

The source code

First, let’s write the condition to execute the code only on the checkout process :

if(typeof Checkout === 'object'){
    if(typeof Checkout.$ === 'function') {
        // checkout pages
    }
}

Then, we trigger a javascript event on the form submit, and we check that we are on the customer information page.

// On form submit
document.querySelector("form").addEventListener("submit", function(e){

    // are we on the customer information page ? 
    var x = document.getElementsByClassName("step");
    attribute = x[0].getAttribute("data-step");
 
    if (attribute == "contact_information") {
        // OK 
    }
}); 

The next step is to write our array of zip codes, and to check is the submitted zip code is valid.

// zip codes
var zipcodes = ["92200", "92250", "92000"];

var y = document.getElementsByClassName('field__input--zip');
var zipcode = y[0].value; // the submitted zip code

if(zipcode) {
    // is the zip code valid ? 
    var j = -1;
    for (i = 0; i < zipcodes.length; i++) {
        if(zipcodes[i] == zipcode) {
            j = zipcode;
        }
    }
    if(j == -1) { // not valid
        e.preventDefault(); // prevent the form to submit
        alert('The zip code is not valid');
        // red border on the zip code field
        var z = document.getElementsByClassName('field__input--zip')[0].parentElement.parentElement;
        z.className += " field--error";
    }
}

Here you go ! It will prevent the user to proceed to the payment process if the array zipcodes doesn’t contain the submitted value. If you want to change the valid zip codes, just update the array zipcodes.

Drawbacks

This method is really easy to implement. The biggest drawback is that anyone can change the source code with the browser’s developers tools, and override the checks. Nevertheless, there will be no safety issues, as Shopify performs safety checks, server-side. Moreover, the customer has no interest in buying a product unavailable in his city.

Conclusion

As a conclusion, here is the entire source code :

if(typeof Checkout === 'object'){
    if(typeof Checkout.$ === 'function') {
 
        // Form submitted
        document.querySelector("form").addEventListener("submit", function(e){

            // are we on the customer information page ?
            var x = document.getElementsByClassName("step");
            attribute = x[0].getAttribute("data-step");
 
            if (attribute == "contact_information") {
 
                // valid zip codes
                var zipcodes = ["92200", "92250", "92000"];

                var y = document.getElementsByClassName('field__input--zip');
                var zipcode = y[0].value; // the submitted zip code

                if(zipcode) {

                    // is the zip code valid ? 
                    var j = -1;

                    for (i = 0; i < zipcodes.length; i++) {
                        if(zipcodes[i] == zipcode) {
                            j = zipcode;
                        }
                    }
                    if(j == -1) { // invalid zipcode
                        e.preventDefault(); // prevent the form submit
                        alert('The zip code is not valid');
                        // red border on the zip code field
                        var z = document.getElementsByClassName('field__input--zip')[0].parentElement.parentElement;
                        z.className += " field--error";
                    }
                }
            }
        }); 
    }
}

You found another solution ? Please let me know !