Recevoir des webhooks en local
Des événements live transmis à localhost, signés par Wajub et sans tunnel.
Votre localhost n'est pas accessible depuis Internet. Tester un handler de webhook nécessite donc
généralement un déploiement ou un tunnel. wajub listen ne fait ni l'un ni l'autre. Il ouvre un flux
depuis votre machine vers Wajub, puis renvoie les événements reçus vers l'URL locale choisie.
wajub listen --forward-to localhost:3000/webhooks/wajubAucun de vos services n'est exposé : ni URL publique, ni port entrant. La CLI récupère les données
de chaque événement auprès de l'API Wajub avec votre clé. Ces données ne transitent donc jamais par
la connexion temps réel, et rien n'est envoyé tant qu'aucun wajub listen ne tourne.
CLI 1.6.1 ou plus récente
Les versions antérieures de la CLI s'arrêtent avec un message qui demande la mise à jour :
npm install -g @wajub/cli@latest. Toutes les autres commandes continuent d'y fonctionner.
Ce que vous voyez
$ wajub listen --forward-to localhost:3000/webhooks/wajub
Ready! Streaming sandbox events for your account.
Your webhook signing secret is whsec_test_xxxxxxxxxxxxxxxx… (^C to quit)
It stays the same between runs: set WAJUB_WEBHOOK_SECRET=whsec_test_xxxxxxxxxxxxxxxx… in your app's .env once.
Forwarding to http://localhost:3000/webhooks/wajub
subscribed — waiting for events…
6:37:35 AM customer.created evt_test_NGHXbVLyHqPLOhNY3HKoXMca → 200 http://localhost:3000/webhooks/wajub
6:37:35 AM payment.created evt_test_wUpoY1JcMvjoUEs8FUdBkbuw → 200 http://localhost:3000/webhooks/wajub
6:37:36 AM payment.processing evt_test_7wP9Ty2ITqLSzVgWaU1VFH8U → 200 http://localhost:3000/webhooks/wajub
6:37:39 AM payment.succeeded evt_test_HObNwAnDRT54qb28OxW7fwQJ → 200 http://localhost:3000/webhooks/wajub
6:37:39 AM balance.updated evt_test_8pymkrpN71IQnazTsIwSxEVB → 200 http://localhost:3000/webhooks/wajub
6:37:39 AM fee.charged evt_test_u5zOJ37yKP2C0HSQZAKbUtme → 200 http://localhost:3000/webhooks/wajubLe nombre à droite est la réponse de votre propre endpoint. Un 500 indique donc l'échec de votre
handler, pas celui de la CLI. L'exécution ci-dessus correspond à un seul
wajub trigger payment.succeeded. Une commande a produit six événements, comme un véritable
paiement.
C'est le moyen le plus rapide de découvrir le nombre de types silencieusement ignorés par votre handler.
La requête transmise est un véritable webhook
Wajub construit et signe chaque livraison locale comme une livraison de production, et la CLI la
relaie à l'octet près : le corps JSON encodé comme en production, échappements compris, avec les
mêmes en-têtes. Seul pending_webhooks peut différer : il compte les livraisons encore en attente au
moment où la CLI récupère l'événement, alors qu'une livraison de production porte le compte du moment
de son envoi.
| En-tête | Valeur |
|---|---|
X-Wajub-Signature | v1= suivi du HMAC |
X-Wajub-Timestamp | Secondes Unix, incluses dans la chaîne signée |
X-Wajub-Event | Le type d'événement |
X-Wajub-Delivery-Id | whd_ suivi d'un UUID, identique pour chaque livraison d'un événement à cette écoute |
User-Agent | Wajub-Webhooks/1.0, comme en production |
Votre code de vérification s'exécute donc réellement en local, au lieu d'être ignoré derrière un
if (process.env.NODE_ENV === 'development') qui masque un défaut jusqu'à la production.
Comme le corps est celui de la production, un handler qui vérifie la signature sur le corps brut
réussit en local exactement quand il réussira une fois déployé. Les CLI antérieures à la 1.6.1
réencodaient le JSON et le signaient elles-mêmes : \/ et les caractères accentués pouvaient alors
différer.
Le secret de signature reste le même à chaque wajub listen pour ce compte et cet environnement :
un pour la sandbox, un pour le live. Placez-le une seule fois dans votre .env et votre handler
effectue la vérification sans autre modification. Ce n'est pas le secret d'un endpoint enregistré :
chaque endpoint garde le sien.
export WAJUB_WEBHOOK_SECRET=$(wajub listen --print-secret)
npm run dev--print-secret affiche le secret seul puis s'arrête, ce qui le rend utilisable dans un script.
Avec une clé live, ajoutez --live (wajub listen --live --print-secret) : sans lui la commande
échoue, et $(…) récupère alors un secret vide.
`--unsigned` supprime entièrement la signature
Cette option permet d'envoyer de force un payload dans un handler qui ne sait pas encore le
vérifier. Elle transmet les événements sans signature. Votre endpoint ne peut alors plus
distinguer Wajub de toute autre source capable de l'atteindre. Ne la laissez jamais dans un script
et ne l'utilisez jamais avec un endpoint également déployé. --skip-verify en est un alias
déprécié, qui le signale.
Si votre application répond sur une adresse https:// avec un certificat auto-signé ou émis par une
autorité locale, comme un site local avec un certificat auto-signé, ajoutez --insecure-tls.
La vérification du certificat est ignorée uniquement pour la transmission à votre handler ; les
appels de la CLI à l'API Wajub restent vérifiés. Faire pointer NODE_EXTRA_CA_CERTS vers votre
autorité locale fonctionne aussi.
Options
| Option | Effet |
|---|---|
--forward-to | Destination du POST. http:// est utilisé lorsque le schéma est absent |
--events | Types séparés par des virgules, jokers acceptés (payment.*), à la place de tous les événements |
--live | Obligatoire avec une clé live : les événements de vrais clients arrivent sur cette machine |
--print-secret | Affiche le secret de signature puis s'arrête |
--unsigned | Transmet sans signature. Consultez l'avertissement ci-dessus |
--insecure-tls | Accepte un certificat auto-signé ou d'une autorité locale sur une URL https:// de transmission |
--profile | Compte et environnement dont le flux est utilisé |
# Only what your handler currently implements
wajub listen \
--forward-to localhost:3000/webhooks/wajub \
--events "payment.*,refund.succeeded"
# Watch without forwarding anywhere
wajub listenSans --forward-to, la commande affiche les événements sans les envoyer. Utilisez-la pour vérifier
si un événement est émis avant d'accuser votre handler. Une valeur --events mal formée arrête la
commande avant tout démarrage, et Wajub n'envoie que les types demandés.
À connaître
L'environnement provient de votre profil. Une clé de sandbox diffuse les événements de la
sandbox. Une clé live diffuse les événements live, et seulement avec --live : les données de vrais
clients arrivent alors sur votre machine. wajub doctor indique le profil utilisé. --profile le
remplace pour une exécution.
Il faut une clé secrète, ou une clé restreinte avec event.read. La clé créée par wajub login
a un accès complet, sauf si vous la restreignez. Une clé publique ne peut pas écouter, et une clé
révoquée par wajub logout arrête un flux en cours en moins d'une demi-minute.
Aucun endpoint enregistré n'est nécessaire. Le flux est indépendant de POST /webhooks. Même
un compte sans endpoint transmet tous ses événements à wajub listen.
Il ne remplace pas vos endpoints enregistrés. Un endpoint live abonné aux mêmes événements continue de les recevoir. L'écoute ne détourne rien.
Vos écoutes apparaissent dans le Dashboard. Konsole › Webhooks liste chaque wajub listen en
cours pour l'environnement actuel, avec la réponse de votre handler aux derniers événements.
Il survit à la mise en veille. Une connexion morte sans prévenir est remplacée en deux minutes et demie au plus, et une session expirée pendant la veille de votre ordinateur est rouverte toute seule.
Vingt à la fois. Un compte peut avoir 20 sessions wajub listen ouvertes par environnement.
La vingt et unième répond 429 : la CLI attend les 30 secondes que demande son Retry-After et
réessaie, autant de fois que WAJUB_MAX_RETRIES le permet (deux par défaut), puis s'arrête en le
disant. Arrêter une commande avec ^C libère sa place aussitôt ; un terminal fermé sans ^C la libère
en 90 secondes au plus.
Un 503 signifie que le temps réel est indisponible. La plateforme n'a pas pu ouvrir le flux :
la commande s'arrête avant de commencer. Réessayez dans un instant ; si cela persiste, transmettez
au support l'identifiant de requête affiché par la CLI. Toutes les autres commandes continuent de
fonctionner.
Aucune donnée n'est mise en mémoire tampon. Les événements produits lorsque la commande est
arrêtée ne sont pas rejoués à son démarrage. Pour les récupérer, consultez
wajub events list et renvoyez ceux qui vous intéressent.
Les événements internes n'apparaissent jamais
Les événements que Wajub enregistre pour son propre usage ne sont jamais livrés : ils
n'atteignent jamais wajub listen et ne peuvent pas être renvoyés.
La boucle
Deux terminaux suffisent, sans toucher à un téléphone.
# 1: forward everything to your handler
wajub listen --forward-to localhost:3000/webhooks/wajub
# 2: make something happen
wajub trigger payment.succeeded
wajub trigger payment.failed --amount 2500Écrivez le handler, enregistrez, puis déclenchez de nouveau l'événement. La boucle dure quelques secondes, ce qui est précisément son intérêt.