# DataFirefly Webhooks — Complete Guide

> Overview DataFirefly Webhooks connects your PrestaShop 8 and 9 store to 5000+ apps, in both directions. Outbound, your store emits events (orders, customers, stock…) to Zapier, Make, n8n or any…

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

## Overview

DataFirefly Webhooks connects your PrestaShop 8 and 9 store to 5000+ apps, in both directions. **Outbound**, your store emits events (orders, customers, stock…) to Zapier, Make, n8n or any HTTP endpoint. **Inbound**, those same tools can push data into the store through a secured API.

The module rests on three pillars: an **async queue** (no order ever slowed down), **automatic retries** with exponential backoff, and **HMAC-SHA256 signing** to guarantee message authenticity.

You don't need any paid plan on Zapier, Make or n8n to get started: any service able to receive or send an HTTP webhook works.

## Installation

1. Download the `dfwebhooks.zip` archive from your DataFirefly account.
2. In the back office, go to _Modules > Module Manager > Upload a module_ and drop the ZIP.
3. Click _Install_, then _Configure_.
4. You land on the main screen showing the cron worker URL and the inbound API URL.

## 1. Schedule the cron worker (outbound flow)

Outbound webhooks are not sent immediately: they are queued and delivered by a worker you trigger periodically. Copy the cron URL shown on the configuration screen and schedule it every 1 to 5 minutes.

```
*/2 * * * * curl -s "https://your-store.com/index.php?fc=module&module=dfwebhooks&controller=cron&token=YOUR_TOKEN" >/dev/null 2>&1
```

On each run, the worker processes up to 50 pending deliveries, applies the necessary retries and purges old logs according to the configured retention.

The token in the URL protects access to the worker. Do not share it or expose it publicly. You can use an external service (cron-job.org, EasyCron) if your hosting has no cron tasks.

## 2. Create an outbound endpoint

An endpoint links an **event** to a **destination URL**. From the main screen, click _Add_, then fill in:

- **Name**: an internal label (e.g. "New order → Zapier").
- **Event**: the trigger event (see the list below).
- **URL**: paste the "Catch Hook" URL from Zapier or "Custom Webhook" from Make.
- **Signing secret** (optional): if set, every payload is signed with HMAC-SHA256.

### Conditional filters

You can send a webhook only when certain conditions are met. Rules are in JSON and combined with logical AND. Available operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `contains`.

```
[{"field":"order.total_paid","op":"gte","value":100}]
```

This example fires the webhook only for orders whose total paid is greater than or equal to 100.

### Field mapping

By default the full payload is sent. To send only certain fields in a precise shape, define a mapping: the key is the output name, the value is the path inside the payload.

```
{"email":"customer.email","total":"order.total_paid"}
```

## 3. Available outbound events

- `order.created` — an order has just been validated.
- `order.status.updated` — an order's status changes.
- `order.refunded` — an order moves to the refunded status.
- `customer.created` — a new customer signs up.
- `address.created` — a new address is created.
- `product.created` — a product is added.
- `product.updated` — a product is modified.
- `product.stock.low` — stock drops below the configured threshold.
- `review.created` — a review is approved (requires a compatible reviews module).

The low-stock threshold is set in the _Settings_ panel of the main screen, alongside the log retention duration.

## 4. Inbound API (Zapier/Make/n8n → PrestaShop)

The inbound API lets your automations modify the store. It is protected by a token and, optionally, an HMAC signature.

### Create a token

In the _Inbound tokens_ panel, give it a label, choose the allowed scopes (`orders`, `products`, `customers`) and, if you wish, a signing secret. The generated token goes into your tool.

### Send a request

Make a `POST` to the inbound API URL. The token goes in the `X-DF-Token` header (or as a `?token=` parameter). The body is JSON with an `action` and a `data` object.

```
POST https://your-store.com/index.php?fc=module&module=dfwebhooks&controller=api
X-DF-Token: YOUR_TOKEN
Content-Type: application/json

{"action":"order.status.update","data":{"id_order":42,"id_order_state":4}}
```

## 5. Available inbound actions

- `order.status.update` (scope orders) — changes an order's status. Fields: `id_order`, `id_order_state`, `send_email` (optional).
- `order.get` (scope orders) — fetches an order. Field: `id_order`.
- `product.stock.update` (scope products) — sets stock. Fields: `id_product`, `quantity`, `id_product_attribute` (optional).
- `product.upsert` (scope products) — creates or updates a product by its `reference`.
- `customer.upsert` (scope customers) — creates or updates a customer by their `email`.
- `customer.get` (scope customers) — fetches a customer by `email` or `id_customer`.

An **anti-loop guard** is active while inbound requests are processed: the changes they cause never re-fire an outbound webhook. No risk of an infinite loop between your store and your automations.

## 6. Verify the HMAC signature

If a secret is configured on the endpoint (outbound) or the token (inbound), the message carries an `X-DF-Signature: sha256=...` header. To verify it on reception, recompute the HMAC of the raw body with your secret and compare in constant time.

```
$expected = "sha256=" . hash_hmac("sha256", $rawBody, $secret);
if (hash_equals($expected, $signatureHeader)) {
    // valid signature
}
```

Always compute the HMAC over the **raw body** (not a re-serialized one), otherwise the signature will not match.

## 7. Delivery log and replay

The _Webhooks Delivery Log_ menu lists every attempt with its status:

- **SENT** — delivered with an HTTP 2xx code.
- **PENDING** — queued, waiting for the next worker run.
- **FAILED** — temporary failure, a retry is scheduled.
- **DEAD** — permanent failure after 6 attempts.

Retries follow an exponential backoff: 1 minute, 5 minutes, 30 minutes, 2 hours, then 6 hours. You can force a new send at any time via the _Replay_ button, and inspect the exact payload from the _View_ action.

## 8. Multistore, GDPR and batch mode

Every endpoint and every token is scoped to a specific shop: one shop's flows never leak into another. The **Anonymize personal data** option masks emails, phones and names before sending, to stay GDPR-compliant when the destination must not receive identifying data. **Batch mode** groups sends for high volumes.

## FAQ and troubleshooting

**No webhook is sent.** Check that the cron worker is scheduled and that its URL (with the right token) responds. Check the log: if rows stay PENDING, the cron is not running.

**The remote endpoint returns a 401/403 error.** Your tool may expect a signature check: set the same secret on both sides, or remove it during testing.

**The inbound API returns "insufficient_scope".** The token used lacks the scope required by the action. Edit the token to tick the matching scope (orders, products or customers).

**The test button shows a failure.** The _Test_ button sends a sample payload synchronously: a failure usually means an unreachable URL or an invalid TLS certificate on the destination.
