UNPKG

skailan-core

Version:

Servicio de autenticación y multitenancy para Skailan.

126 lines 4.36 kB
import crypto from 'crypto'; import { EPaycoConfigService } from '../config/epayco.config.js'; export class EPaycoSignatureService { static instance; configService; constructor() { this.configService = EPaycoConfigService.getInstance(); } static getInstance() { if (!EPaycoSignatureService.instance) { EPaycoSignatureService.instance = new EPaycoSignatureService(); } return EPaycoSignatureService.instance; } /** * Genera la firma esperada para validar la respuesta de ePayco */ generateExpectedSignature(response) { const { x_ref_payco, x_transaction_id, x_amount, x_currency_code } = response; const privateKey = this.configService.getPrivateKey(); const signatureString = `${x_ref_payco}^${privateKey}^${x_transaction_id}^${x_amount}^${x_currency_code}`; return crypto.createHash('md5').update(signatureString).digest('hex'); } /** * Valida la firma de la respuesta de ePayco */ validateSignature(response) { try { const expectedSignature = this.generateExpectedSignature(response); const receivedSignature = response.x_signature; return expectedSignature.toLowerCase() === receivedSignature.toLowerCase(); } catch (error) { console.error('Error validating ePayco signature:', error); return false; } } /** * Valida que todos los campos requeridos estén presentes */ validateRequiredFields(response) { const requiredFields = [ 'x_ref_payco', 'x_transaction_id', 'x_signature', 'x_response', 'x_invoice', 'x_amount', 'x_currency_code' ]; return requiredFields.every(field => response[field] !== undefined && response[field] !== null && response[field] !== ''); } /** * Valida que el monto coincida con el esperado */ validateAmount(response, expectedAmount) { const receivedAmount = parseFloat(response.x_amount); return Math.abs(receivedAmount - expectedAmount) < 0.01; // Tolerancia de 1 centavo } /** * Valida que la moneda sea la correcta */ validateCurrency(response) { const config = this.configService.getConfig(); return response.x_currency_code === config.currency; } /** * Valida que la respuesta sea válida (Aceptada) */ validateResponse(response) { return response.x_response === 'Aceptada'; } /** * Valida completamente una respuesta de ePayco */ validatePaymentResponse(response, expectedAmount) { const errors = []; // Validar campos requeridos if (!this.validateRequiredFields(response)) { errors.push('Campos requeridos faltantes en la respuesta'); } // Validar firma if (!this.validateSignature(response)) { errors.push('Firma inválida'); } // Validar monto if (!this.validateAmount(response, expectedAmount)) { errors.push('Monto no coincide con el esperado'); } // Validar moneda if (!this.validateCurrency(response)) { errors.push('Moneda inválida'); } // Validar respuesta if (!this.validateResponse(response)) { errors.push('Respuesta de pago no exitosa'); } return { isValid: errors.length === 0, errors }; } /** * Genera un hash seguro para almacenar información sensible */ generateSecureHash(data) { return crypto.createHash('sha256').update(data).digest('hex'); } /** * Valida que la transacción no sea duplicada */ validateTransactionId(transactionId, existingTransactionIds) { return !existingTransactionIds.includes(transactionId); } /** * Genera un token de seguridad para el pago */ generatePaymentToken(organizationId, planId, amount) { const timestamp = Date.now().toString(); const data = `${organizationId}-${planId}-${amount}-${timestamp}`; return crypto.createHash('sha256').update(data).digest('hex'); } } //# sourceMappingURL=EPaycoSignatureService.js.map