# Usuwanie konta zgodne z RODO: pełny przewodnik

> Przegląd Moduł Usuwanie konta zgodne z RODO daje Twoim klientom możliwość skorzystania z prawa do usunięcia danych (artykuł 17 RODO) bezpośrednio z poziomu konta klienta, bez ręcznej interwencji z Twojej…

- Strona: <https://www.datafirefly.com/pl/documentation/dfaccountdelete/>
- Język: pl
- Zaktualizowano: 2026-10-11
- Inne języki: [fr](https://www.datafirefly.com/documentation/dfaccountdelete/index.md), [en](https://www.datafirefly.com/en/documentation/dfaccountdelete/index.md), [es](https://www.datafirefly.com/es/documentation/dfaccountdelete/index.md), [de](https://www.datafirefly.com/de/documentation/dfaccountdelete/index.md), [it](https://www.datafirefly.com/it/documentation/dfaccountdelete/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfaccountdelete/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfaccountdelete/index.md)
- Indeks: <https://www.datafirefly.com/pl/documentation/llms.txt>

## Przegląd

Moduł **Usuwanie konta zgodne z RODO** daje Twoim klientom możliwość skorzystania z prawa do usunięcia danych (artykuł 17 RODO) bezpośrednio z poziomu konta klienta, bez ręcznej interwencji z Twojej strony. Jedno żądanie uruchamia kaskadę: potwierdzenie e-mail z tokenem kryptograficznym, anonimizację albo usunięcie konta po stronie sklepu, automatyczne wypisanie z Mailchimp, Brevo i Mailjet oraz zapis dowodu przetwarzania w rejestrze audytowym.

**Dla kogo?** Dla każdego sprzedawcy na PrestaShop 8 lub 9, który przetwarza dane osobowe obywateli Unii Europejskiej i chce uniknąć ręcznej obsługi żądań usunięcia danych. Moduł jest dostarczany po francusku, angielsku, hiszpańsku i niemiecku.

## Instalacja

1. Zaloguj się do back office PrestaShop.
2. Przejdź do _Moduły → Menedżer modułów_, kliknij _Wgraj moduł_ i wskaż plik ZIP `dfaccountdelete-1.0.2.zip`.
3. Moduł zostaje zainstalowany i włączony automatycznie. Kliknij _Konfiguruj_.

Instalacja tworzy dwie tabele: `ps_dfad_log` (rejestr RODO) i `ps_dfad_token` (tokeny potwierdzenia e-mail). Rejestruje też moduł na hooku `displayCustomerAccount`, który dodaje blok „Usuń moje konto" w koncie klienta.

Jeśli masz dużo własnych szablonów, po instalacji sprawdź, czy blok „Usuń moje konto" faktycznie pojawia się w _Moim koncie_ po stronie sklepu. Twój motyw musi obsługiwać hook `displayCustomerAccount`, co jest spełnione w natywnym motywie Classic i w większości motywów komercyjnych.

## Konfiguracja ogólna

Ekran konfiguracji dzieli się na cztery panele: Ustawienia ogólne, Mailchimp, Brevo, Mailjet. Każdy panel zapisuje się niezależnie.

### Tryb usuwania

Do wyboru dwa tryby:

- **Anonimizuj** (zalecane): dane osobowe klienta (imię, nazwisko, e-mail, telefon, adresy, data urodzenia) są zastępowane wartościami anonimowymi. Zamówienia pozostają nietknięte, aby spełnić obowiązek przechowywania dokumentacji księgowej (w Polsce 5 lat liczone od końca roku podatkowego, we Francji 10 lat na podstawie artykułu L123-22 francuskiego Kodeksu handlowego, do którego odwołują się domyślne teksty modułu).
- **Usuń całkowicie, jeśli to możliwe**: konto zostaje skasowane w całości, o ile nie istnieją żadne zamówienia. Jeśli zamówienia istnieją, moduł automatycznie przełącza się w tryb anonimizacji, aby nie naruszyć historii wymaganej prawem.

Nawet w trybie „Usuń całkowicie" nie możesz usunąć konta, z którego złożono zamówienia. To obowiązek prawny w Polsce, we Francji i w całej Unii Europejskiej. Moduł obsługuje to przełączenie automatycznie i zapisuje w rejestrze RODO tryb faktycznie zastosowany.

### Obowiązkowe potwierdzenie e-mail

Włączone domyślnie (bardzo mocno zalecane). Klient musi kliknąć link otrzymany e-mailem, aby zatwierdzić swoje żądanie. Zapobiega to przypadkowemu usunięciu oraz usunięciu przez osobę trzecią, która uzyskała dostęp do otwartej sesji.

### Czas ważności tokenu

W godzinach. Domyślnie 24 godziny. Po tym czasie link w e-mailu wygasa, a żądanie zostaje automatycznie anulowane.

### Rejestrowanie

Włączone domyślnie. Moduł zapisuje w `ps_dfad_log` każde żądanie wyłącznie w postaci spseudonimizowanej: hash SHA-256 adresu e-mail, hash SHA-256 adresu IP, identyfikator klienta, zastosowany tryb, status, skontaktowani dostawcy, user agent, identyfikator sklepu, znacznik czasu. Żadne dane osobowe nie są przechowywane jawnie.

Tabela `ps_dfad_log` **nie** jest usuwana przy deinstalacji modułu. To działanie celowe: stanowi ona dowód przetwarzania w razie kontroli organu ochrony danych. Aby usunąć ją ręcznie, po deinstalacji wykonaj `DROP TABLE ps_dfad_log;`.

### Powiadamiany adres administratora

Adres, który otrzyma powiadomienie (wyłącznie hash adresu e-mail, nigdy adres jawnie) przy każdym skutecznym usunięciu. Domyślnie jest to adres sklepu.

## Konfiguracja platform newsletterowych

Moduł obsługuje w standardzie trzy platformy newsletterowe. Każdy dostawca jest domyślnie wyłączony. Włącz tylko te, z których korzystasz.

### Mailchimp

Podaj:

- **Klucz API** w formacie `xxxxxxxxxxxx-us21`. Sufiks (`-us21`, `-eu1` i tak dalej) to centrum danych Mailchimp. Moduł wykrywa je automatycznie.
- **List ID (Audience ID)**: identyfikator Twojej głównej audiencji. Znajdziesz go w Mailchimp w _Audience → Settings → Audience name and defaults_.
- **Trwałe usunięcie**: włączone domyślnie. Używa endpointu `POST /lists/{list_id}/members/{hash}/actions/delete-permanent`, który odpowiada prawdziwemu prawu do bycia zapomnianym z RODO: adres zostaje trwale usunięty, a Mailchimp odmówi każdego przyszłego zapisu na ten adres. Jeśli wolisz zwykłe zarchiwizowanie (adres może się wtedy zapisać ponownie), wyłącz tę opcję.

Kliknij _Testuj połączenie_, aby zweryfikować konfigurację. Przy poprawnych ustawieniach zobaczysz nazwę swojej audiencji.

### Brevo (dawniej Sendinblue)

Podaj:

- **Klucz API v3** w formacie `xkeysib-xxxxxx`. Znajdziesz go w Brevo w _Moje konto → SMTP & API → Klucze API_.
- **List ID** (opcjonalnie): jeśli podany, kontakt zostaje usunięty wyłącznie z tej listy. Jeśli pole jest puste, kontakt jest usuwany całkowicie (zalecane pod kątem RODO).

Używane endpointy: `DELETE /v3/contacts/{email}` przy pełnym usunięciu albo `POST /v3/contacts/lists/{id}/contacts/remove` przy usunięciu z jednej listy.

### Mailjet

Mailjet stosuje uwierzytelnianie Basic z dwoma kluczami. Podaj:

- **API Key**
- **API Secret**
- **Contact List ID** (opcjonalnie): jeśli podany, wypisanie dotyczy wyłącznie tej listy. Jeśli pole jest puste, kontakt jest usuwany przez oficjalny endpoint GDPR Mailjet.

Przepływ usunięcia w Mailjet ma dwa etapy: wyszukanie identyfikatora kontaktu przez `GET /v3/REST/contact/{email}`, a następnie `DELETE /v4/contacts/{id}` na endpoincie GDPR. Moduł obsługuje tę mechanikę automatycznie.

Jeśli platforma zwróci 404 przy usuwaniu, moduł traktuje to jako sukces (kontakt już nie istnieje, idempotencja). W rejestrze nie zobaczysz błędu.

## Anonimizacja czy usunięcie: co wybrać?

RODO nakłada obowiązek realizacji prawa do usunięcia danych, ale przepisy o rachunkowości nakładają obowiązek przechowywania dokumentów księgowych przez określony czas (w Polsce 5 lat od końca roku podatkowego, we Francji 10 lat). Te dwa obowiązki godzi **anonimizacja**, czyli podejście zalecane przez organy ochrony danych.

### Tryb anonimizacji

Moduł zastępuje w `ps_customer`:

- `firstname` na `Anonymized`
- `lastname` na `Customer`
- `email` na `anon-{id_customer}-{hash}@anonymized.local`
- `passwd` na losowy hash (klient nie będzie mógł się już zalogować)
- `birthday` na NULL
- `note`, `website`, `ip_registration_newsletter` na wartość pustą
- `active` na 0, `deleted` na 1

W przypadku adresów:

- Adresy niepowiązane z zamówieniami są usuwane w całości.
- Adresy powiązane z zamówieniami są anonimizowane (`firstname`, `lastname`, `address1`, `postcode`, `city`, `phone` i pozostałe pola zastąpione wartościami neutralnymi) i oznaczane jako `deleted = 1`.

### Tryb pełnego usunięcia

Jeśli klient nie złożył żadnego zamówienia: pełne usunięcie adresów, a następnie wywołanie `Customer::delete()`. W przeciwnym razie: automatyczne przełączenie w tryb anonimizacji. Żadna opcja nie pozwala wymusić usunięcia konta z zamówieniami, i jest to działanie celowe ze względów prawnych.

## Pełny przepływ żądania

1. Klient wchodzi w _Moje konto_ i klika blok „Usuń moje konto".
2. Trafia na stronę potwierdzenia z ramką ostrzegawczą, polem „Hasło" i polem wyboru „Rozumiem, że tej operacji nie da się cofnąć".
3. Wpisuje hasło i zaznacza pole. Moduł weryfikuje hasło przez klasę `PrestaShop/Core/Crypto/Hashing`.
4. Jeśli potwierdzenie e-mail jest włączone, moduł generuje losowy token o długości 32 bajtów (`random_bytes(32)`), zamienia go na 64 znaki szesnastkowe, zapisuje jego hash SHA-256 w `ps_dfad_token` i wysyła e-mail zawierający token jawnie w adresie URL.
5. Klient odbiera e-mail i klika link. Moduł odczytuje token z adresu, wylicza jego SHA-256 i sprawdza, czy istnieje w tabeli, czy nie wygasł i czy nie został już zużyty.
6. Token zostaje oznaczony jako zużyty (`consumed_at = NOW()`), aby uniemożliwić ponowne użycie.
7. Dla każdego włączonego dostawcy (Mailchimp, Brevo, Mailjet) moduł wywołuje API usunięcia i zapisuje wynik (kod HTTP, komunikat) w rejestrze.
8. Moduł czyści tabele PrestaShop: `ps_emailsubscription`, `ps_newsletter`, `ps_cart`, `ps_cart_product`, `ps_wishlist`, `ps_compare`, `ps_customer_thread`, `ps_customer_message`, `ps_guest`.
9. Zależnie od trybu i obecności zamówień konto jest anonimizowane albo usuwane.
10. Do `ps_dfad_log` trafia wiersz ze statusem `done`, faktycznie zastosowanym trybem i listą wyników dostawców.
11. Do skonfigurowanego administratora wysyłany jest e-mail z powiadomieniem (wyłącznie hash adresu).
12. Klient zostaje wylogowany i przekierowany na stronę potwierdzenia.

## Rejestr przetwarzania RODO

Ekran konfiguracji wyświetla 30 ostatnich żądań wraz z:

- identyfikatorem żądania,
- skróconym hashem e-maila (12 pierwszych znaków SHA-256),
- zastosowanym trybem (anonymize albo delete),
- statusem (awaiting_confirm, done),
- listą dostawców i ich kodem zwrotnym, na przykład `mailchimp:OK(200) | brevo:OK(204) | mailjet:OK(200)`,
- datą i godziną UTC.

Pełna tabela zawiera dodatkowo: hash SHA-256 adresu IP, user agent skrócony do 250 znaków, identyfikator sklepu oraz notatki wewnętrzne (obecność albo brak zamówień).

Aby wyeksportować pełny rejestr na potrzeby kontroli, odpytaj bazę bezpośrednio: `SELECT * FROM ps_dfad_log ORDER BY created_at DESC;`. W rejestrze nigdy nie pojawiają się dane jawne.

## Testowanie przed wdrożeniem produkcyjnym

Zalecana procedura przed włączeniem modułu na sklepie produkcyjnym:

1. **Test połączeń z dostawcami**: w back office modułu kliknij _Testuj połączenie_ dla każdej włączonej platformy. Powinieneś zobaczyć zielony komunikat z nazwą audiencji albo konta. W razie błędu wyświetlany jest dokładny komunikat HTTP zwrócony przez API.
2. **Test pełnego przepływu na koncie testowym**:
   - Utwórz konto klienta z prawdziwym adresem e-mail, który kontrolujesz.
   - Zapisz je do newslettera w Mailchimp, Brevo albo Mailjet ręcznie lub przez formularz w sklepie.
   - Sprawdź, czy adres widnieje na każdej platformie.
   - Zaloguj się na to konto po stronie sklepu i uruchom procedurę usunięcia.
   - Potwierdź przez otrzymany e-mail.
   - Sprawdź w `ps_customer`, czy konto zostało poprawnie zanonimizowane.
   - Sprawdź na każdej platformie newsletterowej, czy adres zniknął.
   - Sprawdź wpis w `ps_dfad_log`.
3. **Test przypadku „klient z zamówieniem"**: utwórz konto, złóż zamówienie testowe (1 €), a następnie uruchom usunięcie w trybie „Usuń całkowicie". Sprawdź, czy moduł przełączył się w anonimizację i czy zamówienie pozostało nienaruszone, ale z anonimowym adresem.

## Rozbudowa: dodanie nowego dostawcy

Architektura realizuje wzorzec Strategy. Dodanie Sendgrid, Mailerlite, HubSpot, ActiveCampaign albo dowolnej innej platformy wymaga wyłącznie utworzenia klasy.

Utwórz `classes/Provider/SendgridProvider.php`:

```
class DfAccountDelete_SendgridProvider extends DfAccountDelete_AbstractProvider
{
    public function getKey() { return 'sendgrid'; }

    public function isEnabled()
    {
        return (bool) Configuration::get('DFAD_SG_ENABLED')
            && Configuration::get('DFAD_SG_API_KEY');
    }

    public function deleteSubscriber($email)
    {
        $headers = ['Authorization: Bearer ' . Configuration::get('DFAD_SG_API_KEY')];
        $url = 'https://api.sendgrid.com/v3/marketing/contacts?emails=' . rawurlencode($email);
        $res = $this->http('DELETE', $url, $headers);
        return ['ok' => $res['ok'], 'status' => $res['status'], 'message' => $res['message']];
    }

    public function testConnection()
    {
        $headers = ['Authorization: Bearer ' . Configuration::get('DFAD_SG_API_KEY')];
        $res = $this->http('GET', 'https://api.sendgrid.com/v3/scopes', $headers);
        return ['ok' => $res['ok'], 'status' => $res['status'], 'message' => $res['message']];
    }
}
```

Wskaż klasę w `DfAccountDeleteService::getProviders()`:

```
public function getProviders()
{
    return [
        new DfAccountDelete_MailchimpProvider(),
        new DfAccountDelete_BrevoProvider(),
        new DfAccountDelete_MailjetProvider(),
        new DfAccountDelete_SendgridProvider(), // nowy
    ];
}
```

Następnie załaduj klasę na górze pliku `dfaccountdelete.php` przez `require_once`. Resztę (panel konfiguracji w back office, przycisk testu, wpięcie w przepływ usuwania) kodujesz analogicznie do istniejących dostawców.

## FAQ i rozwiązywanie problemów

### Klient twierdzi, że nie otrzymał e-maila z potwierdzeniem

Sprawdź: (1) czy konfiguracja SMTP PrestaShop działa (czy wychodzą inne e-maile transakcyjne, na przykład potwierdzenia zamówień), (2) czy e-mail nie trafił do spamu, (3) czy nie upłynął czas ważności. Klient może ponowić procedurę ze swojego konta, nowy token automatycznie unieważnia poprzednie.

### Platforma newsletterowa zwraca błąd 401

Klucz API jest nieprawidłowy albo wygasł. Wygeneruj go ponownie na danej platformie i zaktualizuj w konfiguracji modułu. Do natychmiastowej weryfikacji użyj przycisku _Testuj połączenie_.

### Pojawia się błąd SQL „LIMIT 1 LIMIT 1"

Korzystasz z wersji starszej niż 1.0.1. Zaktualizuj do najnowszej wersji, ten błąd został poprawiony w 1.0.1.

### Konto nie wygląda na zanonimizowane: imię, nazwisko i e-mail są nadal widoczne

Korzystasz z wersji starszej niż 1.0.2. Wewnętrzna walidacja PrestaShop w `Validate::isCustomerName()` odrzucała poprzednią wartość lastname, która zawierała znak `#` i cyfry, przez co aktualizacja kończyła się niepowodzeniem po cichu. Zaktualizuj do 1.0.2: aktualizacja naprawia również konta źle zanonimizowane przez wcześniejsze wersje.

### Jak usunąć rejestr RODO przy deinstalacji?

Tabela `ps_dfad_log` jest celowo zachowywana przy deinstalacji (dowód przetwarzania). Aby usunąć ją ręcznie po deinstalacji: `DROP TABLE ps_dfad_log; DROP TABLE ps_dfad_token;`.

### Czy moduł jest zgodny z moim obecnym modułem RODO (gdpr, psgdpr)?

Tak, oba moduły mogą współistnieć. Oficjalny moduł PrestaShop `psgdpr` służy głównie do eksportu danych i zarządzania zgodami, natomiast `dfaccountdelete` odpowiada za faktyczne usuwanie kont wraz z integracją newsletterową. Nie wchodzą sobie w drogę.

### Czy klient może się wycofać po kliknięciu przycisku?

Tak, dopóki nie kliknie linku w e-mailu potwierdzającym. Token wygasa automatycznie po skonfigurowanym czasie (domyślnie 24 godziny). W tym oknie konto pozostaje w pełni aktywne. Jeśli klient nic nie zrobi, żądanie zostaje anulowane.

### Jak dodać blok usuwania w innym miejscu niż Moje konto?

Możesz utworzyć bezpośredni link do `{shop_url}/{lang}/module/dfaccountdelete/delete` z dowolnej strony (stopka, strona regulaminu i tak dalej). Jeśli odwiedzający nie jest zalogowany, zostanie przekierowany na stronę logowania, a po uwierzytelnieniu wróci na stronę usuwania.

## Wersje i changelog

### 1.0.2: poprawka krytyczna

- **Fix**: `anonymizeCustomer()` używał `Customer::update()`, który przechodzi przez `Validate::isCustomerName()`. Ta walidacja zabrania cyfr i znaku `#` w firstname oraz lastname, przez co anonimizacja rekordu `ps_customer` kończyła się niepowodzeniem po cichu. Zastąpione bezpośrednim `UPDATE` SQL omijającym walidację.
- Aktualizacja `upgrade-1.0.2.php` naprawia wstecznie konta obsłużone przez wcześniejsze wersje, które pozostały niezanonimizowane.

### 1.0.1: poprawka

- **Fix**: `tableExists()` używał `Db::getValue()`, który automatycznie dokleja `LIMIT 1`. Zapytanie `SHOW TABLES LIKE 'xxx' LIMIT 1` jest nieprawidłowym SQL w MariaDB. Zastąpione przez `executeS()`.

### 1.0.0: wersja początkowa

- Zgodność z PrestaShop 8.0 do 9.x
- Tryb anonimizacji i tryb pełnego usunięcia
- Potwierdzenie e-mail z tokenem SHA-256
- Integracje Mailchimp, Brevo, Mailjet
- Rejestr przetwarzania RODO
- Interfejs i szablony e-mail po francusku, angielsku, hiszpańsku i niemiecku
