# License keys and digital products: DataFirefly License Keys documentation

> Installation Install the module from Modules > Module Manager > Upload a module with the ZIP file, or copy the dflicensekeys folder into the shop /modules/ directory and click Install.…

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

## Installation

Install the module from **Modules > Module Manager > Upload a module** with the ZIP file, or copy the `dflicensekeys` folder into the shop `/modules/` directory and click Install. The PHP `openssl` extension is required.

On installation, the module creates its tables, registers its hooks and adds the **Catalog > License keys** menu. It also generates an encryption secret specific to the shop.

Keys are encrypted with a key that combines the PrestaShop cookie key (file `app/config/parameters.php`) and this secret. When you migrate or copy the shop, keep this parameters file: without it, the keys become unreadable. A red banner warns you if that happens.

Uninstalling keeps the keys, deliveries and secret, so that resetting the module does not empty your stock. Enable **Delete all keys, deliveries and files on uninstall** only if you want to erase everything.

## Module settings

### Delivery

- **Deliver when the order reaches**: statuses flagged as paid (Payment accepted, Remote payment accepted, Shipped, Delivered…) are selected at installation. A status change to one of them triggers delivery. Processing is idempotent: going through one of these statuses again does not send new keys.
- **Show the instant delivery notice on product pages**: small box under the price of digital products.
- **Send a copy of delivery emails to the alert address**: blind copy to the first alert address.

### Cancellations and refunds

With automatic revocation enabled, an order set to Canceled or Refunded (default statuses) has its keys revoked and its downloads blocked. Revoked keys never go back to stock on their own.

### Key stock

- **Sync the product quantity with available keys**: the PrestaShop quantity becomes the number of keys really free, meaning available keys minus those reserved by orders not delivered yet (bank transfer awaiting payment, for example) and minus the keys missing on waiting orders. With several keys per unit, the quantity is divided accordingly.
- **Low stock alert threshold** (5 by default) and **Alert email address(es)**: an alert is sent when available keys fall to this threshold or when an order is waiting for keys, at most once a day per product.

### Defaults for new digital products

**Download limit** (5 by default, 0 = unlimited) and **Link validity** in days (0 = no expiry), applied when a product is enabled.

### License API and activations

See the API section below. **Let customers free up activations from their account** is enabled by default.

## Setting up a digital product

Open the product page, **Modules** tab, **Digital delivery and license keys** block. The block is saved with its own **Save digital settings** button, independently from the product form. An "Unsaved changes" message is shown until you click it.

Set the product type to **Virtual product** so that no shipping is asked at checkout. The block reminds you if it is not the case.

### License keys

- **Key source**: imported stock only; imported stock, then generated automatically when empty; always generated automatically.
- **Key pattern**: used by the generator. `X` = letter or digit, `A` = letter, `9` = digit, other characters are kept as is. At least 8 random characters, 128 characters maximum. Ambiguous characters (0, O, 1, I) are never drawn.
- **License validity (days)**: 0 = lifetime license. The end date is calculated when each key is delivered.
- **Maximum activations per key**: 0 = unlimited. Enforced by the license API.
- **Keys per unit ordered**: 5 for a 5-license pack, for example.
- **Low stock alert threshold**: leave empty to use the global setting.
- **Manage a separate key stock for each combination**: useful for "1 year" and "3 years", or "Windows" and "Mac".

With automatic generation, the stock never runs out: the product quantity is no longer synced. Set a large quantity or allow orders when out of stock.

### Downloadable file

Upload the file (installer, PDF, archive). It is stored in the PrestaShop `/download/` folder under a random name and is never reachable directly. Set the **download limit per order line** and the **link validity**. Replacing the file also benefits customers already served.

### Activation instructions

Optional text per language, shown with the keys in the email and in the customer account. A green dot marks the filled languages.

## Importing and generating keys

From the product page (**Add keys to the stock** block) or from **Catalog > License keys > Import keys**:

- Paste the keys, one per line, or choose a TXT file (one key per line) or a CSV file (keys in the first column, `;`, `,` or tab separator). Tick **The first line of the file is a header** if needed.
- For a product managed per combination, choose the combination.
- The **batch label** (supplier invoice, for example) lets you find or export these keys later.

Duplicates, already in stock for this product or repeated in the list, are skipped. Keys longer than 1000 characters are rejected. A product that was not configured yet is enabled with the default settings. Orders waiting for keys are delivered right after the import, oldest first.

To generate a batch into the stock (up to 10,000 keys), enter the number and the pattern, then click **Generate**. Handy to feed your own license system or a reseller through the CSV export.

## What the customer receives

