Caso de uso: firma masiva de documentos¶
Flujo de 3 pasos: encolar el lote, consultar su estado hasta que termine, y descargar el zip con los documentos firmados. Requisito previo: el dni_firmante debe tener un certificado principal cargado, igual que en la firma individual.
1. Encolar el lote¶
PDF1_BASE64=$(base64 -w0 archivo-1.pdf)
PDF2_BASE64=$(base64 -w0 archivo-2.pdf)
curl -X POST http://localhost:8080/api/firma/masiva \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
-H "Content-Type: application/json" \
-d '{
"nombre_zip": "bloque1.zip",
"dni_firmante": "12345678",
"archivos": [
{
"nombre": "archivo-1.pdf",
"base64": "'"$PDF1_BASE64"'",
"nivel_firma": "PAdES-BT",
"firma_visual": {
"type": "TEXTO",
"ubicacion_x": "40",
"ubicacion_y": "40",
"largo": "220",
"alto": "50",
"pagina": "1",
"motivo": "Aprobación de expediente",
"texto": "[FIRMANTE]&[MOTIVO]&[FECHA]"
}
},
{
"nombre": "archivo-2.pdf",
"base64": "'"$PDF2_BASE64"'",
"nivel_firma": "PAdES-B"
}
]
}' \
-o encolado.json
Respuesta 202 ACCEPTED:
{
"success": true,
"mensaje": "2 documentos en cola para firma masiva",
"solicitud": "K3F9QZ1B7C",
"verificar_firmado": "GET /firma/estado/K3F9QZ1B7C"
}
2. Consultar el estado¶
curl http://localhost:8080/api/firma/estado/$SOLICITUD \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."
Mientras se procesa:
{
"success": true,
"solicitud": "K3F9QZ1B7C",
"estado": "PROCESANDO",
"mensaje": "Procesando documentos",
"progreso": { "procesados": 1, "total": 2 }
}
Cuando termina:
{
"success": true,
"solicitud": "K3F9QZ1B7C",
"estado": "COMPLETADO",
"mensaje": "Documentos firmados",
"progreso": { "procesados": 2, "total": 2 },
"descargar_firmado": "GET /firma/zip/K3F9QZ1B7C"
}
Para lotes chicos el procesamiento suele terminar en pocos segundos; para lotes grandes conviene consultar el estado con un intervalo (por ejemplo cada 5-10 segundos) en vez de en un loop cerrado.
3. Descargar el zip¶
curl http://localhost:8080/api/firma/zip/$SOLICITUD \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
-o zip_respuesta.json
jq -r '.zip_base64' zip_respuesta.json | base64 -d > bloque1.zip
unzip -l bloque1.zip
Dentro del zip: archivo-1.pdf, archivo-2.pdf (firmados) y manifest.json con el detalle de checksums, pesos y fecha de firma de cada uno (ver formato del manifest).
Errores frecuentes¶
| Situación | Respuesta |
|---|---|
| Más de 100 archivos, o el peso total decodificado supera 300MB | 400 BAD_REQUEST (no se crea ninguna solicitud) |
GET /estado o GET /zip con un código que no existe, o que pertenece a otro dni | 404 NOT_FOUND |
GET /zip antes de que la solicitud termine de procesarse | 409 CONFLICT |
| Uno o más archivos del lote fallan al firmar (ej. certificado revocado a mitad del lote, PDF corrupto) | La solicitud igual llega a COMPLETADO_CON_ERRORES; el zip se genera con los que sí se firmaron, y manifest.json documenta el error de los que fallaron |
Variante: consultar y descargar en un solo script¶
until [ "$(curl -s http://localhost:8080/api/firma/estado/$SOLICITUD \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." | jq -r '.estado')" \
=~ ^(COMPLETADO|COMPLETADO_CON_ERRORES|ERROR)$ ]]; do
sleep 5
done
curl http://localhost:8080/api/firma/zip/$SOLICITUD \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
| jq -r '.zip_base64' | base64 -d > bloque1.zip