Ir al contenido
FINORA Academy
SistemaFINORA ERP

FINORA ERP · Tutorial

Integrar la nómina por API

En desarrolloVerificadoIntermedio30 minVerificado el 20 oct. 2026

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.

  1. Pide el token con tu usuario de integración y guárdalo en una variable:

    Ventana de terminal
    ERP=https://erp.tuempresa.com/api/v1
    TOKEN=$(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)
  2. 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 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"
    }
  3. 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_DIURNA y ASI_HE_NOCTURNA (horas extra), ASI_BONO_NOCTURNO (horas trabajadas de noche dentro de la jornada) y ASI_FERIADO_TRAB (feriados trabajados, en días enteros). FINORA calcula los montos con el salario y la LOTTT; tú solo envías cantidades.

  4. 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 total es 0, Recursos Humanos tiene que darlo de alta antes (en la ventana Trabajadores, o tu sistema de RR. HH. con el proceso fve_nom_trabajador_alta).

Parte 2: crear la corrida y cargar las novedades

Sección titulada «Parte 2: crear la corrida y cargar las novedades»
  1. 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 responde CONFLICTO, la quincena ya tiene su corrida ordinaria: el detalle te dice cuál, y puedes buscarla con fve_nom_corridas.

  2. Arma el lote con las marcaciones del reloj. Usa como referencia el 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
  3. Lee la respuesta. summary dice 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 RECHAZADA trae el motivo en detalle: 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.

  4. 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…).

  1. 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 .summary
    Calculados 1 trabajador(es): asignaciones 106425.00, deducciones 35124.61, neto 71300.39
  2. 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 advertencia PRE_NOMINA te recuerda que la corrida aún no está completada. En este ejemplo el neto del trabajador es 71.300,39.

  3. ¿Llegó una marcación tarde? Cárgala con fve_nom_novedades. La respuesta trae la advertencia RECALCULAR: 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.

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í.

  1. 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 .summary

    Desde 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.

  2. 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
  3. 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.txt

    El total del archivo es igual al neto de la corrida. Tesorería lo carga en la banca en línea.

  • El reloj envía hechos (cédula, concepto, cantidad, fecha); FINORA calcula los montos.
  • Cada escritura lleva una clave: repetirla es seguro, y la referencia de 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.