Ir al contenido

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.


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ónDescripción
languageIdioma de la versión del documento que se muestra.
metadataPares clave/valor almacenados con el registro (combinados con CMP.setMetadata).
approvalTokenToken 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ónSe envía comoDescripción
version_iddocument_version_idVersió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.
languagelanguageIdioma de la versión.
decisiondecision'accepted' (predeterminado) o 'rejected'.
visitor_idvisitor_idSu 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.
approvalTokenapproval_tokenToken de aprobación de un solo uso.
document_content_base64custom_document_contentContenido de un documento generado por su sistema (HTML, texto sin formato o PDF; hasta unos 500 KB una vez decodificado).
document_mime_typecustom_document_mime_typetext/html, text/plain o application/pdf.
signaturecampos de nivel superiorConsulte Campos de firma.
metadatametadataPares 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.


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:

  1. 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_…).
  2. Usted pasa el token a la página y lo entrega al SDK como approvalToken.
  3. El SDK lo envía como approval_token de 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 con identity_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.

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',
signer_email: '[email protected]',
declaration_text: 'I have read and accept the service contract.',
input_type: 'touch',
stroke_count: 14,
drawing_duration_ms: 3200,
screen_resolution: '390x844'
}
});
CampoSe envía comoNotas
image_base64signature_imagePNG, JPEG o WebP; hasta unos 150 KB una vez decodificado.
mime_typesignature_mime_type
signer_name, signer_email, signer_phone, signer_id_numbermismos nombresLo que el firmante declara sobre sí mismo, salvo que lo avale un token de aprobación.
declaration_textdeclaration_textLa frase que la persona aceptó (máx. 1000 caracteres).
input_typeinput_typetouch, mouse o pen.
stroke_count, drawing_duration_ms, strokes_datamismos nombresTelemetría del trazado.
screen_resolutionscreen_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:
ValorSignificado
self_declaredLos datos del firmante proceden del navegador. Nadie los ha verificado.
tenant_attestedSu 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.


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: false con error.code = "DOCUMENT_VERSION_CHANGED", y se emite document: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.


CMP.on('document:approved', ({ slug, version, consentId }) => {});
CMP.on('document:rejected', ({ slug, version }) => {});
CMP.on('document:error', ({ slug, version, code, status, message }) => {});
error.codeQué hacer
MODULE_LOAD_FAILEDNo se ha podido cargar el archivo del módulo (red, bloqueador de anuncios, CSP). Llame de nuevo para reintentarlo.
DOCUMENT_NOT_FOUND, VERSION_NOT_FOUNDCompruebe el slug, que el documento esté asociado al sitio y que tenga una versión activa en el idioma solicitado.
APPROVAL_TOKEN_REQUIREDEmita un token en su backend y páselo.
APPROVAL_TOKEN_INVALID, APPROVAL_TOKEN_CONFLICTEmita un nuevo token; asegúrese de que los campos del firmante coincidan con el token.
DOCUMENT_VERSION_CHANGEDMuestre de nuevo el documento.
CONFIG_OUTDATEDLa versión que ha pasado no está activa y no se ha podido volver a comprobar.
NETWORK_ERROR, TIMEOUT, RATE_LIMIT_EXCEEDED, QUEUE_OVERLOADEDTemporal. 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.