Webhooks

Webhooks

#Overview

Webhooks allow Hiboutik to automatically notify an external application when an event occurs on your account.

Instead of regularly querying the Hiboutik API to detect changes, you can configure an HTTP endpoint that Hiboutik will call when the corresponding event occurs.

Common use cases include:

  • synchronizing inventory after a sale;
  • synchronizing customers with an external system;
  • reacting to product updates;
  • processing payments or sale items;
  • synchronizing stock transfers;
  • triggering external workflows.

#Configuration

Webhooks can be configured from your Hiboutik account under:

Settings / API

Additional webhook configurations are available through the Hiboutik API.

On multi-store accounts, webhooks can be restricted to specific points of sale.

Webhooks can be processed synchronously or asynchronously.

#Receiving webhooks

Hiboutik sends webhook requests using HTTP POST.

The request body is encoded as:

Content-Type: application/x-www-form-urlencoded

The data contained in the payload depends on the webhook event.

#Webhook authentication

Webhook requests sent by Hiboutik are signed using HMAC-SHA256.

Each Hiboutik account has its own Webhook secret key, available under:

Settings / API → Webhook secret key

This key must be kept confidential.

#Signature header

The HMAC signature is sent in the following HTTP header:

X-HIBOUTIK-HMAC-SHA256: <signature>

The signature is calculated using:

  • the HMAC-SHA256 algorithm;
  • the account's Webhook secret key;
  • the exact URL-encoded HTTP request body sent by Hiboutik.

Conceptually:

HMAC-SHA256(raw_request_body, webhook_secret_key)

The resulting hexadecimal digest is sent in the X-HIBOUTIK-HMAC-SHA256 header.

#Verifying the signature

The signature should always be verified before processing the webhook data.

It is important to calculate the signature from the raw HTTP request body exactly as received.

Do not reconstruct the signed payload from parsed POST parameters. Parsing and serializing the parameters again may change their encoding or ordering and therefore produce a different signature.

#PHP example

<?php

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_HIBOUTIK_HMAC_SHA256'] ?? '';

$webhookSecretKey = 'YOUR_WEBHOOK_SECRET_KEY';

$expectedSignature = hash_hmac(
    'sha256',
    $payload,
    $webhookSecretKey
);

if (
    empty($signature) ||
    !hash_equals($expectedSignature, $signature)
) {
    http_response_code(401);
    exit('Invalid webhook signature');
}

parse_str($payload, $data);

// Process the webhook...

Using hash_equals() is recommended for comparing the received and expected signatures.

#Security considerations

The current webhook signature authenticates the HTTP request body.

The signature does not include a timestamp or a unique delivery identifier. There is currently no timestamp-based replay-protection mechanism associated with the webhook HMAC signature.

Webhook consumers should therefore implement appropriate safeguards according to their own security requirements and should be able to safely handle duplicate deliveries.

HMAC signature verification using X-HIBOUTIK-HMAC-SHA256 is the recommended method for authenticating incoming Hiboutik webhook requests.

#Webhook events and payloads

#sale

Triggered when a sale is closed.

The webhook contains the complete sale payload.

The exact fields therefore depend on the content of the sale and correspond to the sale data exposed by Hiboutik.

#sale_item

Triggered when a product line is added, deleted, or updated on a sale.

The type field identifies the operation.

Product added (type=add)

Field Description
order_id Sale identifier
sale_id Sale identifier
type add
line_item Sale line identifier
product_id Product identifier
product_size Product size identifier
quantity Quantity added
product_price Product price

Example:

order_id=12345
sale_id=12345
type=add
line_item=678
product_id=42
product_size=3
quantity=2
product_price=19.90

Product deleted (type=del)

Field Description
order_id Sale identifier
sale_id Sale identifier
type del
store_id Store identifier
line_item Sale line identifier
product_id Product identifier
product_size Product size identifier
quantity Quantity concerned by the deletion

Product line updated (type=update)

Field Description
order_id Sale identifier
sale_id Sale identifier
type update
store_id Store identifier
line_item Sale line identifier
product_id Product identifier
product_size Product size identifier
quantity Current quantity

Depending on the operation, the fields are not strictly identical. For example, product_price is sent when a product is added, while store_id is sent for deletion and update operations.

#payment

Triggered when a payment method is selected, added, deleted or modified on a sale.

Several payload formats can be sent depending on the payment operation.

Standard payment event

Field Description
sale_id Sale identifier
shop_id Store identifier
vendor_id User/vendor identifier
payment_type Payment method identifier
total Sale total
currency Sale currency

Cash tendered

Field Description
sale_id Sale identifier
shop_id Store identifier
vendor_id User/vendor identifier
total Sale total
action cash_tendered
cash_tendered Amount of cash tendered
cash_change Change returned
payment_type Payment method identifier
currency Sale currency

Additional / split payment

Field Description
sale_id Sale identifier
shop_id Store identifier
vendor_id User/vendor identifier
action_div add
payment_type Payment method identifier
payment_amount Payment amount
payment_detail_id Payment detail identifier
payment_date Payment date
currency Sale currency

