skailan-core
Version:
Servicio de autenticación y multitenancy para Skailan.
126 lines • 4.36 kB
JavaScript
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