StructureJS
0.15.2A class based utility library for building modular and scalable web platform applications. Features opt-in classes and utilities which provide a solid foundation and toolset to build your next project.
/** * A MerchantUtility class that has several static methods to assist in development. * * @class MerchantUtil * @module StructureJS * @submodule util * @author Robert S. (www.codeBelt.com) * @static */ class MerchantUtil { // https://davidwalsh.name/validate-credit-cards // http://www.freeformatter.com/credit-card-number-generator-validator.html // http://www.validcreditcardnumber.com/ public static CARD_TYPES:any = [ { name: 'American Express', range: ['34', '37'], validLength: [15 ], regex: '3[47][0-9]{13}', }, { name: 'Diners Club - Carte Blanche', range: ['300-305'], validLength: [14 ], regex: '3(?:0[0-5][0-9]{11}|[68][0-9]{12})', }, { name: 'Diners Club - International', range: ['36'], validLength: [14], regex: '3(?:0[0-5][0-9]{11}|[68][0-9]{12})', }, { name: 'JCB', range: ['3528-3589'], validLength: [16], regex: '(?:3[0-9]{15}|(2131|1800)[0-9]{11})', }, { name: 'Visa Electron', range: ['4026', '417500', '4508', '4844', '4913', '4917'], validLength: [16], regex: '4(?:[0-9]{12}|[0-9]{15})', }, { name: 'Visa', range: ['4'], validLength: [13, 14, 15, 16, 17, 18, 19], regex: '4(?:[0-9]{12}|[0-9]{15})', }, { name: 'MasterCard', range: ['51-55', '2221-2720'], validLength: [16], regex: '5[1-5][0-9]{14}', }, { name: 'Discover', range: ['6011', '622126-622925', '644-649', '65'], validLength: [16], regex: '6011[0-9]{12}', }, ]; constructor() { throw new Error('[MerchantUtil] Do not instantiate the MerchantUtil class because it is a static class.'); } /** * Encode a credit card number as a string and encode all digits except the last <code>digitsShown</code>. * * @method encodeCreditCardNumber * @param strNumber {string} The credit card number as string. * @param [digitsShown=4] {number} Display this many digits at the end of the card number for security purposes. * @param [encodeChar=*] {string} Optional encoding character to use instead of default '*'. * @returns {string} * @public * @static * @example * MerchantUtil.encodeCreditCardNumber('4556106734384949'); * // ************4949 * * MerchantUtil.encodeCreditCardNumber('4556106734384949', 5, 'x'); * // xxxxxxxxxxx84949 */ public static encodeCreditCardNumber(strNumber:string, digitsShown:number = 4, encodeChar:string = '*'):string { let encoded:string = ''; for (let i:number = 0; i < strNumber.length - digitsShown; i++) { encoded += encodeChar; } encoded += strNumber.slice(-digitsShown); return encoded; } /** * Returns a credit card provider name from the credit card number passed in. * * @method getCreditCardProvider * @param cardNumber {string|number} * @returns {string} * @example * MerchantUtil.getCreditCardProvider("4"); * MerchantUtil.getCreditCardProvider("4556106734384949"); * // visa * * MerchantUtil.getCreditCardProvider("5428070016026573"); * // mastercard */ public static getCreditCardProvider(cardNumber:string|number):string { // Remove all non-numeric chars. const stringNumber = String(cardNumber).replace(/[^0-9]/g, ''); for (let cardType of MerchantUtil.CARD_TYPES) { for (let num of cardType.range) { const regex = new RegExp(`^${num}+`); if (regex.test(stringNumber) === true) { return cardType.name; } } } return null; } /** * Validate a credit card's expiration date. * * @method isValidExpirationDate * @param month {number} * @param year {number} * @returns {boolean} * @example * MerchantUtil.isValidExDate(11, 2010); * // false */ public static isValidExpirationDate(month:number, year:number):boolean { const d:Date = new Date(); const currentMonth:number = d.getMonth() + 1; const currentYear:number = d.getFullYear(); if ((year > currentYear) || (year == currentYear && month >= currentMonth)) { return true; } return false; } /** * Determines if credit card is valid * * @method isCreditCard * @param cardNumber {string|number} The credit card number. * @returns {boolean} * @public * @static * @example * MerchantUtil.isCreditCard('4556106734384949'); * // true */ public static isCreditCard(cardNumber:string|number) { if(this._validateCreditCard(cardNumber) === true) { return this._validateStructure(cardNumber); } return false; } /** * https://davidwalsh.name/validate-credit-cards * * @method _validateStructure * @param cardNumber {string|number} * @return {boolean} */ private static _validateStructure(cardNumber:string|number):boolean { // Remove all non-numeric chars. const stringNumber = String(cardNumber).replace(/[^0-9]/g, ''); const results = []; for(var cardType of MerchantUtil.CARD_TYPES) { if(stringNumber.match('^' + cardType.regex + '$')) { results.push(cardType.name); } } return results.length ? true : false; } /** * Determines if credit card is valid using the Luhn formula. * https://gist.github.com/ShirtlessKirk/2134376 * * @method _validateCreditCard * @param cardNumber {string|number} * @return {boolean} */ private static _validateCreditCard(cardNumber:string|number):boolean { // Remove all non-numeric chars. const stringNumber = String(cardNumber).replace(/[^0-9]/g, ''); const prodArr = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]]; let len = stringNumber.length; let mul = 0; let sum = 0; while (len--) { sum += prodArr[mul][parseInt(stringNumber.charAt(len), 10)]; mul ^= 1; } return sum % 10 === 0 && sum > 0; } /** * @method _updateRanges * @protected */ public static _updateRanges():void { MerchantUtil .CARD_TYPES .forEach(cardType => { cardType.range = cardType.range.reduce((previous, current) => { if (current.indexOf('-') >= 0) { const rangeArray = current.split('-'); for (let i = rangeArray[0]; i <= rangeArray[1]; i++) { previous.push(String(i)); } } else { previous.push(current); } return previous; }, []); }); } } MerchantUtil._updateRanges(); export default MerchantUtil;