diff --git a/src/components/AddPaymentCard/PaymentCardForm.tsx b/src/components/AddPaymentCard/PaymentCardForm.tsx index f38ea60f1aad..5aaa23b238f7 100644 --- a/src/components/AddPaymentCard/PaymentCardForm.tsx +++ b/src/components/AddPaymentCard/PaymentCardForm.tsx @@ -177,18 +177,26 @@ function PaymentCardForm({ }; const onChangeCardNumber = useCallback((newValue: string) => { - // replace all characters that are not spaces or digits + // Replace all characters that are not spaces or digits let validCardNumber = newValue.replace(/[^\d ]/g, ''); - // gets only the first 16 digits if the inputted number have more digits than that + // Gets only the first 16 digits if the inputted number have more digits than that validCardNumber = validCardNumber.match(/(?:\d *){1,16}/)?.[0] ?? ''; - // add the spacing between every 4 digits - validCardNumber = - validCardNumber - .replace(/ /g, '') - .match(/.{1,4}/g) - ?.join(' ') ?? ''; + // Remove all spaces to simplify formatting + const cleanedNumber = validCardNumber.replace(/ /g, ''); + + // Check if the number is a potential Amex card (starts with 34 or 37 and has up to 15 digits) + const isAmex = /^3[47]\d{0,13}$/.test(cleanedNumber); + + // Format based on Amex or standard 4-4-4-4 pattern + if (isAmex) { + // Format as 4-6-5 for Amex + validCardNumber = cleanedNumber.replace(/(\d{1,4})(\d{1,6})?(\d{1,5})?/, (match, p1, p2, p3) => [p1, p2, p3].filter(Boolean).join(' ')); + } else { + // Format as 4-4-4-4 for non-Amex + validCardNumber = cleanedNumber.match(/.{1,4}/g)?.join(' ') ?? ''; + } setCardNumber(validCardNumber); }, []); diff --git a/src/libs/ValidationUtils.ts b/src/libs/ValidationUtils.ts index 80c765f0edf1..fbc1aefe30ce 100644 --- a/src/libs/ValidationUtils.ts +++ b/src/libs/ValidationUtils.ts @@ -20,16 +20,24 @@ import StringUtils from './StringUtils'; */ function validateCardNumber(value: string): boolean { let sum = 0; - for (let i = 0; i < value.length; i++) { - let intVal = parseInt(value.substr(i, 1), 10); - if (i % 2 === 0) { + let shouldDouble = false; + + // Loop through the card number from right to left + for (let i = value.length - 1; i >= 0; i--) { + let intVal = parseInt(value[i], 10); + + // Double every second digit from the right + if (shouldDouble) { intVal *= 2; if (intVal > 9) { - intVal = 1 + (intVal % 10); + intVal -= 9; } } + sum += intVal; + shouldDouble = !shouldDouble; } + return sum % 10 === 0; }