- **Delivery email** in the order language: keys, validity, download button with the remaining count, activation instructions. A new email is sent every time new keys are assigned (delayed delivery or replacement).
- **Order confirmation page**: keys are shown right away when payment is immediate, otherwise a message says they will be sent once payment is confirmed.
- **My account > My license keys**: every key of every order, with copy button, download links, validity and activated devices. The link only appears for customers who received at least one delivery.
- **Order detail and guest tracking**: the keys and downloads of the order. A guest customer gets the tracking link in the email.

An expired or exhausted download link shows a clear message inviting the customer to contact you.

## Managing an order in the back office

On the order page, the **License keys and downloads** panel shows each digital line with its keys, their validity, the activated devices, the downloads and the last five accesses (date, IP).

- **Deliver now / retry**: processes the order whatever its status. Useful for an order placed before the product was enabled, or when the employee who changed the status has no permission to view the module (PrestaShop then skips the module hooks).
- **Resend the email**.
- **Replace** a key: it is revoked and a new key is sent to the customer.
- **Reset downloads**: sets the counter back to zero and extends the link by the product validity.
- **Reset activations** of a key.
- **Revoke all** and **Reactivate**: reactivation restores the keys revoked with the order, not the ones replaced by hand.

## Catalog > License keys page

### Keys

The **Stock by product** table gives, for each product, the available, delivered and revoked keys and the waiting lines. Products with low stock are highlighted. The key list can be filtered by product, status, exact key, order reference or ID and batch. Keys are masked by default (eye button to show them, copy button). Actions: revoke and replace, return a revoked key to stock, delete an available or revoked key, reset activations, CSV export of the filtered keys.

### Deliveries

Every delivered or waiting line, waiting ones first, filterable by status, order reference or ID, or customer email. Actions: retry, resend, reset downloads.

## License API

Enable **Enable the license API** in the settings. The configuration page shows the API address, a curl example and the list of error codes.

Endpoint: `https://your-shop.com/module/dflicensekeys/api` (POST or GET). Parameters:

- `action`: `validate`, `activate` or `deactivate`.
- `license_key`: the key entered by the customer.
- `instance`: unique identifier of the device, domain or installation, required for activate and deactivate.
- `label`: optional readable name shown to the customer ("Office PC").
- `product_id`: optional, restricts the check to one product.
- `secret`: required only if **Require the API secret** is enabled. Enable it when only your server calls the API, not when the software calls it from the customer's computer.

The JSON reply contains `success`, `error` and a `license` object: `status` (active, revoked, expired), `product_id`, `product_name`, `purchased_at`, `expires_at`, `max_activations`, `activations`, `activated`.

```
curl -X POST "https://your-shop.com/module/dflicensekeys/api"
  -d action=activate
  -d license_key=ABCD-EFGH-JKLM-NPQR
  -d instance=7f3c9a1e-workstation
  -d label="Office PC"
```

Error codes: 404 `invalid_license` (unknown key or not sold yet), 403 `license_revoked` or `license_expired`, 403 `activation_limit_reached`, 400 `missing_instance` or `unknown_action`, 401 `invalid_secret`, 429 `too_many_failed_attempts` (more than 30 failures per hour from the same IP).

Call `activate` when the key is first entered, then `validate` with the same `instance` when the software starts. An activation already recorded for this device is never counted twice.

## GDPR and developer hooks

With the official psgdpr module, a customer data export includes their keys, dates, downloads and activated devices. Deleting a customer anonymises their deliveries and activations and erases the download log: the keys stay valid, since they were paid for.

Two hooks let you connect a CRM or an external license server:

- `actionDfLicenseKeysDelivered`: id_order, id_order_detail, id_customer, id_product, id_product_attribute, new_keys, keys (plain keys).
- `actionDfLicenseKeysRevoked`: id_order.

## Troubleshooting

### The customer did not receive their keys

Check that the order status is in **Deliver when the order reaches**, then click **Deliver now / retry** on the order. If the panel shows delivered keys, click **Resend the email** and check the PrestaShop email configuration.

### Orders stay "Waiting for keys"

The stock of the product (or combination) is empty. Import keys: waiting orders go out automatically. Check that the per-combination option matches the combination you import into.

### Keys show "[?]" and a red banner appears

The shop cookie key or the `DFLK_SECRET` setting has changed, often after a migration. Restore the previous `parameters.php` file.

### The download link says the file is temporarily unavailable

The file was removed from the product or deleted from the `/download/` folder. Upload it again from the product Modules tab.

### The product quantity is negative

Orders are waiting for more keys than the stock holds. Import keys and the quantity goes back up on its own.

## Compatibility

- PrestaShop 8.0 to 9.x, the same ZIP covers both branches, old and new product page.
- ModuleAdminController architecture, no Composer dependency, PHP 7.2 and above, openssl extension.
- Interface and emails in French, English, Spanish, German, Italian, Dutch, Polish and Portuguese.
