Wer von der tuerkischen Seite kam, landete bisher auf einer deutschen
Stripe-Seite — fuer die Zielgruppe die groesste Huerde im Kaufvorgang.
/kaufen nimmt jetzt 'sprache' entgegen und gibt sie als locale an Stripe
weiter. Nur Sprachen aus STRIPE_SPRACHEN werden geschickt: Ein unbekannter
Wert laesst Stripe die Session mit 400 ablehnen, der Kauf waere kaputt. Fuer
Arabisch, Tigrinya usw. (kennt Stripe nicht) wird nichts mitgeschickt, dann
waehlt Stripe selbst anhand des Browsers.
Alle drei Kauf-Stellen geben die Sprache mit: Sprachseiten fest ihre eigene,
Demo-Seite die dort gewaehlte Zielsprache, Startseite 'de'.
Geprueft: tr/de/pl/ar liefern Bezahlseiten, und eine erfundene Sprache faellt
sauber zurueck statt den Kauf zu brechen.
Stripe Link (die vorausgewaehlte Schnellzahlung) laesst sich NICHT per API
abschalten — laut Stripe-Docs nur in den Zahlungsmethoden-Einstellungen des
Dashboards.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beim Nachgehen der Frage 'warum gibt es auf den Sprachseiten kein Payment'
kam heraus: Die Web-Demo antwortete AUSSCHLIESSLICH auf Deutsch. Die
Uebersetzung war bisher reine App-Funktion — und die App gibt es noch nicht.
Kauf-Knoepfe auf der tuerkischen Seite haetten also 2,99 EUR fuer eine
deutsche Antwort kassiert. Deshalb zuerst der Worker:
- /demo nimmt jetzt 'zielsprache' entgegen (28 erlaubte Codes, Whitelist —
der Wert geht nie als freier Text in den Prompt, sonst koennte man eigene
Anweisungen einschleusen).
- Der deutsche Fachbegriff bleibt deutsch, nur dessen Erklaerung wird
uebersetzt — der Nutzer muss ihn im Brief wiederfinden.
- demo.html hat eine Sprachauswahl und merkt sich die Wahl; die Sprachseiten
verlinken mit ?sprache=xx.
Erst danach die Sprachseiten: Demo-Knopf als Haupt-Handlung (es gab bisher
GAR KEINEN — man konnte das Produkt in 27 Sprachen nicht einmal ausprobieren)
und ein Kauf-Abschnitt mit uebersetzter Pflicht-Einwilligung nach §356 BGB.
Geprueft: 27 Dateien ohne Syntaxfehler, keine offenen Platzhalter, Kauf
liefert cs_live_. Zwei Tippfehler im bulgarischen Text korrigiert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ohne gesetztes STRIPE_WEBHOOK_SECRET starb der Handler in hmacHex mit einer
Worker-Exception (error 1101 / HTTP 500). Jetzt: sauberes 503 mit Log-Hinweis.
JSON.parse ist zusaetzlich abgefangen -> 400 statt Absturz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
401/403 vom KI-Dienst sagte bisher 'machen Sie ein besseres Foto'. Jetzt
eigener Zweig (ki_konfig) mit ehrlicher Meldung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- demo.html: Kauf-Block mit Paketen (5/15 Analysen), Guthaben-Banner,
Pflicht-Einwilligung (sofortige Leistung, Widerruf erlischt), Rückkehr
von Stripe (/kauf-status), Wallet-Token in localStorage, bezahlte
Analysen umgehen die Gratis-Sperre und zählen das Guthaben herunter.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- /kaufen: Stripe-Checkout-Session (REST, kein SDK)
- /kauf-status: nach Rueckkehr Zahlung pruefen -> Guthaben aktivieren ->
signiertes Wallet-Token (HMAC) zurueckgeben
- /stripe-webhook: Signatur pruefen -> Guthaben aktivieren (idempotent) ->
Wiederherstellungs-Link per Brevo mailen
- demoHandler: nimmt optional walletToken; gueltiges Guthaben umgeht die
Gratis-Grenzen, wird nach Erfolg um 1 verringert
- neue Secrets: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET,
TOKEN_SIGNING_SECRET, BREVO_API_KEY; PAKETE-Mapping (Price-ID->Credits,
echte IDs noch einzutragen)
Typecheck gruen. Noch nicht deployed (wartet auf Stripe-Einrichtung).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Website: alle canonical/OG/hreflang/Sitemap/robots-URLs auf behoerdenklar.de
(alle Sprachseiten, Demo, Ratgeber)
- Worker: Demo-CORS erlaubt jetzt behoerdenklar.de (und www), nicht nur
pages.dev -> Demo funktioniert auf der neuen Domain
- eigene Domain via Cloudflare Pages Custom Domain verbunden (SSL aktiv)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fehler: Der anonyme Erst-Versuch war auf 1 pro IP (30 Tage) begrenzt.
Teilen sich mehrere Menschen eine Leitung (Familie, WLAN, Mobilfunk/CGNAT),
bekam der Zweite sofort 'E-Mail noetig' statt einer Analyse. Trat auch
beim Testen ueber denselben Anschluss auf.
- IP- und Anon-Zaehler jetzt TAEGLICH (Datum im Schluessel), 48h TTL
- Anonyme Erst-Analysen pro Anschluss/Tag: 3 (statt 1/30 Tage)
- IP-Gesamtlimit pro Tag: 8 (statt 3/30 Tage)
- 'Wallet'-Schutz unveraendert: globales Tagesbudget 100 + Turnstile +
E-Mail-Hash (dauerhaft 1x/Adresse)
- Client: email_noetig markiert den Browser NICHT mehr als verbraucht
(sonst dauerhafte Blockade ohne gelungene Analyse); localStorage-Key
auf 'bk_demo_v2' umbenannt -> setzt falsche Testphasen-Staende zurueck
Ende-zu-Ende verifiziert: frischer Erst-Upload liefert wieder das Ergebnis.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Backend-Proxy (Cloudflare Worker in proxy/): API-Key serverseitig,
Modell-Whitelist, max_tokens-Deckel, Tageslimits pro Gerät und IP
- Modell-Split: Analyse auf Sonnet 5, Übersetzung/Antwort auf Haiku 4.5
- Bild-Downscaling auf 2000px vor dem Upload (ScanScreen)
- Expo SDK 56 -> 57 Upgrade
- Freemium: 3 Gratis-Analysen mit lokalem Zähler und Paywall-Hinweis
- Einstellungen: API-Key-Feld nur noch im Dev-Modus (NUTZT_PROXY)
- Build-Setup: Bundle-IDs, eas.json, Splash-Screen-Plugin
- Tests: jest-expo + 17 Tests für die Ampel-/Fristlogik
- Rechtliches: Datenschutzerklärung (Entwurf), Webseite (webseite/,
live auf behoerdenklar.pages.dev), Store-Texte (store/)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>