Skip to content
FINORA Academy
SistemaFINORA ERP

FINORA ERP · Reference

API de nómina: informe técnico

In developmentVerifiedAdvanced25 minVerified on Oct 20, 2026

This content is not available in your language yet.

La API de integración de nómina permite que sistemas externos trabajen las nóminas de FINORA ERP: el sistema de Recursos Humanos da de alta trabajadores y cambia salarios, el control de asistencia carga las horas extra y las inasistencias, y un portal consulta el resultado de cada quincena. Llega con el módulo Nómina (diccionario 1.2.8).

La API no reemplaza al motor de nómina: los montos los calcula FINORA. El sistema externo envía hechos (cédulas, horas, días, fechas) y recibe resultados.

Cada operación es un proceso de iDempiere que se ejecuta por REST:

POST https://erp.tuempresa.com/api/v1/processes/<slug>
Authorization: Bearer <token>
Content-Type: application/json

El cuerpo lleva los parámetros del proceso. El contenido de negocio viaja como una cadena JSON dentro del parámetro FVE_NOM_Payload. Es el mismo contrato que usan la app del chofer de FINORA Transporte y FINORA Merchant.

TipoParámetros
LecturaSolo FVE_NOM_Payload, con la consulta ({} si no hay filtros)
EscrituraFVE_NOM_IdemKey (clave de idempotencia, hasta 120 caracteres), FVE_NOM_PayloadSha256 (sha256 del contenido) y FVE_NOM_Payload
Ventana de terminal
ERP=https://erp.tuempresa.com/api/v1
curl -s -X POST "$ERP/auth/tokens" -H 'Content-Type: application/json' -d '{
"userName": "integracion-rrhh", "password": "***",
"parameters": {"clientId": 1000000, "roleId": 1000100, "organizationId": 0}}'

La respuesta trae token. Guárdalo en TOKEN y úsalo en cada llamada. Ante un HTTP 401, pide otro token una vez y repite la llamada; el primer 401 puede llegar como página HTML, así que no lo leas como JSON.

  • Usa un usuario de integración propio de la empresa, con un rol de nómina. Nunca uses un usuario de una persona.
  • El alcance es el del rol: la empresa del token y sus organizaciones. Una organización fuera del rol responde FUERA_DE_ALCANCE; en las consultas, sus trabajadores y corridas no aparecen.
  • La organización del token puede ser 0. Al crear una corrida o un trabajador sin indicar organizacion, FINORA usa la de la nómina; si la nómina es compartida, la única organización con Datos laborales de la organización. Si hay más de una, la pide.

El contenido viaja en JSON canónico, para que el sistema externo y FINORA calculen el mismo hash:

  1. Claves ordenadas por punto de código Unicode y sin espacios.
  2. Cadenas con el escape mínimo; los acentos van tal cual, en UTF-8.
  3. Solo números enteros. Los montos, las cantidades y las tasas viajan como texto decimal ("180000.00", "2.5"; también se acepta la coma, "2,5", nunca separador de miles). Las fechas, como "AAAA-MM-DD".
  4. El hash es el sha256 de los bytes UTF-8 del texto canónico, en hexadecimal minúscula.

FINORA vuelve a canonizar el contenido y compara el hash; si no coincide, responde VALIDACION. Los campos desconocidos se ignoran, pero cuentan para el hash.

Una función de ayuda en Bash, con jq y shasum (en producción usa tu lenguaje; Java, Kotlin y Python producen los mismos bytes):

Ventana de terminal
nom() { # nom <slug> '<json>' [clave] con clave es una escritura
local canon hash body
canon=$(printf '%s' "$2" | jq -cS .)
if [ -n "$3" ]; then
hash=$(printf '%s' "$canon" | shasum -a 256 | cut -d' ' -f1)
body=$(jq -n --arg k "$3" --arg h "$hash" --arg p "$canon" \
'{FVE_NOM_IdemKey:$k, FVE_NOM_PayloadSha256:$h, FVE_NOM_Payload:$p}')
else
body=$(jq -n --arg p "$canon" '{FVE_NOM_Payload:$p}')
fi
curl -s -X POST "$ERP/processes/$1" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d "$body"
}

La respuesta HTTP es 200 siempre que el proceso se ejecutó, también cuando FINORA rechaza la operación. Lee isError y el sobre, que es una cadena JSON en summary:

{"advertencias":[],"clave":"corrida-Q-2026-10-01","codigo":"OK","resultado":{"corrida":1000123,"documento":"90010","estado":"DR"},"v":1,"yaExistia":false}
{"codigo":"ESTADO_INVALIDO","detalle":"la corrida 90010 está en estado CO: las novedades solo se registran en una corrida en borrador","estado":409,"v":1}

Cada elemento de una lista viaja en una entrada de logs[], también como JSON. Su campo tipo dice qué es: concepto, trabajador, salario, vacaciones, corrida, novedad o linea.

codigoestadoQué significa y qué hacer
OK200Lee resultado, advertencias y logs[]
VALIDACION400El contenido no es válido. Corrígelo y envíalo con otra clave: el rechazo queda guardado con la clave usada
FUERA_DE_ALCANCE403La organización no es del rol
NO_ENCONTRADO404No existe la cédula, la nómina, el departamento, el cargo, el período o la corrida. No queda guardado: puedes repetir con la misma clave cuando exista
CONFLICTO409La clave ya se usó con otro contenido, o el dato choca con uno existente: otra relación laboral abierta, otra corrida ordinaria del período, otro salario el mismo día
ESTADO_INVALIDO409La corrida no está en borrador
REINTENTAR503Falla pasajera: repite con la misma clave y el mismo contenido
ERROR_INTERNO500Repórtalo a soporte con la clave
AdvertenciaDóndeSignificado
RECALCULARNovedadesLa corrida estaba calculada: hay que calcularla de nuevo antes de completarla
LINEAS_RECHAZADASNovedadesAlguna línea del lote se rechazó; las demás se registraron
PRE_NOMINAResultadoLa corrida todavía no está completada
SIN_CALCULARResultadoLa corrida no tiene cálculo
ANULADAResultadoLa corrida está anulada
SIN_DATOS_LABORALESCrear corridaLa organización no tiene Datos laborales de la organización; el cálculo fallará
TERCERO_EXISTENTEAltaSe reutilizó un tercero que ya tenía ese código
BANCO_NO_REGISTRADOAltaLa empresa no tiene registrado el banco de la cuenta
OTRA_CUENTA_ACTIVAAltaEl tercero ya tenía otra cuenta: el archivo del banco paga la más antigua
RETROACTIVOSalarioLa fecha cae en un período ya completado: la diferencia va en una corrida complementaria

Cada escritura lleva una clave que el sistema externo genera y guarda antes de enviar. FINORA la bloquea mientras procesa y guarda, en la misma transacción que los datos, la llamada con su respuesta:

  • Misma clave y mismo contenido: FINORA devuelve la respuesta guardada con yaExistia: true, también las líneas de un lote. Un reintento tras un corte de red es siempre seguro.
  • Misma clave y otro contenido: CONFLICTO.
  • Clave nueva: se procesa.

Además hay reglas de negocio que impiden duplicados aunque cambie la clave: una sola corrida ordinaria no anulada por nómina y período, una sola relación laboral abierta por cédula, un salario por trabajador y fecha, y la referencia de cada novedad, única dentro de la corrida.

Una buena clave es <sistema>-<operación>-<id propio>, por ejemplo asistencia-2026-10-01-lote-3. Las llamadas quedan en la tabla Llamadas de la API de nómina (FVE_NOM_ApiCall).

  • Cada contenido admite como máximo 3.999 caracteres. Un lote de novedades ocupa unos 110 caracteres por línea con fecha y referencia: unas 35 líneas por llamada.
  • Hasta 200 líneas por lote y 200 elementos por página en las consultas.
  • No hay límite de llamadas por minuto, pero no envíes en paralelo escrituras sobre la misma corrida: FINORA las procesa una a una.

Los ejemplos usan la función nom y datos ficticios.

Ventana de terminal
nom fve_nom_conceptos '{"soloNovedades": true}'

Filtros: fase (EARNING, NON_SALARY, PAYOUT, DEDUCTION, EMPLOYER, LEDGER) y soloNovedades. Cada concepto trae su código, nombre, fase, las bases que alimenta y la norma. Los que se cargan como novedad traen novedad con la unidad (HORAS o DIAS), si es entera, el tipo de corrida y si requiere fecha de inicio.

Ventana de terminal
nom fve_nom_trabajadores '{"nomina": "Q", "estado": "ACTIVO", "pagina": 1, "porPagina": 50}'

