Aprobación y firma de documentos
Además del consentimiento de cookies, el SDK puede registrar que una persona aprobó una versión concreta de un documento: unas condiciones de servicio, un contrato de venta a distancia, un aviso de privacidad o un documento generado por su propio sistema.
El código de aprobación no forma parte de cmp.js. Se carga automáticamente la primera vez que se llama a uno de los dos métodos siguientes (o por adelantado con data-modules="documents"); consulte Paquetes y módulos bajo demanda.
Dos formas de recoger una aprobación
Sección titulada «Dos formas de recoger una aprobación»1. CMP.showDocumentApproval(slug, options) — el diálogo de HashEntry
Sección titulada «1. CMP.showDocumentApproval(slug, options) — el diálogo de HashEntry»Carga la versión activa del documento, la muestra en un diálogo con los botones “Aceptar” y “Rechazar” y registra la aprobación cuando la persona acepta.
const result = await CMP.showDocumentApproval('distance-sales-agreement', { language: 'en', // opcional, por defecto el idioma del SDK metadata: { order_id: 'ORD-54321' }, // opcional approvalToken: tokenFromYourBackend // opcional / obligatorio, véase más abajo});
if (result.success && result.decision === 'accepted') { continueCheckout(result.consent_token);} else if (result.decision === 'rejected') { // la persona ha rechazado} else { showError(result.error); // { code, status, message }}| Opción | Descripción |
|---|---|
language | Idioma de la versión del documento que se muestra. |
metadata | Pares clave/valor almacenados con el registro (combinados con CMP.setMetadata). |
approvalToken | Token de aprobación de un solo uso emitido por su backend. |
Por compatibilidad con versiones anteriores, un objeto simple que no contenga ninguna de estas claves se trata como metadata.
El rechazo cierra el diálogo y emite document:rejected; no se envía ningún registro al servidor. Si el guardado falla con un error temporal, el diálogo permanece abierto y la persona puede pulsar “Aceptar” de nuevo; el reintento utiliza la misma clave de idempotencia (y el mismo token).
2. CMP.approveDocument(slug, options) — su propia interfaz
Sección titulada «2. CMP.approveDocument(slug, options) — su propia interfaz»Registra una aprobación sin mostrar nada; sirve para una casilla de verificación de su formulario, su propio visor de contratos o un panel de firma que usted mismo renderiza.
const result = await CMP.approveDocument('terms-of-service', { approvalToken: tokenFromYourBackend, metadata: { order_id: 'ORD-54321' }});| Opción | Se envía como | Descripción |
|---|---|---|
version_id | document_version_id | Versión que se aprueba. Si se omite, el SDK resuelve la versión activa para language. |
version | — | Etiqueta de versión devuelta en el resultado cuando se pasa version_id. |
language | language | Idioma de la versión. |
decision | decision | 'accepted' (predeterminado) o 'rejected'. |
visitor_id | visitor_id | Su referencia de la persona (máx. 100 caracteres). Se ignora cuando se utiliza un token de aprobación: en su lugar se almacena el subject del token. |
approvalToken | approval_token | Token de aprobación de un solo uso. |
document_content_base64 | custom_document_content | Contenido de un documento generado por su sistema (HTML, texto sin formato o PDF; hasta unos 500 KB una vez decodificado). |
document_mime_type | custom_document_mime_type | text/html, text/plain o application/pdf. |
signature | campos de nivel superior | Consulte Campos de firma. |
metadata | metadata | Pares clave/valor almacenados con el registro. |
Dos llamadas para el mismo documento, la misma versión y la misma decisión que se solapan en el tiempo comparten una única solicitud y un único resultado, de modo que un doble clic no crea dos registros.
Tokens de aprobación de un solo uso
Sección titulada «Tokens de aprobación de un solo uso»El SDK de navegador firma sus solicitudes con la clave API del sitio, que es visible en el código fuente de su página. Por tanto, una aprobación de documento enviada desde un navegador prueba que la envió alguien con acceso a su página; el nombre o la dirección de correo electrónico que contiene es lo que se haya escrito.
Un token de aprobación permite que su backend avale quién está aprobando:
- Su backend, que conoce al usuario que ha iniciado sesión, llama a
POST /tool/v1/s2s/approval-tokens(consulte API REST) y recibe un token (hat_…). - Usted pasa el token a la página y lo entrega al SDK como
approvalToken. - El SDK lo envía como
approval_tokende nivel superior. El servidor lo consume de forma atómica, toma la identidad de la persona del token y no del navegador, y almacena el registro conidentity_assurance: tenant_attested.
Reglas:
- Un token es válido para un sitio y un documento (opcionalmente, una versión), durante un tiempo limitado (10 minutos de forma predeterminada, 1 hora como máximo) y una sola vez.
- Un documento puede configurarse en el panel para que exija un token. Para un documento así, el SDK falla de inmediato, sin enviar ninguna solicitud, cuando no se proporciona un token:
error.code = "APPROVAL_TOKEN_REQUIRED". El servidor aplica la misma regla. - Los códigos del servidor se transmiten sin cambios:
APPROVAL_TOKEN_REQUIRED,APPROVAL_TOKEN_INVALID(desconocido, caducado, ya utilizado o emitido para otro sitio/documento),APPROVAL_TOKEN_CONFLICT(un campo del firmante o el contenido del documento enviados por el navegador contradicen lo que el token avala). - Ante un fallo de red o una respuesta 5xx, el SDK reintenta con el mismo token y la misma clave de idempotencia; el servidor trata la repetición como la misma solicitud. Tras una respuesta 4xx definitiva no se reintenta nada, y las aprobaciones nunca se almacenan en la cola sin conexión. Emita un nuevo token para volver a intentarlo.
Campos de firma
Sección titulada «Campos de firma»approveDocument acepta un objeto signature para las aprobaciones recogidas con una firma dibujada o una declaración explícita. El SDK no incluye un panel de firma: usted renderiza el panel (o la casilla de declaración) y pasa el resultado.
await CMP.approveDocument('service-contract', { approvalToken: tokenFromYourBackend, signature: { image_base64: canvas.toDataURL('image/png'), mime_type: 'image/png', signer_name: 'Jane Doe', declaration_text: 'I have read and accept the service contract.', input_type: 'touch', stroke_count: 14, drawing_duration_ms: 3200, screen_resolution: '390x844' }});| Campo | Se envía como | Notas |
|---|---|---|
image_base64 | signature_image | PNG, JPEG o WebP; hasta unos 150 KB una vez decodificado. |
mime_type | signature_mime_type | |
signer_name, signer_email, signer_phone, signer_id_number | mismos nombres | Lo que el firmante declara sobre sí mismo, salvo que lo avale un token de aprobación. |
declaration_text | declaration_text | La frase que la persona aceptó (máx. 1000 caracteres). |
input_type | input_type | touch, mouse o pen. |
stroke_count, drawing_duration_ms, strokes_data | mismos nombres | Telemetría del trazado. |
screen_resolution | screen_resolution |
Todos ellos se envían como campos de nivel superior de la solicitud, no dentro de metadata. Los campos otp_verified / otp_reference no se aceptan desde un navegador; solo se tienen en cuenta en la ruta de servidor a servidor o a través de un token de aprobación.
Qué significa aquí “firma electrónica simple”
Sección titulada «Qué significa aquí “firma electrónica simple”»Un registro creado de este modo es una firma electrónica simple: datos en formato electrónico (la imagen dibujada, la declaración, el contexto técnico) que se adjuntan a una versión concreta de un documento y que el firmante utilizó para firmar. No es una firma electrónica avanzada ni cualificada: no se emite ningún certificado al firmante y HashEntry no verifica la identidad del firmante.
Lo que muestra la evidencia:
- qué versión del documento (por hash de contenido) se aprobó, cuándo, desde qué dirección IP y agente de usuario, y con qué datos declarados del firmante;
- que el registro no se ha alterado desde que se escribió (consulte Verificación de evidencias sin conexión);
- con qué solidez está respaldada la identidad, en el campo
identity_assurance:
| Valor | Significado |
|---|---|
self_declared | Los datos del firmante proceden del navegador. Nadie los ha verificado. |
tenant_attested | Su backend ha avalado a la persona, bien con un token de aprobación de un solo uso, bien declarando una comprobación OTP completada en la ruta de servidor a servidor. La garantía es suya: HashEntry registra que usted lo ha atestiguado, no que HashEntry lo haya comprobado. |
Que una firma electrónica simple sea suficiente para un contrato determinado depende de la legislación aplicable y del tipo de operación; algunas operaciones exigen una forma específica. Consulte con su asesor jurídico qué nivel necesita.
Cuando cambia la versión del documento
Sección titulada «Cuando cambia la versión del documento»Si el servidor responde 409 CONFIG_OUTDATED, el SDK vuelve a leer la versión activa del documento:
- sin cambios (la caché del servidor estaba fría) → la misma solicitud se envía una vez más;
- con cambios → la aprobación no se reenvía. El resultado es
success: falseconerror.code = "DOCUMENT_VERSION_CHANGED", y se emitedocument:error.
En el segundo caso, muestre de nuevo el documento (la persona no ha visto la nueva versión) y recoja una nueva aprobación, con un nuevo token si utiliza tokens.
Resultados, eventos y errores
Sección titulada «Resultados, eventos y errores»CMP.on('document:approved', ({ slug, version, consentId }) => {});CMP.on('document:rejected', ({ slug, version }) => {});CMP.on('document:error', ({ slug, version, code, status, message }) => {});error.code | Qué hacer |
|---|---|
MODULE_LOAD_FAILED | No se ha podido cargar el archivo del módulo (red, bloqueador de anuncios, CSP). Llame de nuevo para reintentarlo. |
DOCUMENT_NOT_FOUND, VERSION_NOT_FOUND | Compruebe el slug, que el documento esté asociado al sitio y que tenga una versión activa en el idioma solicitado. |
APPROVAL_TOKEN_REQUIRED | Emita un token en su backend y páselo. |
APPROVAL_TOKEN_INVALID, APPROVAL_TOKEN_CONFLICT | Emita un nuevo token; asegúrese de que los campos del firmante coincidan con el token. |
DOCUMENT_VERSION_CHANGED | Muestre de nuevo el documento. |
CONFIG_OUTDATED | La versión que ha pasado no está activa y no se ha podido volver a comprobar. |
NETWORK_ERROR, TIMEOUT, RATE_LIMIT_EXCEEDED, QUEUE_OVERLOADED | Temporal. Permita que la persona lo intente de nuevo. |
VALIDATION_ERROR y errores de tamaño (SIGNATURE_IMAGE_TOO_LARGE, CUSTOM_DOCUMENT_TOO_LARGE, …) | Corrija la solicitud. |
Considere otorgada una aprobación únicamente cuando result.success === true. Conserve result.consent_token: identifica el registro para su posterior verificación y para la exportación de evidencias.