Notifications
Wino envoie une requête POST avec un corps JSON à votre URL :
{
"kind": "Variant",
"source": {
"shopId": "20258224-05f3-49a7-9299-fab4acb89ee5",
"deviceId": "b1fd5f30-a879-40a0-9a86-46804c16ed12"
},
"data": {
"id": "4e584c64-a377-4689-aa01-7fbd32f12a44",
"…": "the properties of the variant"
},
"clientState": "<a secret of yours>"
}
| Champ | Description |
|---|---|
kind | Le type de données qui a changé : l'un des noms de settings. Il ne dit pas ce qui s'est passé (création, modification, archivage) : récupérez l'enregistrement pour voir son état actuel |
source.shopId | La boutique où le changement a eu lieu |
source.deviceId | L'appareil d'où le changement est remonté. Pour les changements faits via l'API, c'est l'appareil Web de la boutique (slug W), pas votre appareil : il ne vous dit pas qui a fait le changement |
data | L'enregistrement après le changement. Ses propriétés dépendent de kind et utilisent les noms de champs internes de Wino, pas toujours ceux de GraphQL. Ses dates sont des timestamps en millisecondes (GraphQL renvoie des dates ISO). data.id est toujours présent |
clientState | La valeur que vous avez définie sur l'abonnement |
D'autres propriétés peuvent apparaître : ignorez celles que vous n'utilisez pas.
Recevoir les notifications
- Répondez vite avec un statut
2xx. Wino attend 10 secondes au plus. Enregistrez la notification et traitez-la ensuite (une file d'attente, une tâche en arrière-plan). - Vérifiez
clientStatepar rapport au secret que vous avez défini, et ignorez les notifications qui ne correspondent pas. - Utilisez HTTPS, et donnez l'URL finale. Si votre URL redirige (par exemple de
httpvershttps), la notification arrive sous forme deGETsans corps. - Récupérez les données actuelles avec l'API GraphQL à partir de
data.id, plutôt que de vous fier uniquement àdata: c'est le moyen le plus sûr d'obtenir aussi les enregistrements liés. - Attendez-vous à des doublons et à n'importe quel ordre. Quand une livraison échoue (un statut d'erreur, ou pas de réponse sous 10 secondes), Wino renvoie la notification à chaque abonné de la boutique, et continue d'essayer pendant un moment : vous pouvez la recevoir à nouveau même après avoir répondu
2xx. Si votre URL continue d'échouer, Wino vous contacte par e-mail. Traitez deux fois la même notification sans dommage, par exemple en comparantdata.updatedAt(en millisecondes) avec la dernière que vous avez traitée. Un mouvement de stock ne change jamais : ignorez unStockActivitydont vous avez déjà ledata.id. - Ne réécrivez pas ce que vous avez déjà. Vous êtes aussi notifié des changements que fait votre intégration. Avant de réécrire un changement dans Wino, comparez-le avec vos propres données, et ne faites rien s'il est identique : c'est ce qui évite les boucles (vous mettez à jour le stock, êtes notifié, le mettez à jour à nouveau…). Pour les mouvements de stock (
StockActivity),data.deviceIdest l'appareil avec lequel le mouvement a été enregistré : l'ID de votre appareil pour les mouvements que vous créez.
Dans ces récepteurs, WINO_CLIENT_STATE contient le clientState de votre abonnement. Ils refusent de fonctionner sans lui : sinon une requête sans clientState passerait la vérification. queue représente votre propre file d'attente ou système de tâches.
- JavaScript
- PHP
- Python
import express from "express";
const clientState = process.env.WINO_CLIENT_STATE;
if (!clientState) throw new Error("Set WINO_CLIENT_STATE before starting");
const app = express();
app.use(express.json({ limit: "5mb" })); // the default 100 kB is too small for some notifications
app.post("/wino-webhooks", (req, res) => {
const notification = req.body;
if (notification.clientState !== clientState) {
return res.sendStatus(401);
}
queue.push(notification); // your queue or job system: process it later, outside the request
res.sendStatus(200);
});
app.listen(3000);
<?php
$clientState = getenv('WINO_CLIENT_STATE');
if (!$clientState) {
http_response_code(500); // WINO_CLIENT_STATE isn't set
exit;
}
$notification = json_decode(file_get_contents('php://input'), true);
if (($notification['clientState'] ?? null) !== $clientState) {
http_response_code(401);
exit;
}
// One file per notification, processed later by a script
$file = '/var/wino/queue/' . bin2hex(random_bytes(16)) . '.json';
if (file_put_contents($file, json_encode($notification)) === false) {
http_response_code(500); // not saved: Wino will send it again
exit;
}
http_response_code(200);
import os
from flask import Flask, request
CLIENT_STATE = os.environ.get("WINO_CLIENT_STATE")
if not CLIENT_STATE:
raise RuntimeError("Set WINO_CLIENT_STATE before starting")
app = Flask(__name__)
@app.post("/wino-webhooks")
def wino_webhooks():
notification = request.get_json()
if notification.get("clientState") != CLIENT_STATE:
return "", 401
queue.append(notification) # your queue or job system: process it later, outside the request
return "", 200