Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP Staging] Fix credit card validation #52078

Merged
merged 5 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/components/AddPaymentCard/PaymentCardForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}, []);
Expand Down
16 changes: 12 additions & 4 deletions src/libs/ValidationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB, but maybe there is some better explanation we could add here about the doubling stuff?

intVal *= 2;
if (intVal > 9) {
intVal = 1 + (intVal % 10);
intVal -= 9;
}
}

sum += intVal;
shouldDouble = !shouldDouble;
}

return sum % 10 === 0;
}

Expand Down
Loading