import * as yup from 'yup'; import type { MasterpassRestOptionTexts } from '../types/custom-render.types'; export const createCreditCardFormSchema = ( texts: MasterpassRestOptionTexts ) => { const creditCardNumberSchema = yup .string() .required(texts.cardNumberRequiredText) .test('card-number', texts.cardNumberInvalidText, (value) => { if (!value) return false; const cleanNumber = value.replace(/\D/g, ''); if (cleanNumber.length < 13 || cleanNumber.length > 19) { return false; } let sum = 0; let isEven = false; for (let i = cleanNumber.length - 1; i >= 0; i--) { let digit = parseInt(cleanNumber.charAt(i), 10); if (isEven) { digit *= 2; if (digit > 9) { digit -= 9; } } sum += digit; isEven = !isEven; } return sum % 10 === 0; }); const expiryDateSchema = yup .string() .required(texts.expiryDateRequiredText) .matches(/^(0[1-9]|1[0-2])\/([0-9]{2})$/, texts.expiryDateInvalidText) .test('expiry-date', texts.expiryDateExpiredText, (value) => { if (!value) return false; const [month, year] = value.split('/'); const expiry = new Date( 2000 + parseInt(year, 10), parseInt(month, 10) - 1 ); const now = new Date(); return expiry > now; }); const cvvSchema = yup .string() .required(texts.cvvRequiredText) .matches(/^[0-9]{3,4}$/, texts.cvvInvalidText); const cardholderNameSchema = yup .string() .required(texts.cardholderNameRequiredText) .min(2, texts.cardholderNameTooShortText) .max(50, texts.cardholderNameTooLongText) .matches(/^[a-zA-ZçÇğĞıİöÖşŞüÜ\s]+$/, texts.cardholderNameInvalidText); return yup.object({ cardNumber: creditCardNumberSchema, expiryDate: expiryDateSchema, cvv: cvvSchema, cardholderName: cardholderNameSchema, saveCard: yup.boolean().default(false), cardAlias: yup.string().when('saveCard', { is: true, then: (schema) => schema .required(texts.cardAliasRequiredText) .min(2, texts.cardAliasTooShortText) .max(20, texts.cardAliasTooLongText), otherwise: (schema) => schema.notRequired() }) }); }; export type CreditCardFormData = { cardNumber: string; expiryDate: string; cvv: string; cardholderName: string; saveCard: boolean; cardAlias?: string; };