Intelligent Payment Verification

Universidad Nacional de Colombia · 2026 - At present

Next.jsTypeScriptAI SDKMistral AI

A contractor at the National University of Colombia has to prove, every month, that their social security contributions are in order before they can be paid. This app takes that whole procedure — reading the contract, the ARL certificate and the PILA form, checking the figures against Colombian regulation, and filling the institutional templates — and turns it into a four-step wizard for the university office that handles those payments.

Architecture and Tech Stack

Core Architecture

  • Framework: Next.js 16 (App Router), TypeScript, deployed on Vercel
  • AI extraction: Vercel AI SDK over a Mistral + OpenAI model chain with automatic fallback
  • Document reading: native text extraction for born-digital PDFs, OCR for scans and screenshots
  • Business rules: a pure calculation engine, parameterized per fiscal year
  • Validation: Zod schemas per document type (contract, ARL, payment sheet, activity report)
  • PDF generation: the official templates are filled and merged with their annexes
  • State: Zustand store across the wizard steps
  • UI: shadcn/ui + Tailwind CSS 4
  • Analytics: PostHog behind a typed event whitelist

Layered Architecture

The browser never talks to a model directly: every extraction goes through a route handler that streams NDJSON back, so the wizard can render fields as they are recognized instead of waiting for the whole document.

Request Flow

Key Features

Features at a Glance

Multi-document upload

Contract, ARL certificate, paid PILA form and — when the contract requires it — the activity report, all dropped at once. Each file is profiled and validated before extraction, so a wrong document is caught at the door rather than halfway through the flow.

Extraction with per-field confidence

The model returns every field tagged with how confident it is. Step 2 renders those tags, so review effort concentrates on what is actually uncertain instead of re-reading everything. The user edits inline and the corrected values feed the rest of the flow.

Regulation validation

Contributions, ARL validity and coverage, PILA deadlines, activity report percentages and the tax certification are each checked by an independent validator. Every finding cites the specific rule it comes from — and only rules whose text was verified directly.

Form 069 calculation engine

A pure, side-effect-free engine computes the contribution base and deductions. Fiscal parameters live in their own files per year, so rolling the app into a new year is a parameter change, not a rewrite.

Signature-ready output

The two official institutional formats are filled and merged with their annexes into a single downloadable PDF.

Technical Highlights

Nothing is cited that has not been read

The regulation catalog only holds rules whose text was verified first-hand, and that rule extends to every sentence quoted inside a validation message. When a source cannot be opened, the app says so instead of reconstructing it — a plausible-sounding citation is worse than no citation in a procedure that ends in a signature.

Analytics that cannot leak a person

The analytics layer accepts only enums, counts, booleans and field keys — never values, names, ID numbers, amounts or document content. The whitelist is a type, so TypeScript enforces it at compile time. Rule identifiers are never renamed either: they identify the situation, not the wording, so the historical series in PostHog stays comparable.

The official spreadsheet wins

When normative research and the official .xlsx contradict each other, the spreadsheet wins — the app has to reproduce the format the university actually receives, not the one the regulation implies.

Never silently overwrite a declaration

These formats are signed statements, so the app never normalizes what the person declared. When it detects an inconsistency it raises a warning and lets the person decide, instead of quietly correcting a field that someone is about to put their signature under.

Dates that often are not there

About a quarter of contracts express their term only in days ("doscientos sesenta y ocho (268) días calendario"), so no start or end date can be read at all — only a duration. The app infers the dates from the ARL certificate when the match is unambiguous; otherwise the user types the start date and the end is derived from it, never overwriting an end date already present.

A case corpus as the test harness

A fixture corpus pairs representative documents with their expected output — different operators, insurers and contract shapes, plus the awkward ones: scans, screenshots, rotated pages, expired coverage, incomplete contributions, several payment sheets. Obvious heuristics have failed against it more than once, which is exactly why every rule or extractor change is replayed over the corpus before it ships. "It works on my document" is not evidence.

Impact and Scalability

  • Replaces a fully manual procedure: reading each document by hand, cross-checking figures and typing the templates.
  • Review time concentrates on low-confidence fields instead of every field.
  • Rolling to a new fiscal year is one parameter file.
  • The case corpus makes every rule change verifiable before it ships.
  • Usage is measured in PostHog without storing a single personal value.

Notes

Built with Next.js 16, the Vercel AI SDK over Mistral and OpenAI, @pdfme, Zod and shadcn/ui. The repository is private — it belongs to the Centro de Prototipado at the National University of Colombia.


© 2026 Felipe Giraldo