@montarist/nestpay-api-v2
Version:
Unofficial comprehensive TypeScript API client for Nestpay payment gateway with 3D Secure support
358 lines • 12.7 kB
JavaScript
;
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