formbasedocs
Aller à l'applicationAppli

Guides · API REST

Recevoir et vérifier le callback

Une demande avec une callbackUrl se termine par un POST signé vers cette URL : les réponses quand le destinataire soumet, ou l'annonce qu'elle a expiré ou a été annulée. Ce guide exécute un récepteur sur votre machine, vérifie la signature, et affiche les réponses.

Last checked


Il vous faut un token API et un formulaire publié, comme dans Envoyer une demande avec l’API REST, et Node ou Python sur votre machine. Ce que porte un callback, et comment fonctionnent les nouvelles tentatives, est dans Callbacks et signature.

1. Copiez le secret de signature

formbase signe chaque callback avec le secret de signature des demandes de votre espace de travail. Ouvrez OAuth et clés API dans la barre latérale de l’espace de travail et trouvez la carte Secret de signature des demandes :

La carte Request signing secret : Workspace secret, masqué sous la forme rqs_ suivi d'astérisques, avec des boutons pour l'afficher, le copier et le régénérer

Cliquez sur le bouton de copie et gardez le secret dans une variable d’environnement dans le terminal où votre récepteur s’exécutera :

bash
export FORMBASE_SIGNING_SECRET='rqs_...'

2. Écrivez le récepteur

Enregistrez la fonction verify depuis Callbacks et signature à côté de votre récepteur : sous verify.mjs pour Node, puisqu’il utilise import, ou sous verify.py pour Python. Le récepteur lit le corps brut, vérifie la signature, et ne parse le JSON qu’ensuite :

Hachez le corps exactement comme il est arrivé. Le parser puis le retransformer en JSON change les octets, et la signature ne correspond plus.

3. Exécutez-le et donnez-lui une URL publique

Démarrez le récepteur :

bash
node receiver.mjs      # or: python3 receiver.py

formbase n’appelle que des adresses HTTPS publiques, donc localhost ne suffira pas. Pendant que vous testez, un tunnel en donne une à votre machine.

Le tunnel rapide de Cloudflare

ne nécessite aucun compte. Exécutez-le dans un second terminal :

bash
cloudflared tunnel --url http://localhost:8787

Il affiche une adresse comme https://horn-cod-classics-arab.trycloudflare.com. ngrok et les outils similaires fonctionnent de la même façon. En production, utilisez plutôt l’URL HTTPS propre à votre serveur.

4. Envoyez une demande avec une URL de callback

Créez une demande de test comme dans le guide précédent, et ajoutez callbackUrl avec l’adresse du tunnel. Utilisez votre propre ID de formulaire :

bash
curl -X POST https://api.formbase.so/api/v1 \
  -H "Authorization: Bearer $FORMBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "requests.create",
    "params": {
      "formId": "jx75hdx8vb5hy1x85gm17nqgkn8f674g",
      "recipient": { "email": "ada@acme.example", "name": "Ada Lovelace" },
      "prefill": { "company_name": "Analytical Engines Ltd" },
      "readonly": ["company_name"],
      "externalId": "supplier-2044",
      "idempotencyKey": "supplier-2044",
      "callbackUrl": "https://horn-cod-classics-arab.trycloudflare.com/formbase",
      "test": true
    }
  }'

Utilisez une nouvelle idempotencyKey : la même clé avec un corps différent est rejetée. Ouvrez url depuis la réponse, répondez au formulaire, et soumettez.

5. Voyez le callback arriver

Quelques secondes après votre soumission, le récepteur affiche le type d’événement, votre ID externe et les réponses. Le récepteur Node affiche :

text
request.completed supplier-2044 {"certificate_of_incorporation":[{"name":"certificate-of-incorporation.pdf","size":635,"type":"application/pdf","url":"https://api.formbase.so/api/storage/...",...}],"company_name":"Analytical Engines Ltd","contact_email":"ada@acme.example","do_you_accept_our_30_day_payment_terms":"yes","vat_number":"GB123456789"}

Pour voir un rejet, envoyez vous-même n’importe quel POST au récepteur, par exemple curl -X POST -d ‘’ http://localhost:8787. Il n’a pas de signature valide, donc le récepteur affiche rejected: bad signature et répond 401.

Avant de passer en production

  • Répondez 2xx en moins de 10 secondes. formbase marque le callback comme livré sur n’importe quel 2xx. Un 5xx, un 408, un 429 ou un délai dépassé est retenté pendant environ quatre heures ; tout autre 4xx, comme le 401 ci-dessus, arrête les tentatives. Voir Nouvelles tentatives.

  • Bifurquez sur type.

    La même URL entend aussi request.expired et request.canceled, qui ne portent aucune réponse.

  • Traitez chaque événement une fois. Une nouvelle tentative porte le même id. Stockez les ids déjà traités et ignorez les répétitions.

  • Vérifiez test.

    Un callback venant d’une demande de test porte “test”: true. Retirez test de requests.create pour les destinataires réels.

Si votre récepteur était hors service plus longtemps que la durée des tentatives, les réponses ne sont pas perdues. Relisez-les avec requests.get, ou renvoyez le callback avec requests.replayCallback ou depuis la page Demandes.

Suite