# DataFirefly Push Pro — Komplettleitfaden

> DataFirefly Push Pro bringt native Web-Push-Benachrichtigungen zu PrestaShop 8 und 9, ohne jeden Drittanbieterdienst wie OneSignal und ohne Monatsabo. Diese Anleitung behandelt Installation, Erstkonfiguration, die neun Automatisierungen, den Kampagnen-Builder, Segmentierung,…

- Seite: <https://www.datafirefly.com/de/documentation/dfpushnotifications/>
- Sprache: de
- Aktualisiert am: 2026-06-28
- Weitere Sprachen: [fr](https://www.datafirefly.com/documentation/dfpushnotifications/index.md), [en](https://www.datafirefly.com/en/documentation/dfpushnotifications/index.md), [es](https://www.datafirefly.com/es/documentation/dfpushnotifications/index.md), [it](https://www.datafirefly.com/it/documentation/dfpushnotifications/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfpushnotifications/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfpushnotifications/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfpushnotifications/index.md)
- Index: <https://www.datafirefly.com/de/documentation/llms.txt>

DataFirefly Push Pro bringt native Web-Push-Benachrichtigungen zu PrestaShop 8 und 9, ohne jeden Drittanbieterdienst wie OneSignal und ohne Monatsabo. Diese Anleitung behandelt Installation, Erstkonfiguration, die neun Automatisierungen, den Kampagnen-Builder, Segmentierung, A/B-Tests, Umsatzzuordnung, Topics, den Posteingang, Webhooks und die Fehlerbehebung.

## 1. Überblick und Anwendungsfälle

Das Modul implementiert das Web-Push-VAPID-Protokoll (RFC 8292) nativ mit aes128gcm-Verschlüsselung serverseitig. Abonnements werden in Ihrer PrestaShop-Datenbank gespeichert, Sendungen gehen direkt von Ihrem Hosting aus, keine Daten laufen über einen Drittanbieterdienst.

Typische Anwendungsfälle:

- **Wiedergewinnung abgebrochener Warenkörbe**: drei gestaffelte Erinnerungen (1 h, 24 h, 72 h), ohne von der E-Mail des Besuchers abhängig zu sein.
- **Produktalarme**: wieder verfügbar, Preissenkung, Opt-in direkt auf der Produktseite.
- **Transaktional**: Bestellbestätigung, Versand, Bewertungsanfrage nach Lieferung.
- **Reaktivierung**: Geburtstag, inaktive Kunden, Neuheiten-Zusammenfassung.
- **Einmalige Kampagnen**: Sale, Launches, Black Friday, mit Segmentierung und A/B-Tests.

## 2. Voraussetzungen

- PrestaShop 8.0 bis 9.x
- PHP 7.4 minimum, 8.x empfohlen
- MySQL 5.7 minimum oder MariaDB 10.3
- **HTTPS Pflicht**: Die Web-Push-API der Browser funktioniert nur auf einer sicheren Origin. Nur `localhost` ist die Ausnahme für Entwicklungstests.
- Ein externer Cron, der alle 5 Minuten eine HTTP-URL aufrufen kann (Linux-Cron, geplante Aufgaben des Hosters, nativer PrestaShop-Cron, etc.)
- OpenSSL in PHP aktiviert (für die VAPID-Schlüsselgenerierung und die aes128gcm-Verschlüsselung)

**Warum HTTPS?** Alle Browser (Chrome, Firefox, Safari, Edge) weigern sich, einen Service Worker zu registrieren oder die Benachrichtigungsberechtigung auf einer HTTP-Seite zu gewähren. Das ist eine Browser-Einschränkung, keine des Moduls.

## 3. Installation

1. Laden Sie das ZIP `dfpushnotifications-v1.2.0-phase3.zip` aus Ihrem DataFirefly-Kundenbereich herunter.
2. PrestaShop-Backoffice → Module → Modul-Manager → **Modul hochladen** → ZIP auswählen.
3. Klicken Sie auf **Installieren**. Die Installation erstellt 14 Tabellen mit dem Präfix `ps_dfpush_*`, generiert ein einmaliges Cron-Token und registriert die BO-Tabs.
4. Ein neues Menü erscheint: **Verbessern → DataFirefly Push** mit 8 Tabs (Dashboard, Kampagnen, Automatisierungen, Queue, Abonnenten, Topics, Webhooks, Einstellungen).

## 4. VAPID-Schlüsselgenerierung

Die VAPID-Schlüssel identifizieren Ihren Server bei den Push-Services der Browser (FCM, Mozilla autopush, Apple push). Sie werden einmalig generiert und dürfen nach dem Go-Live nie mehr geändert werden (sonst werden alle Abonnenten unerreichbar).

1. Gehen Sie zu **DataFirefly Push → Opt-in & Einstellungen**.
2. Klicken Sie auf **VAPID-Schlüssel generieren**. Das Modul erstellt ein ECDSA P-256-Schlüsselpaar, das in der PrestaShop-Konfiguration gespeichert wird.
3. Geben Sie ein **VAPID Subject** ein: eine `mailto:`-URL mit Ihrer technischen Kontaktadresse (z. B. `mailto:admin@ihrshop.com`). Sie ist die Kennung, über die Push-Services bei Missbrauch Kontakt aufnehmen können.
4. Aktivieren Sie das Modul über den Schalter **Push-Benachrichtigungen aktiviert**.

**Sichern Sie Ihre Schlüssel.** Wenn Sie die VAPID-Schlüssel nach dem Launch neu generieren, werden alle bestehenden Abonnenten von den Push-Services mit einem 410-Gone-Code abgelehnt. Bewahren Sie ein Backup der PrestaShop-Datenbank vor jeder Schlüsselmanipulation auf.

## 5. Opt-in-Konfiguration

Der Tab **Opt-in & Einstellungen** steuert die Anzeige der Berechtigungsanfrage. Drei Stile stehen zur Verfügung:

- **Glocke**: eine schwebende Glocke unten rechts. Der Nutzer klickt, dann zeigt der Browser seine native Anfrage. Am wenigsten aufdringlich.
- **Banner**: ein dauerhaftes Banner oben oder unten auf der Seite mit zwei Schaltflächen (zulassen / ablehnen).
- **Modal**: ein zentriertes Modalfenster, sichtbarer, aber auch aggressiver.

### Auslöser

Um die Anfrage nicht ab der ersten Sekunde anzuzeigen (hohe Ablehnungsrate), wählen Sie einen Auslöser:

- **Verzögerung**: anzeigen nach X Sekunden (Standard 15 s)
- **Scroll**: anzeigen nach X % Seiten-Scroll (Standard 40 %)
- **Seiten**: anzeigen nach X angesehenen Seiten in der Session (Standard 2)

### Cooldown

Schließt der Besucher die Anfrage oder lehnt sie ab, verhindert ein Cooldown das erneute Anzeigen für N Tage (Standard 7). So wird der "Popup-Belästigungseffekt" vermieden, der Nutzer dazu treibt, die Domain dauerhaft zu blockieren.

### Tageslimit und Ruhezeiten

- **Max pro Tag**: maximale Anzahl an Benachrichtigungen pro Tag und Abonnent (Standard 3). Darüber hinaus weist die Versand-Queue überzählige Nachrichten stillschweigend ab.
- **Ruhezeiten**: Zeitraum, in dem keine Benachrichtigung zugestellt wird. Während dieses Zeitraums eingereihte Nachrichten werden auf den Morgen des ersten nicht-stillen Fensters umgeplant.

## 6. Cron: Einrichtung und Token

Der Cron steuert alle aufgeschobenen Vorgänge: Automatisierungen, Versand-Queue, Webhook-Versand, Bereinigung. Er muss alle 5 Minuten über eine token-geschützte HTTP-URL aufgerufen werden.

### Token

Bei der Installation wird ein eindeutiges Token erzeugt. Abrufen: **DataFirefly Push → Automatisierungen**, das blaue Banner oben zeigt die vollständige URL zum Kopieren in Ihren Cron.

### Beispiel Linux-Cron

```
*/5 * * * * curl -s "https://ihrshop.com/module/dfpushnotifications/cron?token=IHR_TOKEN" > /dev/null
```

### Bei jedem Tick ausgeführte Aufgaben

1. Zurücksetzen der täglichen Zähler (einmal pro Tag, beim Überschreiten von Mitternacht)
2. Ausführung der Automatisierungen mit fälliger Verzögerung (abgebrochene Warenkörbe 1 h / 24 h / 72 h, Geburtstag, Inaktivität, neue Produkte, geplante Bewertungsanfragen)
3. Auslösen geplanter Kampagnen, deren Datum erreicht ist
4. Versand-Queue abarbeiten (standardmäßig bis zu 50 Benachrichtigungen pro Batch, konfigurierbar)
5. Webhook-Queue abarbeiten (bis zu 100 pro Batch)
6. Bereinigung alter Einträge (sent > 60 Tage, Webhook-Log > 30 Tage)

Die Cron-Antwort ist ein JSON mit den Details jedes Schritts:

```
{
  "success": true,
  "tasks": {
    "reset_counters": "ok",
    "triggers": { "abandoned_1h": 12, "abandoned_24h": 4, "birthday": 2, "inactivity": 38 },
    "scheduled_campaigns": 1,
    "queue": { "processed": 50, "sent": 47, "failed": 2, "expired": 1 },
    "webhooks": { "processed": 8, "sent": 8, "failed": 0, "dropped": 0 },
    "cleanup": "ok"
  },
  "duration_ms": 1842
}
```

Falls Ihr Hoster keinen Cron bereitstellt, richten Sie einen kostenlosen Drittanbieterdienst (cron-job.org, EasyCron, cronless) ein, der dieselbe URL alle 5 Minuten aufruft.

## 7. Automatisierungen: die 9 Auslöser

Standardmäßig deaktiviert; aktivieren Sie sie einzeln über **DataFirefly Push → Automatisierungen**. Jede Karte zeigt Titel, Body und Statistiken. Klicken Sie auf **Bearbeiten**, um Text und Optionen anzupassen.

### Verfügbare Variablen

Je nach Auslöser können Sie in Titel und Body einfügen:

- `{first_name}`: Vorname des Kunden (leer bei anonymen Besuchern)
- `{cart_total}`: Betrag des abgebrochenen Warenkorbs, formatiert mit Währung
- `{order_reference}`: Bestellreferenz
- `{order_total}`: Gesamtbetrag der Bestellung
- `{product_name}`: Produktname (wieder verfügbar, Preissenkung)
- `{product_price}`: aktueller Produktpreis
- `{products_count}`: Anzahl neuer Produkte (Digest)

### Abgebrochener Warenkorb (3 Erinnerungen)

Drei unabhängige Auslöser: `abandoned_cart_1h`, `abandoned_cart_24h`, `abandoned_cart_72h`. Das Modul erfasst jede Warenkorbänderung in `ps_dfpush_cart_watch` und markiert den Warenkorb als konvertiert, sobald eine Bestellung validiert wird. Der Cron versendet jede Erinnerung zum fälligen Zeitpunkt, es sei denn, der Warenkorb wurde zwischenzeitlich konvertiert.

### Wieder verfügbar

Auf der Produktseite erscheint automatisch ein Button _Benachrichtigen, wenn wieder verfügbar_, sobald das Produkt vergriffen ist. Der Abonnent klickt, das Push-Opt-in wird bei Bedarf angefragt, dann legt das Modul einen Watcher in `ps_dfpush_product_watch` an. Sobald eine Bestandsänderung die verfügbare Menge über 0 anhebt, wird der Watcher benachrichtigt und als verarbeitet markiert.

### Preissenkung

Gleiches Prinzip mit dem Button _Benachrichtigen bei Preissenkung_. Der Watcher speichert den Referenzpreis zum Zeitpunkt des Opt-in. Die Benachrichtigung wird gesendet, sobald eine Produktaktualisierung den Preis unter 99 % des Referenzpreises bringt (eine Schwelle, die parasitäre Auslösungen durch Rundungen verhindert).

### Bestellbestätigung

Ausgelöst durch den Hook `actionValidateOrder`. Sofort gesendet, ohne Berücksichtigung der Ruhezeiten (transaktional). Direkter Link zur Bestelldetailseite.

### Versand

Ausgelöst durch `actionOrderStatusUpdate`, sobald der Status auf einen als _shipped_ markierten Zustand in PrestaShop wechselt. Link zu den Bestelldetails (mit Tracking, falls Sie ein Tracking-Modul nutzen).

### Bewertungsanfrage

Geplant X Tage nachdem die Bestellung in einen Zustand _delivery_ übergeht (Standard 7 Tage, im Auslöser-JSON konfigurierbar). Die Benachrichtigung wird mit zukünftigem `scheduled_at` in die Queue gestellt; der Cron stellt sie zur fälligen Uhrzeit zu.

### Geburtstag

Der Cron liest das Feld `birthday` des PrestaShop-Kunden und versendet die Benachrichtigung am Tag X zur konfigurierten Uhrzeit. Ein Deduplikator verhindert mehrere Sendungen im selben Jahr.

### Inaktivität

Identifiziert Abonnenten, deren `last_visit` mehr als N Tage zurückliegt (Standard 30). Zur Vermeidung von Belästigung wird ein Abonnent über diesen Auslöser höchstens einmal alle 30 Tage benachrichtigt.

### Neue Produkte

Täglicher Digest, gesendet zu einer konfigurierbaren Uhrzeit (Standard 10 Uhr). Das Modul aggregiert die in den letzten 24 Stunden erstellten Produkte und sendet eine Benachrichtigung mit dem Namen des ersten und der Gesamtzahl. Ideal für Shops, die regelmäßig Katalog hinzufügen.

## 8. Kampagnen-Builder

Für einmalige Aktionen: **DataFirefly Push → Kampagnen → Neue Kampagne**. Das Formular ist in fünf Abschnitte gegliedert.

### Inhalt

- **Kampagnenname**: interner Name (Abonnenten nie angezeigt)
- **Benachrichtigungstitel**: max. 80 Zeichen
- **Body**: max. 250 Zeichen
- **Click-URL**: wohin der Klick weiterleitet
- **Icon-URL**: kleines Logo (standardmäßig Ihr Shop-Logo)
- **URL des großen Bildes**: Hero-Bild, 1024 × 512 empfohlen (nur Chrome)
- **Badge-URL**: monochromes 72 × 72 PNG (Android)

### Aktionsschaltflächen

Bis zu zwei Schaltflächen mit Label und URL. Sie erscheinen unter der Benachrichtigung auf Chrome Desktop und Android. Ideal für mehrere CTAs (_Angebot ansehen_ / _Ignorieren_).

### Zielgruppe

Siehe Abschnitt Segmentierung weiter unten.

### Planung & Zustellung

- **Senden am**: Datum / Uhrzeit des Versands. Leer = sofort (beim nächsten Cron-Lauf).
- **Dringlichkeit**: `very-low`, `low`, `normal`, `high`. Beeinflusst die Priorität auf Push-Service-Seite.
- **TTL**: Lebensdauer in Sekunden (Standard 86400 = 24 h). Ist der Browser des Abonnenten länger offline, läuft die Benachrichtigung ab.
- **Interaktion erforderlich**: dauerhafte Benachrichtigung bis Klick oder manuelles Schließen (nur Chrome).

## 9. Segmentierung

Kombinierbar mit logischem UND. Alle Kriterien leer = keine Einschränkung.

| Kriterium | Wirkung |
| --- | --- |
| Sprachen | Der Abonnent spricht mindestens eine dieser Sprachen (angekreuzte Kästchen) |
| Länder | Beim Abonnieren erkanntes Land (basierend auf Sprache / IP / Geo) |
| Geräte | mobile / desktop / tablet (beim Abonnieren erkannt) |
| Browser | Chrome, Firefox, Safari, Edge, Opera, Samsung Internet |
| Kundengruppen | Der Abonnent ist mit einem PrestaShop-Kunden in mindestens einer der Gruppen verknüpft |
| Kaufhistorie | _Beliebig_ (Standard), _Hat gekauft_, _Hat nie gekauft_ |
| Aktiv in den letzten N Tagen | Letzter Besuch vor weniger als N Tagen (basierend auf `ps_dfpush_customer_activity`) |

Die Schaltfläche **Zielgruppengröße in der Vorschau** berechnet per AJAX die genaue Zahl passender Abonnenten. Nützlich, um vor dem Versand zu prüfen, dass das Targeting nicht zu restriktiv ist.

## 10. A/B-Tests

Auf jeder Kampagne definiert das Feld **% Zielgruppe für Variante B** den Anteil der Zielgruppe, der Variante B erhält (von 0 bis 50). Die Aufteilung ist deterministisch: Für eine gegebene `id_subscriber` erhält der Abonnent immer dieselbe Variante (basierend auf `id_subscriber % 100 < split`).

Variante B überschreibt nur die ausgefüllten Felder. Sie können z. B. nur den Titel ändern oder nur ein Bild testen. Statistiken werden getrennt gespeichert:

- `stats_delivered` / `stats_clicked` / `stats_revenue`: Variante A
- `stats_b_delivered` / `stats_b_clicked` / `stats_b_revenue`: Variante B

Die Spalten erscheinen in der Kampagnenliste mit einem _A/B_-Badge neben dem Namen.

## 11. Umsatzzuordnung

Schlüsselmechanismus des Moduls: Bestellungen mit den Benachrichtigungen verknüpfen, die sie ausgelöst haben.

### Ablauf

1. Das Modul sendet eine Benachrichtigung mit einem eindeutigen `track_token` (32 Hex-Zeichen) im Payload.
2. Der Service Worker fängt den Klick ab und leitet auf `/module/dfpushnotifications/track?t=TOKEN&click=1&u=URL` um.
3. Der `track`-Controller setzt ein Cookie `dfpush_attr=TOKEN` (30 Tage, SameSite=Lax) und leitet zur Ziel-URL um.
4. Der Kunde surft, legt in den Warenkorb, validiert die Bestellung.
5. Beim Hook `actionValidateOrder` liest der `AttributionService` das Cookie, findet die Benachrichtigung in `ps_dfpush_notifications`, schreibt `id_order` + `revenue` + `currency` in die Zeile.
6. Der Service erhöht `stats_revenue` (oder `stats_b_revenue` je nach Variante) auf der Kampagne oder dem Auslöser, feuert den Webhook `order.attributed` und löscht dann das Cookie.

### Grenzen der Zuordnung

- Festes 30-Tage-Fenster. Darüber hinaus erfolgt keine Zuordnung mehr.
- Ein Cookie pro Abonnent. Klickt der Nutzer vor dem Bestellen auf eine zweite Benachrichtigung, wird die letzte gutgeschrieben (_Last-Click_-Modell).
- Die Zuordnung setzt voraus, dass Klick und Bestellung im selben Browser stattfinden (das Cookie ist browsergebunden).
- Eine bereits zugeordnete Bestellung kann nicht erneut zugeordnet werden (das Feld `id_order > 0` verhindert Doppelzählung).

## 12. Topics

Topics sind thematische Abo-Kanäle, die Kunden in ihrem Konto aktivieren. Beispiel: _Aktionen_, _Neue Produkte_, _Bestandswarnungen_. Ein Abonnent, der nur _Aktionen_ ankreuzt, erhält nur die Kampagnen, die dieses Topic ansprechen.

### Topic erstellen

1. **DataFirefly Push → Topics → Neues Topic**
2. **Code**: interner Identifier ohne Leerzeichen (z. B. `flash_deals`)
3. **Anzeigereihenfolge**: Position in der dem Kunden gezeigten Liste
4. **Aktiv**: für Kunden sichtbar
5. **Standard-Opt-in**: bei der Anmeldung vorab angekreuzt
6. **Übersetzungen**: ein Name und eine Beschreibung pro installierter Sprache

### Topic in einer Kampagne ansprechen

Die Segmentierung enthält ein Kriterium _Topics_ im Resolver. Zur Aktivierung über die UI: derzeit nur per benutzerdefiniertem JSON (die Topics-Checkbox kommt in einem Minor-Update). Abonnenten ohne abonniertes Topic erhalten alles (Rückwärtskompatibilität).

## 13. In-App-Posteingang

Der Endpoint `/module/dfpushnotifications/inbox` gibt die 20 neuesten Benachrichtigungen des aktuellen Abonnenten als JSON zurück. Das Frontend öffnet diesen Posteingang über das einheitliche Modal, das aus dem Kundenkonto erreichbar ist (Kachel _Push-Benachrichtigungen_).

Das Modal zeigt auch den Abonnementstatus (mit Subscribe/Unsubscribe-Schaltfläche) und die Topic-Liste. So rufen Sie es manuell aus Ihrem Theme auf:

```
// Modal öffnen
window.dfpush.openManagePopup();

// Abonnement-Status prüfen
const isOn = window.dfpush.isSubscribed();
```

## 14. Webhooks

Webhooks senden Modulereignisse an Zapier, Make, n8n oder Ihr eigenes Backend. Jeder Webhook wird mit HMAC-SHA256 über den rohen Request-Body signiert.

### Webhook erstellen

1. **DataFirefly Push → Webhooks → Neuer Webhook**
2. **URL**: Ihr Endpoint (HTTPS empfohlen)
3. **Secret**: automatisch generiert, kopieren Sie es empfängerseitig
4. **Events**: kreuzen Sie unter den 8 verfügbaren Events die zuzustellenden an
5. Klicken Sie auf **Test-Ping senden**, um zu prüfen, dass Ihr Endpoint mit 2xx antwortet

### Verfügbare Events

- `subscriber.subscribed`: neues Opt-in
- `subscriber.unsubscribed`: Abmeldung
- `subscriber.expired`: Push-Service hat 410 Gone zurückgegeben
- `notification.sent`: Benachrichtigung erfolgreich zugestellt
- `notification.clicked`: Klick erfasst
- `notification.failed`: endgültiger Fehler nach 3 Versuchen
- `campaign.sent`: Kampagne abgeschlossen
- `order.attributed`: Bestellung mit einer Benachrichtigung verknüpft

### Payload-Format

```
{
  "event": "notification.clicked",
  "timestamp": "2026-05-28T14:32:18+00:00",
  "shop": 1,
  "data": {
    "id_subscriber": 482,
    "id_campaign": 12,
    "id_trigger": 0,
    "id_notification": 9182,
    "track_token": "abc123...",
    "url": "https://ihrshop.com/aktionen",
    "ab_variant": "A"
  }
}
```

### Gesendete HTTP-Header

- `Content-Type: application/json`
- `X-DfPush-Event: notification.clicked`
- `X-DfPush-Signature: sha256=`
- `X-DfPush-Timestamp: 1748443938`
- `User-Agent: DataFireflyPush/1.2`

### Signatur empfängerseitig prüfen

PHP-Beispiel:

```
$body     = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, $IHR_SECRET);
$received = explode('=', $_SERVER['HTTP_X_DFPUSH_SIGNATURE'])[1] ?? '';
if (!hash_equals($expected, $received)) {
    http_response_code(401);
    exit;
}
// Signatur gültig, Payload verarbeiten
$payload = json_decode($body, true);
```

### Retry und Drop

Antwortet Ihr Endpoint mit etwas anderem als 2xx, versucht das Modul es mit exponentiellem Backoff bis zu 5-mal erneut. Danach wird das Log als _dropped_ markiert und das Event geht verloren. _Sent_- und _dropped_-Logs werden nach 30 Tagen bereinigt.

## 15. Multishop und mehrsprachig

Alle Abonnenten, Kampagnen, Automatisierungen, Topics und Webhooks sind an eine `id_shop` gebunden. Im Multishop:

- Wählen Sie den Zielshop im Backoffice-Selektor, bevor Sie eine Kampagne oder Automatisierung erstellen
- Der Cron ist einmalig, filtert aber automatisch nach Shop
- VAPID-Schlüssel werden shopübergreifend geteilt (ein einziges Paar für alle)

Auf der Sprachseite: Das Modul wird in DE, EN, FR, ES und IT geliefert. Die Sprache des Abonnenten wird beim Abonnieren erkannt und gespeichert. Sie können in Kampagnen nach Sprache segmentieren.

## 16. DSGVO und Best Practices

- **Einwilligung**: Das Abonnement beruht auf dem nativen Browser-Opt-in, das ein DSGVO-konformer Einwilligungsnachweis ist.
- **Personenbezogene Daten**: Das Modul speichert den Web-Push-Endpoint, die IP zum Anmeldezeitpunkt, den User-Agent, Sprache und Land. Keine Übermittlung an Dritte.
- **Abmeldung**: Ein Klick auf den Button _Abbestellen_ im Modal oder das Deaktivieren der Benachrichtigungen im Browser setzt den Abonnenten in den Status `revoked`.
- **Recht auf Löschung**: Das Löschen eines Kundenkontos im BO entfernt auch die verknüpften Abonnenten.
- **Ruhezeiten**: standardmäßig 22 Uhr - 8 Uhr. Passen Sie sie an Ihre Zielgruppe an (B2B = Bürozeiten, B2C = Abend).
- **Tageslimit**: standardmäßig 3/Tag. Darüber hinaus sehr hohe Abmelderate.

## 17. Fehlerbehebung

### Das Opt-in erscheint nicht

- Prüfen Sie, dass Ihre Seite HTTPS verwendet (nicht HTTP).
- Prüfen Sie, dass die VAPID-Schlüssel generiert sind (**Einstellungen**).
- Prüfen Sie, dass der Schalter **Push-Benachrichtigungen aktiviert** an ist.
- Öffnen Sie die Browser-Konsole (F12) und suchen Sie nach Fehlern in `dfpush-frontend.js`.
- Haben Sie die Anfrage bereits abgelehnt oder ignoriert, blockiert der Cooldown für N Tage. Löschen Sie die Cookies der Domain zum Zurücksetzen oder testen Sie in einem anderen Browser.

### Der Cron läuft nicht

- Rufen Sie die URL manuell im Browser auf: Sie sollten ein JSON mit `success: true` sehen. Bei `403 invalid_token` ist das Token falsch übernommen.
- Prüfen Sie die letzte Ausführung im Dashboard (**Dashboard**, Block _System_).
- Bei manchen Hostern beträgt das cURL-Timeout der Crons 30 s. Ist die Queue sehr groß, erhöhen Sie die Cron-Frequenz auf alle 1 bis 2 Minuten, um kleinere Batches zu verarbeiten.

### Benachrichtigungen gehen nicht raus

- Tab **Queue**: Sind die Zeilen in _pending_, ist der Cron seit ihrer Erstellung nicht gelaufen.
- Sind sie in _failed_, klicken Sie auf die Zeile, um den HTTP-Code und die Fehlermeldung des Push-Service zu sehen.
- `410 Gone` = das Abonnement ist nicht mehr gültig (Nutzer hat sich abgemeldet oder den Browser geleert). Das Modul markiert den Abonnenten automatisch als _expired_.
- `429 Too Many Requests` = Rate-Limit auf Push-Service-Seite. Das Modul versucht es automatisch mit Backoff erneut.

### Bestellungen werden nicht zugeordnet

- Prüfen Sie, dass Third-Party-Cookies vom Browser des Kunden nicht blockiert sind (privater Modus, manche Anti-Tracker).
- Das Cookie läuft nach 30 Tagen ab: Eine Bestellung 31 Tage nach dem Klick wird nicht zugeordnet.
- Sehen Sie `id_order = 0` in `ps_dfpush_notifications`, obwohl die Bestellung getätigt wurde, prüfen Sie, dass die `actionValidateOrder`-Hooks korrekt registriert sind (**Module → Hooks → actionValidateOrder**).

### SQL-Fehler mit "LIMIT 1 LIMIT 1"

Interner Bug in 1.2.0 behoben (`Db::getValue` und `Db::getRow` hängen ihr eigenes `LIMIT 1` automatisch an). Sehen Sie diesen Fehler weiterhin, prüfen Sie, dass Sie die neueste Modulversion installiert haben.

## 18. FAQ

### Wie viele Abonnenten kann das Modul verwalten?

Das Modul hat keine codierte Obergrenze. Praktisch ist der limitierende Faktor die Cron-Ausführungszeit: Rechnen Sie auf einem Standard-Shared-Hoster mit etwa 50 Sendungen pro Minute (durch die Push-Services begrenzt). Für 10 000 Abonnenten planen Sie beim Versand einer großen Kampagne einen Cron alle 1 bis 2 Minuten.

### Ist Safari iOS wirklich ausgeschlossen?

Safari iOS unterstützt Web Push seit iOS 16.4, aber nur für als PWA auf dem Startbildschirm installierte Sites. In einem klassischen Safari gibt die `Notification`-API `undefined` zurück. Das ist eine Apple-Einschränkung, keine des Moduls.

### Kann ich meine Abonnenten von OneSignal oder Firebase migrieren?

Nein. Push-Endpoints sind an das beim Abonnieren genutzte VAPID-Schlüsselpaar gebunden. Ändern Sie das Paar, werden bestehende Abonnements ungültig. Eine Migration würde eine erneute Anmeldung der Nutzer erfordern.

### Funktioniert das Modul mit PrestaShop 1.7?

Nein, nur PrestaShop 8.0 bis 9.x. Version 1.7 nutzt eine andere Admin-Architektur, die einen eigenen Fork erfordern würde.

### Kann ich den Service Worker anpassen?

Ja, die Datei `views/js/sw-template.js` wird vom Controller `swjs.php` gerendert und kann erweitert werden. Achtung: Jede Service-Worker-Änderung erfordert ein neues `register()` auf Client-Seite. Bestehende Besucher behalten die vorherige Version, bis der Browser die Änderung erkennt (in der Regel 24 h).

### Wie exportiere ich die Abonnenten?

Tab **Abonnenten**, Button **CSV exportieren**. Die Datei enthält Endpoint, Browser, Gerät, Sprache, Land, Anmeldedatum und Sende-/Klick-Zähler.

## Support

Für alle Fragen, die diese Anleitung nicht abdeckt, kontaktieren Sie den DataFirefly-Support. Zur Fehlermeldung fügen Sie bitte Details Ihrer PrestaShop- und PHP-Version sowie den Inhalt der Cron-JSON-Antwort bei.
