Search code examples
javavalidationcredit-card

Credit Card validator for java


I need to do a Credit card number validation.

When I googled this I found the org.apache.commons.validator.CreditCardValidator. But seems like it is not working correctly. When I pass a non-digit character also it porvides true.

Code for Apache CreditCardValidator:

String ccNumber = "378282246310005";
CreditCardValidator creditCardValidator = new CreditCardValidator();
if(!creditCardValidator.isValid(ccNumber)) throw new Exception("Credit Card Number is not a valid one!");

Then, I wrote following methods to validate credit card numbers based on the card type and the card number (using the luhn's algorithm).

CardType validator (null if an invalid card type)

public String getCCType(String ccNumber){

        String visaRegex        = "^4[0-9]{12}(?:[0-9]{3})?$";
        String masterRegex      = "^5[1-5][0-9]{14}$";
        String amexRegex        = "^3[47][0-9]{13}$";
        String dinersClubrRegex = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$";
        String discoverRegex    = "^6(?:011|5[0-9]{2})[0-9]{12}$";
        String jcbRegex         = "^(?:2131|1800|35\\d{3})\\d{11}$";
        String commonRegex      = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$";

        try {
            ccNumber = ccNumber.replaceAll("\\D", "");
            return (ccNumber.matches(visaRegex) ? "VISA" : ccNumber.matches(masterRegex) ? "MASTER" :ccNumber.matches(amexRegex) ? "AMEX" :ccNumber.matches(dinersClubrRegex) ? "DINER" :ccNumber.matches(discoverRegex) ? "DISCOVER"  :ccNumber.matches(jcbRegex) ? "JCB":null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

CardNumber validator using Luhn's algorithem.

public boolean isValidCardNumber(String ccNumber){

        try {
            ccNumber = ccNumber.replaceAll("\\D", "");
            char[]      ccNumberArry    = ccNumber.toCharArray();

            int         checkSum        = 0;
            for(int i = ccNumberArry.length - 1; i >= 0; i--){

                char            ccDigit     = ccNumberArry[i];

                if((ccNumberArry.length - i) % 2 == 0){
                    int doubleddDigit = Character.getNumericValue(ccDigit) * 2;
                    checkSum    += (doubleddDigit % 9 == 0 && doubleddDigit != 0) ? 9 : doubleddDigit % 9;

                }else{
                    checkSum    += Character.getNumericValue(ccDigit);
                }

            }

            return (checkSum != 0 && checkSum % 10 == 0);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return false;
    }

I want to know,

  1. Is there any other thrid party class to validate the credit cards other than the org.apache one?
  2. Is there any issue with the my code? (I tested it for several times. So far so good. I just want to know if you could spot something that I didn't.)

References : How do you detect Credit card type based on number?


Solution

  • You can find custom implantation of credit card validator here which is doing both credit card number validation plus credit card type detection,

    http://www.esupu.com/credit-card-validator-java/