Webshop: IP-Hash entfällt mit Zahlung oder Storno, keine Käufer-Telefonnummer mehr gespeichert

schliesseAb und verwirf entfernen ipHash aus dem Bestell-JSON, sobald die Bestellung nicht mehr offen ist
(Begrenzung offener Bestellungen je IP bleibt). customer_details.phone wird nicht mehr in kaeufer.telefon
übernommen; Kundenansicht und Bestelldetail geben auch in alten Datensätzen keine Telefonnummer aus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 10:26:56 +00:00
1 parent 4ab84e31ac
commit 43473c0879
9 files changed
+79 -19

No files matched your search

+11 -5
View File
@@ -20,8 +20,9 @@ import { holeProdukt, listeProdukte, parseProdukt } from './produkte.js'
* bestellung (geparst: bestellDaten(doc), auch als doc.daten aus bestellungLesen):
* { positionen, summen: { zwischensummeCent, versandCent, gesamtCent, steuer, texte }, lieferart, land, anbieter, shopname,
* lieferzeit, zahlungsarten, abholung?, rechtstexteHash, verlauf: [{ at, was, ... }] }
* E2 ergaenzt im selben JSON: kaeufer { name, email, telefon }, lieferadresse / rechnungsadresse { name?, line1, line2, postal_code,
* E2 ergaenzt im selben JSON: kaeufer { name, email } (keine Telefonnummer), lieferadresse / rechnungsadresse { name?, line1, line2, postal_code,
* city, country }, zahlungsart ('card' | 'klarna' | 'sepa_debit', nur wenn eindeutig), ueberverkauft, spaet; E3 erstattungen[]. Status offen reserviert Bestand bis ablaufAt.
* ipHash steht nur, solange die Bestellung offen ist (Begrenzung offener Bestellungen je IP); schliesseAb und verwirf entfernen ihn.
* Fehler: Error mit status, code und Kaeufertext (Sie-Form) in message.
*/
@@ -565,9 +566,11 @@ export async function schliesseAb({ accountId, session, now = new Date() }) {
const at = jetzt.toISOString()
let verlauf = verlaufMit(daten, { at, was: 'bezahlt', ...(spaet ? { spaet: true } : {}) })
if (abweichend) verlauf = verlaufMit({ verlauf }, { at, was: 'betrag_abweichend', erwartetCent: order.summeCent, bezahltCent: Number.isInteger(session.amount_total) ? session.amount_total : null })
// Datenminimierung: Der IP-Hash dient nur der Begrenzung offener Bestellungen und entfaellt mit der Zahlung; eine Telefonnummer wird nie gespeichert
const { ipHash: _ipHash, ...datenOhneIp } = daten
const neueDaten = {
...daten,
kaeufer: { name: kurz(kunde.name, 200), email, telefon: kurz(kunde.phone, 50) },
...datenOhneIp,
kaeufer: { name: kurz(kunde.name, 200), email },
...(lieferadresse ? { lieferadresse } : {}),
...(rechnungsadresse ? { rechnungsadresse } : {}),
...(zahlungsart ? { zahlungsart } : {}),
@@ -663,9 +666,11 @@ export async function verwirf(orderId, grund, { now = new Date(), mail = false,
if (!shop || shop.stripeAccountId !== accountId) return { order: null, verworfen: false }
}
if (order.status !== 'offen') return { order, verworfen: false }
// Der IP-Hash dient nur der Begrenzung offener Bestellungen und entfaellt, sobald die Bestellung nicht mehr offen ist
const { ipHash: _ipHash, ...datenOhneIp } = order.daten
const doc = await updateDocument(col(), orderId, {
status: 'storniert',
bestellung: JSON.stringify({ ...order.daten, verlauf: verlaufMit(order.daten, { at: jetzt.toISOString(), was: String(grund).slice(0, 40) }) }),
bestellung: JSON.stringify({ ...datenOhneIp, verlauf: verlaufMit(order.daten, { at: jetzt.toISOString(), was: String(grund).slice(0, 40) }) }),
})
return { order: { ...doc, daten: bestellDaten(doc) }, verworfen: true }
})
@@ -1037,7 +1042,8 @@ export function bestellungKunde(order) {
erstattetText: euro(erstattet),
restCent: Math.max(0, summeCent - erstattet),
restText: euro(Math.max(0, summeCent - erstattet)),
kaeufer: istObjekt(daten.kaeufer) ? daten.kaeufer : { name: '', email: order?.kaeuferEmail ?? '', telefon: '' },
// Alte Datensaetze koennen noch eine Telefonnummer enthalten: nie ausgeben
kaeufer: istObjekt(daten.kaeufer) ? { name: daten.kaeufer.name ?? '', email: daten.kaeufer.email ?? '' } : { name: '', email: order?.kaeuferEmail ?? '' },
lieferart: daten.lieferart ?? '',
land: daten.land ?? '',
lieferadresse: istObjekt(daten.lieferadresse) ? daten.lieferadresse : null,
+1 -1
View File
@@ -161,7 +161,7 @@ async function anonymisiereBestellungen(lauf, shopId, grenze) {
delete daten.lieferadresse
delete daten.rechnungsadresse
delete daten.ipHash
daten.kaeufer = { name: '', email: '', telefon: '' }
daten.kaeufer = { name: '', email: '' }
await updateDocument(sammlung, doc.$id, {
kaeuferEmail: '',
bestellung: JSON.stringify(daten),
+1 -1
View File
@@ -30,7 +30,7 @@ import { gewaehrleistungsHinweis } from './rechtstexte.js'
* snap.positionen[] { name, varianteText, menge, summeCent, summeText?, widerruf ('gesetzlich'|'verderblich'|'individuell'|'hygiene') }
* snap.summen | snap { zwischensummeCent, versandCent, gesamtCent, texte?: { zwischensumme, versand, gesamt, steuerHinweis } }
* snap.lieferart ('versand'|'abholung'), snap.land ('DE'|'AT')
* snap.kaeufer { name, email, telefon } (oder snap.name)
* snap.kaeufer { name, email } (oder snap.name)
* snap.lieferadresse { name?, line1|strasse, line2?, postal_code|plz, city|ort, country|land }
* snap.zahlungsart 'card' | 'klarna' | 'sepa_debit' | Text
* snap.einstellungenAuszug { anbieter, lieferzeit, abholung } (sonst die aktuellen Einstellungen des Shops)