preloder

Custom Frontend Payment Validation in Magento 2

Prev Next

In this article, I will go through validators used for payment method forms in Magento 2 and show how to create a new custom validator.

Overview

Sometimes payment methods require additional frontend validations. Whether we want to customize validation message or add extra checks before payment form is marked as valid and data can be sent to a backend for further processing.

Validation Messages for Payment Method in Magento 2

In this article you will learn:

  1. Extending Checkout in Magento 2 using UI Component
  2. How to add custom Payment Method validator using UI Component

Payment Method Validation

For payment method form fields it is expected to have frontend validation. Credit Card validators are located in the Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js JavaScript component. Here is an out-of-box list of validators you may use for your custom payment method implementations:

Validator Message
validate-card-type Please enter a valid credit card type number.
validate-card-number Please enter a valid credit card number.
validate-card-date Incorrect credit card expiration month.
validate-card-cvv Please enter a valid credit card verification number.
validate-card-year Incorrect credit card expiration year.

These validators can be declared for input form field let’s say cc_number to add extra validators once payment form is submitted. Here is an example of using data-bind attribute. This attribute is processed by JavaScript UI Component responsible for rendering a template:

    <input type="number" name="payment[cc_number]" class="input-text" value="" data-bind=" attr: { autocomplete: off, id: getCode() + '_cc_number', 'data-validate': JSON.stringify({ 'required-number':true, 'validate-card-type':getCcAvailableTypesValues(), 'validate-card-number':'#' + getCode() + '_cc_type', 'validate-cc-type':'#' + getCode() + '_cc_type' }) }"/>

Custom Payment Method Validator

In order to add custom validator with new validation message, we need to declare our own UI Component into checkout_index_index.xml layout file. We may add child component into the existing “additional-payment-validators” component declared in the Magento/Checkout/view/frontend/layout/checkout_index_index.xml file.

<item name="additional-payment-validators" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
    <item name="children" xsi:type="array">
        <!-- merge payment validators here -->
        <item name="email-validator" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/email-validator</item>
        </item>
    </item>
</item>

The custom-validator.js file is located in the app/design/frontend/CustomTheme/default/js/model/credit-card-validation/ directory. It allows introducing the custom-validator.js file only in CustomTheme theme. It is useful in case your website is configured to serve 2 and more stores/themes and you would like to change only one of it.

Here is an example of adding custom-validator.js file into app/design/frontend/CustomTheme/default/Magento_Checkout/layout/checkout_index_index.xml file:

<page>
    <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="billing-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="payment" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="additional-payment-validators" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="custom-credit-card-number-validator" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Magento_Payment/js/model/credit-card-validation/custom-validator</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Recommended to Read
Magento 2 Payment Gateway Configuration
Magento 2.1.3 Payment Changes Overview and Recommendations
Database Query Logging in Magento 2

Custom Validator Component

The custom-validator.js JavaScript Component is responsible for declaring custom-validate-card-type validator callback and adding this callback into a list of existing validators using $.validator.addMethod.apply() function call.

/*jshint browser:true jquery:true*/
/*global alert*/
define(
    [
        'jquery',
        'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator'
    ],
    function ($, creditCardNumberValidator) {
        'use strict';

        $.each({
            'custom-validate-card-type': [
                function (number, item, allowedTypes) {
                    var cardInfo, i, l;

                    if (!creditCardNumberValidator(number).isValid) {
                        return false;
                    } else {
                        cardInfo = creditCardNumberValidator(number).card;

                        for (i = 0, l = allowedTypes.length; i < l; i++) {
                            if (cardInfo.title == allowedTypes[i].type) {
                                return true;
                            }
                        }
                        return false;
                    }
                },
                $.mage.__('My Custom Validator Message')
            ]
        }, function (i, rule) {
            rule.unshift(i);
            $.validator.addMethod.apply($.validator, rule);
        });
    }
);

The only missing part left in our customization is to add custom-validate-card-type validator into data-validate array of validators for the cc_number field. Newly customized fields.html (for some payment methods it may be form.html file) template should be located in the app/design/frontend/CustomTheme/default/PronkoRealex/web/template/payment/fields.html file.

<input type="number" name="payment[cc_number]" class="input-text" value="" data-bind=" attr: { autocomplete: off, id: getCode() + '_cc_number', title: $t('Credit Card Number'), 'data-container': getCode() + '-cc-number', 'data-validate': JSON.stringify({ 'required-number':true, 'custom-validate-card-type':getCcAvailableTypesValues(), 'validate-card-number':'#' + getCode() + '_cc_type', 'validate-cc-type':'#' + getCode() + '_cc_type' }) }, enable: isActive($parents), value: creditCardNumber, valueUpdate: 'keyup' "/>

Summary

Hope this information will help you to better understand Frontend part of Checkout in Magento 2. Adding a custom validator for Payment Method is as easy as creating new UI Component and declaring own JavaScript validator to be executed every time payment form is submitted.

Max Pronko is an international Magento Expert, development consultant, motivational speaker and Magento award-winning developer. He is known for the educational development programs for organizations of all sizes and has positively affected thousands of people and organizations worldwide.

Posted on Dec 19, 2016

The Devletter

Subscribe to my Magento 2 tips and tutorials content.
Every week I send an interesting email directly to your inbox

Related Posts