PARA DESARROLLO Y TI

API de firma · v1

Un endpoint para solicitar firmas desde cualquier módulo de transformaup.cl o sistema externo. FirmaUp se encarga de invitar a los firmantes, verificar su identidad (KYC) y aplicar el doble factor en cada firma. Tu sistema recibe un webhook cuando ambas partes firmaron.

1 · AUTENTICACIÓN

Crea una clave en el panel (API de firma → Crear clave). El secreto se muestra una sola vez y puedes revocarla cuando quieras. Envíala en cada llamada:

Authorization: Bearer fup_live_xxxxxxxxxxxxxxxxxxxx # alternativa equivalente X-API-Key: fup_live_xxxxxxxxxxxxxxxxxxxx

La instalación incluye una clave de demostración (fup_test_dem…) — úsala solo en pruebas y revócala al salir a producción.

2 · CREAR SOLICITUD DE FIRMAPOST

https://firma.transformaup.cl/api/v1/firmas.php

PETICIÓN
curl -X POST https://firma.transformaup.cl/api/v1/firmas.php \
  -H "Authorization: Bearer fup_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "titulo": "Orden de servicio OS-2231",
    "categoria": "CONTRATO",                    // CONTRATO|AUTORIZACION|DECLARACION|OTRO
    "contenido": "Texto completo que ambas partes firmarán…",
    "firmantes": [                              // exactamente 2, RUTs distintos
      {"rut": "12.345.678-5", "nombre": "María Rojas",  "email": "maria@empresa.cl"},
      {"rut": "15.222.333-1", "nombre": "Carlos Muñoz", "email": "carlos@proveedor.cl"}
    ],
    "callbackUrl": "https://tu-sistema.cl/webhooks/firma"   // opcional
  }'
RESPUESTA 201Created
{
  "ok": true,
  "id": "doc_3f8a91c2b7d4",
  "estado": "PENDIENTE",
  "hash_contenido": "9f2c41…e71a",           // sello SHA-256 del contenido
  "url_firma": "https://firma.transformaup.cl/firmar.php?token=…",
  "firmantes": [
    {"rut": "12.345.678-5", "rol": "EMISOR",   "estado": "PENDIENTE"},
    {"rut": "15.222.333-1", "rol": "RECEPTOR", "estado": "PENDIENTE"}
  ]
}

FirmaUp envía por correo a ambos firmantes el enlace url_firma. Quien no tenga cuenta la crea con verificación de identidad (KYC) y firma con contraseña + código 2FA. El primer firmante es el EMISOR y el segundo el RECEPTOR.

3 · CONSULTAR SOLICITUDESGET

Lista las solicitudes creadas con tu clave, o consulta una específica:

GET https://firma.transformaup.cl/api/v1/firmas.php GET https://firma.transformaup.cl/api/v1/firmas.php?c=doc_3f8a91c2b7d4

La respuesta incluye el estado (PENDIENTE → PARCIAL → COMPLETADO) y el hash de cada firma ejecutada.

4 · WEBHOOK documento.completado

Si enviaste callbackUrl, cuando ambas partes firmaron hacemos un POST JSON a tu URL (timeout 6 s). Cada entrega queda registrada en el panel.

POST https://tu-sistema.cl/webhooks/firma
X-FirmaUp-Evento: documento.completado

{
  "evento": "documento.completado",
  "documento": {
    "id": "doc_3f8a91c2b7d4",
    "titulo": "Orden de servicio OS-2231",
    "estado": "COMPLETADO",
    "hash_contenido": "9f2c41…e71a",
    "completado": "2026-01-15 16:42:10"
  },
  "firmas": [
    {"rol": "EMISOR",   "rut": "12.345.678-5", "hash": "a71b…", "firmada": "2026-01-15 16:40:02"},
    {"rol": "RECEPTOR", "rut": "15.222.333-1", "hash": "5d90…", "firmada": "2026-01-15 16:42:10"}
  ]
}
5 · ERRORES
HTTPerrorCuándo
401unauthorizedClave ausente, inválida o revocada.
400invalid_requestFalta un campo, RUT inválido (módulo 11), firmantes repetidos, contenido corto.
404no_encontradoEl id no corresponde a esta clave.
500error_internoProblema del servidor. Reintenta con retroceso exponencial.

CORS habilitado para llamar desde el navegador con fetch(). Orígenes configurables en config.php (API_CORS_ORIGEN).

6 · EJEMPLO DESDE OTRA PÁGINA (JS)
// Desde una página de transformaup.cl, tras que el usuario complete un formulario:
const respuesta = await fetch('https://firma.transformaup.cl/api/v1/firmas.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer fup_live_…',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    titulo: 'Autorización de retiro ' + folio,
    contenido: textoDelDocumento,
    firmantes: [
      { rut: rutCliente,  nombre: nombreCliente,  email: emailCliente },
      { rut: rutEmpresa,  nombre: 'TransformaUp', email: 'firmas@transformaup.cl' }
    ],
    callbackUrl: 'https://www.transformaup.cl/api/webhook-firma'
  })
});
const datos = await respuesta.json();
if (datos.ok) {
  // Muestra el enlace al usuario o guárdalo en tu flujo:
  console.log('Enlace de firma:', datos.url_firma);
}