The exact fields depend on the payment action. Consumers should not assume that every payment webhook contains all payment fields listed above.

#customer

Triggered when a customer record is created, modified, or deleted.

Field Description
customer_id Customer identifier
shop_id Store identifier
date_time Date and time of the event

The payload identifies the affected customer but does not contain the complete customer record.

If additional customer information is required, it can be retrieved through the Hiboutik API.

The payload itself does not indicate whether the customer was created, modified, or deleted.

#store_credit

Triggered when a store credit entry is added to a customer account.

Field Description
customer_id Customer identifier
credit_line_id Store credit line identifier
shop_id Store identifier
date_time Date and time of the event

#product

Triggered when a product is created, modified, deleted, or when a lightweight stock update occurs.

Product record change

Field Description
product_id Product identifier
shop_id Store identifier
date_time Date and time of the event

The payload identifies the affected product but does not contain the complete product record.

If additional product information is required, it can be retrieved through the Hiboutik API.

For this payload, the webhook itself does not indicate whether the product was created, modified, or deleted.

Lightweight stock update

Field Description
product_id Product identifier
shop_id Store identifier
action update_stock_light
size_id Product size identifier
warehouse_id Warehouse identifier
quantity Updated stock quantity
date_time Date and time of the event

#stock_order

Triggered when a stock order is received, unreceived, or when one of its product lines is updated.

Common fields

Field Description
inventory_input_id Stock order identifier
shop_id Store identifier
user_id Identifier of the user who performed the action
date_time Date and time of the event
event[label] Type of stock order event

Possible values for event[label] include:

  • stock_order_received
  • stock_order_unreceived
  • qtity_updated
  • product_line_received
  • product_line_unreceived
  • product_line_price_update

For qtity_updated, product_line_received, product_line_unreceived and product_line_price_update, the following additional fields are sent:

Field Description
event[inventory_input_detail_id] Stock order line identifier
event[product_id] Product identifier
event[product_size] Product size identifier
event[quantity] Quantity associated with the event

Example:

inventory_input_id=123
shop_id=1
user_id=12
date_time=2026-09-01+11%3A00%3A00
event[label]=product_line_received
event[inventory_input_detail_id]=456
event[product_id]=42
event[product_size]=3
event[quantity]=10

For product_line_price_update, the updated purchase price itself is not included in the webhook payload. Retrieve the stock order information through the Hiboutik API if the new value is required.

#stock_transfer

Triggered when a stock transfer between stores is confirmed.

Field Description
transfer_id Stock transfer identifier
shop_id Store identifier
date_time Date and time of the event

#line_item_exchange

Triggered when a product is returned or exchanged on a sale.

Field Description
sale_id Sale identifier
line_item_id Sale line identifier
warehouse_id Warehouse identifier
shop_id Store identifier
date_time Date and time of the event
vendor_id User/vendor identifier

#sale_creation

Triggered when a sale is created.

Field Description
order_id Sale identifier
sale_id Sale identifier
shop_id Store identifier
type sale_creation

#sale_deletion

Triggered when a sale is deleted.

Field Description
order_id Deleted sale identifier
sale_id Deleted sale identifier
shop_id Store identifier
type sale_deletion

#Synchronous webhooks

Synchronous webhook requests have a 4-second timeout.

The receiving endpoint must return:

HTTP 200 OK

The endpoint should perform only the operations required before acknowledging the request.

If processing may take longer, asynchronous webhooks should be used.

#Asynchronous webhooks

Asynchronous webhook requests have a 10-second timeout.

A successful delivery must return:

HTTP 200 OK

As soon as Hiboutik receives an HTTP 200 response, the webhook is considered successfully delivered and no further attempts are made.

If Hiboutik does not receive HTTP 200, for example because the endpoint returns another status code, the connection fails, or the request times out, another delivery attempt is scheduled.

Hiboutik performs up to 8 additional attempts, with an increasing delay between attempts.

Retry attempts stop immediately when an HTTP 200 response is received.

If no HTTP 200 response is received after all attempts, the webhook is abandoned.

Because asynchronous webhooks may be delivered more than once, webhook consumers should process requests idempotently whenever possible.

When receiving a Hiboutik webhook:

  1. Read the raw HTTP request body.
  2. Read the X-HIBOUTIK-HMAC-SHA256 header.
  3. Calculate the HMAC-SHA256 of the raw body using your Webhook secret key.
  4. Compare the calculated signature with the received signature using a timing-safe comparison.
  5. Reject the request if the signature is invalid.
  6. Parse the application/x-www-form-urlencoded payload.
  7. Process the webhook.
  8. Return HTTP 200 OK within the applicable timeout.

For asynchronous webhooks, the receiving application should also be designed to safely handle duplicate deliveries.

Envoyer un message

Nous contacter
  • 🇫🇷 +33 (0)1 48 78 40 06
  • 🇨🇭 +41 (0)21 519 00 17
  • 🇧🇪 +32 (0)2 318 82 77
  • 🇪🇸 +34 (0)912 69 39 94