Creditcard Validity

Circular icon with two abstract cats

Click here to view the creditcard checker || Click here to view the Github Repo

 

Creditcard validity checker

 

For an online assignment I had to create a way to verify a creditcard number. Creditcard numbers are generated with the Luhn Algorithm ( see Wikipedia ).

If, for some reason, you cannot access Wikipedia, this is what the algorithm is:

  1. From the rightmost digit, which is the check digit, and moving left, double the value of every second digit. If the result of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), then add the digits of the product (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9) or alternatively subtract 9 from the product (e.g., 16: 16 – 9 = 7, 18: 18 – 9 = 9).
  2. Take the sum of all the digits.
  3. If the total modulo 10 is equal to 0 (if the total ends in zero) then the number is valid according to the Luhn formula; else it is not valid.

I wrote the Luhn algorithm as follows:

 

// Luhn algorithm
  // start at the end of array and skip every other index
  for (var i = cardNumbers.length - 1; i >= 0; i -= 2)
  {
    var numberAtPosition = parseInt(cardNumbers[i], 10);
    var totalNumberAtPosition = totalNumberAtPosition + numberAtPosition;
  }

  // start at the end of the array, but go to secondlast index
  for (var j = cardNumbers.length - 2; j >= 0; j -= 2)
  {
    var multipliedNumber = (parseInt(cardNumbers[j], 10)) * 2;
    // If the result of this doubling operation is greater than 9 (e.g., 8 × 2 = 16),
    // then add the digits of the product (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9)

    if (multipliedNumber > 9)
    {
      var baseNumber = Math.floor(multipliedNumber / 10);
      var remainingNumber = multipliedNumber % 10;
      var sumOfBaseRemaining = baseNumber + remainingNumber;
      var totalSumOfBaseRemaining = totalSumOfBaseRemaining + sumOfBaseRemaining;
    }
    else
    {
      var totalMultipliedNumber = totalMultipliedNumber + multipliedNumber;
      console.log(totalMultipliedNumber);
    }
  }

  var sumOfNumbers = totalMultipliedNumber + totalSumOfBaseRemaining + totalNumberAtPosition;

  //  If the total modulo 10 is equal to 0 then the number is valid according to the Luhn formula;
  var validityCreditCard = sumOfNumbers % 10;

 

There are also a set of rules for creditcard numbers. For instance, Visa cards always start with a 4 and are between 13 and 16 numbers long.
Mastercard always starts with a 5 and are exactly 16 numbers long. And American Express always starts with a 3 and the second number is either a 4 or a 7 and there are a total of 15 numbers.

You can start to see a lot of potential if/else statements and that is exactly what I did:
 

if(cardNumbers.length > 12)
  {
    if(validityCreditCard == 0)
    {
      console.log("Creditcard is valid");

      if (cardNumbers.charAt(0) === "4" && cardNumbers.length >= 13 && cardNumbers.length <= 16)
      {
        // this is a visa card;
        // 412345678902348
        document.getElementById("errormessage").innerHTML = "Visa " + "" + "✔" + "";
        creditcardIsValid(movingLightAnimation, activateButton);
      }
      else if (cardNumbers.charAt(0) === "5" && cardNumbers.length === 16)
      {
        //this is a Mastercard;
        document.getElementById("errormessage").innerHTML = "Mastercard " + "" + "✔" + "";
        creditcardIsValid(movingLightAnimation, activateButton);
      }
      else if (cardNumbers.charAt(0) === "3" && cardNumbers.charAt(1) === "4" || cardNumbers.charAt(1) === "7" && cardNumbers.length === 15)
      {
        //this is an american express card;
        document.getElementById("errormessage").innerHTML = "American Express " + "" + "✔" + "";
        creditcardIsValid(movingLightAnimation, activateButton);
      }
      else
      {
        return false;
      }
    }

 

 

The actual code to check a creditcard's validity isn't actually that complicated. I thought it was pretty easy! The real problem was something else that bothered me.
When a user fills in their numbers, it's not very clear where they are. What if they make a typo? Can I do something to help guide the user?
I wanted to insert dashes after every 4th number to make it easier to see how far the user is. But I ran into a problem.

Maybe you know about the HTML5 element input type="text". Well, input type="text" can take a few arguments, like input type="number". It does exactly what you think it does: it only accepts numbers. There is also the input type = "tel", which stands for telephone. This one also accepts numbers only. The advantage it has over "number" is that on mobile you get your numerical pad instead of your normal keyboard.

So if it only accepts numbers, how do I get a dash in there?
 

var cardNumbersOriginal = document.getElementById("card").value;

// remove dashes from input for algorithm check
  var cardNumbers = cardNumbersOriginal.split('-');
  cardNumbers = cardNumbers.join("");

 // add dashes to input for user to see
 if(cardNumbers != "")
 {
   var arrayFromNumbers = cardNumbers.match(/.{1,4}/g);
   var cardNumbersWithDashes = arrayFromNumbers.join('-');
 }
 else
 {
   var arrayFromNumbers = "";
   var cardNumbersWithDashes = "";
 }

 
The key element here is the Regex /.{1,4}/g . This splits up every 4th character or to put it differently: It will split up my array of numbers into bits of 4. When I have a bit of 4, I stick a dash behind it and continue.

 

 

I use 2 different variables to make this happen:
1) A visible one; the user input = arrayFromNumbers
2) The invisible one; for my program to use = cardNumbers
If you remember in the previous code snippet, I use cardNumbers in the Luhn algorithm. The user sees the arrayFromNumbers.
And that reults into: