UNPKG

@montarist/nestpay-api-v2

Version:

Unofficial comprehensive TypeScript API client for Nestpay payment gateway with 3D Secure support

358 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Validators = void 0; const enums_1 = require("../types/enums"); /** * Static utility class for input validation */ class Validators { /** * Validate credit card information using Luhn algorithm * @param card Credit card information * @returns Validation result */ static validateCreditCard(card) { const errors = []; // Validate PAN (Primary Account Number) if (!card.pan || card.pan.length < 13 || card.pan.length > 19) { errors.push('Credit card number must be between 13 and 19 digits'); } else if (!this.luhnCheck(card.pan)) { errors.push('Invalid credit card number (Luhn check failed)'); } // Validate expiry date (MMYY format) if (!card.expiry || card.expiry.length !== 4) { errors.push('Expiry date must be in MMYY format'); } else { const month = parseInt(card.expiry.substring(0, 2)); const year = parseInt('20' + card.expiry.substring(2, 4)); const currentDate = new Date(); const currentYear = currentDate.getFullYear(); const currentMonth = currentDate.getMonth() + 1; if (month < 1 || month > 12) { errors.push('Invalid expiry month'); } else if (year < currentYear || (year === currentYear && month < currentMonth)) { errors.push('Credit card has expired'); } } // Validate CVV if (!card.cvv || card.cvv.length < 3 || card.cvv.length > 4) { errors.push('CVV must be 3 or 4 digits'); } // Validate cardholder name (optional but if provided, should be valid) if (card.cardHolderName && card.cardHolderName.trim().length < 2) { errors.push('Card holder name must be at least 2 characters long'); } return { isValid: errors.length === 0, errors }; } /** * Validate transaction amount * @param amount Transaction amount * @param currency Currency code * @returns Validation result */ static validateAmount(amount, currency) { const errors = []; if (amount <= 0) { errors.push('Amount must be greater than 0'); } if (amount > 999999.99) { errors.push('Amount cannot exceed 999,999.99'); } // Check for reasonable decimal places const decimalPlaces = (amount.toString().split('.')[1] || '').length; if (decimalPlaces > 2) { errors.push('Amount cannot have more than 2 decimal places'); } // Currency-specific validations switch (currency) { case enums_1.Currency.TRY: if (amount < 0.01) { errors.push('Minimum amount for TRY is 0.01'); } break; case enums_1.Currency.USD: case enums_1.Currency.EUR: if (amount < 0.01) { errors.push(`Minimum amount for ${currency} is 0.01`); } break; } return { isValid: errors.length === 0, errors }; } /** * Validate order ID * @param orderId Order ID * @returns Validation result */ static validateOrderId(orderId) { const errors = []; if (!orderId || orderId.trim().length === 0) { errors.push('Order ID is required'); } else if (orderId.length > 64) { errors.push('Order ID cannot exceed 64 characters'); } else if (!/^[a-zA-Z0-9\-_]+$/.test(orderId)) { errors.push('Order ID can only contain alphanumeric characters, hyphens, and underscores'); } return { isValid: errors.length === 0, errors }; } /** * Validate URL * @param url URL to validate * @param fieldName Field name for error messages * @returns Validation result */ static validateUrl(url, fieldName) { const errors = []; if (!url || url.trim().length === 0) { errors.push(`${fieldName} is required`); } else { // Simple URL validation using regex const urlPattern = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/; if (!urlPattern.test(url)) { errors.push(`${fieldName} must be a valid HTTP or HTTPS URL`); } else if (!url.startsWith('https://') && !url.startsWith('http://')) { errors.push(`${fieldName} must start with http:// or https://`); } } return { isValid: errors.length === 0, errors }; } /** * Validate email address * @param email Email address * @returns Validation result */ static validateEmail(email) { const errors = []; if (!email || email.trim().length === 0) { errors.push('Email is required'); } else { const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailPattern.test(email)) { errors.push('Invalid email address format'); } else if (email.length > 254) { errors.push('Email address cannot exceed 254 characters'); } } return { isValid: errors.length === 0, errors }; } /** * Validate phone number * @param phone Phone number * @returns Validation result */ static validatePhone(phone) { const errors = []; if (phone && phone.trim().length > 0) { // Remove all non-digit characters for validation const digitsOnly = phone.replace(/\D/g, ''); if (digitsOnly.length < 10 || digitsOnly.length > 15) { errors.push('Phone number must be between 10 and 15 digits'); } // Turkish phone number format validation (optional) if (phone.startsWith('+90') || phone.startsWith('90')) { const turkishPattern = /^(\+90|90)?5\d{9}$/; if (!turkishPattern.test(digitsOnly)) { errors.push('Invalid Turkish phone number format'); } } } return { isValid: errors.length === 0, errors }; } /** * Validate installment * @param installment Installment type * @returns Validation result */ static validateInstallment(installment) { const errors = []; if (installment) { const validInstallments = Object.values(enums_1.InstallmentType); if (!validInstallments.includes(installment)) { errors.push('Invalid installment option'); } } return { isValid: errors.length === 0, errors }; } /** * Validate bank provider * @param provider Bank provider * @returns Validation result */ static validateProvider(provider) { const errors = []; if (!provider) { errors.push('Provider is required'); } else { const validProviders = Object.values(enums_1.BankProvider); if (!validProviders.includes(provider)) { errors.push('Invalid bank provider'); } } return { isValid: errors.length === 0, errors }; } /** * Validate provider endpoints * @param endpoints Provider endpoints * @returns Validation result */ static validateProviderEndpoints(endpoints) { const errors = []; // Validate production endpoints if (!endpoints.production) { errors.push('Production endpoints are required'); } else { const prodApiValidation = this.validateUrl(endpoints.production.api, 'Production API endpoint'); const prodThreeDValidation = this.validateUrl(endpoints.production.threeD, 'Production 3D endpoint'); if (!prodApiValidation.isValid) { errors.push(...prodApiValidation.errors); } if (!prodThreeDValidation.isValid) { errors.push(...prodThreeDValidation.errors); } } // Validate test endpoints if (!endpoints.test) { errors.push('Test endpoints are required'); } else { const testApiValidation = this.validateUrl(endpoints.test.api, 'Test API endpoint'); const testThreeDValidation = this.validateUrl(endpoints.test.threeD, 'Test 3D endpoint'); if (!testApiValidation.isValid) { errors.push(...testApiValidation.errors); } if (!testThreeDValidation.isValid) { errors.push(...testThreeDValidation.errors); } } return { isValid: errors.length === 0, errors }; } /** * Validate complete Nestpay configuration * @param config Nestpay configuration * @returns Validation result */ static validateConfig(config) { const errors = []; // Required fields if (!config.clientId || config.clientId.trim().length === 0) { errors.push('Client ID is required'); } if (!config.username || config.username.trim().length === 0) { errors.push('Username is required'); } if (!config.password || config.password.trim().length === 0) { errors.push('Password is required'); } if (!config.storeKey || config.storeKey.trim().length === 0) { errors.push('Store key is required'); } if (!config.storeType) { errors.push('Store type is required'); } // Provider validation if (config.provider) { const providerValidation = this.validateProvider(config.provider); if (!providerValidation.isValid) { errors.push(...providerValidation.errors); } // Custom provider must have custom endpoints if (config.provider === enums_1.BankProvider.CUSTOM && !config.customEndpoints) { errors.push('Custom endpoints are required when using CUSTOM provider'); } } // Custom endpoints validation if (config.customEndpoints) { const endpointsValidation = this.validateProviderEndpoints(config.customEndpoints); if (!endpointsValidation.isValid) { errors.push(...endpointsValidation.errors); } } // Optional URL validations if (config.apiEndpoint) { const apiValidation = this.validateUrl(config.apiEndpoint, 'API endpoint'); if (!apiValidation.isValid) { errors.push(...apiValidation.errors); } } if (config.threeDEndpoint) { const threeDValidation = this.validateUrl(config.threeDEndpoint, '3D Secure endpoint'); if (!threeDValidation.isValid) { errors.push(...threeDValidation.errors); } } if (config.payHostingUrl) { const payHostingValidation = this.validateUrl(config.payHostingUrl, 'Pay hosting URL'); if (!payHostingValidation.isValid) { errors.push(...payHostingValidation.errors); } } return { isValid: errors.length === 0, errors }; } /** * Luhn algorithm implementation for credit card validation * @param cardNumber Credit card number * @returns True if valid according to Luhn algorithm */ static luhnCheck(cardNumber) { // Remove any non-digit characters const number = cardNumber.replace(/\D/g, ''); let sum = 0; let isEven = false; // Process digits from right to left for (let i = number.length - 1; i >= 0; i--) { let digit = parseInt(number.charAt(i)); if (isEven) { digit *= 2; if (digit > 9) { digit -= 9; } } sum += digit; isEven = !isEven; } return sum % 10 === 0; } } exports.Validators = Validators; //# sourceMappingURL=validators.js.map