Custom Frontend Payment Validation in Magento 2

Custom Frontend Payment Validation in Magento 2
In this article we will review validators used for payment method forms in Magento 2 and create new custom payment validator.

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

Overview

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

Validation Messages for Payment Method in Magento 2

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 a 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_indexindex.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 to introduce 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 customisation is to add custom-validate-card-type validator into data-validate array of validators for the cc_number field. New cusomised 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 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.

magento 2 payment howto

Related Articles

Comments

Next Article Previous Article

LinkedIn Twitter Facebook