> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stockshift.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Recevez un POST signé dès qu'un événement se produit dans StockShift, au lieu d'interroger l'API pour le savoir.

Un point de terminaison webhook est une adresse à laquelle StockShift envoie des événements. Ajoutez-en un dans l'application sous **Paramètres > Webhooks**, ou avec les [opérations sur les points de terminaison webhook](https://docs.stockshift.io/fr-ca/api-reference/introduction.md) de l'API.

## Ajouter un point de terminaison

1. Appuyez sur **Nouveau point de terminaison**.
2. Entrez l'URL. Elle doit être en HTTPS et accessible sur Internet. Les adresses privées et locales sont refusées.
3. Cochez les événements voulus. La [liste des événements](https://docs.stockshift.io/fr-ca/api-reference/webhook-events.md) donne le corps de chacun.
4. Appuyez sur **Ajouter le point de terminaison**.
5. Copiez le secret de signature affiché. Il n'est affiché qu'une fois. **Renouveler le secret** en crée un nouveau.

**Envoyer un ping de test** envoie immédiatement un événement `webhook.ping` pour que vous puissiez vérifier votre point de terminaison.

## Ce que reçoit votre point de terminaison

Chaque événement est un `POST` avec un corps JSON :

```json theme={null}
{
  "id": "0199f2d4-6b1e-7c3a-9a51-2f0e8c1d4b7a",
  "type": "inventory.stock.adjusted",
  "created": "2026-10-29T14:03:11Z",
  "data": {}
}
```

Répondez avec n'importe quel `2xx` en moins de 10 secondes. StockShift ne suit pas les redirections.

Un événement peut arriver plus d'une fois et dans le désordre. Les nouvelles tentatives gardent le même `id` : enregistrez-le et ignorez les événements que vous avez déjà traités.

## Vérifier la signature

Vérifiez l'en-tête `StockShift-Signature` avant de vous fier au corps. Il ressemble à `t=1760000000,v1=5257a8...` :

* `t` est l'heure Unix à laquelle l'événement a été envoyé.
* `v1` est le HMAC-SHA256 de `<t>.<raw body>` calculé avec le secret de signature du point de terminaison, en hexadécimal.

Calculez le même HMAC sur le corps brut, exactement tel qu'il est arrivé, comparez-le en temps constant et rejetez tout ce dont le `t` date de plus de cinq minutes. Chaque SDK offre une fonction utilitaire qui fait tout cela :

```ts TypeScript theme={null}
import { verifyWebhook, WebhookVerificationError } from "@stockshift/sdk";

export async function POST(request: Request): Promise<Response> {
  try {
    const event = await verifyWebhook({
      payload: await request.text(),
      header: request.headers.get("StockShift-Signature"),
      secret: process.env.STOCKSHIFT_WEBHOOK_SECRET!,
    });
    if (event.type === "inventory.stock.adjusted") {
      console.log(event.data.item_id, event.data.quantity);
    }
    return new Response(null, { status: 204 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) {
      return new Response(null, { status: 400 });
    }
    throw error;
  }
}
```

```php PHP theme={null}
use StockShift\Sdk\Exception\WebhookVerificationException;
use StockShift\Sdk\Webhook;

try {
    $event = Webhook::verify(
        file_get_contents('php://input'),
        $_SERVER['HTTP_STOCKSHIFT_SIGNATURE'] ?? null,
        getenv('STOCKSHIFT_WEBHOOK_SECRET'),
    );
} catch (WebhookVerificationException) {
    http_response_code(400);
    exit;
}

http_response_code(204);
```

```python Python theme={null}
from stockshift import WebhookVerificationError, verify_webhook
from stockshift.models import InventoryStockAdjustedEvent


def receive(body: bytes, signature: str | None) -> int:
    try:
        event = verify_webhook(body, signature, os.environ["STOCKSHIFT_WEBHOOK_SECRET"])
    except WebhookVerificationError:
        return 400

    if isinstance(event, InventoryStockAdjustedEvent):
        print(event.data.item_id, event.data.quantity)
    return 204
```

```go Go theme={null}
verifier := stockshift.WebhookVerifier{Secret: os.Getenv("STOCKSHIFT_WEBHOOK_SECRET")}

http.HandleFunc("POST /webhooks/stockshift", func(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	event, err := verifier.Verify(body, r.Header.Get(stockshift.SignatureHeader))
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	fmt.Println(event.ID, event.Type)
	w.WriteHeader(http.StatusNoContent)
})
```

```rust Rust theme={null}
use stockshift::webhook::{EventData, Webhook};

fn receive(body: &[u8], signature: Option<&str>, secret: &str) -> u16 {
    let Ok(event) = Webhook::new(secret).verify(body, signature) else {
        return 400;
    };
    if let EventData::InventoryStockAdjusted(adjusted) = &event.data {
        println!("{} {}", adjusted.item_id, adjusted.quantity);
    }
    204
}
```

```csharp .NET theme={null}
app.MapPost("/webhooks/stockshift", async (HttpRequest request) =>
{
    using var reader = new StreamReader(request.Body);
    var payload = await reader.ReadToEndAsync();

    try
    {
        var webhookEvent = StockShiftWebhook.Verify(payload, request.Headers[StockShiftWebhook.SignatureHeader], secret);
        return Results.NoContent();
    }
    catch (WebhookVerificationException)
    {
        return Results.BadRequest();
    }
});
```

Dans une application Laravel, le [paquet Laravel](https://docs.stockshift.io/fr-ca/sdks/laravel.md) ajoute une route qui vérifie la signature et déclenche un événement Laravel pour chaque livraison.

## Nouvelles tentatives

Une livraison qui reçoit autre chose qu'un `2xx` est retentée après 1, 5, 30, 120, 360 et 720 minutes. Si elle échoue encore, ou si 24 heures s'écoulent, la livraison est marquée comme échouée, le point de terminaison est désactivé et les propriétaires de l'organisation reçoivent un courriel. Les événements qui surviennent pendant qu'un point de terminaison est désactivé ne sont pas envoyés plus tard.

La carte **Livraisons** d'un point de terminaison liste ses 50 dernières livraisons avec leur statut, leur code de réponse, leur durée et leurs tentatives. **Réessayer** renvoie une livraison échouée une fois de plus. Les livraisons sont conservées 30 jours.

Pour mettre un point de terminaison en pause, décochez **Activé** et appuyez sur **Enregistrer le point de terminaison**.


## Related topics

- [Événements webhook](https://docs.stockshift.io/fr-ca/api-reference/webhook-events.md)
- [Lister les événements webhook](https://docs.stockshift.io/fr-ca/api-reference/événements-webhook/lister-les-événements-webhook.md)
- [Réessayer une livraison de webhook](https://docs.stockshift.io/fr-ca/api-reference/webhooks/réessayer-une-livraison-de-webhook.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.