API Webhooks

Les webhooks permettent à votre application de recevoir des notifications HTTP en temps réel lorsque des événements se produisent dans votre boutique Mercozy. Au lieu d'interroger l'API, enregistrez une URL et Mercozy enverra automatiquement les données de l'événement.

Démarrage rapide

Commencez en 3 étapes :

Étape 1 : Enregistrez votre endpoint

Obtenez votre clé API depuis Paramètres > Intégration > Clés API. Autorisation admin requise. Le secret de signature du webhook (whsec_xxx) est généré automatiquement lors de la création d'un endpoint et affiché une seule fois.

bash
curl -X POST "https://api.mercozy.com/api/v1/external/webhooks" \
  -H "X-API-Key: mk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My ERP Integration",
    "url": "https://your-app.com/webhooks/mercozy",
    "events": ["order.created", "order.cancelled", "payment.received"]
  }'
Étape 2 : Traitez les événements entrants
javascript
app.post('/webhooks/mercozy', (req, res) => {
  // 1. Verify signature (see below)
  const signature = req.headers['x-webhook-signature'];
  if (!verifySignature(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // 2. Process the event
  const { type, data } = req.body;
  switch (type) {
    case 'order.created':
      syncOrderToERP(data);
      break;
    case 'payment.received':
      updateAccountingSystem(data);
      break;
  }

  // 3. Respond quickly with 200
  res.status(200).json({ received: true });
});
Étape 3 : Testez votre endpoint
bash
curl -X POST "https://api.mercozy.com/api/v1/external/webhooks/{id}/test" \
  -H "X-API-Key: mk_live_your_key_here"

Endpoints

GET

/webhooks

webhooks:read

Listez tous les endpoints de webhook enregistres.

POST

/webhooks

webhooks:write

Enregistrez un nouveau endpoint de webhook pour recevoir les notifications d'evenements.

PUT

/webhooks/:id

webhooks:write

Mettez a jour un endpoint de webhook existant (URL, evenements ou statut actif).

DELETE

/webhooks/:id

webhooks:write

Supprimez un endpoint de webhook. Les evenements ne seront plus livres.

Reference des Champs
ChampTypeObligatoireDescription

id

string

Non

Identifiant unique du webhook (lecture seule)

name

string

Oui

Un nom descriptif pour cet endpoint

url

string

Oui

URL du endpoint HTTPS pour recevoir les evenements de webhook

events

string[]

Oui

Tableau de types d'evenements a souscrire

secret

string

Non

Secret de signature pour la verification du payload (lecture seule, genere a la creation)

isActive

boolean

Non

Si le webhook est actif (defaut : true)

createdAt

datetime

Non

Horodatage ISO 8601 (lecture seule)


Types d'Evenements Disponibles

Mercozy prend en charge 18 types d'événements webhook dans 6 catégories. Abonnez-vous uniquement aux événements dont vous avez besoin.

Commandes
  • order.created

    Déclenché lors de la création d'une commande

  • order.updated

    Déclenché lors de la modification d'une commande

  • order.cancelled

    Déclenché lors de l'annulation d'une commande

  • order.completed

    Déclenché lorsqu'une commande est marquée comme terminée

  • order.status_changed

    Déclenché lors de tout changement de statut de commande

Paiements
  • payment.received

    Déclenché lors de la capture du paiement ou du paiement à la livraison

  • payment.refunded

    Déclenché lors d'un remboursement ou d'une annulation de paiement

Produits
  • product.created

    Déclenché lors de l'ajout d'un nouveau produit

  • product.updated

    Déclenché lors de la modification des détails du produit

  • product.deleted

    Déclenché lors de la suppression d'un produit

Inventaire
  • stock.low

    Déclenché lorsque le stock passe sous le seuil

  • stock.updated

    Déclenché lors du changement de quantité en stock

Clients
  • customer.created

    Déclenché lors de l'inscription d'un nouveau client

  • customer.updated

    Déclenché lors de la mise à jour des informations client

Livraisons
  • delivery.batch_started

    Déclenché lors du départ d'un lot de livraisons

  • delivery.batch_completed

    Déclenché lorsque tous les arrêts du lot sont terminés

  • delivery.completed

    Déclenché lorsqu'une livraison individuelle est terminée

  • delivery.failed

    Déclenché lors de l'échec d'une tentative de livraison


Payload du Webhook

Chaque livraison de webhook inclut le type d'evenement, l'horodatage et les donnees de la ressource concernee.

Données de l'événement de commande
json
{
  "id": "evt_clx1abc2def3",
  "type": "order.created",
  "timestamp": "2026-03-19T10:30:00Z",
  "data": {
    "id": "clx9order123",
    "orderNumber": "ORD-1042",
    "status": "PENDING",
    "total": 4999,
    "currency": "USD"
  }
}
Données de l'événement de paiement
json
{
  "id": "evt_clx2pay4ghi5",
  "type": "payment.received",
  "timestamp": "2026-03-19T10:35:00Z",
  "data": {
    "orderId": "clx9order123",
    "orderNumber": "ORD-1042",
    "amount": 4999,
    "currency": "USD",
    "paymentMethod": "CARD",
    "status": "CAPTURED"
  }
}
Données de l'événement de produit
json
{
  "id": "evt_clx3prod6jkl",
  "type": "product.created",
  "timestamp": "2026-03-19T11:00:00Z",
  "data": {
    "id": "clx9prod789",
    "name": "Organic Coffee Beans",
    "sku": "COF-001",
    "price": 1299,
    "status": "ACTIVE"
  }
}
Données de l'événement de livraison
json
{
  "id": "evt_clx4del7mno",
  "type": "delivery.completed",
  "timestamp": "2026-03-19T14:22:00Z",
  "data": {
    "orderId": "clx9order123",
    "orderNumber": "ORD-1042"
  }
}

En-têtes HTTP

Chaque requête webhook inclut les en-têtes suivants :

ChampTypeObligatoireDescription

Content-Type

string

Oui

application/json

X-Webhook-Signature

string

Oui

Signature HMAC-SHA256 : sha256={résumé_hexadécimal}

X-Webhook-Timestamp

string

Oui

Horodatage Unix en millisecondes

X-Webhook-ID

string

Oui

ID d'événement unique pour la déduplication

User-Agent

string

Oui

Mercozy-Webhook/1.0 (+https://www.mercozy.com/docs/webhooks)


Verification de Signature

Chaque webhook inclut un en-tête X-Webhook-Signature contenant une signature HMAC-SHA256. Vérifiez toujours cette signature avant de traiter l'événement pour vous assurer que la requête provient de Mercozy.

Node.js
javascript
const crypto = require('crypto');

function verifyWebhook(rawBody, signature, timestamp, secret) {
  // Signature is computed over "timestamp.body"
  const message = timestamp + '.' + rawBody;
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express middleware
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-webhook-signature'];
  const ts = req.headers['x-webhook-timestamp'];
  if (!verifyWebhook(req.body, sig, ts, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const event = JSON.parse(req.body);
  // Process event...
  res.status(200).json({ received: true });
});
Python
python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
    # Signature is computed over "timestamp.body"
    message = (timestamp + '.').encode() + payload
    expected = 'sha256=' + hmac.new(
        secret.encode(),
        message,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# Flask example
@app.route('/webhooks', methods=['POST'])
def handle_webhook():
    sig = request.headers.get('X-Webhook-Signature')
    ts = request.headers.get('X-Webhook-Timestamp')
    if not verify_webhook(request.data, sig, ts, WEBHOOK_SECRET):
        return 'Invalid signature', 401
    event = request.get_json()
    # Process event...
    return {'received': True}, 200
PHP
php
<?php
function verifyWebhook(string $payload, string $signature, string $timestamp, string $secret): bool {
    // Signature is computed over "timestamp.body"
    $message = $timestamp . '.' . $payload;
    $expected = 'sha256=' . hash_hmac('sha256', $message, $secret);
    return hash_equals($expected, $signature);
}

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
if (!verifyWebhook($payload, $signature, $timestamp, $webhookSecret)) {
    http_response_code(401);
    exit('Invalid signature');
}
$event = json_decode($payload, true);
// Process event...
http_response_code(200);
echo json_encode(['received' => true]);

Politique de réessai

Si votre endpoint renvoie un code de statut non-2xx ou expire (10 secondes), Mercozy réessaiera la livraison avec un backoff exponentiel :

ChampTypeObligatoireDescription

Tentative 1

Non

Immédiat

Tentative 2

Non

Après ~1s

Tentative 3

Non

Après ~4s

Après 3 tentatives échouées, la livraison est marquée comme échouée. Vous pouvez réessayer manuellement depuis le tableau de bord ou via l'API.


Bonnes pratiques

  • Répondez en moins de 5 secondesRenvoyez un statut 200 immédiatement et traitez l'événement de manière asynchrone. Le délai d'expiration de Mercozy est de 10 secondes.

  • Vérifiez toujours les signaturesVérifiez l'en-tête X-Webhook-Signature avant de traiter tout événement pour empêcher les requêtes usurpées.

  • Gérez les doublons (idempotence)Utilisez l'en-tête X-Webhook-ID pour dédupliquer les événements. Stockez les ID d'événements traités et ignorez ceux déjà gérés.

  • Utilisez des endpoints HTTPSMercozy exige des URL HTTPS en production pour protéger les données webhook en transit.

  • Journalisez et surveillezJournalisez tous les webhooks entrants et surveillez les échecs. Utilisez l'API de journaux de livraison pour vérifier le statut.