UNPKG

react-svg-credit-card-payment-icons

Version:

React components library with 6 styles, 108 icons, TypeScript support, and a variety of types and formats for easy integration into React applications.

452 lines (448 loc) 13.6 kB
// generated/cardMetadata.ts var CARD_METADATA = [ { type: "Alipay", legacyType: null, displayName: "Alipay", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: [], patterns: { full: [].map((p) => new RegExp(p)), prefix: null }, lengthRange: null, formatPattern: null, issuingCountries: ["GLOBAL"] }, { type: "AmericanExpress", legacyType: "Americanexpress", displayName: "American Express", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: ["Amex"], variants: {}, testNumbers: ["378282246310005", "371449635398431"], patterns: { full: ["^3[47][0-9]{13}$"].map((p) => new RegExp(p)), prefix: new RegExp("^3[47]") }, lengthRange: { "min": 15, "max": 15 }, formatPattern: [4, 6, 5], issuingCountries: ["US"] }, { type: "DinersClub", legacyType: "Diners", displayName: "Diners Club", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["3056930009020004", "30569309025904", "38520000023237", "36227206271667"], patterns: { full: ["^3[0689][0-9]{12}$", "^30[0-5][0-9]{11}$", "^3[0689][0-9]{14}$"].map((p) => new RegExp(p)), prefix: new RegExp("^3(0[0-5]|6|8)") }, lengthRange: { "min": 14, "max": 16 }, formatPattern: { "14": [4, 6, 4], "16": [4, 4, 4, 4] }, issuingCountries: ["US"] }, { type: "Discover", legacyType: null, displayName: "Discover", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["6011111111111117", "6011000990139424", "6011981111111113"], patterns: { full: ["^6(?:011|5[0-9]{2})[0-9]{12}$"].map((p) => new RegExp(p)), prefix: new RegExp("^6(011|5[0-9]{2}|[45])") }, lengthRange: { "min": 16, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["US"] }, { type: "Elo", legacyType: null, displayName: "Elo", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["5066991111111118"], patterns: { full: ["^(?:4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|627780|63(6297|6368|6369))[0-9]*$"].map((p) => new RegExp(p)), prefix: new RegExp("^(4011(78|79)|43(1274|8935)|45(1416|7393|763[12])|50(4175|6699|67[0-6]|677[0-8])|627780|636(297|368|369))") }, lengthRange: { "min": 16, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["BR"] }, { type: "Generic", legacyType: null, displayName: "Generic Card (Front)", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: ["GenericCard", "GenericCardFront"], variants: { "Code": { "slug": "code", "displayName": "Generic Card (Back) - Security Code", "aliases": ["GenericBack", "GenericCardBack", "CvvBack", "CvcBack"] }, "CodeFront": { "slug": "code-front", "displayName": "Generic Card (Front) - Security Code", "aliases": ["GenericFrontCode", "CvvFront", "CvcFront"] } }, testNumbers: [], patterns: { full: [].map((p) => new RegExp(p)), prefix: null }, lengthRange: null, formatPattern: null, issuingCountries: null }, { type: "Hipercard", legacyType: null, displayName: "Hipercard", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: { "Hiper": { "slug": "hiper", "displayName": "Hiper", "iconAuthor": "Aaron Fagan", "iconLicense": "Apache-2.0" } }, testNumbers: ["6062825624254001", "6062823936268330", "6062828888666688"], patterns: { full: ["^(606282\\d{10}(\\d{3})?)|(3841\\d{15})$"].map((p) => new RegExp(p)), prefix: new RegExp("^(606282|3841)") }, lengthRange: { "min": 16, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["BR"] }, { type: "JCB", legacyType: "Jcb", displayName: "JCB", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["3566002020360505"], patterns: { full: ["^(?:2131|1800|35[0-9]{3})[0-9]{11}$"].map((p) => new RegExp(p)), prefix: new RegExp("^(2131|1800|35)") }, lengthRange: { "min": 15, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["JP"] }, { type: "Maestro", legacyType: null, displayName: "Maestro", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["6771798021000008", "6771798021000016"], patterns: { full: ["^(?:5[0678][0-9]{2}|6304|6390|67[0-9]{2})[0-9]{8,15}$"].map((p) => new RegExp(p)), prefix: new RegExp("^(5[0678]|6304|6390|67)") }, lengthRange: { "min": 12, "max": 19 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["GLOBAL"] }, { type: "Mastercard", legacyType: null, displayName: "Mastercard", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["5555555555554444", "2223003122003222", "5200828282828210", "5105105105105100"], patterns: { full: ["^5[1-5][0-9]{14}$", "^2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9][0-9]|7(?:[01][0-9]|20))[0-9]{12}$"].map((p) => new RegExp(p)), prefix: new RegExp("^(5[1-5]|2(22[1-9]|2[3-9]|[3-6]|7[01]|720))") }, lengthRange: { "min": 16, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["GLOBAL"] }, { type: "Mir", legacyType: null, displayName: "Mir", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["2200000000000004", "2200000000000012", "2202207558945880"], patterns: { full: ["^220[0-4][0-9]{12}$"].map((p) => new RegExp(p)), prefix: new RegExp("^220[0-4]") }, lengthRange: { "min": 16, "max": 16 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["RU"] }, { type: "PayPal", legacyType: "Paypal", displayName: "PayPal", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: [], patterns: { full: [].map((p) => new RegExp(p)), prefix: null }, lengthRange: null, formatPattern: null, issuingCountries: ["GLOBAL"] }, { type: "Swish", legacyType: null, displayName: "Swish", iconAuthor: "ThorANilsson", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: [], patterns: { full: [].map((p) => new RegExp(p)), prefix: null }, lengthRange: null, formatPattern: null, issuingCountries: ["SE"] }, { type: "UnionPay", legacyType: "Unionpay", displayName: "UnionPay", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["6200000000000005", "6200000000000047", "6205500000000000004"], patterns: { full: ["^62[0-9]{14,17}$"].map((p) => new RegExp(p)), prefix: new RegExp("^62") }, lengthRange: { "min": 16, "max": 19 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["CN"] }, { type: "Visa", legacyType: null, displayName: "Visa", iconAuthor: "Aaron Fagan", iconLicense: "Apache-2.0", aliases: [], variants: {}, testNumbers: ["4242424242424242", "4000056655665556", "4012888888881881"], patterns: { full: ["^4[0-9]{12}(?:[0-9]{3})?$"].map((p) => new RegExp(p)), prefix: new RegExp("^4") }, lengthRange: { "min": 13, "max": 19 }, formatPattern: [4, 4, 4, 4], issuingCountries: ["GLOBAL"] } ]; // src/utils/loadCardDefinitions.ts function calculateSpecificity(pattern) { if (!pattern) return 0; const patternStr = pattern.source; let specificity = 0; const exactChars = patternStr.match(/[0-9]/g); specificity += (exactChars?.length || 0) * 10; const ranges = patternStr.match(/\[\d-\d\]/g); specificity += (ranges?.length || 0) * 5; const groups = patternStr.match(/\([^)]+\|[^)]+\)/g); specificity += (groups?.length || 0) * 3; const wildcards = patternStr.match(/\[0-9\]/g); specificity -= (wildcards?.length || 0) * 1; if (patternStr.startsWith("^")) specificity += 20; return specificity; } var CARD_DEFINITIONS = null; function getCardDefinitions() { if (CARD_DEFINITIONS) { return CARD_DEFINITIONS; } const definitions = []; for (const metadata of CARD_METADATA) { const specificity = calculateSpecificity(metadata.patterns.prefix); definitions.push({ type: metadata.type, legacyType: metadata.legacyType, patterns: metadata.patterns, lengthRange: metadata.lengthRange, formatPattern: metadata.formatPattern, issuingCountries: metadata.issuingCountries, specificity }); } definitions.sort((a, b) => b.specificity - a.specificity); CARD_DEFINITIONS = definitions; return CARD_DEFINITIONS; } // src/utils/cardUtils.ts function sanitizeCardNumber(cardNumber) { return cardNumber.replace(/\D/g, ""); } function getCardType(cardNumber) { const sanitized = sanitizeCardNumber(cardNumber); if (sanitized.length < 4) { return "Generic"; } const isPartial = sanitized.length < 13; for (const { type, patterns } of getCardDefinitions()) { if (isPartial) { if (patterns.prefix?.test(sanitized)) { return type; } } else { if (patterns.full.some((p) => p.test(sanitized))) { return type; } } } return "Generic"; } function detectCardType(cardNumber) { const sanitized = sanitizeCardNumber(cardNumber); if (sanitized.length < 4) { return "Generic"; } const isPartial = sanitized.length < 13; for (const { type, legacyType, patterns } of getCardDefinitions()) { if (isPartial) { if (patterns.prefix?.test(sanitized)) { return legacyType || type; } } else { if (patterns.full.some((p) => p.test(sanitized))) { return legacyType || type; } } } return "Generic"; } function validateCardNumber(cardNumber) { const sanitized = sanitizeCardNumber(cardNumber); if (sanitized.length < 13 || sanitized.length > 19) { return false; } let sum = 0; let alternate = false; for (let i = sanitized.length - 1; i >= 0; i--) { let digit = parseInt(sanitized[i]); if (alternate) { digit *= 2; if (digit > 9) { digit = digit % 10 + 1; } } sum += digit; alternate = !alternate; } return sum % 10 === 0; } function formatCardNumber(cardNumber) { const sanitized = sanitizeCardNumber(cardNumber); const cardType = getCardType(sanitized); const cardDefinition = getCardDefinitions().find((def) => def.type === cardType); if (!cardDefinition?.formatPattern) { return sanitized; } let pattern; if (Array.isArray(cardDefinition.formatPattern)) { pattern = cardDefinition.formatPattern; } else { const lengthKey = sanitized.length.toString(); pattern = cardDefinition.formatPattern[lengthKey] || cardDefinition.formatPattern[Object.keys(cardDefinition.formatPattern)[0]]; } let formatted = ""; let position = 0; for (const groupSize of pattern) { if (position >= sanitized.length) break; if (formatted) formatted += " "; formatted += sanitized.slice(position, position + groupSize); position += groupSize; } if (position < sanitized.length) { if (formatted) formatted += " "; formatted += sanitized.slice(position); } return formatted; } function validateCardForType(cardNumber, cardType) { const sanitized = sanitizeCardNumber(cardNumber); const cardEntry = getCardDefinitions().find(({ type }) => type === cardType); if (!cardEntry || cardEntry.patterns.full.length === 0) { return false; } return cardEntry.patterns.full.some((pattern) => pattern.test(sanitized)) && validateCardNumber(sanitized); } function getCardLengthRange(cardType) { return getCardDefinitions().find(({ type }) => type === cardType)?.lengthRange ?? null; } function isCardNumberPotentiallyValid(cardNumber) { const sanitized = sanitizeCardNumber(cardNumber); const cardType = getCardType(sanitized); const lengthRange = getCardLengthRange(cardType); if (!lengthRange) { return false; } return sanitized.length >= lengthRange.min && sanitized.length <= lengthRange.max; } function maskCardNumber(cardNumber, maskChar = "*") { const sanitized = sanitizeCardNumber(cardNumber); if (sanitized.length < 4) { return sanitized; } const lastFour = sanitized.slice(-4); const maskedPortion = maskChar.repeat(sanitized.length - 4); return formatCardNumber(maskedPortion + lastFour); } function getCardsByCountry(countryCode, options = {}) { const { includeGlobal = true } = options; const definitions = getCardDefinitions(); return definitions.filter((def) => { const countries = def.issuingCountries; if (countries === null) { return false; } if (countryCode === "GLOBAL") { return countries.includes("GLOBAL"); } if (countries.includes(countryCode)) { return true; } if (includeGlobal && countries.includes("GLOBAL")) { return true; } return false; }).map((def) => def.type); } export { CARD_METADATA, sanitizeCardNumber, getCardType, detectCardType, validateCardNumber, formatCardNumber, validateCardForType, getCardLengthRange, isCardNumberPotentiallyValid, maskCardNumber, getCardsByCountry };