Filtros: nomina, departamento (sus códigos), estado (ACTIVO, EGRESADO, TODOS), cedula, fecha (por defecto hoy), pagina y porPagina. Cada trabajador trae cédula, nombres, nómina, departamento, cargo, ingreso, egreso, tipo de contrato, tipo de salario, jornada, el salario normal vigente a la fecha y la cuenta bancaria enmascarada (código del banco y últimos 4 dígitos).

Ventana de terminal
nom fve_nom_trabajador '{"cedula": "V-00000001"}'

La ficha de la relación laboral más reciente de la cédula, con el saldo de prestaciones (garantía e intereses), los días de vacaciones pendientes y el porcentaje de la AR-I del año. En logs[], el historial de salario y las vacaciones por año de servicio. La cédula se acepta como V00000001, V-00.000.001 o solo los dígitos.

Ventana de terminal
nom fve_nom_trabajador_alta '{"cedula": "V-00000001", "primerNombre": "TRABAJADOR",
"primerApellido": "DE EJEMPLO", "fechaIngreso": "2026-10-01", "nomina": "Q",
"departamento": "ADM", "cargo": "ANA", "salarioMensual": "180000.00",
"jornada": "DIURNA", "tipoContrato": "INDETERMINADO", "tipoSalario": "FIJO",
"cuentaBancaria": "00000000000000000001"}' alta-V00000001

Crea en una sola transacción el tercero, la relación laboral, los datos legales, el salario desde el ingreso y, si se envía, la cuenta de nómina. Si algo falla, no queda nada a medias. Aplica las mismas reglas que las ventanas: nombres sin comas (el archivo del BANAVIH separa por comas), valores válidos de las listas, cuenta de 20 dígitos y salario no negativo. salarioMensual es el salario normal (LOTTT art. 104), no el básico.

Una cédula con una relación laboral abierta responde CONFLICTO. La AR-I y el egreso no están en la API: la AR-I la revisa el contador y el egreso decide la liquidación, así que se registran en las ventanas o por /models.

Ventana de terminal
nom fve_nom_salario '{"cedula": "V-00000001", "desde": "2026-11-01", "salarioMensual": "200000.00"}' salario-V00000001-20261101

Solo agrega una fila al historial de salario. El mismo monto el mismo día responde sinCambios: true; otro monto el mismo día responde CONFLICTO. Una fecha en un período ya completado se acepta con la advertencia RETROACTIVO.

Ventana de terminal
nom fve_nom_corridas '{"nomina": "Q", "estado": "DR"}'

Filtros: nomina, periodo, desde y hasta (fecha de pago), estado (DR borrador, CO completada, VO anulada…) y tipo. Cada corrida trae su número, estado, período, fecha de pago, si está calculada, cuántos trabajadores tiene y el neto.

Ventana de terminal
nom fve_nom_corrida_crear '{"nomina": "Q", "fecha": "2026-10-01", "tipo": "ORDINARIA"}' corrida-Q-2026-10-01

Crea la corrida en borrador. El período se indica con periodo (su número interno) o con fecha (cualquier día del período). Tipos: ORDINARIA, VACACIONES, UTILIDADES, PRESTACIONES y LIQUIDACION. Opcionales: fechaPago (por defecto, el fin del período), fechaContable, nombre y organizacion. Guarda el corrida que devuelve: es el número que usan los demás procesos.

Ventana de terminal
nom fve_nom_novedades '{"corrida": 1000123, "lineas": [
{"cedula": "V-00000001", "concepto": "ASI_HE_DIURNA", "cantidad": "6", "fecha": "2026-10-09", "referencia": "MARC-1"},
{"cedula": "V-00000001", "concepto": "ASI_BONO_NOCTURNO", "cantidad": "3", "fecha": "2026-10-10", "referencia": "MARC-2"},
{"cedula": "V-00000001", "concepto": "ASI_FERIADO_TRAB", "cantidad": "1", "fecha": "2026-10-12", "referencia": "MARC-3"}]}' asistencia-2026-10-01-1

Solo se aceptan las novedades que el cálculo lee, por cantidad:

ConceptoUnidadCorrida
ASI_HE_DIURNA, ASI_HE_NOCTURNAhoras, hasta 2 decimalesORDINARIA
ASI_BONO_NOCTURNOhorasORDINARIA
ASI_FERIADO_TRAB, ASI_DESCANSO_TRABdías enterosORDINARIA
DED_INASISTENCIAdías, hasta 2 decimalesORDINARIA
ASI_VACACIONESdías hábiles enteros, con inicio (primer día de vacaciones)VACACIONES

