Thursday, March 15, 2012

jQuery Validation plugin and Credit Card validation issue

This post is just a simple solution to a situation that we ran into in one of my previous projects. We were using jQuery Validation plugin to validate forms in our project and found issues with credit card number validation.

I did some research on the internet related to this issue and found a very interesting post "Validation using 'creditcard2' extension". It is another extension which extends credit card validation for jQuery Validation plugin. Here are some issues fixed in this new extension:

Validation using jQuery Validation extension:

542418083235Passes
5424180832351Passes
41111111111111113Passes
370000000000002Passes
4111111111111111Passes

Validation using jQuery 'CreditCard2' Validation extension:

542418083235Fails
5424180832351Fails
41111111111111113Fails
370000000000002Passes
4111111111111111Passes

After adding new 'CreditCard2' extension in our project along with jQuery Validation extension at least we got the fix for credit card number. Than we ran into another issue related to credit card type. Both extensions require "Card Type" as a field on the form. As per the project requirement we need to get payment details without asking for "Card Type". Based on the entered credit card number we need to figure out which card type is this. To fulfill this requirement with the existing extension, I made a change in ‘CreditCard2’ extension. This is as followings:

Added a new method in script to get the card type from number:

function CreditCardTypeFromNumber(num) {
// first, sanitize the number by removing all non-digit characters.
num = num.replace(/[^\d]/g, '');
// now test the number against some regexes to figure out the card type.
if (num.match(/^5[1-5]\d{14}$/)) {
return 'MasterCard';
} else if (num.match(/^4\d{15}/) || num.match(/^4\d{12}/)) {
return 'Visa';
} else if (num.match(/^3[47]\d{13}/)) {
return 'AmEx';
} else if (num.match(/^6011\d{12}/)) {
return 'Discover';
}
return 'UNKNOWN';
}

Change the signature of 'CreditCard2' method with the following:

Old: jQuery.validator.addMethod("creditcard2", function(value, element, param) {
New: jQuery.validator.addMethod("creditcard2", function(value, element) {

Replace the first line of the ‘CreditCard2’ extension with the following:

Old: var cardName = param; New: var cardName = CreditCardTypeFromNumber(cardNo);

Move the following lines at the start of the method:

value = value.replace(/[\s-]/g, ""); // remove spaces and dashes
if (value.length == 0) { return false; } // no length
var cardNo = value;
var cardexp = /^[0-9]{13,19}$/;
if (!cardexp.exec(cardNo)) { return false; } // has chars or wrong length
cardNo = cardNo.replace(/\D/g, ""); // strip down to digits

By making the above changes ‘CreditCard2’ extension is ready to work without Card Type field.

2 comments:

  1. var cardexp = /^[0-9]{13,19}$/;

    this line in the extension you mentioned should be
    var cardexp = /^[0-9]{12,19}$/;
    other wise it'll not validate 12 number maestro cards :)

    ReplyDelete