FINORA ERP · Tutorial
Integrar la nómina por API
En este tutorial conectas un control de asistencia con FINORA: al cierre de la quincena, el sistema del reloj envía las horas extra, las horas nocturnas y los feriados trabajados de cada trabajador. FINORA calcula la nómina y tú obtienes el resultado, los recibos y el archivo del banco, sin pasar por las ventanas.
Todos los datos de este tutorial son ficticios: la empresa es erp.tuempresa.com, el trabajador es Trabajador de
ejemplo, cédula V-00000001.
Parte 1: preparar la sesión
Sección titulada «Parte 1: preparar la sesión»-
Pide el token con tu usuario de integración y guárdalo en una variable:
Ventana de terminal ERP=https://erp.tuempresa.com/api/v1TOKEN=$(curl -s -X POST "$ERP/auth/tokens" -H 'Content-Type: application/json' -d '{"userName": "integracion-asistencia", "password": "***","parameters": {"clientId": 1000000, "roleId": 1000100, "organizationId": 0}}' | jq -r .token) -
Carga la función de ayuda
nom. Convierte tu JSON al formato canónico, calcula el hash y arma el cuerpo de la llamada:Ventana de terminal nom() { # nom <proceso> '<json>' [clave] con clave es una escrituralocal canon hash bodycanon=$(printf '%s' "$2" | jq -cS .)if [ -n "$3" ]; thenhash=$(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}')elsebody=$(jq -n --arg p "$canon" '{FVE_NOM_Payload:$p}')ficurl -s -X POST "$ERP/processes/$1" -H "Authorization: Bearer $TOKEN" \-H 'Content-Type: application/json' -d "$body"} -
Comprueba la conexión pidiendo las novedades que acepta FINORA:
Ventana de terminal nom fve_nom_conceptos '{"soloNovedades": true}' | jq -r '.logs[] | (.msg? // .)' | jq -c '{codigo, novedad}'Verás siete conceptos. Los cuatro de este tutorial son
ASI_HE_DIURNAyASI_HE_NOCTURNA(horas extra),ASI_BONO_NOCTURNO(horas trabajadas de noche dentro de la jornada) yASI_FERIADO_TRAB(feriados trabajados, en días enteros). FINORA calcula los montos con el salario y la LOTTT; tú solo envías cantidades. -
Confirma que el trabajador existe en la nómina:
Ventana de terminal nom fve_nom_trabajadores '{"nomina": "Q", "cedula": "V-00000001"}' | jq -r '.summary'Si
totales 0, Recursos Humanos tiene que darlo de alta antes (en la ventana Trabajadores, o tu sistema de RR. HH. con el procesofve_nom_trabajador_alta).
Parte 2: crear la corrida y cargar las novedades
Sección titulada «Parte 2: crear la corrida y cargar las novedades»-
Crea la corrida de la quincena. La clave identifica esta operación: si la red se corta y repites la llamada con la misma clave, FINORA devuelve la misma corrida en vez de crear otra.
Ventana de terminal nom fve_nom_corrida_crear '{"nomina": "Q", "fecha": "2026-10-01", "tipo": "ORDINARIA"}' corrida-Q-2026-10-01 \| jq -r '.summary' | jq '.resultado'Guarda el valor de
corrida(en este ejemplo,1000123). Si respondeCONFLICTO, la quincena ya tiene su corrida ordinaria: el detalle te dice cuál, y puedes buscarla confve_nom_corridas. -
Arma el lote con las marcaciones del reloj. Usa como
referenciael identificador que tu sistema ya tiene para cada marcación: así un reenvío nunca duplica una novedad.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-lote-1 -
Lee la respuesta.
summarydice cuántas líneas se registraron y cuántas se rechazaron;logs[]trae una entrada por línea, en el mismo orden del lote:{"cedula":"V00000001","concepto":"ASI_HE_DIURNA","estado":"REGISTRADA","linea":0,"movimiento":1000501,"referencia":"MARC-1","tipo":"novedad"}Una línea
RECHAZADAtrae el motivo endetalle: por ejemplo, una fecha fuera de la quincena o un trabajador de otra nómina. Las demás líneas sí se registraron. Corrige la línea y envíala en un lote nuevo, con otra clave. -
Si la quincena tiene muchos trabajadores, divide las marcaciones en lotes de unas 35 líneas: cada llamada admite como máximo 3.999 caracteres. Cada lote lleva su propia clave (
asistencia-2026-10-01-lote-2,-lote-3…).
Parte 3: calcular y revisar
Sección titulada «Parte 3: calcular y revisar»-
Calcula la corrida. Este es un proceso de nómina de siempre: responde texto, no el sobre JSON, y se puede repetir.
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"}' | jq -r .summaryCalculados 1 trabajador(es): asignaciones 106425.00, deducciones 35124.61, neto 71300.39 -
Revisa el resultado por trabajador:
Ventana de terminal nom fve_nom_corrida_resultado '{"corrida": 1000123}' | jq -r '.logs[] | (.msg? // .)' \| jq -r 'select(.tipo == "linea") | [.seccion, .codigo, .cantidad, .monto] | @tsv'Cada línea viene con su sección: asignaciones salariales (
EARNING), no salariales (NON_SALARY), deducciones (DEDUCTION) y aportes patronales (EMPLOYER). La advertenciaPRE_NOMINAte recuerda que la corrida aún no está completada. En este ejemplo el neto del trabajador es 71.300,39. -
¿Llegó una marcación tarde? Cárgala con
fve_nom_novedades. La respuesta trae la advertenciaRECALCULAR: calcula de nuevo antes de seguir. Si intentas completar sin recalcular, FINORA lo rechaza con “Los movimientos o las novedades cambiaron después del cálculo”; así nunca se paga una quincena sin sus últimas novedades.
Parte 4: completar, recibos y banco
Sección titulada «Parte 4: completar, recibos y banco»Completar la corrida es una decisión de Recursos Humanos o de quien aprueba la nómina, no del reloj. Hazlo por API solo si tu empresa lo acordó así.
-
Completa la corrida. FINORA genera el asiento contable y alimenta los libros de ISLR, prestaciones y vacaciones:
Ventana de terminal curl -s -X POST "$ERP/processes/fve_payrollcomplete" -H "Authorization: Bearer $TOKEN" \-H 'Content-Type: application/json' -d '{"record-id": 1000123, "model-name": "hr_process"}' | jq -r .summaryDesde ahora, cualquier novedad nueva para esta corrida responde
ESTADO_INVALIDO. Una corrida completada no se modifica: si hay que corregir, se anula y se hace de nuevo, o se paga la diferencia en una corrida complementaria. -
Descarga los recibos de pago en PDF, uno por trabajador:
Ventana de terminal curl -s -X POST "$ERP/processes/fve_payrollpayslip" -H "Authorization: Bearer $TOKEN" \-H 'Content-Type: application/json' -d '{"HR_Process_ID": 1000123, "report-type": "PDF"}' \| jq -r .reportFile | base64 -d > recibos-2026-10-01.pdf -
Genera el archivo del banco con la cuenta de la empresa a debitar (te la indica Tesorería):
Ventana de terminal curl -s -X POST "$ERP/processes/fve_payrollbankfile" -H "Authorization: Bearer $TOKEN" \-H 'Content-Type: application/json' \-d '{"HR_Process_ID": 1000123, "C_BankAccount_ID": 1000010, "FVE_FileLayout": "banco-generico"}' \| jq -r .exportFile | base64 -d > pago-nomina-2026-10-01.txtEl total del archivo es igual al neto de la corrida. Tesorería lo carga en la banca en línea.
Qué aprendiste
Sección titulada «Qué aprendiste»- El reloj envía hechos (cédula, concepto, cantidad, fecha); FINORA calcula los montos.
- Cada escritura lleva una clave: repetirla es seguro, y la
referenciade cada novedad evita duplicados aunque cambie la clave. - Una novedad cargada después del cálculo obliga a calcular de nuevo antes de completar.
- El resultado de la API, el recibo y el archivo del banco muestran los mismos números.
Siguiente paso
Sección titulada «Siguiente paso»- API de nómina: informe técnico: todos los procesos, el alta de trabajadores, el cambio de salario, los códigos de error y los permisos.
- Las declaraciones del mes: BANAVIH, IVSS, TIUNA, pensiones e INCES de las corridas completadas.