Solicitudes de Certificado
Gestión CRUD de solicitudes de certificados digitales: creación, listado, actualización de estado, búsqueda por DNI y eliminación definitiva (borra también los archivos y reintegra el cupo).
Listar las solicitudes de mi empresa
Lista paginada de las solicitudes de la empresa del usuario autenticado, de la más reciente a la más antigua (`created_at`). Sin `request_status` devuelve todos los estados. Las URLs de paginación de la respuesta no conservan los filtros ni `limit`: para paginar un listado filtrado, reenvíe los mismos parámetros cambiando `page`.
Crear solicitud de certificado
Crea una solicitud de certificado digital para la empresa del usuario autenticado y consume un cupo del tipo de emisión y la vigencia pedidos (`life`). **Tipo de emisión (`issuance_flow`, opcional):** `BIOMETRIC` o `DOCUMENTARY`. Si no se envía se usa el de la empresa: `issuance_provider` = `viafirma` → BIOMETRIC; `mail` → DOCUMENTARY; `dual` (la empresa puede elegir en cada solicitud) → DOCUMENTARY. Se valida contra los tipos que la empresa tiene habilitados (`viafirma` solo BIOMETRIC, `mail` solo DOCUMENTARY, `dual` ambos). El tipo queda guardado en la solicitud y no cambia después; decide el proveedor, las acciones disponibles y el saldo que se consume (un cupo de un tipo nunca se consume en el otro). **BIOMETRIC:** exige `legal_rep_email`, `legal_rep_first_name` y `legal_rep_last_name`; los adjuntos son opcionales (si llegan se guardan sin validar cantidad ni tamaño); la solicitud nace en PROCESSING y la emisión automática se encola (llega el enlace de verificación por correo y WhatsApp). Si la emisión biométrica está apagada en la plataforma responde 400 `ISSUANCE_FLOW_UNAVAILABLE`. **DOCUMENTARY:** `attachments` es obligatorio, con 2 a 3 archivos, máximo 7 MB por archivo y 10 MB en total (valores por defecto, configurables en el servidor); formatos esperados: PDF, JPG o PNG; el servidor genera y adjunta además un Excel con los datos de la solicitud; la solicitud nace en DRAFT. **En todos los casos:** no puede existir otra solicitud de la misma empresa con el mismo NIT y DV en DRAFT, SENT, PENDING, ACCEPTED o PROCESSING; `terms_version_id` debe ser la versión vigente de los Términos y Condiciones; los archivos viajan en Base64 dentro del JSON (no multipart). Las etiquetas HTML (`<...>`) se eliminan sin error de `document_number`, `address`, `legal_representative`, `legal_rep_first_name`, `legal_rep_last_name`, `company_name`, `info`, `phone` y `mobile` antes de guardar (un `<` sin cerrar seguido de un carácter distinto de espacio, p. ej. en `Calle 5 <3 piso 2`, elimina todo el texto que le sigue); `legal_rep_email` se guarda sin cambios. Nota sobre el cupo: el cupo se consume en la misma transacción que crea la solicitud; si la creación falla, no se consume. Límite: 10 solicitudes por minuto por usuario.
Obtener detalle de una solicitud
Devuelve una solicitud de la empresa del usuario autenticado, con sus relaciones. La solicitud viene como **único elemento** del arreglo `dataRecords.data`. Si el `id` no existe o pertenece a otra empresa, responde 200 con `dataRecords.data = [null]`.
Actualizar los datos de una solicitud
Reemplaza los datos de una solicitud de la empresa del usuario autenticado. No cambia el estado (para eso use `PUT /certificate-request/{id}/status`) y registra una entrada en el historial. El DV se recalcula a partir de `dni`. `phone` y `mobile` se sobrescriben siempre (si se omiten quedan en null) e `info` omitido queda vacío. `legal_rep_first_name`, `legal_rep_last_name`, `legal_rep_email`, `country_id` y `entity_document_type_id` no se modifican con este endpoint. Nota: no se valida el estado de la solicitud, así que se puede editar en cualquier estado (incluidas PROCESSING, PROCESSED o REVOKED); cambiar `life` no ajusta el cupo consumido al crear la solicitud; y la entrada del historial queda registrada como `USER` aunque la haga un administrador. Las etiquetas HTML (`<...>`) se eliminan sin error de `document_number`, `address`, `legal_representative`, `company_name`, `dni` e `info` antes de guardar (un `<` sin cerrar seguido de un carácter distinto de espacio, p. ej. en `Calle 5 <3 piso 2`, elimina todo el texto que le sigue); `phone` y `mobile` se guardan sin cambios.
Eliminar una solicitud
Elimina **definitivamente** (no es borrado lógico) una solicitud de la empresa del usuario autenticado: borra sus archivos del almacenamiento y sus registros, y devuelve a la empresa el cupo consumido. Solo se permite en estado DRAFT (borrador) o REJECTED (rechazada); en cualquier otro estado hay un trámite en curso o un certificado emitido y responde 409. Dispara el webhook de eliminación.
Obtener el historial de cambios de una solicitud
Historial de cambios de estado y de datos de una solicitud de la empresa del usuario autenticado, del más reciente al más antiguo. Cada entrada incluye el usuario que hizo el cambio (`user`, null en acciones automáticas).
Cambiar el estado de una solicitud
Cambia el estado de una solicitud de tu empresa y registra el cambio en el historial. Solo actúa sobre tus propias solicitudes (una ajena responde 404, igual que una inexistente) y solo hacia DRAFT, SENT o CANCELLED (otro destino responde 403). Las transiciones que puedes hacer son DRAFT → SENT y REJECTED → DRAFT, SENT o CANCELLED; cualquier otra combinación responde 422. Los demás estados los asigna MATICERTS durante la tramitación; REVOKED, EXPIRED y CANCELLED son finales. **Efectos:** el actor del historial (`user_of_change`) lo fija el servidor (USER); cada cambio de estado envía un correo de notificación a tu empresa y a soporte y dispara el webhook de cambio de estado. Pasar a CANCELLED con este endpoint **no** reintegra el cupo consumido al crear la solicitud, y una solicitud CANCELLED ya no se puede eliminar; para anular una solicitud biométrica en curso con reintegro del cupo use `POST /certificate-request/{id}/issuance/reject`.
Estadísticas de solicitudes por año de una empresa
Totales de solicitudes de una empresa agrupados por año de **emisión efectiva** (`issued_at`, o `updated_at` si la solicitud aún no tiene `issued_at`; la misma regla que /consume), del más reciente al más antiguo, con todos los estados, desglose por estado, desglose por tipo de emisión de la solicitud (`by_flow`) y el estado actual de su cupo. Use `companyId` = 0 (o el ID de tu empresa) para la empresa del usuario autenticado; otra empresa responde 404.