Skip to content

Configuración SRI

Esta sección documenta los endpoints relacionados con la configuración del SRI (Servicio de Rentas Internas), incluyendo gestión de credenciales, validación de contraseñas y configuración de parámetros de facturación electrónica.

  • Endpoint: PUT /api/v1/companies/update-my-sri-password
  • Método: PUT
  • Autenticación: Bearer Token requerido
  • Descripción: Actualiza la contraseña del SRI para el usuario autenticado
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
CampoTipoRequeridoDescripción
sri_passwordstringNueva contraseña del SRI
confirm_passwordstringConfirmación de la nueva contraseña
current_passwordstringNoContraseña actual del usuario (para validación adicional)
{
"sri_password": "NuevaPassword123!",
"confirm_password": "NuevaPassword123!",
"current_password": "MiPasswordActual"
}
{
"message": "Contraseña SRI actualizada exitosamente",
"status": "SUCCESS",
"payload": {
"user_id": 123,
"sri_configured": true,
"last_updated": "2024-01-15T14:30:00Z",
"password_strength": "strong",
"next_validation_required": "2024-04-15T14:30:00Z"
}
}

Respuesta de Error (422 Unprocessable Content)

Section titled “Respuesta de Error (422 Unprocessable Content)”
{
"message": "Error de validación",
"status": "ERROR",
"payload": null,
"error": {
"sri_password": [
"La contraseña debe tener al menos 8 caracteres",
"La contraseña debe contener al menos una mayúscula"
],
"confirm_password": [
"Las contraseñas no coinciden"
]
}
}
Terminal window
curl -X PUT \
{{apiFacEcDev}}/api/v1/companies/update-my-sri-password \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {{bearerToken}}' \
-H 'Content-Type: application/json' \
-d '{
"sri_password": "NuevaPassword123!",
"confirm_password": "NuevaPassword123!",
"current_password": "MiPasswordActual"
}'

  • Endpoint: POST /api/v1/companies/check-my-sri-password
  • Método: POST
  • Autenticación: Bearer Token requerido
  • Descripción: Verifica la validez de la contraseña del SRI del usuario autenticado
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
CampoTipoRequeridoDescripción
sri_passwordstringContraseña del SRI a verificar
validate_with_sribooleanNoSi debe validar directamente con el SRI (default: false)
environmentstringNoAmbiente a validar: “production” o “test” (default: “production”)
{
"sri_password": "MiPasswordSRI123!",
"validate_with_sri": true,
"environment": "production"
}
{
"message": "Contraseña SRI verificada exitosamente",
"status": "SUCCESS",
"payload": {
"is_valid": true,
"sri_connection_status": "active",
"last_validation": "2024-01-15T14:45:00Z",
"environment": "production",
"ruc": "1234567890001",
"company_name": "Mi Empresa S.A.",
"validation_details": {
"password_format": "valid",
"sri_response_time": "1.2s",
"certificate_status": "active",
"permissions": [
"facturacion_electronica",
"comprobantes_retencion",
"guias_remision"
]
}
}
}
{
"message": "Credenciales SRI inválidas",
"status": "ERROR",
"payload": null,
"error": {
"sri_password": [
"La contraseña del SRI es incorrecta"
],
"sri_details": {
"error_code": "INVALID_CREDENTIALS",
"sri_message": "Usuario o contraseña incorrectos",
"attempts_remaining": 2,
"lockout_time": null
}
}
}
Terminal window
curl -X POST \
{{apiFacEcDev}}/api/v1/companies/check-my-sri-password \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {{bearerToken}}' \
-H 'Content-Type: application/json' \
-d '{
"sri_password": "MiPasswordSRI123!",
"validate_with_sri": true,
"environment": "production"
}'

  • Endpoint: PUT /api/v1/companies/update-sri-password/:accountId
  • Método: PUT
  • Autenticación: Bearer Token requerido
  • Descripción: Actualiza la contraseña del SRI para una empresa específica (requiere permisos de administrador)
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
ParámetroTipoRequeridoDescripción
accountIdstringID de la cuenta empresarial
CampoTipoRequeridoDescripción
sri_passwordstringNueva contraseña del SRI
confirm_passwordstringConfirmación de la nueva contraseña
environmentstringNoAmbiente: “production” o “test” (default: “production”)
validate_immediatelybooleanNoValidar inmediatamente con el SRI (default: true)
reasonstringNoMotivo del cambio (para auditoría)
{
"sri_password": "NuevaPasswordEmpresa123!",
"confirm_password": "NuevaPasswordEmpresa123!",
"environment": "production",
"validate_immediately": true,
"reason": "Actualización de seguridad programada"
}
{
"message": "Contraseña SRI de empresa actualizada exitosamente",
"status": "SUCCESS",
"payload": {
"account_id": "61247344",
"company_name": "Mi Empresa S.A.",
"ruc": "1234567890001",
"sri_configured": true,
"environment": "production",
"last_updated": "2024-01-15T15:00:00Z",
"updated_by": {
"user_id": 456,
"username": "[email protected]",
"role": "administrator"
},
"validation_result": {
"is_valid": true,
"sri_connection_status": "active",
"certificate_status": "active",
"permissions_verified": true
}
}
}
{
"message": "No tiene permisos para actualizar la configuración SRI de esta empresa",
"status": "ERROR",
"payload": null,
"error": {
"authorization": [
"Se requieren permisos de administrador para esta operación"
],
"required_permissions": [
"companies.update_sri_config",
"companies.manage_credentials"
]
}
}
Terminal window
curl -X PUT \
{{apiFacEcDev}}/api/v1/companies/update-sri-password/61247344 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {{bearerToken}}' \
-H 'Content-Type: application/json' \
-d '{
"sri_password": "NuevaPasswordEmpresa123!",
"confirm_password": "NuevaPasswordEmpresa123!",
"environment": "production",
"validate_immediately": true,
"reason": "Actualización de seguridad programada"
}'

const validateSriPassword = (password) => {
const validations = {
minLength: password.length >= 8,
hasUppercase: /[A-Z]/.test(password),
hasLowercase: /[a-z]/.test(password),
hasNumbers: /\d/.test(password),
hasSpecialChars: /[!@#$%^&*(),.?":{}|<>]/.test(password),
noCommonPatterns: !/(123456|password|qwerty|admin)/i.test(password)
};
const errors = [];
if (!validations.minLength) {
errors.push('La contraseña debe tener al menos 8 caracteres');
}
if (!validations.hasUppercase) {
errors.push('La contraseña debe contener al menos una mayúscula');
}
if (!validations.hasLowercase) {
errors.push('La contraseña debe contener al menos una minúscula');
}
if (!validations.hasNumbers) {
errors.push('La contraseña debe contener al menos un número');
}
if (!validations.hasSpecialChars) {
errors.push('La contraseña debe contener al menos un carácter especial');
}
if (!validations.noCommonPatterns) {
errors.push('La contraseña no puede contener patrones comunes');
}
return {
isValid: errors.length === 0,
errors: errors,
strength: calculatePasswordStrength(validations)
};
};
const calculatePasswordStrength = (validations) => {
const score = Object.values(validations).filter(Boolean).length;
if (score <= 2) return 'weak';
if (score <= 4) return 'medium';
return 'strong';
};
class SriPasswordAttempts
{
private const MAX_ATTEMPTS = 3;
private const LOCKOUT_DURATION = 900; // 15 minutos
public function recordFailedAttempt($userId, $accountId = null)
{
$key = $this->getAttemptKey($userId, $accountId);
$attempts = Cache::get($key, 0) + 1;
Cache::put($key, $attempts, self::LOCKOUT_DURATION);
if ($attempts >= self::MAX_ATTEMPTS) {
$this->lockAccount($userId, $accountId);
// Notificar al administrador
$this->notifySecurityTeam($userId, $accountId, $attempts);
}
return [
'attempts' => $attempts,
'remaining' => max(0, self::MAX_ATTEMPTS - $attempts),
'locked' => $attempts >= self::MAX_ATTEMPTS,
'lockout_expires' => $attempts >= self::MAX_ATTEMPTS ?
now()->addSeconds(self::LOCKOUT_DURATION) : null
];
}
public function clearAttempts($userId, $accountId = null)
{
$key = $this->getAttemptKey($userId, $accountId);
Cache::forget($key);
$this->unlockAccount($userId, $accountId);
}
private function getAttemptKey($userId, $accountId)
{
return "sri_password_attempts:{$userId}" . ($accountId ? ":{$accountId}" : '');
}
}
class SriCredentialManager
{
public function encryptSriPassword($password, $accountId)
{
// Usar clave específica por cuenta para mayor seguridad
$key = $this->generateAccountKey($accountId);
return encrypt($password, $key);
}
public function decryptSriPassword($encryptedPassword, $accountId)
{
$key = $this->generateAccountKey($accountId);
try {
return decrypt($encryptedPassword, $key);
} catch (DecryptException $e) {
Log::error("Error desencriptando contraseña SRI para cuenta {$accountId}: {$e->getMessage()}");
throw new SriCredentialException('Error al acceder a las credenciales SRI');
}
}
private function generateAccountKey($accountId)
{
return hash('sha256', config('app.key') . $accountId . 'sri_salt');
}
public function rotateSriCredentials($accountId)
{
// Implementar rotación automática de credenciales
$currentPassword = $this->getCurrentSriPassword($accountId);
// Generar nueva contraseña segura
$newPassword = $this->generateSecurePassword();
// Actualizar en el SRI (si la API lo permite)
$this->updateSriPassword($accountId, $currentPassword, $newPassword);
// Actualizar en nuestra base de datos
$this->storeSriPassword($accountId, $newPassword);
return $newPassword;
}
}
  • 200 OK: Operación exitosa
  • 400 Bad Request: Parámetros inválidos
  • 401 Unauthorized: Token de autorización inválido o credenciales SRI incorrectas
  • 403 Forbidden: Sin permisos para la operación
  • 422 Unprocessable Entity: Error de validación
  • 429 Too Many Requests: Demasiados intentos fallidos
  • 500 Internal Server Error: Error interno del servidor
  • 503 Service Unavailable: Servicio SRI no disponible
  • Use encriptación fuerte para almacenar contraseñas
  • Implemente rotación automática de credenciales
  • Registre todos los accesos para auditoría
  • Use autenticación de dos factores cuando sea posible
  • Implemente límites de intentos fallidos
  • Use timeouts apropiados para conexiones SRI
  • Registre errores para análisis posterior
  • Implemente alertas para fallos críticos
  • Use caché para validaciones frecuentes
  • Implemente conexiones persistentes al SRI
  • Optimice timeouts según el ambiente
  • Considere validaciones asíncronas
  • Monitoree disponibilidad del servicio SRI
  • Registre métricas de tiempo de respuesta
  • Implemente alertas para errores de conexión
  • Mantenga estadísticas de uso
const setupCompanySriConfig = async (accountId, sriCredentials) => {
try {
// 1. Validar credenciales con el SRI
const validationResult = await checkMySriPassword({
sri_password: sriCredentials.password,
validate_with_sri: true,
environment: sriCredentials.environment
});
if (!validationResult.payload.is_valid) {
throw new Error('Credenciales SRI inválidas');
}
// 2. Actualizar contraseña en el sistema
const updateResult = await updateCompanySriPassword(accountId, {
sri_password: sriCredentials.password,
confirm_password: sriCredentials.password,
environment: sriCredentials.environment,
validate_immediately: true,
reason: 'Configuración inicial de empresa'
});
// 3. Configurar parámetros adicionales
await configureAdditionalSriSettings(accountId, {
auto_send_documents: true,
retry_failed_documents: true,
notification_email: sriCredentials.notificationEmail
});
return {
success: true,
message: 'Configuración SRI completada exitosamente',
data: updateResult
};
} catch (error) {
console.error('Error en configuración SRI:', error);
throw error;
}
};
class SriConnectionDiagnostic
{
public function runDiagnostic($accountId)
{
$results = [
'account_id' => $accountId,
'timestamp' => now(),
'tests' => []
];
// Test 1: Verificar credenciales almacenadas
$results['tests']['credentials'] = $this->testStoredCredentials($accountId);
// Test 2: Conectividad con SRI
$results['tests']['connectivity'] = $this->testSriConnectivity();
// Test 3: Validación de certificados
$results['tests']['certificates'] = $this->testCertificates($accountId);
// Test 4: Permisos de facturación
$results['tests']['permissions'] = $this->testBillingPermissions($accountId);
// Test 5: Estado de establecimientos
$results['tests']['establishments'] = $this->testEstablishments($accountId);
$results['overall_status'] = $this->calculateOverallStatus($results['tests']);
$results['recommendations'] = $this->generateRecommendations($results['tests']);
return $results;
}
private function testStoredCredentials($accountId)
{
try {
$credentials = $this->credentialManager->getSriCredentials($accountId);
return [
'status' => 'pass',
'message' => 'Credenciales encontradas y accesibles',
'details' => [
'has_password' => !empty($credentials['password']),
'has_ruc' => !empty($credentials['ruc']),
'environment' => $credentials['environment'] ?? 'unknown',
'last_updated' => $credentials['updated_at'] ?? null
]
];
} catch (Exception $e) {
return [
'status' => 'fail',
'message' => 'Error accediendo a credenciales: ' . $e->getMessage(),
'details' => []
];
}
}
}
  • Seguridad: Las contraseñas del SRI se almacenan encriptadas en la base de datos
  • Validación: Se recomienda validar credenciales directamente con el SRI periódicamente
  • Límites: Máximo 3 intentos fallidos antes del bloqueo temporal
  • Ambientes: Soporte para ambientes de producción y pruebas del SRI
  • Auditoría: Todos los cambios de credenciales quedan registrados
  • Rotación: Se recomienda cambiar contraseñas cada 90 días
  • Monitoreo: El sistema monitorea la conectividad con el SRI continuamente