Dokumentzustimmung & Signatur
Neben der Cookie-Einwilligung kann das SDK erfassen, dass eine Person einer bestimmten Version eines Dokuments zugestimmt hat — Nutzungsbedingungen, einem Fernabsatzvertrag, einer Datenschutzerklärung oder einem von Ihrem eigenen System erzeugten Dokument.
Der Code für die Zustimmung ist nicht Teil von cmp.js. Er wird automatisch geladen, wenn Sie zum ersten Mal eine der beiden unten genannten Methoden aufrufen (oder vorab mit data-modules="documents"); siehe Bundles und bei Bedarf geladene Module.
Zwei Wege, eine Zustimmung einzuholen
Abschnitt betitelt „Zwei Wege, eine Zustimmung einzuholen“1. CMP.showDocumentApproval(slug, options) — der Dialog von HashEntry
Abschnitt betitelt „1. CMP.showDocumentApproval(slug, options) — der Dialog von HashEntry“Lädt die aktive Version des Dokuments, zeigt sie in einem Dialog mit den Schaltflächen „Akzeptieren“ und „Ablehnen“ an und erfasst die Zustimmung, wenn die Person akzeptiert.
const result = await CMP.showDocumentApproval('distance-sales-agreement', { language: 'en', // optional, Standard ist die SDK-Sprache metadata: { order_id: 'ORD-54321' }, // optional approvalToken: tokenFromYourBackend // optional / erforderlich, siehe unten});
if (result.success && result.decision === 'accepted') { continueCheckout(result.consent_token);} else if (result.decision === 'rejected') { // die Person hat abgelehnt} else { showError(result.error); // { code, status, message }}| Option | Beschreibung |
|---|---|
language | Sprache der anzuzeigenden Dokumentversion. |
metadata | Schlüssel/Wert-Paare, die mit dem Datensatz gespeichert werden (zusammengeführt mit CMP.setMetadata). |
approvalToken | Einmaliges Zustimmungstoken, das von Ihrem Backend ausgestellt wurde. |
Aus Gründen der Abwärtskompatibilität wird ein einfaches Objekt ohne einen dieser Schlüssel als metadata behandelt.
Das Ablehnen schließt den Dialog und löst document:rejected aus; es wird kein Datensatz an den Server gesendet. Schlägt das Speichern mit einem vorübergehenden Fehler fehl, bleibt der Dialog geöffnet und die Person kann erneut auf „Akzeptieren“ klicken — der erneute Versuch verwendet denselben Idempotenzschlüssel (und dasselbe Token).
2. CMP.approveDocument(slug, options) — Ihre eigene UI
Abschnitt betitelt „2. CMP.approveDocument(slug, options) — Ihre eigene UI“Erfasst eine Zustimmung, ohne etwas anzuzeigen — für eine Checkbox in Ihrem Formular, Ihren eigenen Vertragsbetrachter oder ein Signaturfeld, das Sie selbst rendern.
const result = await CMP.approveDocument('terms-of-service', { approvalToken: tokenFromYourBackend, metadata: { order_id: 'ORD-54321' }});| Option | Gesendet als | Beschreibung |
|---|---|---|
version_id | document_version_id | Version, der zugestimmt werden soll. Wird sie weggelassen, ermittelt das SDK die aktive Version für language. |
version | — | Versionsbezeichnung, die im Ergebnis zurückgegeben wird, wenn Sie version_id übergeben. |
language | language | Sprache der Version. |
decision | decision | 'accepted' (Standard) oder 'rejected'. |
visitor_id | visitor_id | Ihre Referenz für die Person (max. 100 Zeichen). Wird ignoriert, wenn ein Zustimmungstoken verwendet wird — stattdessen wird das subject des Tokens gespeichert. |
approvalToken | approval_token | Einmaliges Zustimmungstoken. |
document_content_base64 | custom_document_content | Inhalt eines von Ihrem System erzeugten Dokuments (HTML, reiner Text oder PDF; dekodiert bis zu etwa 500 KB). |
document_mime_type | custom_document_mime_type | text/html, text/plain oder application/pdf. |
signature | Felder auf oberster Ebene | Siehe Signaturfelder. |
metadata | metadata | Schlüssel/Wert-Paare, die mit dem Datensatz gespeichert werden. |
Zwei Aufrufe für dasselbe Dokument, dieselbe Version und dieselbe Entscheidung, die sich zeitlich überschneiden, teilen sich eine Anfrage und ein Ergebnis, sodass ein Doppelklick keine zwei Datensätze erzeugt.
Einmalige Zustimmungstoken
Abschnitt betitelt „Einmalige Zustimmungstoken“Das Browser-SDK signiert seine Anfragen mit dem API-Schlüssel der Website, der im Quelltext Ihrer Seite sichtbar ist. Eine aus einem Browser gesendete Dokumentzustimmung belegt daher, dass jemand mit Zugriff auf Ihre Seite sie gesendet hat; der darin enthaltene Name oder die E-Mail-Adresse ist das, was eingegeben wurde.
Mit einem Zustimmungstoken kann sich Ihr Backend dafür verbürgen, wer zustimmt:
- Ihr Backend — das den angemeldeten Benutzer kennt — ruft
POST /tool/v1/s2s/approval-tokensauf (siehe REST-API) und erhält ein Token (hat_…). - Sie geben das Token an die Seite weiter und übergeben es dem SDK als
approvalToken. - Das SDK sendet es als
approval_tokenauf oberster Ebene. Der Server verbraucht es atomar, übernimmt die Identität der Person aus dem Token statt aus dem Browser und speichert den Datensatz mitidentity_assurance: tenant_attested.
Regeln:
- Ein Token gilt für eine Website und ein Dokument (optional eine Version), für eine begrenzte Zeit (Standard 10 Minuten, höchstens 1 Stunde) und einmal.
- Ein Dokument kann im Dashboard so konfiguriert werden, dass es ein Token erfordert. Bei einem solchen Dokument schlägt das SDK sofort fehl, ohne eine Anfrage zu senden, wenn kein Token angegeben wird:
error.code = "APPROVAL_TOKEN_REQUIRED". Der Server setzt dieselbe Regel durch. - Server-Codes werden unverändert durchgereicht:
APPROVAL_TOKEN_REQUIRED,APPROVAL_TOKEN_INVALID(unbekannt, abgelaufen, bereits verwendet oder für eine andere Website / ein anderes Dokument ausgestellt),APPROVAL_TOKEN_CONFLICT(ein Unterzeichnerfeld oder der vom Browser gesendete Dokumentinhalt widerspricht dem, wofür sich das Token verbürgt). - Bei einem Netzwerkfehler oder einer 5xx-Antwort versucht es das SDK mit demselben Token und demselben Idempotenzschlüssel erneut; der Server behandelt die Wiederholung als dieselbe Anfrage. Nach einer endgültigen 4xx-Antwort wird nichts erneut versucht, und Zustimmungen werden nie in der Offline-Warteschlange gespeichert. Stellen Sie ein neues Token aus, um es erneut zu versuchen.
Signaturfelder
Abschnitt betitelt „Signaturfelder“approveDocument akzeptiert ein Objekt signature für Zustimmungen, die mit einer gezeichneten Unterschrift oder einer ausdrücklichen Erklärung eingeholt werden. Das SDK enthält kein Signaturfeld zum Zeichnen: Sie rendern das Signaturfeld (oder die Checkbox für die Erklärung) und übergeben das Ergebnis.
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' }});| Feld | Gesendet als | Hinweise |
|---|---|---|
image_base64 | signature_image | PNG, JPEG oder WebP; dekodiert bis zu etwa 150 KB. |
mime_type | signature_mime_type | |
signer_name, signer_email, signer_phone, signer_id_number | gleiche Namen | Was der Unterzeichner über sich selbst angibt, sofern nicht durch ein Zustimmungstoken verbürgt. |
declaration_text | declaration_text | Der Satz, dem die Person zugestimmt hat (max. 1000 Zeichen). |
input_type | input_type | touch, mouse oder pen. |
stroke_count, drawing_duration_ms, strokes_data | gleiche Namen | Telemetrie des Zeichenvorgangs. |
screen_resolution | screen_resolution |
Alle diese Felder werden als Felder auf oberster Ebene der Anfrage gesendet, nicht innerhalb von metadata. Die Felder otp_verified / otp_reference werden von einem Browser nicht akzeptiert; sie werden nur auf der Server-to-Server-Route oder über ein Zustimmungstoken berücksichtigt.
Was “einfache elektronische Signatur” hier bedeutet
Abschnitt betitelt „Was “einfache elektronische Signatur” hier bedeutet“Ein auf diese Weise erstellter Datensatz ist eine einfache elektronische Signatur: Daten in elektronischer Form (das gezeichnete Bild, die Erklärung, der technische Kontext), die einer bestimmten Dokumentversion beigefügt sind und die der Unterzeichner zum Unterzeichnen verwendet hat. Er ist keine fortgeschrittene oder qualifizierte elektronische Signatur — dem Unterzeichner wird kein Zertifikat ausgestellt, und HashEntry überprüft die Identität des Unterzeichners nicht.
Was der Nachweis zeigt:
- welcher Dokumentversion (anhand des Inhalts-Hashs) zugestimmt wurde, wann, von welcher IP-Adresse und mit welchem User-Agent und mit welchen angegebenen Unterzeichnerdaten;
- dass der Datensatz seit seiner Erstellung nicht verändert wurde (siehe Nachweise offline prüfen);
- wie stark die Identität abgesichert ist, im Feld
identity_assurance:
| Wert | Bedeutung |
|---|---|
self_declared | Die Unterzeichnerdaten stammen aus dem Browser. Niemand hat sie überprüft. |
tenant_attested | Ihr Backend hat sich für die Person verbürgt, entweder mit einem einmaligen Zustimmungstoken oder indem es auf der Server-to-Server-Route eine abgeschlossene OTP-Prüfung erklärt hat. Die Zusicherung stammt von Ihnen: HashEntry hält fest, dass Sie sie bestätigt haben, nicht, dass HashEntry sie geprüft hat. |
Ob eine einfache elektronische Signatur für einen bestimmten Vertrag ausreicht, hängt vom anwendbaren Recht und von der Art des Rechtsgeschäfts ab; manche Rechtsgeschäfte erfordern eine bestimmte Form. Fragen Sie Ihre Rechtsberatung, welches Niveau Sie benötigen.
Wenn sich die Dokumentversion ändert
Abschnitt betitelt „Wenn sich die Dokumentversion ändert“Antwortet der Server mit 409 CONFIG_OUTDATED, liest das SDK die aktive Version des Dokuments erneut:
- unverändert (der Cache des Servers war kalt) → dieselbe Anfrage wird noch einmal gesendet;
- geändert → die Zustimmung wird nicht erneut gesendet. Das Ergebnis ist
success: falsemiterror.code = "DOCUMENT_VERSION_CHANGED", unddocument:errorwird ausgelöst.
Zeigen Sie im zweiten Fall das Dokument erneut an (die Person hat die neue Version nicht gesehen) und holen Sie eine neue Zustimmung ein — mit einem neuen Token, wenn Sie Token verwenden.
Ergebnisse, Ereignisse und Fehler
Abschnitt betitelt „Ergebnisse, Ereignisse und Fehler“CMP.on('document:approved', ({ slug, version, consentId }) => {});CMP.on('document:rejected', ({ slug, version }) => {});CMP.on('document:error', ({ slug, version, code, status, message }) => {});error.code | Was zu tun ist |
|---|---|
MODULE_LOAD_FAILED | Die Moduldatei konnte nicht geladen werden (Netzwerk, Werbeblocker, CSP). Rufen Sie die Methode erneut auf, um es noch einmal zu versuchen. |
DOCUMENT_NOT_FOUND, VERSION_NOT_FOUND | Prüfen Sie den Slug, ob das Dokument der Website zugeordnet ist und ob es eine aktive Version in der angeforderten Sprache hat. |
APPROVAL_TOKEN_REQUIRED | Stellen Sie in Ihrem Backend ein Token aus und übergeben Sie es. |
APPROVAL_TOKEN_INVALID, APPROVAL_TOKEN_CONFLICT | Stellen Sie ein neues Token aus; achten Sie darauf, dass die Unterzeichnerfelder mit dem Token übereinstimmen. |
DOCUMENT_VERSION_CHANGED | Zeigen Sie das Dokument erneut an. |
CONFIG_OUTDATED | Die von Ihnen übergebene Version ist nicht aktiv und konnte nicht erneut geprüft werden. |
NETWORK_ERROR, TIMEOUT, RATE_LIMIT_EXCEEDED, QUEUE_OVERLOADED | Vorübergehend. Lassen Sie die Person es erneut versuchen. |
VALIDATION_ERROR und Größenfehler (SIGNATURE_IMAGE_TOO_LARGE, CUSTOM_DOCUMENT_TOO_LARGE, …) | Korrigieren Sie die Anfrage. |
Betrachten Sie eine Zustimmung nur dann als erteilt, wenn result.success === true ist. Bewahren Sie result.consent_token auf: Es identifiziert den Datensatz für die spätere Prüfung und den Export von Nachweisen.