-- ===================================================================== -- 0014_webdesign_widerruf.sql -- -- ELEKTRONISCHE WIDERRUFSFUNKTION (§ 356a BGB, seit 19.06.2026) -- -- Recherchiert am 23.08.2026. Der Befund ist eindeutig und betrifft -- diese Seite unmittelbar: -- -- § 356a BGB gilt seit dem 19.06.2026 für ALLE Fernabsatzverträge, die -- über eine Online-Benutzeroberfläche geschlossen werden — nicht nur -- für Finanzdienstleistungen. Wer Verbrauchern erlaubt, online einen -- Vertrag zu schliessen, muss eine elektronische Widerrufsfunktion -- bereitstellen: gut lesbar mit "Vertrag widerrufen" beschriftet, -- während der gesamten Widerrufsfrist ständig verfügbar, hervorgehoben -- platziert und leicht zugänglich. -- -- WARUM DAS HIER GILT: Im Kundenportal nimmt der Kunde Zusatzangebote -- mit einem Klick VERBINDLICH an ("Damit nimmst du das Zusatzangebot -- verbindlich an"). Das ist ein Vertragsschluss über eine -- Online-Benutzeroberfläche. Dasselbe wird für die PayPal-Zahlungen -- gelten. Die Pflicht besteht also bereits. -- -- Der Anbieter sitzt in Luxemburg. Für Verbraucher mit gewöhnlichem -- Aufenthalt in Deutschland gilt nach Art. 6 Rom-I-VO trotzdem das -- deutsche zwingende Verbraucherrecht, weil die Seite sich erkennbar an -- den deutschsprachigen Markt richtet. Deshalb wird hier der strengere -- Standard umgesetzt, nicht der bequemere. -- -- Ablauf nach § 356a: Der Verbraucher gibt Name, Vertragskennzeichnung -- und eine Kontaktmöglichkeit an, betätigt eine ZWEITE Schaltfläche -- ("Widerruf bestätigen") und erhält unverzüglich eine -- Eingangsbestätigung auf dauerhaftem Datenträger, die die Erklärung und -- den Zeitpunkt enthält. -- -- Genau dafür ist diese Tabelle da: Sie ist der dauerhafte Datenträger -- und zugleich der Nachweis. Sie wird NIE geleert. -- ===================================================================== CREATE TABLE IF NOT EXISTS wd_widerrufe ( id TEXT PRIMARY KEY, nummer TEXT NOT NULL UNIQUE, -- W-2608-0001, für die Bestätigung /* Die Angaben, die § 356a verlangt. Sie stehen hier als FREITEXT und nicht nur als Verweis auf einen Datensatz: Ein Widerruf muss auch dann vollständig belegbar bleiben, wenn Kunde oder Projekt später gelöscht werden. Der Nachweis darf nicht davon abhängen, dass ringsherum noch alles existiert. */ name TEXT NOT NULL, kontakt TEXT NOT NULL, -- E-Mail für die Eingangsbestätigung vertrag TEXT NOT NULL, -- Vertragskennzeichnung, vom Kunden benannt betrifft TEXT, -- optional: welcher Teil des Vertrags begruendung TEXT, -- freiwillig; ein Widerruf braucht KEINE /* Zuordnung, falls vorhanden — aber ausdrücklich ohne Fremdschlüssel. Ein Fremdschlüssel mit ON DELETE CASCADE würde den Nachweis mit dem Kunden mitlöschen; einer mit RESTRICT würde das Löschen eines Kunden blockieren, obwohl die DSGVO es verlangen kann. Beides wäre falsch. Deshalb nur eine lose Notiz. */ kunde_id TEXT, projekt_id TEXT, /* Zeitpunkt des Eingangs. Massgeblich für die Fristwahrung — der Widerruf ist rechtzeitig, wenn er innerhalb der Frist ABGESENDET wurde, nicht wenn er bearbeitet wurde. */ eingegangen_am TEXT NOT NULL, ip_hash TEXT, -- nur der Hash, nie die IP selbst sprache TEXT NOT NULL DEFAULT 'de', /* Bestätigung: wurde sie versendet, und wann? "unverzüglich" ist Pflicht, also muss man sehen können, ob es geklappt hat. */ bestaetigt_am TEXT, bestaetigung_weg TEXT, -- 'email' | 'anzeige' /* Bearbeitung auf unserer Seite. Der Widerruf ist wirksam, sobald er zugeht — diese Felder ändern daran nichts, sie halten nur fest, was wir damit gemacht haben. */ status TEXT NOT NULL DEFAULT 'eingegangen', -- eingegangen | bearbeitet notiz TEXT, erledigt_am TEXT ); CREATE INDEX IF NOT EXISTS idx_wd_widerrufe_zeit ON wd_widerrufe(eingegangen_am DESC); CREATE INDEX IF NOT EXISTS idx_wd_widerrufe_offen ON wd_widerrufe(status, eingegangen_am DESC); -- --------------------------------------------------------------------- -- NACHWEIS DER ZUSTIMMUNG ZUM VORZEITIGEN LEISTUNGSBEGINN -- -- § 356 Abs. 4 BGB: Bei Dienstleistungen erlischt das Widerrufsrecht nur -- dann vorzeitig, wenn der Verbraucher AUSDRÜCKLICH zugestimmt hat, dass -- vor Ablauf der Widerrufsfrist begonnen wird, UND gleichzeitig bestätigt -- hat, dass er dadurch sein Widerrufsrecht verliert. -- -- Die Beweislast für BEIDES liegt beim Unternehmer. Ohne Nachweis bleibt -- das Widerrufsrecht bestehen — und die 30-%-Anzahlung, die vor Ablauf -- der Frist verlangt wird, wäre dann angreifbar. -- -- Deshalb wird die Zustimmung mit Zeitstempel und dem GENAUEN Wortlaut -- gespeichert, der dem Kunden angezeigt wurde. Nur den Haken zu -- speichern reicht nicht: Im Streit zählt, WAS er bestätigt hat, und der -- Text kann sich über die Jahre ändern. -- --------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS wd_zustimmungen ( id TEXT PRIMARY KEY, kunde_id TEXT, projekt_id TEXT, anfrage_id TEXT, -- 'sofortbeginn' | 'agb' | 'datenschutz' art TEXT NOT NULL, /* Der Wortlaut, den der Kunde tatsächlich gesehen hat — vollständig, nicht als Verweis auf eine Textbaustein-Kennung. */ wortlaut TEXT NOT NULL, fassung TEXT, -- z. B. "2026-08-23" sprache TEXT NOT NULL DEFAULT 'de', erteilt_am TEXT NOT NULL, ip_hash TEXT ); CREATE INDEX IF NOT EXISTS idx_wd_zust_kunde ON wd_zustimmungen(kunde_id, art);