Un concepto de monto (préstamo, embargo, comisión) y el campo monto se rechazan: el motor no los lee y quedarían guardados sin efecto. La fecha debe estar dentro del período (por defecto, su último día) y el trabajador debe ser de la nómina de la corrida y estar activo en el período.

Cada línea se responde en logs[] con su estado: REGISTRADA, EXISTENTE (la misma referencia con los mismos datos ya estaba), ANULADA o RECHAZADA con el motivo. Una línea rechazada no detiene las demás; con "atomico": true se registran todas o ninguna. Para corregir una novedad, anúlala con {"anular": true, "referencia": "MARC-1"} y vuelve a enviarla con otra referencia.

Resultado de la corrida: fve_nom_corrida_resultado

Sección titulada «Resultado de la corrida: fve_nom_corrida_resultado»
Ventana de terminal
nom fve_nom_corrida_resultado '{"corrida": 1000123}'

En resultado, los totales de la corrida: asignaciones salariales y no salariales, pagos de prestaciones, deducciones, neto y aportes patronales. En logs[], por trabajador, una entrada con sus totales seguida de sus líneas por sección (asignaciones, no salariales, pagos de prestaciones, deducciones, aportes patronales y movimientos de libro). Son los mismos números del recibo, del asiento contable y del archivo del banco: nada se recalcula. Con cedula, un solo trabajador.

Calcular, completar, anular, los recibos y el archivo del banco son los procesos de nómina de siempre. Responden texto en summary (no el sobre) e isError. Se ejecutan sobre la corrida:

Ventana de terminal
curl -s -X POST "$ERP/processes/fve_payrollcalculate" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d '{"record-id": 1000123, "model-name": "hr_process"}'
PasoProcesoNota
Calcularfve_payrollcalculateSe puede repetir: reemplaza lo calculado y nunca toca las novedades
Completarfve_payrollcompleteGenera el asiento contable y alimenta los libros de ISLR, prestaciones y vacaciones
Anularfve_payrollvoidReversa el asiento; una corrida completada nunca se borra
Recibosfve_payrollpayslip{"HR_Process_ID": 1000123, "report-type": "PDF"}; el PDF llega en reportFile (base64)
Archivo del bancofve_payrollbankfileSolo corrida completada; el total es igual al neto; el archivo llega en exportFile

Al calcular, FINORA guarda una huella (hash) de la corrida: los movimientos calculados y las novedades. Al completar la vuelve a calcular. Si una novedad se registró, cambió, desactivó o borró después del cálculo, por la API, por /models o en la ventana, completar responde:

Los movimientos o las novedades cambiaron después del cálculo: ejecute Calcular de nuevo (payroll-processes §9)

Así nunca se paga una nómina que no incluye las últimas novedades. La API además avisa RECALCULAR en cuanto registras la novedad.

  1. Crear la corrida con fve_nom_corrida_crear y guardar su número.
  2. Cargar las novedades con fve_nom_novedades, en lotes de unas 35 líneas, cada lote con su clave.
  3. Calcular con fve_payrollcalculate.
  4. Revisar con fve_nom_corrida_resultado (pre-nómina, advertencia PRE_NOMINA).
  5. Si llega una novedad tarde: cargarla, calcular de nuevo y revisar.
  6. Completar con fve_payrollcomplete; después, las novedades de esa corrida responden ESTADO_INVALIDO.
  7. Recibos con fve_payrollpayslip y archivo del banco con fve_payrollbankfile.

Con el caso de prueba de la documentación de nómina (salario de 180.000,00, 6 horas extra diurnas, 3 horas nocturnas y un feriado trabajado en la primera quincena de octubre de 2026), el neto es 71.300,39 en el resultado, en el recibo y en el archivo del banco.

  • Los nueve procesos se dan a los roles que ya ejecutan Calcular nómina, y a los roles con el módulo Nómina en Configurar tenant. Quita el acceso a los roles que no deben ver salarios.
  • Los salarios son datos sensibles: no des estos procesos al rol de consulta. Las cuentas bancarias siempre se devuelven enmascaradas.
  • Cada escritura queda registrada con su clave, usuario, contenido y respuesta. Una novedad con referencia la guarda en su descripción como ref:<referencia>.