Skip to content

💻 Ejemplos de Uso en PHP

Antes de empezar, configura las constantes necesarias en tu aplicación:

config.php
<?php
// URL base de tu instancia de Dataemunah
define('DATAEMUNAH_HOST', 'https://aw.dataemunah.com');
// Tu API Key proporcionada por el líder técnico
define('API_PAYROLL_KEY', 'tu_api_key_aqui');
// Endpoint de nómina
define('NOMINA_ENDPOINT', DATAEMUNAH_HOST . '/api/nomina/calculate');

Crea una función reutilizable para hacer peticiones al endpoint:

<?php
/**
* Realiza una petición al endpoint de simulación de nómina
*
* @param array $requestData Datos del request
* @return array Respuesta decodificada del API
* @throws Exception Si hay error en la petición
*/
function calcularNomina($requestData)
{
// Configurar headers
$headers = [
'Content-Type: application/json',
'X-Api-Key: Bearer ' . API_PAYROLL_KEY
];
// Inicializar cURL
$ch = curl_init(NOMINA_ENDPOINT);
// Configurar opciones
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Timeout de 30 segundos
// Ejecutar petición
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// Verificar errores de cURL
if ($curlError) {
throw new Exception('Error en la conexión: ' . $curlError);
}
// Decodificar respuesta
$apiResponse = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('Error al decodificar JSON: ' . json_last_error_msg());
}
// Verificar respuesta exitosa
if ($statusCode !== 200 || !$apiResponse['success']) {
$errorMsg = $apiResponse['error']['message'] ?? 'Error desconocido';
throw new Exception('Error del API (HTTP ' . $statusCode . '): ' . $errorMsg);
}
return $apiResponse;
}

Calcula la nómina de un empleado en escenario promedio sin novedades:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
try {
$requestData = [
'periodo' => [
'mes' => 1,
'anio' => 2025
],
'nivelCalculo' => 'empleado',
'escenario' => 'promedio',
'porcentajeNovedades' => 0, // Sin novedades
'perfiles' => [
[
'idEmpleado' => 'EMP001',
'tipoContrato' => 'indefinido',
'salarioBasico' => 3000000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 1
]
]
];
$respuesta = calcularNomina($requestData);
// Extraer datos del empleado
$empleado = $respuesta['data']['resultados']['detalleEmpleados'][0];
echo "=== RESUMEN EMPLEADO {$empleado['idEmpleado']} ===\n";
echo "Salario Básico: $" . number_format($empleado['devengos']['salarioBasico'], 2) . "\n";
echo "Auxilio Transporte: $" . number_format($empleado['devengos']['auxilioTransporte'], 2) . "\n";
echo "Total Devengos: $" . number_format($empleado['devengos']['totalDevengos'], 2) . "\n";
echo "Total Deducciones: $" . number_format($empleado['deducciones']['totalDeducciones'], 2) . "\n";
echo "Nómina Neta: $" . number_format($empleado['totales']['nominaNeta'], 2) . "\n";
echo "Costo Empleador: $" . number_format($empleado['totales']['costoEmpleador'], 2) . "\n";
echo "Provisiones: $" . number_format($empleado['totales']['totalProvisiones'], 2) . "\n";
echo "COSTO TOTAL RH: $" . number_format($empleado['totales']['costoTotalRecursoHumano'], 2) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Salida esperada:

=== RESUMEN EMPLEADO EMP001 ===
Salario Básico: $3,000,000.00
Auxilio Transporte: $200,000.00
Total Devengos: $3,200,000.00
Total Deducciones: $240,000.00
Nómina Neta: $2,960,000.00
Costo Empleador: $735,000.00
Provisiones: $266,560.00
COSTO TOTAL RH: $3,961,560.00

Ejemplo 2: Escenario de Proyecto con Múltiples Empleados

Section titled “Ejemplo 2: Escenario de Proyecto con Múltiples Empleados”

Calcula el costo total de un proyecto con varios empleados:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
try {
$requestData = [
'periodo' => [
'mes' => 2,
'anio' => 2025
],
'nivelCalculo' => 'proyecto',
'escenario' => 'promedio',
'porcentajeNovedades' => 30, // 30% de empleados con novedades
'perfiles' => [
[
'idEmpleado' => 'EMP001',
'idProyecto' => 'PROYECTO_ALPHA',
'tipoContrato' => 'indefinido',
'salarioBasico' => 4500000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => false,
'nivelRiesgoArl' => 2
],
[
'idEmpleado' => 'EMP002',
'idProyecto' => 'PROYECTO_ALPHA',
'tipoContrato' => 'termino_fijo',
'salarioBasico' => 3000000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 2
],
[
'idEmpleado' => 'EMP003',
'idProyecto' => 'PROYECTO_ALPHA',
'tipoContrato' => 'indefinido',
'salarioBasico' => 2500000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 1
]
]
];
$respuesta = calcularNomina($requestData);
// Extraer totales por proyecto
$proyectos = $respuesta['data']['resultados']['totalesPorProyecto'];
foreach ($proyectos as $proyecto) {
echo "\n=== PROYECTO: {$proyecto['idProyecto']} ===\n";
echo "Empleados: {$proyecto['cantidadEmpleados']}\n";
echo "Empleados con novedades: {$proyecto['empleadosConNovedades']}\n";
echo "Total Salarios: $" . number_format($proyecto['totales']['totalSalariosBasicos'], 2) . "\n";
echo "Total Nómina Neta: $" . number_format($proyecto['totales']['totalNominaNeta'], 2) . "\n";
echo "Total Costo RH: $" . number_format($proyecto['totales']['totalCostoRecursoHumano'], 2) . "\n";
}
// Estadísticas de novedades
$stats = $respuesta['data']['resultados']['estadisticasNovedades'];
echo "\n=== ESTADÍSTICAS DE NOVEDADES ===\n";
echo "Porcentaje configurado: {$stats['porcentajeConfigurado']}%\n";
echo "Porcentaje real aplicado: {$stats['porcentajeReal']}%\n";
echo "Empleados con novedades: {$stats['empleadosConNovedades']} de {$stats['totalEmpleados']}\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Compara los 3 escenarios para el mismo grupo de empleados:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
// Datos base de empleados
$perfiles = [
[
'idEmpleado' => 'EMP001',
'tipoContrato' => 'indefinido',
'salarioBasico' => 3500000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 1
],
[
'idEmpleado' => 'EMP002',
'tipoContrato' => 'indefinido',
'salarioBasico' => 2800000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 1
]
];
$escenarios = ['mejor', 'promedio', 'peor'];
$resultados = [];
try {
foreach ($escenarios as $escenario) {
$requestData = [
'periodo' => ['mes' => 1, 'anio' => 2025],
'nivelCalculo' => 'empleado',
'escenario' => $escenario,
'porcentajeNovedades' => 50, // Solo aplica en promedio
'perfiles' => $perfiles
];
$respuesta = calcularNomina($requestData);
$totales = $respuesta['data']['resultados']['totalesGenerales'];
$resultados[$escenario] = [
'nominaNeta' => $totales['totalNominaNeta'],
'costoTotal' => $totales['totalCostoRecursoHumano']
];
}
// Mostrar comparación
echo "=== COMPARACIÓN DE ESCENARIOS ===\n\n";
echo str_pad("ESCENARIO", 15) . str_pad("NÓMINA NETA", 20) . "COSTO TOTAL RH\n";
echo str_repeat("-", 60) . "\n";
foreach ($resultados as $escenario => $datos) {
echo str_pad(strtoupper($escenario), 15);
echo str_pad("$" . number_format($datos['nominaNeta'], 2), 20);
echo "$" . number_format($datos['costoTotal'], 2) . "\n";
}
// Calcular diferencias
$difMejorPeor = $resultados['peor']['costoTotal'] - $resultados['mejor']['costoTotal'];
$porcDif = ($difMejorPeor / $resultados['mejor']['costoTotal']) * 100;
echo "\n=== ANÁLISIS ===\n";
echo "Diferencia Mejor vs Peor: $" . number_format($difMejorPeor, 2) . "\n";
echo "Porcentaje de variación: " . number_format($porcDif, 2) . "%\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Ejemplo 4: Empleado con Novedades Específicas

Section titled “Ejemplo 4: Empleado con Novedades Específicas”

Calcula nómina con horas extras, bonificaciones y otros conceptos:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
try {
$requestData = [
'periodo' => [
'mes' => 3,
'anio' => 2025
],
'nivelCalculo' => 'empleado',
'escenario' => 'promedio',
'perfiles' => [
[
'idEmpleado' => 'EMP001',
'tipoContrato' => 'indefinido',
'salarioBasico' => 3000000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => true,
'nivelRiesgoArl' => 2,
'novedades' => [
'horasExtras' => [
'diurnas' => 15, // 15 horas extras diurnas
'nocturnas' => 8 // 8 horas extras nocturnas
],
'recargos' => [
'nocturno' => 20 // 20 horas trabajo nocturno
],
'bonificaciones' => [
[
'concepto' => 'Bonificación por cumplimiento de objetivos',
'tipo' => 'salarial',
'monto' => 600000
],
[
'concepto' => 'Auxilio de alimentación',
'tipo' => 'no_salarial',
'monto' => 300000
]
]
]
]
]
];
$respuesta = calcularNomina($requestData);
$empleado = $respuesta['data']['resultados']['detalleEmpleados'][0];
echo "=== DETALLE DE NÓMINA CON NOVEDADES ===\n\n";
// Devengos
echo "DEVENGOS:\n";
echo " Salario Básico: $" . number_format($empleado['devengos']['salarioBasico'], 2) . "\n";
echo " Auxilio Transporte: $" . number_format($empleado['devengos']['auxilioTransporte'], 2) . "\n";
echo " Horas Extras: $" . number_format($empleado['devengos']['horasExtras'], 2) . "\n";
echo " Recargos: $" . number_format($empleado['devengos']['recargos'], 2) . "\n";
echo " Bonificaciones: $" . number_format($empleado['devengos']['bonificaciones'], 2) . "\n";
echo " TOTAL DEVENGOS: $" . number_format($empleado['devengos']['totalDevengos'], 2) . "\n\n";
// Deducciones
echo "DEDUCCIONES:\n";
echo " Salud: $" . number_format($empleado['deducciones']['salud'], 2) . "\n";
echo " Pensión: $" . number_format($empleado['deducciones']['pension'], 2) . "\n";
echo " Retención: $" . number_format($empleado['deducciones']['retencionFuente'], 2) . "\n";
echo " TOTAL DEDUCCIONES: $" . number_format($empleado['deducciones']['totalDeducciones'], 2) . "\n\n";
// Detalle de novedades aplicadas
if (!empty($empleado['novedades']['horasExtras'])) {
echo "DETALLE HORAS EXTRAS:\n";
foreach ($empleado['novedades']['horasExtras']['detalle'] as $he) {
echo " {$he['tipo']}: {$he['cantidad']}h x $" .
number_format($he['valorHora'], 2) . " = $" .
number_format($he['total'], 2) . "\n";
}
echo "\n";
}
// Totales finales
echo "=== TOTALES ===\n";
echo "Nómina a Pagar: $" . number_format($empleado['totales']['nominaNeta'], 2) . "\n";
echo "Costo Empleador: $" . number_format($empleado['totales']['costoEmpleador'], 2) . "\n";
echo "Provisiones: $" . number_format($empleado['totales']['totalProvisiones'], 2) . "\n";
echo "COSTO TOTAL: $" . number_format($empleado['totales']['costoTotalRecursoHumano'], 2) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Ejemplo 5: Porcentajes Personalizados (Exoneración Parafiscales)

Section titled “Ejemplo 5: Porcentajes Personalizados (Exoneración Parafiscales)”

Calcula nómina con empresa exonerada de SENA e ICBF:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
try {
$requestData = [
'periodo' => [
'mes' => 1,
'anio' => 2025
],
'nivelCalculo' => 'empleado',
'escenario' => 'promedio',
'porcentajeNovedades' => 0,
'porcentajesPersonalizados' => [
'saludEmpleado' => 0.04,
'saludEmpleador' => 0.085,
'pensionEmpleado' => 0.04,
'pensionEmpleador' => 0.12,
'sena' => 0, // ✅ Exonerado
'icbf' => 0, // ✅ Exonerado
'cajaCompensacion' => 0.04,
'cesantias' => 0.0833,
'interesesCesantias' => 0.01,
'primaServicios' => 0.0833,
'vacaciones' => 0.0417
],
'perfiles' => [
[
'idEmpleado' => 'EMP001',
'tipoContrato' => 'indefinido',
'salarioBasico' => 5000000,
'tipoSalario' => 'no_integral',
'diasContratados' => 30,
'aplicaAuxilioTransporte' => false,
'nivelRiesgoArl' => 1
]
]
];
$respuesta = calcularNomina($requestData);
$empleado = $respuesta['data']['resultados']['detalleEmpleados'][0];
echo "=== APORTES EMPLEADOR (CON EXONERACIÓN) ===\n";
echo "Salud: $" . number_format($empleado['aportesEmpleador']['salud'], 2) . "\n";
echo "Pensión: $" . number_format($empleado['aportesEmpleador']['pension'], 2) . "\n";
echo "ARL: $" . number_format($empleado['aportesEmpleador']['arl'], 2) . "\n";
echo "SENA: $" . number_format($empleado['aportesEmpleador']['sena'], 2) . " ✅ EXONERADO\n";
echo "ICBF: $" . number_format($empleado['aportesEmpleador']['icbf'], 2) . " ✅ EXONERADO\n";
echo "Caja Compensación: $" . number_format($empleado['aportesEmpleador']['cajaCompensacion'], 2) . "\n";
echo "TOTAL: $" . number_format($empleado['aportesEmpleador']['totalAportesEmpleador'], 2) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Calcula nómina de un empleado con salario integral:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
try {
$requestData = [
'periodo' => [
'mes' => 1,
'anio' => 2025
],
'nivelCalculo' => 'empleado',
'escenario' => 'promedio',
'perfiles' => [
[
'idEmpleado' => 'GERENTE001',
'tipoContrato' => 'indefinido',
'salarioBasico' => 20000000, // > 13 SMMLV
'tipoSalario' => 'integral', // ✅ Salario integral
'diasContratados' => 30,
'aplicaAuxilioTransporte' => false, // No aplica en integral
'nivelRiesgoArl' => 1
]
]
];
$respuesta = calcularNomina($requestData);
$empleado = $respuesta['data']['resultados']['detalleEmpleados'][0];
echo "=== SALARIO INTEGRAL ===\n\n";
echo "Salario Total: $" . number_format($empleado['devengos']['salarioBasico'], 2) . "\n";
echo "Factor Prestacional (30%): $" . number_format($empleado['devengos']['salarioBasico'] * 0.3, 2) . "\n";
echo "Salario Base (70%): $" . number_format($empleado['devengos']['baseIbc'], 2) . "\n\n";
echo "DEDUCCIONES:\n";
echo "Salud: $" . number_format($empleado['deducciones']['salud'], 2) . " ❌ NO APLICA\n";
echo "Pensión: $" . number_format($empleado['deducciones']['pension'], 2) . " ❌ NO APLICA\n\n";
echo "APORTES EMPLEADOR:\n";
echo "Todos los aportes: $" . number_format($empleado['aportesEmpleador']['totalAportesEmpleador'], 2) . " ❌ NO APLICAN\n\n";
echo "PROVISIONES:\n";
echo "Todas las provisiones: $" . number_format($empleado['provisiones']['totalProvisiones'], 2) . " ❌ NO APLICAN\n";
echo "(Ya están incluidas en el factor prestacional del 30%)\n\n";
echo "COSTO TOTAL: $" . number_format($empleado['totales']['costoTotalRecursoHumano'], 2) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Ejemplo de manejo robusto de errores:

<?php
require_once 'config.php';
require_once 'funciones_nomina.php';
function calcularNominaSeguro($requestData)
{
try {
$respuesta = calcularNomina($requestData);
// Log exitoso
error_log("Cálculo exitoso - Tiempo: " .
$respuesta['metadata']['tiempoProcesamientoMs'] . "ms");
return [
'exito' => true,
'datos' => $respuesta['data']
];
} catch (Exception $e) {
// Log del error
error_log("Error en cálculo de nómina: " . $e->getMessage());
// Determinar tipo de error
$mensaje = $e->getMessage();
if (strpos($mensaje, 'HTTP 400') !== false) {
$tipoError = 'validacion';
$mensajeUsuario = 'Hay errores en los datos enviados. Verifica los parámetros.';
} elseif (strpos($mensaje, 'HTTP 403') !== false) {
$tipoError = 'autenticacion';
$mensajeUsuario = 'API Key inválido. Contacta al líder técnico.';
} elseif (strpos($mensaje, 'HTTP 500') !== false) {
$tipoError = 'servidor';
$mensajeUsuario = 'Error interno del servidor. Intenta más tarde.';
} elseif (strpos($mensaje, 'timeout') !== false) {
$tipoError = 'timeout';
$mensajeUsuario = 'La petición tardó demasiado. Intenta con menos perfiles.';
} else {
$tipoError = 'conexion';
$mensajeUsuario = 'Error de conexión. Verifica tu conexión a internet.';
}
return [
'exito' => false,
'tipoError' => $tipoError,
'mensaje' => $mensajeUsuario,
'detallesTecnicos' => $mensaje
];
}
}
// Uso
$resultado = calcularNominaSeguro($requestData);
if ($resultado['exito']) {
// Procesar datos exitosos
$datos = $resultado['datos'];
// ... tu lógica
} else {
// Manejar error
echo "Error: " . $resultado['mensaje'] . "\n";
if (DEBUG_MODE) {
echo "Detalles: " . $resultado['detallesTecnicos'] . "\n";
}
}

Para escenarios que se consultan frecuentemente:

<?php
function obtenerCostoProyecto($idProyecto, $mes, $anio, $escenario)
{
$cacheKey = "nomina_{$idProyecto}_{$mes}_{$anio}_{$escenario}";
// Intentar obtener del caché (ej: Redis, Memcached, archivo)
$cached = obtenerDeCache($cacheKey);
if ($cached !== null) {
return $cached;
}
// Si no está en caché, calcular
$resultado = calcularNomina(/* ... */);
// Guardar en caché por 1 hora
guardarEnCache($cacheKey, $resultado, 3600);
return $resultado;
}

Para muchos proyectos, procesa de forma asíncrona:

<?php
function calcularMultiplesProyectos($proyectos)
{
$resultados = [];
foreach ($proyectos as $proyecto) {
try {
$resultado = calcularNomina($proyecto['requestData']);
$resultados[$proyecto['id']] = $resultado;
// Pequeña pausa entre peticiones
usleep(100000); // 0.1 segundos
} catch (Exception $e) {
$resultados[$proyecto['id']] = ['error' => $e->getMessage()];
}
}
return $resultados;
}

Valida datos localmente antes de hacer la petición:

<?php
function validarSalarioMinimo($salario, $porcentajeJornada = 100)
{
$SMMLV_2025 = 1423500;
$salarioMinimo = ($SMMLV_2025 * $porcentajeJornada) / 100;
if ($salario < $salarioMinimo) {
throw new Exception(
"El salario ($salario) es menor al SMMLV proporcional ($salarioMinimo)"
);
}
return true;
}
// Uso
try {
validarSalarioMinimo(1200000, 100); // Lanza excepción
} catch (Exception $e) {
echo "Error de validación: " . $e->getMessage();
// No hacer la petición al API
}

En la siguiente sección encontrarás el detalle completo de las respuestas del endpoint y cómo manejar cada tipo de error.