Integrar la firma electrónica significa que tu sistema envía a firma un documento sin que nadie lo suba a mano a una plataforma, y que se entera solo cuando vuelve firmado. El contrato sale de tu ERP, de tu sistema de RR. HH. o de tu CRM, y el PDF firmado vuelve al mismo registro de donde salió.
Esta guía es para quien va a construir esa integración. Cubre lo que conviene decidir antes de escribir código, cómo es el flujo con una API de firma electrónica simple (FES), qué guardar de tu lado y los errores que más cuestan corregir después. Los ejemplos usan la API de ValidaFirma, pero las decisiones valen para cualquier proveedor.
Qué construyes tú y qué no
Una firma electrónica que se sostenga necesita 4 piezas además de tu sistema: las pantallas donde la persona lee y firma, la verificación de su identidad, los mensajes que la invitan (WhatsApp, SMS, correo) y el sello del PDF con su custodia. Construir cualquiera de esas cuatro es un proyecto en sí mismo, y la verificación de identidad es la más difícil.
Con una API de firma, esas cuatro corren del lado del proveedor. A tu sistema le quedan tres tareas:
- Enviar el PDF y los datos de cada firmante.
- Escuchar el aviso de que el documento terminó.
- Guardar el resultado junto al registro de tu sistema.
Todo lo demás de esta guía sirve para hacer bien esas tres.
5 decisiones antes de escribir código
1. Si te sirve la firma electrónica simple
La Ley 19.799 reconoce 2 firmas electrónicas: la simple (FES) y la avanzada (FEA). La simple vale como firma manuscrita (art. 3.º), salvo en los actos que ese artículo excluye y en los instrumentos públicos, que piden avanzada (art. 4.º). Un contrato de servicios, un contrato de trabajo, un anexo, una orden de compra o un consentimiento caben en la simple. Una escritura pública no.
Revísalo antes de integrar, porque cambiar de tipo de firma después es cambiar de proveedor. El detalle está en firma electrónica simple y avanzada: diferencias.
2. Qué sabes de cada firmante
Una firma vale lo que vale la prueba de quién firmó. En ValidaFirma, el dato que identifica al firmante es su RUT: con él se verifica que la cédula sea vigente y de esa persona, y que quien está frente a la cámara sea el mismo de la cédula. El nombre es opcional, porque en la evidencia se usa el que dice la cédula.
Si tu sistema no guarda el RUT de las personas a quienes les envía documentos, ese es el primer cambio de tu modelo de datos.
3. Por qué canal le llega la invitación
Hay 3 opciones por firmante:
- WhatsApp, con respaldo por SMS si el WhatsApp no llega.
- Correo. Si no eliges canal, la invitación sale por correo, así que en ese caso el firmante necesita su email.
- Enlace. La respuesta de la API trae la
url_firmade cada firmante y la entregas tú. Sirve cuando la persona ya está dentro de tu aplicación o de tu portal y no quieres que le llegue un mensaje de un tercero.
4. Cuánto plazo das
Un documento vence si no firman todos a tiempo. Por defecto son 7 días, y con dias_expiracion
eliges entre 1 y 30. Decide qué hace tu sistema cuando vence: volver a enviarlo, avisarle a
alguien o cerrar el trámite. Un documento vencido no se reactiva.
5. Con qué cuenta vas a integrar
- Cuenta personal: una llave
X-API-Keyque creas en el panel. - Cuenta corporativa: una credencial de máquina por cada sistema de tu empresa, con la carpeta
donde quedan sus documentos. Va en
Authorization: Bearer.
El llamado es el mismo en las dos. El detalle está en llaves y cuenta corporativa.
El flujo de una integración, paso a paso
Paso 1: tu sistema genera el PDF
El documento sale de tu sistema como siempre: una plantilla con los datos del cliente o del trabajador. Tiene que ser PDF y pesar hasta 10 MB.
Paso 2: lo envía a firma
Un POST en multipart/form-data con el PDF, de 1 a 20 firmantes y la URL donde quieres recibir
el aviso:
curl -X POST https://api.validafirma.cl/api/fes/documentos \
-H "X-API-Key: $VALIDAFIRMA_API_KEY" \
-F "documento=@contrato.pdf" \
-F 'firmantes=[{"rut":"49999901-1","canal":"whatsapp","telefono":"+56912345678"}]' \
-F "webhook_url=https://tu-sistema.cl/webhooks/validafirma" \
-F "idempotencyKey=contrato-8812"
La respuesta es un 201 con el id del documento, su codigo_verificacion y la url_firma de
cada firmante. Guarda el id en el registro de tu sistema antes de seguir: es lo que une las dos
cosas.
El campo idempotencyKey es opcional y conviene usarlo. Si la llamada se corta y tu sistema la
repite con la misma clave, la API devuelve el documento que ya creó, sin invitar de nuevo a nadie
ni cobrar 2 veces. Usa una clave que salga de tu propio registro, como el número del contrato.
Paso 3: cada firmante firma en su celular
Esto ya no pasa por tu sistema. Cada firmante recibe su invitación, abre el documento en el navegador del celular, lo lee hasta el final, confirma con su rostro que es él y firma. Puede también rechazarlo.
Paso 4: tu sistema recibe el aviso
Cuando firma el último, el PDF se sella y tu webhook_url recibe un POST con el evento
documento.completado. Trae el sello, la verificación de cada firmante y el enlace para descargar
el PDF. Tu sistema actualiza el registro y sigue con su proceso: activa el servicio, despacha el
pedido o archiva el contrato.
Paso 5: guarda el PDF firmado
El aviso no trae el archivo. Lo descargas con tu llave, con
GET /api/fes/documentos/{id}/descargar, y lo guardas junto al registro.
Webhook o consultar el estado
Hay 2 maneras de enterarte de que un documento terminó: esperar el aviso o preguntar cada cierto
tiempo con GET /api/fes/documentos/{id}. El aviso es la buena. Preguntar en un bucle gasta
llamadas y llega tarde, y con 100 documentos abiertos se vuelve un problema.
Consultar el estado sirve para otra cosa: reconciliar. Si tu servidor estuvo caído un rato, una tarea diaria que revise los documentos abiertos más viejos que su plazo te dice si se perdió algún aviso.
Al recibir el aviso:
- Comprueba la firma. Cada aviso trae la cabecera
X-Webhook-Signature, un HMAC-SHA256 del cuerpo calculado con el secreto de tu cuenta. Calcúlalo sobre el cuerpo tal como llegó, sin volver a serializar el JSON, y rechaza el aviso si la hora de la firma se aleja más de 300 segundos de tu reloj. Hay ejemplos en Node.js, Python y PHP en cómo verificar la firma de los webhooks. - No proceses 2 veces el mismo aviso. Un aviso que falla se reintenta, así que puede llegarte
más de una vez. La cabecera
X-ValidaFirma-Deliveryes la misma en cada reintento: guárdala y descarta la que ya viste. - Responde rápido y procesa después. Recibe, guarda y responde. La descarga del PDF y el resto del trabajo van en una tarea aparte.
Los 5 finales que tu sistema tiene que manejar
documento.completado es el que todos programan. Los otros cuatro son los que quedan sin manejar:
| Evento | Qué pasó | Qué suele hacer tu sistema |
|---|---|---|
documento.completado |
Firmaron todos | Descargar el PDF y seguir con el proceso |
documento.rechazado |
Un firmante rechazó | Avisar a quien lo envió; el motivo puede venir |
documento.cancelado |
Tú lo cancelaste | Cerrar el trámite |
documento.expirado |
Venció el plazo sin todas las firmas | Enviar uno nuevo o escalar |
documento.no_emitido |
No se pudo sellar al cierre | Revisarlo: nunca se entrega como firmado |
Hay además 5 eventos de un firmante mientras el documento sigue abierto, como una invitación que no llegó o una cédula que no corresponde al RUT que enviaste. Están todos en la documentación de webhooks.
Qué guardar en tu sistema
De cada documento, guarda:
- el
idy elcodigo_verificacion; - el estado, actualizado con cada aviso;
- el PDF firmado, descargado apenas llega
documento.completado; - los avisos recibidos, con su
X-ValidaFirma-Delivery.
Lo que no vas a recibir ni tienes que guardar son datos biométricos. La verificación de identidad la hace el proveedor, y tu sistema recibe el resultado: el nombre tal como está en la cédula, el método y la fecha de la verificación, y un comprobante firmado. Eso simplifica tu tratamiento de datos personales. El detalle de quién guarda qué está en seguridad en las API de firma electrónica.
El PDF firmado se valida sin pasar por tu sistema: cualquiera lo comprueba en validar con su código de verificación, y Adobe Acrobat verifica su sello sin conexión.
Errores que más cuestan corregir después
- La llave en el navegador o en una aplicación móvil. La llave va siempre en tu servidor. Quien la tenga puede enviar documentos a tu nombre.
- Creer el aviso sin comprobar su firma. Cualquiera que conozca tu
webhook_urlpuede hacerle unPOST. - Procesar un reintento como si fuera nuevo. El mismo contrato queda activado 2 veces.
- Esperar el PDF dentro del aviso. No viene: se descarga aparte.
- Programar solo el caso feliz. Rechazos, vencimientos y documentos no emitidos pasan, y si tu sistema no los maneja, el trámite queda colgado sin que nadie se entere.
- Esperar recordatorios automáticos. No los hay. Si un firmante no ha firmado, tu sistema puede
reenviar la invitación con
POST /api/fes/documentos/{id}/reenviar-notificaciones. - Probar con RUT de personas reales. Para eso está el modo de prueba.
Pruébala completa sin costo
Con una llave de prueba corre la integración entera contra el mismo servidor de producción: las validaciones, los estados, los webhooks firmados y el PDF sellado, marcado «PRUEBA, sin validez». Los mensajes no salen, la verificación de identidad se simula y nada se cobra.
Hay un RUT de prueba para cada desenlace: el 49999901-1 firma, el 49999904-6 rechaza y el
49999907-0 nunca actúa y deja vencer el documento. Así pruebas cada uno de los 5 finales
antes de que le pase a un cliente. Pasar a producción es cambiar la llave.
El paso a paso está en el tutorial del modo de prueba.
Lista antes de pasar a producción
- La llave de producción está en una variable de entorno del servidor.
- Tu webhook comprueba la firma y descarta los avisos repetidos.
- Tu sistema maneja los 5 finales: completado, rechazado, cancelado, expirado y no emitido.
- El PDF firmado se descarga y se guarda junto al registro.
- Cada llamada de creación lleva una
idempotencyKeyque sale de tu registro. - Una tarea revisa los documentos abiertos que pasaron su plazo.
- Probaste los RUT de prueba de cada desenlace.
Preguntas frecuentes
¿Qué significa FES?
FES es la sigla de firma electrónica simple, una de las 2 firmas que reconoce la Ley 19.799. La
otra es la firma electrónica avanzada, o FEA. En la API de ValidaFirma, los llamados de firma
viven bajo la ruta /api/fes/.
¿Cuánto toma integrar la firma electrónica?
Depende de tu sistema, pero el llamado para enviar a firma es uno solo, y lo que más tiempo toma es manejar bien los avisos: comprobar su firma, descartar los repetidos y resolver cada final. Con el modo de prueba puedes recorrer todos los casos antes de escribir una línea para producción.
¿Necesito una librería o un SDK?
No. Basta con un cliente HTTP y una función HMAC-SHA256, que vienen en cualquier lenguaje. La referencia OpenAPI sirve también para generar un cliente si lo prefieres.
¿Se puede integrar sin programar?
Sí, con la carpeta en la nube: dejas el PDF en una carpeta de Google Drive, Dropbox u OneDrive y vuelve firmado a la misma carpeta. Los documentos que entran por ahí no envían webhook.
¿Los firmantes necesitan crear una cuenta?
No. Cada firmante abre su enlace en el navegador del celular, sin instalar nada y sin crear cuenta.
Para seguir
- API de firma electrónica simple: qué hace y cuánto cuesta.
- Documentación: el llamado, los firmantes, los webhooks y las llaves.
- Firmantes y opciones del documento: canales, validación de contacto, documentos confidenciales y carátula.