# DfPreorder SW — Full guide

> Shopware ships no native "notify me when back in stock" feature. DfPreorder SW fills that gap: on every sold-out product page, a subscription form appears automatically, and the customer receives…

- Page: <https://www.datafirefly.com/en/documentation/dfpreorder-sw/>
- Language: en
- Last updated: 2026-06-24
- Other languages: [fr](https://www.datafirefly.com/documentation/dfpreorder-sw/index.md), [es](https://www.datafirefly.com/es/documentation/dfpreorder-sw/index.md), [de](https://www.datafirefly.com/de/documentation/dfpreorder-sw/index.md), [it](https://www.datafirefly.com/it/documentation/dfpreorder-sw/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfpreorder-sw/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfpreorder-sw/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfpreorder-sw/index.md)
- Index: <https://www.datafirefly.com/en/documentation/llms.txt>

Shopware ships no native "notify me when back in stock" feature. DfPreorder SW fills that gap: on every sold-out product page, a subscription form appears automatically, and the customer receives an email alert — in their own language — as soon as the product returns. The plugin also adds a lightweight pre-order mode (badge and expected shipping date) and an admin module to track subscriptions. A single ZIP installs on Shopware 6.5, 6.6 and 6.7. This guide covers installation, asset compilation, the worker and scheduled task, configuration, storefront usage, pre-order mode, emails, the Store API, GDPR compliance and troubleshooting.

Compatible with Shopware 6.5.x, 6.6.x and 6.7.x on a single codebase. No Composer dependency is added. Unlike some plugins shipped with a pre-built dist, DfPreorder bundles the JavaScript sources: a storefront and administration build is required after installation (see below).

## How restock detection works

DfPreorder detects replenishments in two complementary ways, which converge on the same idempotent routine — so your customers are always notified, never twice:

- **Real time**: a subscriber listens to product writes and reacts as soon as stock or available stock changes.
- **Scheduled sweep**: a scheduled task runs every 15 minutes and catches stock updates made via direct SQL — typically the available-stock decrement on order placement, or an ERP import, which do not fire an application event.

The waitlist form appears on a product page when two conditions are met: the product is in closeout mode _and_ its available stock has dropped to zero.

## Installation

1. Download the `DfPreorder-v1.0.0.zip` archive from your DataFirefly account.
2. Copy the unzipped `DfPreorder` folder into `custom/plugins/`, or install the ZIP via **Administration → Extensions → My extensions → Upload extension**.
3. Install and activate the plugin: ``` bin/console plugin:refresh bin/console plugin:install --activate DfPreorder ```
4. Compile the storefront and administration assets (required step — no dist is shipped): ``` ./bin/build-storefront.sh ./bin/build-administration.sh ```
5. Clear the cache: ``` bin/console cache:clear ```

On installation, the plugin creates the `df_stock_notification` table, the `df_preorder` custom field set on the product entity, two email templates and the scheduled task. On uninstall without keeping data, everything is removed.

## Worker and scheduled task

For emails to actually go out, two mechanisms must be running — usually already the case in production via the admin-worker, systemd or cron:

- The **Messenger worker**, which consumes the async restock message and sends the emails;
- The **scheduled task scheduler**, which triggers the safety-net sweep every 15 minutes.

```
bin/console messenger:consume async --time-limit=60
bin/console scheduled-task:run
```

If neither the worker nor the scheduler is running, subscriptions are recorded but no email is sent. This is the number-one cause of "the plugin doesn't notify anyone". Check the admin-worker status under **Settings → System → Message queue** and the scheduled tasks under **Settings → System → Scheduled tasks**.

## Configuration

Open **Extensions → My extensions → DataFirefly Pre-order & Waitlist → ⋯ → Configure**. Every option can be set **per sales channel** using the native selector at the top of the page.

- **Enable waitlist**: master switch. Shows the form on sold-out product pages.
- **Double opt-in**: requires email confirmation before the subscription becomes active (recommended for GDPR). Off by default.
- **Allow guests**: if disabled, only logged-in customers can subscribe.
- **Delete entry after notification**: data minimization — the email address is erased once the alert has been sent. If off, the entry is kept with status "notified".
- **Notifications per batch**: maximum number of emails sent per run (worker or sweep). 100 by default.
- **Show pre-order badge**: enables the badge and shipping date on products configured for pre-order.

## The waitlist on the storefront

When a product is sold out (closeout + available stock at zero), the "Get notified when back in stock" form appears automatically below the buy button. The customer enters their email (pre-filled if logged in) and submits.

- Submission is done via **AJAX** with a full non-JavaScript fallback (flash message + redirect).
- An invisible **honeypot** field filters out bots.
- If **double opt-in** is enabled, a confirmation email is sent; the subscription only becomes active after the confirmation link is clicked.
- Each email can carry a **one-click unsubscribe link**.

The form is rendered in an overridable template: `views/storefront/component/df-waitlist/waitlist-form.html.twig`, injected via the buy widget. Override it in your theme to change its appearance or placement.

## Pre-order mode

The plugin creates a **Pre-order** custom field group on the product entity. Open a product in **Catalogues → Products**, tab **Specifications → Custom fields**, group **Pre-order**:

- **Enable pre-order**: activation switch for this product.
- **Expected shipping date**: the date shown in the badge.
- **Pre-order note**: free text shown below the badge.

When pre-order is enabled and the badge is allowed in the configuration, an amber badge appears above the buy button with the expected shipping date. The rendering is isolated in the buy-widget template and remains overridable.

## Emails and translations

Two email templates are created on installation and translated into five languages — French, English, German, Spanish and Italian:

- **Back in stock** (`df_preorder.back_in_stock`): variables `productName`, `productUrl` and the full `product` object.
- **Subscription confirmation** (`df_preorder.double_opt_in`): adds the `confirmUrl` variable.

Each customer is notified in the storefront language at the time of subscription: the plugin rebuilds a language context specific to the subscriber to resolve the translated product name and the right template. The product URL is resolved via the canonical SEO URL for the relevant channel and language.

The templates remain fully editable under **Settings → Emails → Email templates**. Search for "back in stock" to find them.

## Admin module

The **Marketing → Waitlist & Pre-order** menu lists all subscriptions: email address, product, status (pending / confirmed / notified), subscription date and notification date. Bulk delete is available, handy for manually purging old subscriptions.

## Store API (headless / mobile)

For headless stores or mobile apps, a Store API endpoint lets you subscribe a customer to the waitlist:

```
POST /store-api/df-waitlist/subscribe
Content-Type: application/json
sw-access-key: <your-access-key>

{
  "productId": "0189a1b2c3d4...",
  "email": "customer@example.com"
}
```

A valid request returns a success response; an invalid product id or email returns a 400 error. The same configuration rules apply (double opt-in, guest allowance, etc.).

## GDPR compliance

- Email addresses are collected solely for the requested notification.
- The optional double opt-in records explicit consent.
- Default behaviour deletes the personal data as soon as the alert is sent.
- A one-click unsubscribe link can be inserted into the email templates.
- Uninstalling with data removal erases the table, templates, custom fields and configuration.

## 6.5 → 6.7 compatibility and troubleshooting

**The form doesn't appear on a sold-out product.** Check that "Enable waitlist" is ticked for the right sales channel, that the product is in closeout mode, and that its available stock is zero. Clear the cache after any configuration change.

**Subscriptions are recorded but no email goes out.** The Messenger worker and/or the scheduler are not running. Run them manually to test (see the Worker section), then make sure they run continuously in production.

**Mail service error on activation on Shopware 6.7.** The abstract mail service class was replaced by a concrete class in 6.7. The plugin handles this difference automatically via a compiler pass that creates the right alias; a simple `cache:clear` recompiles the container if the error persists after an update.

**The email goes out in the wrong language.** The language used is that of the sales channel at the time of subscription. Check that the relevant channel has the expected language and that the email template has a translation for it.

**Emails appear to be sent twice.** This shouldn't happen: processing is idempotent and marks (or deletes) each entry after sending. If you observe it, check that you're not running several concurrent workers without the proper transport configuration.

**What happens on uninstall?** With the data-removal option, the `df_stock_notification` table, the two email templates, the `df_preorder` field set, the scheduled task and the configuration are removed. Without it, everything is kept for a later reinstall.
