Datenexport, Löschkonzept und Consent-Verwaltung technisch umgesetzt
Magento Open Source bringt anders als Adobe Commerce kein eingebautes Werkzeug für Auskunftsrecht und Löschung mit, obwohl beide Rechte in der DSGVO klar geregelt sind. Ein eigener Datenexport-Service, ein Anonymisierungskonzept, das Aufbewahrungspflichten respektiert, und eine nachvollziehbare Consent-Verwaltung lassen sich mit PHP 8.4, Service Contracts und einem eigenen Cronjob sauber im Shop verankern.
Inhaltsverzeichnis
- 1. Rechtlicher Rahmen und die Lücke in Magento Open Source
- 2. Personenbezogene Daten in Magento identifizieren
- 3. Auskunftsrecht technisch umsetzen
- 4. Löschkonzept und der Zielkonflikt mit Aufbewahrungspflichten
- 5. Anonymisierungs-Implementierung
- 6. Consent-Verwaltung
- 7. Automatisierte Löschfristen per Cron
- 8. Audit-Trail und Nachweispflicht
- 9. Vergleich: Anforderung vs. technische Umsetzung vs. Risiko
- 10. Zusammenfassung
- 11. FAQ
1. Rechtlicher Rahmen und die Lücke in Magento Open Source
DSGVO-Konformität in einem Magento-Shop betrifft im Kern drei Artikel: Art. 15 regelt das Auskunftsrecht, also den vollständigen Export aller über eine Person gespeicherten Daten. Art. 17 regelt das Recht auf Löschung, mit wichtigen Ausnahmen für gesetzliche Aufbewahrungspflichten. Art. 20 regelt die Datenübertragbarkeit, also die Bereitstellung der Daten in einem strukturierten, maschinenlesbaren Format. Diese drei Rechte sind rechtlich eindeutig, ihre technische Umsetzung in einem gewachsenen Magento-Shop mit Jahren an Bestell- und Kundendaten ist es nicht.
Der entscheidende Unterschied zwischen Adobe Commerce und Magento Open Source: Adobe Commerce liefert mit dem "Compliance Tool" eine eingebaute Oberfläche für Datenexport und Löschung mit. Magento Open Source, die Basis der meisten mittelständischen Shops, bringt dagegen keinerlei eingebaute DSGVO-Funktionalität mit. Wer als Agentur oder Entwickler auf Magento Open Source arbeitet, muss Auskunftsrecht, Löschkonzept und Consent-Verwaltung komplett selbst implementieren, es gibt keine Admin-Schaltfläche, die das übernimmt.
Dieser Artikel behandelt bewusst nicht die reine Rechtstheorie, sondern die technische Umsetzung: welche Tabellen personenbezogene Daten enthalten, wie ein Export-Service mit PHP 8.4 aufgebaut wird, warum Anonymisierung statt Hard-Delete bei Bestelldaten die richtige Strategie ist, und wie Consent-Tracking sowie automatisierte Löschfristen konkret implementiert werden. Die DSGVO-Konformität eines Shops ist am Ende immer eine Kombination aus technischer Implementierung und organisatorischem Prozess, dieser Artikel deckt die technische Seite ab.
2. Personenbezogene Daten in Magento identifizieren
Bevor überhaupt ein Export- oder Löschkonzept entworfen werden kann, muss feststehen, wo personenbezogene Daten in Magento tatsächlich liegen. Die offensichtlichsten Tabellen sind customer_entity mit Name, E-Mail und Adresse, sowie customer_address_entity für Liefer- und Rechnungsadressen. Weniger offensichtlich, aber ebenso relevant: sales_order, sales_order_address und sales_order_payment enthalten personenbezogene Daten auch für Gastbestellungen ohne Kundenkonto, ebenso quote und quote_address für noch nicht abgeschlossene Warenkörbe.
Häufig übersehen werden customer_log und customer_visitor, die Login-Zeitpunkte und IP-Adressen speichern, sowie report_event und report_viewed_product_index, die das Nutzerverhalten für Produktempfehlungen tracken und dabei ebenfalls personenbezogene Kennungen speichern. Newsletter-Daten in newsletter_subscriber gehören ebenso zum Umfang wie gespeicherte Zahlungsinformationen bei Zahlungsanbietern, die zwar meist nicht in Magento selbst, aber über eine Customer-ID referenziert in der Datenbank des Payment-Providers vorliegen und beim Löschkonzept berücksichtigt werden müssen. Eine vollständige DSGVO-Konformität setzt eine dokumentierte, vollständige Liste aller dieser Tabellen voraus, bevor ein einziger Export- oder Löschbefehl geschrieben wird.
3. Auskunftsrecht technisch umsetzen
Für die technische Umsetzung von Art. 15 empfiehlt sich ein eigener Service, der die relevanten Repository-Schnittstellen bündelt und ein strukturiertes Export-Array liefert, das anschließend als JSON ausgegeben werden kann. Der Service sollte bewusst auf CustomerRepositoryInterface, OrderRepositoryInterface und CartRepositoryInterface aufsetzen, statt direkt SQL gegen die Tabellen aus Abschnitt 2 zu schreiben, weil Repositories automatisch Berechtigungsprüfungen und Store-Scope-Filterung übernehmen.
Wichtig ist außerdem, dass der Export sowohl für eingeloggte Kunden über die customer_id als auch für Gastbestellungen über die verknüpfte E-Mail-Adresse funktioniert, da Art. 15 nicht zwischen registrierten und nicht registrierten Personen unterscheidet. Ein sauber strukturierter Export erleichtert gleichzeitig die Umsetzung von Art. 20, weil ein bereits maschinenlesbares JSON-Format die Anforderung an Datenübertragbarkeit direkt mit erfüllt.
declare(strict_types=1);
namespace Vendor\GdprTools\Model;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
/**
* Builds a structured personal data export for a customer or guest, per Art. 15 GDPR.
*/
final class PersonalDataExportService
{
/**
* @param CustomerRepositoryInterface $customerRepository Provides registered customer master data
* @param OrderRepositoryInterface $orderRepository Provides order history for the requested identity
* @param SearchCriteriaBuilder $searchCriteriaBuilder Builds filtered order search criteria
*/
public function __construct(
private readonly CustomerRepositoryInterface $customerRepository,
private readonly OrderRepositoryInterface $orderRepository,
private readonly SearchCriteriaBuilder $searchCriteriaBuilder,
) {
}
/**
* Assembles the full export structure for a customer, ready to be encoded as JSON.
*
* @param int $customerId Entity ID of the registered customer
* @return array<string, mixed> Structured export payload covering master data and order history
*/
public function exportForCustomer(int $customerId): array
{
$customer = $this->customerRepository->getById($customerId);
$criteria = $this->searchCriteriaBuilder
->addFilter('customer_id', $customerId)
->create();
$orders = $this->orderRepository->getList($criteria)->getItems();
return [
'master_data' => [
'email' => $customer->getEmail(),
'firstname' => $customer->getFirstname(),
'lastname' => $customer->getLastname(),
'created_at' => $customer->getCreatedAt(),
],
'orders' => array_map(
static fn ($order): array => [
'increment_id' => $order->getIncrementId(),
'created_at' => $order->getCreatedAt(),
'grand_total' => $order->getGrandTotal(),
'shipping_address' => $order->getShippingAddress()?->getData(),
],
$orders,
),
];
}
}
4. Löschkonzept und der Zielkonflikt mit Aufbewahrungspflichten
Art. 17 DSGVO gewährt das Recht auf Löschung, das jedoch nicht absolut gilt. Handels- und Steuerrecht, konkret HGB und AO, verpflichten zur Aufbewahrung von Rechnungs- und Buchungsbelegen für sechs bis zehn Jahre. Ein Shop, der Bestelldaten nach einem Löschantrag sofort per Hard-Delete aus sales_order entfernt, verstößt damit gegen steuerrechtliche Aufbewahrungspflichten, selbst wenn er formal dem Löschantrag der betroffenen Person nachkommt.
Die in der Praxis etablierte Lösung für diesen Zielkonflikt ist Anonymisierung statt Hard-Delete: Name, Adresse, E-Mail und alle direkt identifizierenden Felder werden durch Platzhalter ersetzt, während order_increment_id, Beträge, Steuersätze und Zahlungsart für die Buchhaltung vollständig erhalten bleiben. Nach der Anonymisierung ist die Bestellung für steuerliche Zwecke weiterhin vollständig nachvollziehbar, aber nicht mehr einer identifizierbaren Person zuordenbar, womit dem Grundgedanken des Art. 17 entsprochen wird, ohne die Aufbewahrungspflicht zu verletzen. Diese Strategie ist der zentrale Baustein jeder realistischen DSGVO-Konformität für Bestelldaten in Magento.
5. Anonymisierungs-Implementierung
Die konkrete Anonymisierungsklasse sollte gezielt nur die identifizierenden Felder überschreiben und dabei niemals die komplette Order-Entity löschen. Personenbezogene Freitextfelder wie Firmenname im Adressfeld oder Telefonnummer gehören ebenso zum Anonymisierungsumfang wie Vor- und Nachname, während numerische und steuerrelevante Felder unangetastet bleiben müssen. Ein sauberer Ansatz markiert zusätzlich ein eigenes Flag gdpr_anonymized_at auf der Order-Entity, damit spätere Prozesse, etwa ein erneuter Exportversuch, erkennen können, dass die Bestellung bereits anonymisiert wurde.
Wichtig für die Implementierung: Die Anonymisierung darf nicht kaskadierend auch verknüpfte Tabellen wie sales_order_grid vergessen, die eine denormalisierte Kopie der Kundendaten für die Admin-Grid-Darstellung enthält. Ein häufiger Fehler in eigenen DSGVO-Implementierungen ist, nur die Haupttabelle zu anonymisieren und die Grid-Tabelle, die separat für Performance-Zwecke existiert, zu übersehen, wodurch personenbezogene Daten trotz vermeintlich abgeschlossener Löschung im Admin-Panel sichtbar bleiben.
declare(strict_types=1);
namespace Vendor\GdprTools\Model;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\App\ResourceConnection;
/**
* Anonymizes personally identifiable fields on an order while preserving
* amounts and tax data required for statutory retention (HGB/AO).
*/
final class OrderAnonymizer
{
private const string PLACEHOLDER = 'anonymized';
/**
* @param OrderRepositoryInterface $orderRepository Loads and saves the order entity
* @param ResourceConnection $resourceConnection Direct connection for the denormalized sales_order_grid table
*/
public function __construct(
private readonly OrderRepositoryInterface $orderRepository,
private readonly ResourceConnection $resourceConnection,
) {
}
/**
* Replaces identifying fields with placeholders, keeps totals and tax data untouched.
*
* @param int $orderId Entity ID of the order to anonymize
* @return void
*/
public function anonymize(int $orderId): void
{
$order = $this->orderRepository->get($orderId);
$order->setCustomerEmail(self::PLACEHOLDER . '@example.invalid');
$order->setCustomerFirstname(self::PLACEHOLDER);
$order->setCustomerLastname(self::PLACEHOLDER);
$order->setData('gdpr_anonymized_at', date('Y-m-d H:i:s'));
// Totals, tax rates and order_increment_id are intentionally left untouched
// to preserve statutory bookkeeping requirements.
$this->orderRepository->save($order);
// The order grid is a denormalized read model and must be anonymized separately.
$connection = $this->resourceConnection->getConnection();
$connection->update(
$this->resourceConnection->getTableName('sales_order_grid'),
['customer_email' => self::PLACEHOLDER . '@example.invalid', 'customer_name' => self::PLACEHOLDER],
['entity_id = ?' => $orderId],
);
}
}
6. Consent-Verwaltung
Nachweisbarkeit der Einwilligung nach Art. 7 Abs. 1 DSGVO verlangt mehr als nur ein gesetztes Häkchen im Checkout. Für den Newsletter-Versand über Magento\Newsletter ist Double-Opt-In technisch bereits vorbereitet, aber der Zeitpunkt und die konkrete Version des Einwilligungstexts, dem zugestimmt wurde, werden von Magento standardmäßig nicht dokumentiert. Eine eigene Tabelle, die Zeitstempel, IP-Adresse, Consent-Version und Zustimmungstext-Hash speichert, schließt diese Lücke und liefert im Streitfall den erforderlichen Nachweis.
Für Cookie-Consent gilt dasselbe Prinzip: Die reine Speicherung eines Cookies "Consent erteilt: ja" reicht nicht aus, wenn sich der Consent-Banner-Text oder die abgefragten Kategorien später ändern. Jede Einwilligung sollte mit der zum Zeitpunkt der Zustimmung gültigen Version des Consent-Textes verknüpft gespeichert werden, damit auch Monate später nachvollziehbar ist, wozu genau eine Person zugestimmt hat, nicht nur, dass irgendeine Zustimmung erfolgte.
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="vendor_gdpr_consent_log" resource="default" engine="innodb" comment="GDPR consent audit trail">
<column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="true"/>
<column xsi:type="varchar" name="email" nullable="false" length="255" comment="Identifying email at consent time"/>
<column xsi:type="varchar" name="consent_type" nullable="false" length="64" comment="newsletter, cookies, marketing"/>
<column xsi:type="varchar" name="consent_version" nullable="false" length="32" comment="Version of the consent text shown"/>
<column xsi:type="varchar" name="ip_address" nullable="false" length="45"/>
<column xsi:type="timestamp" name="consented_at" nullable="false" default="CURRENT_TIMESTAMP"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="entity_id"/>
</constraint>
</table>
</schema>
7. Automatisierte Löschfristen per Cron
Manuelle Löschprozesse skalieren nicht über viele tausend Kundendatensätze hinweg, weshalb ein eigener Cronjob, der über crontab.xml registriert wird, feste Regeln für automatisierte Löschfristen umsetzen sollte. Typische Regeln sind: Gastbestellungen ohne zugehöriges Kundenkonto werden nach Ablauf der steuerlichen Aufbewahrungsfrist automatisch anonymisiert, inaktive Kundenkonten ohne Login seit mehreren Jahren werden nach vorheriger Benachrichtigung gelöscht oder anonymisiert, und Warenkorb-Daten in quote ohne abgeschlossene Bestellung werden nach wenigen Wochen bereinigt.
Wichtig bei der Implementierung ist, dass der Cronjob niemals sofort und ohne Protokollierung löscht, sondern zunächst nur markiert und mit einer Vorlaufzeit tatsächlich anonymisiert, damit ein versehentlich zu aggressiv konfigurierter Job nicht unwiderruflich Daten zerstört, bevor der Fehler bemerkt wird.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="vendor_gdpr_anonymize_expired_orders" instance="Vendor\GdprTools\Cron\AnonymizeExpiredOrders" method="execute">
<!-- Runs nightly at 2 AM, well outside typical business hours -->
<schedule>0 2 * * *</schedule>
</job>
</group>
</config>
8. Audit-Trail und Nachweispflicht
Bei einer Anfrage einer Aufsichtsbehörde muss ein Shop nicht nur nachweisen, dass er Anfragen zur Löschung oder zum Export bearbeitet, sondern auch, wann, durch wen und mit welchem Ergebnis. Eine eigene Logging-Tabelle, die jeden Export- und Anonymisierungsvorgang mit Zeitstempel, ausführendem Admin-Benutzer und betroffener Entity-ID protokolliert, ist der zentrale Baustein für diese Nachweispflicht. Ohne einen solchen Audit-Trail lässt sich im Streitfall nicht belegen, dass ein Löschantrag tatsächlich fristgerecht bearbeitet wurde.
Diese Protokollierung sollte selbst nicht dem Löschkonzept unterliegen, sondern über die reguläre Aufbewahrungsfrist hinaus erhalten bleiben, da sie gerade den Nachweis der ordnungsgemäßen DSGVO-Konformität erbringt. Ein Widerspruch, der auf den ersten Blick überraschend wirkt: Die Protokolle über gelöschte Daten müssen selbst länger aufbewahrt werden als die ursprünglichen Daten, weil sie den einzigen Beleg für die korrekte Umsetzung darstellen.
9. Vergleich: Anforderung vs. technische Umsetzung vs. Risiko
Die folgende Übersicht ordnet die wichtigsten Artikel der DSGVO ihrer technischen Umsetzung in Magento und dem Risiko bei Nichtbeachtung zu.
| Anforderung | Technische Umsetzung | Risiko bei Nichtbeachtung | Priorität |
|---|---|---|---|
| Art. 15 Auskunftsrecht | Export-Service mit Repository-Bündelung | Bußgeld, Beschwerde bei Aufsichtsbehörde | Hoch |
| Art. 17 Löschung | Anonymisierung statt Hard-Delete | Verstoß gegen Aufbewahrungspflicht oder DSGVO | Hoch |
| Art. 20 Übertragbarkeit | Strukturiertes JSON-Exportformat | Formal unvollständige Erfüllung des Anspruchs | Mittel |
| Art. 7 Abs. 1 Nachweis | Consent-Log mit Version und Zeitstempel | Fehlender Nachweis bei Beschwerde | Mittel |
| Nachweispflicht allgemein | Audit-Trail für Export und Löschung | Keine Belegbarkeit bei Behördenprüfung | Mittel |
Diese Priorisierung zeigt: Export und Löschkonzept sind die beiden dringlichsten Bausteine jeder DSGVO-Konformität, weil sie unmittelbar von betroffenen Personen eingefordert werden können, während Consent-Log und Audit-Trail eher die dauerhafte Nachweisbarkeit absichern.
10. Zusammenfassung
DSGVO-Konformität in Magento Open Source ist ausschließlich über eigene Entwicklung erreichbar, da anders als bei Adobe Commerce kein eingebautes Compliance-Werkzeug existiert. Ein Export-Service auf Basis von Repository-Schnittstellen deckt Art. 15 ab, ein Anonymisierungskonzept statt Hard-Delete löst den Zielkonflikt zwischen Art. 17 und handels- sowie steuerrechtlichen Aufbewahrungspflichten, und ein strukturiertes JSON-Format erfüllt gleichzeitig Art. 20.
Consent-Verwaltung mit versionierten Einwilligungstexten, automatisierte Löschfristen über einen dokumentierten Cronjob und ein eigener Audit-Trail für alle Export- und Löschvorgänge runden eine belastbare DSGVO-Konformität ab. Wichtig bleibt: Diese technische Implementierung ersetzt keine rechtliche Beratung, ein Datenschutzbeauftragter oder Anwalt sollte das konkrete Löschkonzept vor dem produktiven Einsatz prüfen, insbesondere bei branchenspezifischen Aufbewahrungsfristen.
DSGVO-Konformität in Magento 2: Das Wichtigste auf einen Blick
Keine eingebaute Lösung
Magento Open Source bringt kein Compliance-Tool mit, anders als Adobe Commerce. Eigene Entwicklung ist zwingend.
Anonymisierung statt Hard-Delete
Bestelldaten wegen HGB/AO-Aufbewahrungspflicht anonymisieren, nicht vollständig löschen. Auch sales_order_grid nicht vergessen.
Consent versioniert protokollieren
Zeitstempel, IP und Version des Einwilligungstextes speichern, nicht nur ein einfaches Ja/Nein-Flag.
Audit-Trail langfristig erhalten
Protokolle über Export und Löschung länger aufbewahren als die ursprünglichen Daten selbst, als Nachweis.
11. FAQ: DSGVO-Konformität in Magento 2
1Eingebautes DSGVO-Werkzeug in Open Source?
2Welche Tabellen enthalten personenbezogene Daten?
3Warum kein Hard-Delete bei Bestellungen?
4Richtige Alternative zum Hard-Delete?
5sales_order_grid separat behandeln?
6Reicht ein einfaches Consent-Cookie?
7Löschfristen automatisieren?
8Warum ein Audit-Trail?
9Wie lange Audit-Trail aufbewahren?
10Ersetzt das eine Rechtsberatung?
Mironsoft
Magento-Datenschutz-Module, Anonymisierungskonzepte und Consent-Verwaltung
DSGVO-Konformität für euren Magento-Shop noch offen?
Wir entwickeln Datenexport-Services, Anonymisierungskonzepte und Consent-Verwaltung als eigenes Magento-2-Modul, abgestimmt auf eure Aufbewahrungspflichten und Datenmodelle.
Datenaudit
Alle personenbezogenen Daten in eurem Shop vollständig dokumentieren
Löschkonzept
Anonymisierung statt Hard-Delete, abgestimmt mit eurer Buchhaltung
Consent-Modul
Versioniertes Consent-Tracking mit vollständigem Audit-Trail