Kaufland-Kassenbons automatisch importieren — Machbarkeits-Recherche
Tiefenrecherche · 07.06.2026 · für Dennis (Silverscale Family Hub) · zweiter Bon-Import-Weg analog zur Lidl-Plus-Anbindung
Frage: Können wir Kaufland-Kassenbons automatisch in die Familien-App ziehen
(Bon-Archiv, Preisstatistik, Vorrat) — so, wie heute schon lidl.py +
importer.py die Lidl-Plus-Bons holen?
1. Executive Summary — Verdikt
Machbar, aber nicht 1:1 wie bei Lidl. Es gibt die Datenquelle (Kaufland Card führt seit Mitte 2024 digitale Kassenbons in der App, 3 Jahre gespeichert, als PDF exportierbar), und Kaufland sitzt unter derselben Mutter (Schwarz-Gruppe) und derselben Auth-Technik (NetIQ Access Manager / NIDP) wie Lidl. Aber:
- Es existiert KEIN öffentlicher, fertiger Kaufland-App-Client — kein Pendant
zur
lidl-plus-Library (Andre0512), kein GitHub-Projekt, keine Home-Assistant-Integration, keine dokumentierten Bon-Endpoints. Für Edeka gibt es so etwas (edekompile), für Kaufland-Consumer nichts. Wir wären die Ersten und müssten die App-API selbst reverse-engineeren (mitmproxy gegen die Android-App). Das ist die ehrliche Faktenlage — alles andere wäre Wunschdenken. - Unser
lidl.py-Code ist NICHT direkt wiederverwendbar. Schwarz teilt die IT-Infrastruktur (Schwarz Digits, gleiche Identity-Federation-Technik), aber Lidl Plus und Kaufland Card sind getrennte Apps mit getrennten Konten, Client-IDs, Hosts und Token-Scopes. Das OAuth/PKCE-Muster (Dennis loggt im Browser ein → Code → refresh_token → rotieren) ist mit hoher Wahrscheinlichkeit übertragbar; die konkreten Endpoints/Client-IDs/Bon-Routen sind es nicht.
Empfehlung (gestuft, vom kleinsten Risiko aufwärts):
- Sofort & risikofrei: PDF-Bon-Import. Kaufland-Bons lassen sich in der App
als PDF speichern/teilen. Wir haben bereits eine KI-Job-Queue mit
Bildverarbeitung (ADR-13,
ai_jobs.py, Sonnet mit Bild-Input). Ein neuer Job-Typ „Bon-PDF → strukturierte Positionen" füttert direkt unserereceipts/receipt_items-Tabellen mitstore='Kaufland'. Manueller Trigger (Dennis exportiert nach einem Einkauf 1 PDF), kein ToS-Bruch, sofort nutzbar. - Mittelfristig & wenn es sich lohnt: App-API reverse-engineeren →
kaufland.pyanaloglidl.py, dann automatischer Cron-Pull wie bei Lidl. Höherer Aufwand, kleines ToS-/Sperr-Risiko, eigenständige Recherche-Session am echten Traffic nötig.
Für „erstmal Kaufland-Bons drin haben" ist Weg 1 die richtige Wahl. Weg 2 ist die Komfort-Kür, falls Kaufland zu einem regelmäßigen Einkaufsort wird.
2. In einfachen Worten
Bei Lidl haben wir einen kleinen Roboter (lidl.py), der sich mit deinem
Lidl-Plus-Login bei Lidls Server meldet und jede Nacht die neuen Kassenbons
abholt — fix und fertig als saubere Datenliste. Das geht so gut, weil jemand
anderes vor uns herausgefunden hat, wo genau Lidls App ihre Bons abruft, und das
als Bauanleitung ins Netz gestellt hat.
Für Kaufland gibt es diese Bauanleitung nicht. Kaufland hat zwar seit 2024 auch digitale Bons in seiner App (und gehört sogar derselben Firma wie Lidl), aber niemand hat öffentlich aufgeschrieben, wie man da rankommt. Wir müssten das selbst herausfinden — mit einem „Mithörgerät" zwischen Handy und Kaufland-Server. Machbar, aber Bastelarbeit, und Kaufland könnte das theoretisch unterbinden.
Der bequeme Sofort-Weg: In der Kaufland-App kannst du jeden Bon als PDF speichern. Unsere App kann schon heute Bilder/Dokumente mit KI lesen (das machen wir beim Foto-Bon und beim Barcode-Scan). Also: nach dem Einkauf einmal das Bon-PDF in die App geben, die KI liest Artikel, Preise, Pfand, Steuersätze heraus und legt es genauso ab wie einen Lidl-Bon — nur mit dem Stempel „Kaufland". Kein Hacken, kein Risiko, sofort fertig.
3. Recherche-Ergebnisse je Punkt
3.1 Kaufland-Ökosystem: Gibt es digitale Bons? (Ja)
- Eingeführt Mitte 2024 in Deutschland für Kaufland-Card-Nutzer („Spare den Papierbon"-Schieberegler in der Karte). Quelle: offizielle Kaufland-Pressemitteilung Juli 2024.
- Speicherung 3 Jahre in der App unter „digitale Kassenbons", als Einkaufshistorie einsehbar.
- Export: als PDF speichern und teilen. Rechtlich vollwertiger Beleg (Garantie/Umtausch/Rückgabe), konform zur Kassensicherungsverordnung.
- Ab Herbst 2024 wurde der Papierbon für Card-Nutzer nach App-Update automatisch auf digital umgestellt (abschaltbar).
- Wichtig: Voraussetzung ist die Kaufland Card (kostenloses Loyalty-Konto). Ohne Card-Scan an der Kasse kein digitaler Bon.
Bedeutung für uns: Die Datenquelle existiert, ist persönlich (deine eigenen Einkäufe), enthält Positionen, und ist als PDF rausholbar — das ist die verlässliche Konstante, egal ob die App-API knackbar ist.
Quellen: Kaufland-Presse Juli 2024 · Lebensmittelpraxis · Lebensmittelzeitung: digitalen Kassenzettel aufgewertet · heise: Digitaler Kassenbon — PDF statt Zettelwirtschaft (Paywall)
3.2 Technischer Weg: App-Backend-APIs (dünne Faktenlage)
Ehrlich: zur Consumer-App-API gibt es öffentlich praktisch nichts. Was kursiert, ist durchweg etwas anderes:
- „Kaufland API" = Marketplace/Seller-API (kaufland.de Onlineshop, ex-real.de,
HMAC-SHA256-signiert, Client-/Secret-Key). Das ist der Händler-Marktplatz,
hat mit Kassenbons/Loyalty nichts zu tun. Treffer wie
saleweaver/python-kaufland-api,productflowbv/kaufland-php-client,kaufland-csharp-sdk,hitmeister/api-sdk-phpfallen alle in diesen Topf. - Preis-Scraper (
kaufland-discounts, diversekaufland-price-tracker) ziehen öffentliche Angebote per Web-Scraping — kein Login, keine Bons. - Kein Consumer-App-Client: GitHub-Topic
kauflandenthält kein einziges Projekt für Loyalty-App/Bons/Card. Auch keine Home-Assistant-Integration.
Auth-Infrastruktur (das einzige harte technische Indiz): Sowohl Lidl als auch
Kaufland fahren ihre Identity-Federation über NetIQ Access Manager (NIDP) unter
Schwarz IT:
federation.auth.lidl.com bzw. federation.auth.kaufland.com
(beides /nidp/...-Endpoints), gemeinsame Staging-Domain federation-q.auth.schwarz.
Das belegt gemeinsame Auth-Technik, nicht gemeinsame Konten. Der Lidl-Plus-
App-Login läuft in unserem lidl.py zudem nicht über die NIDP-Federation,
sondern über einen Duende-IdentityServer-OIDC auf accounts.lidl.com
(/connect/authorize, /connect/token, client_id=LidlPlusNativeClient, PKCE,
Scope openid profile offline_access lpprofile lpapis, Redirect
com.lidlplus.app://callback). Kauflands App-Login wird sehr wahrscheinlich
einem analogen OIDC-/PKCE-Muster folgen (eigener Host, eigene Client-ID,
eigene Scopes) — aber das ist eine begründete Vermutung, kein bestätigter Fund.
Bot-Schutz: Bei Lidl bekannt: Akamai blockt python-requests →
curl_cffi impersonate="chrome"; Fake-Header lassen Requests hängen. Schwarz
nutzt gruppenweit ähnliche CDN/WAF-Schichten, daher ist bei Kaufland mit
demselben Klassen-Problem zu rechnen (Akamai/Cloudflare-Fingerprinting). Unser
curl_cffi-Wissen wäre hier der eine wirklich übertragbare Baustein.
Token-Lebensdauer/Refresh: unbekannt für Kaufland. Bei Lidl: rotierender refresh_token (lidl.py schreibt bei jedem Refresh neu). Plausibel analog, aber nicht belegt.
Fazit 3.2: Der App-API-Weg ist nicht recherchierbar, nur experimentell
erschließbar — eine eigene mitmproxy-Session gegen die echte Kaufland-Android-App
ist Pflicht, bevor irgendeine Zeile kaufland.py Sinn ergibt.
Quellen: GitHub-Topic kaufland · Marketplace Seller API (HMAC) · federation.auth.kaufland.com (NIDP) · federation.auth.lidl.com (NIDP) · Schwarz Digits / gemeinsame IT-Infra (CIO.de) · Schwarz Group (Wikipedia)
3.3 Bon-Detail-Format
- Sicher belegt: PDF (App-Export „als PDF speichern"). Layout-Bon, kein strukturiertes JSON im Export.
- Über die App-API: Format unbekannt. Beim Vergleichsprojekt
edekompile(Edeka) liefert die App-API Bons als geparstes JSON. Bei Lidl ist es gemischt: Bon-Liste JSON (tickets.lidlplus.com/api/v2/.../tickets), Bon-Detail nur HTML (v3). Welche Variante Kaufland fährt, lässt sich erst am abgefangenen Traffic sagen. - Benötigte Felder (haben wir bei Lidl bereits modelliert, müssen auch im Kaufland-Bon vorkommen, sonst leidet die Statistik): Positionen mit Name/Menge/Einzelpreis/Gesamt, Rabatte, Pfand (Ein- und Rückgabe), Gewichtsartikel (kg-Folgezeile), Steuersätze (A=7 %/B=19 % als Food-Flag). Diese Felder sind auf jedem deutschen GoBD-Kassenbon enthalten, also auch im Kaufland-PDF lesbar — das macht den KI-PDF-Weg robust.
Quellen: edekompile (Edeka-App-API, Bons als JSON) · heise: PDF-Bon
3.4 Vergleichbare Open-Source-Projekte
| Händler | Consumer-App-Bon-Client? | Projekt |
|---|---|---|
| Lidl | Ja | Andre0512/lidl-plus (Python, OIDC, Bons als JSON) + Fork zsobix/lidlplus-api, titov-vv/lidl-plus-login, Android LittleMinus, LidlToGrocy |
| Edeka/Marktkauf/Scheck-in | Ja | ByteSizedMarius/edekompile (Go; Bearer aus Browser-Login → virtuelles Gerät → API-Credentials → Bons) |
| Kaufland | Nein | — nichts. Nur Marketplace-/Preis-Scraper. |
lidl-plusals Blaupause: Es ist genau das Muster, das unserlidl.pyumsetzt. Für Kaufland gäbe es keine fremde Vorlage — wohl aber unsere eigenelidl.pyals Strukturvorlage (gleiche Klassen-Architektur: Login-CLI → refresh_token → authentifizierter Client → fetch/parse).- Schwarz-Gemeinsamkeit: Wiederverwendbar ist das Konzept und das
curl_cffi-Anti-Akamai-Wissen — nicht Hosts/Client-IDs/Scopes/Routen. - edekompile-Detail wert zu kennen: Dort warnt der Autor, die erlangten Credentials könnten In-Store-Zahlungen autorisieren → Token streng schützen. Falls Kaufland (Schwarz Pay!) ähnlich gebaut ist, gilt das auch hier — ein zusätzliches Argument, den App-API-Weg vorsichtig anzugehen.
3.5 Fallback-Wege ohne App-API
- PDF-Import via KI-Job (empfohlener Primärweg, nicht nur Fallback).
Kaufland-Bon in der App als PDF exportieren → in Silverscale hochladen →
neuer
ai_jobs-Handler (Sonnet, Bild-/PDF-Input, eng begrenztes Tool-Set, ADR-13) extrahiert Positionen → schreibt inreceipts/receipt_items(store='Kaufland'). Nutzt vorhandene Infrastruktur (Foto-Bon, Bild-Pipeline), null ToS-Risiko, sofort lauffähig. - eBon per E-Mail: Bei Kaufland kein dedizierter E-Mail-Versand belegt (nur „speichern/teilen"). Über „Teilen → an eigene Mail" technisch möglich, aber manuell — kein Automatisierungs-Gewinn gegenüber PDF-Upload.
- Foto-Papierbon + KI: Fällt mit Weg 1 zusammen (gleicher Handler kann Foto und PDF). Sinnvoll, falls Card mal nicht gescannt wurde.
- DSGVO-Datenkopie (Art. 20): Kaufland muss auf Anfrage eine
maschinenlesbare Kopie der Einkaufsdaten liefern
(
kundenmanagement@kaufland.de). Gut für einen einmaligen Historie- Bulk-Import, ungeeignet für laufenden Betrieb (Bearbeitungszeit Wochen). - CSV-Export: kein offizieller CSV-Export bekannt.
Quellen: Kaufland Card Datenschutz / Betroffenenrechte · Kaufland Card Datenkopie-Kontakt
3.6 Rechtliches / Risiko (kurz)
- Eigene Daten, privater Gebrauch — gleiche Einordnung wie beim Lidl-Weg: Es sind deine eigenen Bons aus deinem eigenen Konto. DSGVO gibt dir das Recht auf diese Daten.
- PDF-Weg (3.5.1): rechtlich unkritisch — du exportierst, was die App dir ausdrücklich zum Speichern anbietet. Keine ToS-Grauzone, keine Sperr-Gefahr.
- App-API-Weg (3.2): verstößt gegen die App-Nutzungsbedingungen („automatisierter Zugriff", reverse-engineerte private API). Ehrlich benannt: kleines, aber reales Risiko einer Konto-Sperrung — wie bei Lidl Plus auch (dort fahren wir es bewusst, niedrigfrequent, Login manuell durch Dennis). Bei Schwarz-Pay-Verflechtung (siehe edekompile-Warnung) wäre eine Sperre ärgerlicher als bei reinem Loyalty. → erst durchführen, wenn der PDF-Weg nicht reicht.
4. Empfohlener Implementierungsweg
Phase A — PDF/KI-Bon-Import (jetzt, ~0,5–1 Tag)
Architektur (nutzt vorhandene Bausteine, neuer Code minimal):
Kaufland-App ──(Dennis exportiert Bon als PDF)──► Upload in Silverscale-UI
│ (neuer „Bon importieren"-Button
│ im Einkäufe-Tab, store-Auswahl)
▼
ai_jobs-Queue (ADR-13)
neuer Handler "receipt_pdf":
Sonnet, PDF/Bild-Input, Prompt = "extrahiere Positionen,
Rabatte, Pfand, Gewichtsartikel, Steuersätze als JSON"
▼
importer.py (vorhandene import_receipt-Logik wiederverwenden)
r = {id: "KAUFLAND:<hash>", date, store:{name:"Kaufland"}, totalAmount, items[...]}
▼
receipts (store='Kaufland', in_inventory wie gewünscht)
receipt_items (name, unit_price, qty, is_weight, discount, tax_type, is_deposit)
- Idempotenz: Bon-ID aus stabilem Hash (Datum + Summe + Positions-Hash) oder
aus der im PDF gedruckten Beleg-/Bon-Nummer.
importer.pyprüft schon heuteSELECT 1 FROM receipts WHERE id=?→ doppelter Upload no-op. - Mapping: läuft durch die bestehende
art2food-/Anreicherungs-Kette; Kaufland-Positionen bekommenart_id=NULL(keine Lidl-interne Nummer) und matchen über Name → OFF, exakt wie Frischware bei Lidl. - Validierung: Kontrollsumme wie bei Lidl (Σ Positionen + Rabatte + Pfand == Bon-Summe). Bei Abweichung → Job als „prüfen" markieren, UI-Toast.
- Verifikation: KI-Extraktion ist nie 100 % — ein kurzer Bestätigungs-Dialog („so erkannt, passt das?") vor dem Schreiben ist Pflicht (UI-Feedback-Regel, ADR-13).
Phase B — kaufland.py (später, nur falls Phase A nicht reicht)
- Recherche-Session am echten Traffic (separat, eigener Bericht ins Archiv): mitmproxy + Android-Emulator/Gerät mit Kaufland-App, Login + Bon-Abruf abfangen → Auth-Host, Client-ID, Scopes, Bon-Liste-/Detail-Routen, Format dokumentieren. Ohne diesen Schritt kein Code.
kaufland.pyals Klon derlidl.py-Struktur:login-CLI (Dennis macht Browser-Login + 2FA selbst, liefert Redirect-URL — feste Nie-automatisieren-Regel), refresh_token in.env(rotierend),curl_cffi impersonate="chrome"gegen Akamai,fetch-Befehl → gleiches receipts-JSON-Schema wielidl.pyausgibt.importer.py --pullum eine--source kauflanderweitern (oder zweiter Cron-Eintrag), Idempotenz über Kaufland-Bon-IDs,store='Kaufland'.- Cron analog Lidl (z. B. 07:50, gestaffelt nach dem Lidl-Pull 07:45).
Schema steht bereits Kaufland-tauglich: receipts.store (TEXT) und
receipt_items (Name/Preis/Menge/Gewicht/Rabatt/Pfand/Steuer) brauchen
keine Migration — Kaufland-Bons passen in die vorhandenen Spalten. art_id
bleibt NULL (Lidl-spezifisch). foods.store kennt schon Mehr-Händler-Logik.
5. Aufwandsschätzung
| Schritt | Aufwand | Risiko |
|---|---|---|
| Phase A: KI-PDF-Handler + Upload-UI + importer-Anbindung | 0,5–1 Tag | gering (KI-Genauigkeit; mit Bestätigungs-Dialog abgefedert) |
| Phase B.1: mitmproxy-Recherche Kaufland-App | 0,5–1 Tag (ergebnisoffen, kann scheitern) | mittel (Cert-Pinning? Akamai?) |
Phase B.2–4: kaufland.py + Cron + Parser (wenn B.1 klappt) |
1–2 Tage | mittel (ToS/Sperre, API-Bruch jederzeit) |
Empfehlung: Phase A bauen, Phase B nur bei echtem Bedarf (Kaufland wird regelmäßiger Einkaufsort). Phase A liefert 90 % des Nutzens für 20 % des Aufwands und null Risiko.
6. Risiken
- KI-Fehlextraktion (Phase A): falsche Preise/Mengen verfälschen die Statistik → Bestätigungs-Dialog + Kontrollsumme zwingend.
- Reverse-Engineering kann scheitern (Phase B): Cert-Pinning der App, Akamai-Fingerprinting, undokumentierte Signierung → Session evtl. ohne Ergebnis. Deshalb erst Recherche, dann Code-Entscheidung.
- ToS/Konto-Sperre (Phase B): real, klein, bei möglicher Schwarz-Pay-Kopplung unangenehmer als bei Lidl. Niedrigfrequent fahren, Login manuell durch Dennis.
- API-Bruch (Phase B): wie bei Lidl jederzeit möglich; Schwarz hat 2024 die Lidl-EAN-API abgeschaltet — Präzedenz, dass sich diese APIs ohne Vorwarnung ändern.
- Card-Pflicht: Ohne gescannte Kaufland Card kein digitaler Bon → Foto- Fallback (Phase A deckt das mit ab).
7. Offene Fragen an Dennis (max. 3)
- Wie oft kauft ihr bei Kaufland ein? Selten → Phase A (PDF-Upload) reicht dauerhaft. Regelmäßig → Phase B (Auto-Pull) lohnt die Recherche-Session.
- Habt ihr eine Kaufland Card mit aktiviertem digitalem Bon? (Voraussetzung für beide Wege — sonst nur Foto vom Papierbon.)
- Phase B überhaupt gewünscht? Sie braucht eine eigene mitmproxy-Recherche- Session und akzeptiert ein kleines Konto-Sperr-Risiko — oder bleiben wir bewusst beim risikofreien PDF/KI-Weg?
8. Nachtrag (07.06.2026 abends): Phase B getestet → Cert-Pinning
Dennis wollte Phase B und hat — wie beim eGYM-Capture — eine mitmproxy-Session mit dem iPhone 16 gefahren. Befund eindeutig: Die Kaufland-App betreibt Certificate Pinning auf ihren kritischen Hosts.
server connect app.kaufland.net:443 → Client TLS handshake failed.
The client disconnected during the handshake.
server connect account.kaufland.com:443 → dito (konsequent)
Gleichzeitig liefen 1Password, Amazon Music, Outlook sauber durch denselben
Proxy → das mitm-Cert war korrekt installiert und vertraut. Die App prüft
zusätzlich selbst die Server-Identität und bricht ab, sobald ein Proxy
dazwischensteht. app.kaufland.net ist die eigentliche Bon-/API-Domain,
account.kaufland.com die Auth — beide gepinnt, also kein passiver Capture
möglich (anders als Netpulse/eGYM, das nicht pinnte).
Plan-C-Optionen (für eine etwaige spätere Phase B):
- iOS-Unpinning: Kaufland-IPA + Frida-Gadget/objection einbauen, mit dem
Apple-Dev-Account neu signieren, per SideStore installieren → dann Capture.
- Android-Unpinning: Emulator + apk-mitm/objection (kein Signing-Tanz,
oft robuster).
Entscheidung Dennis (07.06.2026): Phase B vertagt, wir bauen Phase A (PDF-Upload → KI-Extraktion). Deckt das Ziel (Kaufland-Bons im Archiv/Vorrat) ohne Pinning-Kampf und ohne ToS-Risiko ab. → Umsetzung in ADR-52.