All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.worldpay.cse.WPCardValidator Maven / Gradle / Ivy

Go to download

Android SDK is a library created to help you integrate Worldpay client side encryption into your mobile applications.

There is a newer version: 1.0.4
Show newest version
package com.worldpay.cse;

import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * Card data field validator
 *
 The following is list of error codes mapped to their meanings which would be provided back to the caller application.
 
    • 101 - Credit card number is mandatory.
    • 102 - Enter a valid credit card number, numbers only and should be between 12 and 20 digits.
    • 103 - Enter a valid credit card number, input doesn't verify Luhn check.
    • 201 - Enter a valid security code, numbers only and should be between 3 and 4 digits.
    • 301 - Expiry month is mandatory.
    • 302 - Enter a valid expiry month; only numbers expected and in XX form (e.g. 09).
    • 303 - Enter a valid expiry month, should range from 01 to 12.
    • 304 - Expiry year is mandatory.
    • 305 - Enter a valid expiry year, only numbers expected.
    • 306 - Expiry date should be in future.
    • 401 - Card holder's name is mandatory.
    • 402 - Name should not exceed thirty characters.
* */ class WPCardValidator { private static final String EX_MONTH_PATTERN = "^[0-9]{2}$"; private static final String EX_YEAR_PATTERN = "^[0-9]{4}$"; private static final String CARD_NUMBER_PATTERN = "[0-9]{12,20}"; private static final String CARD_HOLDER_PATTERN = "^.{1,30}$"; private static final String CVC_PATTERN = "^[0-9]{3,4}$"; private static final int MAX_SINGLE_DIGIT_NUMBER = 9; private static final int DIVIDER_VALUE = 10; private static final int AMPLIFIER_VALUE = 2; private static final int INVALID_MONTH = 300; private static final int INVALID_MONTH_2 = 303; private static final int INVALID_YEAR = 303; private static final int INVALID_DATE = 306; private static final int INVALID_CARD_HOLDER_NAME = 400; private static final int INVALID_CVC = 201; private static final int INVALID_CARD_NUMBER = 100; private static final int INVALID_LUHN = 103; private static final int MIN_MONTH = 1; private static final int MAX_MONTH = 12; private static final int EMPTY_VALUE = 1; private static final int INVALID_VALUE = 2; private static final int NO_ERROR = 0; /** * Validates card data. * * @param cardData the card data object * @return the list of error codes */ public Set validateCardData(WPCardData cardData) { Set errorsCodes = new HashSet<>(); checkErrorCode(validateCardNumber(cardData.getCardNumber()), errorsCodes); checkErrorCode(validateCvc(cardData.getCvc()), errorsCodes); checkErrorCode(validateMonth(cardData.getExpiryMonth()), errorsCodes); checkErrorCode(validateYear(cardData.getExpiryYear()), errorsCodes); checkErrorCode(validateDate(cardData.getExpiryMonth(), cardData.getExpiryYear()), errorsCodes); checkErrorCode(validateCardHolderName(cardData.getCardHolderName()), errorsCodes); return errorsCodes; } private int validateMonth(String expiryMonth) { int validNumber = validateValue(expiryMonth, EX_MONTH_PATTERN); if (validNumber != NO_ERROR) { return INVALID_MONTH + validNumber; } int exMonth = Integer.parseInt(expiryMonth); if (exMonth < MIN_MONTH || exMonth > MAX_MONTH) { return INVALID_MONTH_2; } return NO_ERROR; } private int validateYear(String expiryYear) { int validNumber = validateValue(expiryYear, EX_YEAR_PATTERN); if (validNumber != NO_ERROR) { return INVALID_YEAR + validNumber; } return NO_ERROR; } private int validateDate(String expiryMonth, String expiryYear) { if (validateMonth(expiryMonth) == NO_ERROR && validateYear(expiryYear) == NO_ERROR) { int exMonth = Integer.parseInt(expiryMonth); int exYear = Integer.parseInt(expiryYear); if (!isFutureDate(exMonth, exYear)) { return INVALID_DATE; } } return NO_ERROR; } private int validateValue(String value, String pattern) { if (isEmpty(value) || isEmpty(value.trim())) { return EMPTY_VALUE; } if(!evaluateRegex(value, pattern)) { return INVALID_VALUE; } return NO_ERROR; } private boolean isFutureDate(int expiryMonth, int expiryYear) { Date today = new Date(); Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(expiryYear, expiryMonth - 1, 0); return calendar.getTime().after(today); } private int validateCardHolderName(String cardHolderName) { int valid = validateValue(cardHolderName, CARD_HOLDER_PATTERN); if (valid != NO_ERROR) { return INVALID_CARD_HOLDER_NAME + valid; } return NO_ERROR; } private int validateCvc(String cvc) { if (isEmpty(cvc) || evaluateRegex(cvc, CVC_PATTERN)) { return NO_ERROR; } else { return INVALID_CVC; } } private int validateCardNumber(String cardNumber) { int valid = validateValue(cardNumber, CARD_NUMBER_PATTERN); if (valid != NO_ERROR) { return INVALID_CARD_NUMBER + valid; } else if (!validateLuhn(cardNumber)) { return INVALID_LUHN; } return NO_ERROR; } public boolean validateLuhn(String value) { int nCheck = 0; boolean alternate = false; for (int i = value.length() - 1; i >= 0; i--) { int nDigit = Integer.parseInt(String.valueOf(value.charAt(i))); if (alternate) { nDigit *= AMPLIFIER_VALUE; if (nDigit > MAX_SINGLE_DIGIT_NUMBER) { nDigit -= MAX_SINGLE_DIGIT_NUMBER; } } nCheck += nDigit; alternate = !alternate; } return (nCheck % DIVIDER_VALUE) == 0; } private boolean checkErrorCode(int errorCode, Set errorsCodes) { if (errorCode != NO_ERROR) { errorsCodes.add(errorCode); return false; } else { return true; } } private boolean evaluateRegex(String data, String re) { return Pattern.matches(re, data); } private boolean isEmpty(String data) { return (data == null) || "".equals(data) || evaluateRegex(data, "!/[^\\s]/"); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy