Documento Base
Utilizado para pagos de nómina regulares mensuales, quincenales o semanales.
La Nómina Individual es el documento estándar para el pago de nómina electrónica. Este XML contiene toda la información del período de pago, devengados, deducciones y totales del empleado.
Documento Base
Utilizado para pagos de nómina regulares mensuales, quincenales o semanales.
Validación
Estructura validada contra esquema XSD de la DIAN antes del envío.
Componentes
18+ nodos principales con sub-nodos obligatorios y opcionales.
Cálculos
Totales, porcentajes y deducciones deben cuadrar matemáticamente (±2.00 tolerancia).
<?xml version="1.0" encoding="UTF-8"?><NominaIndividual xmlns="dian:gov:co:facturaelectronica:NominaIndividual" ...>
<!-- 1. Extensiones DIAN --> <ext:UBLExtensions/>
<!-- 2. Novedad (false para nómina normal) --> <Novedad CUNENov="">false</Novedad>
<!-- 3. Período de liquidación --> <Periodo ... />
<!-- 4. Numeración del documento --> <NumeroSecuenciaXML ... />
<!-- 5. Lugar de generación --> <LugarGeneracionXML ... />
<!-- 6. Proveedor (generado por Facturatech) --> <ProveedorXML ... />
<!-- 7. Código QR --> <CodigoQR>...</CodigoQR>
<!-- 8. Información general --> <InformacionGeneral ... />
<!-- 9. Notas (opcional) --> <Notas>...</Notas>
<!-- 10. Datos del empleador --> <Empleador ... />
<!-- 11. Datos del trabajador --> <Trabajador ... />
<!-- 12. Forma de pago --> <Pago ... />
<!-- 13. Fechas de pago --> <FechasPagos> <FechaPago>...</FechaPago> </FechasPagos>
<!-- 14. Devengados --> <Devengados> <Basico ... /> <!-- Otros devengados opcionales --> </Devengados>
<!-- 15. Deducciones --> <Deducciones> <Salud ... /> <FondoPension ... /> <!-- Otras deducciones opcionales --> </Deducciones>
<!-- 16. Redondeo --> <Redondeo>0.00</Redondeo>
<!-- 17. Totales --> <DevengadosTotal>...</DevengadosTotal> <DeduccionesTotal>...</DeduccionesTotal> <ComprobanteTotal>...</ComprobanteTotal>
</NominaIndividual><NominaIndividual xmlns="dian:gov:co:facturaelectronica:NominaIndividual" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SchemaLocation="" xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd"><Periodo FechaIngreso="2024-01-01" FechaRetiro="" FechaLiquidacionInicio="2024-11-01" FechaLiquidacionFin="2024-11-30" TiempoLaborado="330" FechaGen="2024-11-20"/>| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| FechaIngreso | F | OK | Fecha de ingreso del trabajador (AAAA-MM-DD) |
| FechaRetiro | F | OP | Fecha de retiro (solo si aplica) |
| FechaLiquidacionInicio | F | OK | Inicio del período de nómina |
| FechaLiquidacionFin | F | OK | Fin del período de nómina |
| TiempoLaborado | N | OK | Días laborados desde ingreso |
| FechaGen | F | OK | Fecha de generación del documento |
function calcularTiempoLaborado($fechaIngreso, $fechaLiquidacionFin) { $inicio = new DateTime($fechaIngreso); $fin = new DateTime($fechaLiquidacionFin);
$diff = $inicio->diff($fin);
// 1 año = 360 días, 1 mes = 30 días $anos = $diff->y; $meses = $diff->m; $dias = $diff->d;
$tiempoLaborado = ($anos * 360) + ($meses * 30) + $dias;
// Si el mes de liquidación tiene más de 30 días, sumar 1 $diasEnMes = cal_days_in_month( CAL_GREGORIAN, $fin->format('m'), $fin->format('Y') );
if ($diasEnMes > 30) { $tiempoLaborado += 1; }
return $tiempoLaborado;}function validarPeriodo($periodo) { $errores = [];
// FechaIngreso debe ser anterior a FechaLiquidacionFin if ($periodo['FechaIngreso'] > $periodo['FechaLiquidacionFin']) { $errores[] = "FechaIngreso no puede ser posterior a FechaLiquidacionFin"; }
// FechaLiquidacionInicio debe ser anterior a FechaLiquidacionFin if ($periodo['FechaLiquidacionInicio'] > $periodo['FechaLiquidacionFin']) { $errores[] = "FechaLiquidacionInicio debe ser anterior a FechaLiquidacionFin"; }
// TiempoLaborado debe ser coherente $calculado = calcularTiempoLaborado( $periodo['FechaIngreso'], $periodo['FechaLiquidacionFin'] );
if (abs($calculado - $periodo['TiempoLaborado']) > 1) { $errores[] = "TiempoLaborado inconsistente"; }
return $errores;}<NumeroSecuenciaXML CodigoTrabajador="001" Prefijo="NOM" Consecutivo="35921" Numero="NOM35921"/>| Campo | Descripción |
|---|---|
| CodigoTrabajador | Código interno del trabajador (opcional) |
| Prefijo | Prefijo de la serie (ej: NOM, NOMINA) |
| Consecutivo | Número consecutivo |
| Numero | Concatenación de Prefijo + Consecutivo |
<Empleador RazonSocial="MI EMPRESA SAS" NIT="901143311" DV="8" Pais="CO" DepartamentoEstado="68" MunicipioCiudad="68001" Direccion="Calle 123 # 45-67"/>Todos los campos son obligatorios. El NIT debe incluir el dígito de verificación por separado.
<Trabajador TipoTrabajador="01" SubTipoTrabajador="00" AltoRiesgoPension="false" TipoDocumento="13" NumeroDocumento="1234567890" PrimerApellido="PEREZ" SegundoApellido="GOMEZ" PrimerNombre="JUAN" OtrosNombres="CARLOS" LugarTrabajoPais="CO" LugarTrabajoDepartamentoEstado="68" LugarTrabajoMunicipioCiudad="68001" LugarTrabajoDireccion="Carrera 27 # 34-56" SalarioIntegral="false" TipoContrato="1" Sueldo="1300000" CodigoTrabajador="001"/>Obligatorio
Basico
Opcionales Comunes
Bonificaciones
Especiales
<Devengados> <!-- Obligatorio --> <Basico DiasTrabajados="30" SueldoTrabajado="1300000"/>
<!-- Auxilio de transporte --> <Transporte AuxilioTransporte="162000"/>
<!-- Horas extras (si aplica) --> <HEDs> <HED HoraInicio="2024-11-15T17:00:00" HoraFin="2024-11-15T19:00:00" Cantidad="2" Porcentaje="25.00" Pago="13541.67"/> </HEDs>
<!-- Bonificaciones (si aplica) --> <Bonificaciones> <Bonificacion BonificacionS="100000"/> </Bonificaciones></Devengados><Deducciones> <!-- Salud (4% empleado) --> <Salud Porcentaje="4.00" Deduccion="52000"/>
<!-- Pensión (4% empleado) --> <FondoPension Porcentaje="4.00" Deduccion="52000"/>
<!-- Fondo Solidaridad (solo si sueldo >= 4 SMLV) --> <FondoSP Porcentaje="1.00" DeduccionSP="13000" PorcentajeSub="0" DeduccionSub="0"/></Deducciones>function calcularDeducciones($devengadosTotal, $sueldo) { $smlv = 1300000; // Salario mínimo vigente
$deducciones = [];
// Salud: 4% del total devengado $deducciones['salud'] = [ 'porcentaje' => 4.00, 'deduccion' => round($devengadosTotal * 0.04, 2) ];
// Pensión: 4% del total devengado $deducciones['pension'] = [ 'porcentaje' => 4.00, 'deduccion' => round($devengadosTotal * 0.04, 2) ];
// Fondo Solidaridad: 1% si sueldo >= 4 SMLV if ($sueldo >= ($smlv * 4)) { $deducciones['fondo_sp'] = [ 'porcentaje' => 1.00, 'deduccion' => round($sueldo * 0.01, 2) ]; }
return $deducciones;}Deducciones opcionales disponibles:
<Redondeo>0.00</Redondeo><DevengadosTotal>1462000.00</DevengadosTotal><DeduccionesTotal>104000.00</DeduccionesTotal><ComprobanteTotal>1358000.00</ComprobanteTotal>Fórmulas:
DevengadosTotal = Suma de todos los devengadosDeduccionesTotal = Suma de todas las deduccionesComprobanteTotal = DevengadosTotal - DeduccionesTotalfunction validarTotales($xml) { $devengados = (float)$xml->DevengadosTotal; $deducciones = (float)$xml->DeduccionesTotal; $comprobante = (float)$xml->ComprobanteTotal;
$calculado = $devengados - $deducciones; $diferencia = abs($calculado - $comprobante);
if ($diferencia > 2.00) { throw new Exception( "Totales no cuadran. Diferencia: $diferencia. " . "Calculado: $calculado vs Comprobante: $comprobante" ); }
return true;}| Tipo | Descripción | Ejemplo |
|---|---|---|
| A | Alfanumérico | "JUAN PEREZ" |
| B | Booleano | "true" o "false" (minúsculas) |
| N | Numérico | "1300000.00" |
| F | Fecha | "2024-11-20" (AAAA-MM-DD) |
| H | Hora | "15:13:46-05:00" (HH:MM:SS-05:00) |
Antes de enviar, verificar: