Intégration iframe
Embarquez le flow de signature dans votre app via une iframe sécurisée.
Signlift expose une page de signature /sign/:token que vous pouvez intégrer
directement dans votre interface via une iframe. Le signataire ne quitte
jamais votre app.
Autoriser votre domaine
Avant d'embarquer l'iframe, ajoutez votre domaine (https://app.yourcompany.com,
wildcards https://*.yourcompany.com acceptés) dans Paramètres → Domaines
autorisés depuis le dashboard.
Signlift positionne dynamiquement le header Content-Security-Policy: frame-ancestors par organisation — seuls les domaines autorisés peuvent
embarquer l'iframe ; toute autre origine voit le chargement bloqué par le
navigateur.
Récupération de l'URL de signature
À la création d'une signature_request côté serveur, chaque signataire reçoit
dans la réponse un champ signing_url — une URL absolue prête à l'emploi qui
ouvre la page de signature. Pas de token à extraire, pas d'URL à
reconstruire.
const res = await fetch("https://app.signlift.eu/api/v1/signature_requests", {
method: "POST",
headers: {
"X-Api-Key": process.env.SIGNLIFT_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
/* … */
}),
})
const { signers } = await res.json()
const signingUrl = signers[0].signing_url
// → https://app.signlift.eu/sign/eyJhbGciOiJIUzI1NiJ9...Transmettez ce signingUrl au client (via un endpoint de votre app, un cookie
HttpOnly, ou directement dans la page rendue côté serveur) et utilisez-le tel
quel.
Embedding de l'iframe
<iframe
src="https://app.signlift.eu/sign/eyJhbGciOiJIUzI1NiJ9..."
width="100%"
height="800"
sandbox="allow-scripts allow-same-origin allow-forms"
title="Signature électronique Signlift"
></iframe>En React :
<iframe
src={signingUrl}
width="100%"
height="800"
sandbox="allow-scripts allow-same-origin allow-forms"
title="Signature électronique Signlift"
/>postMessage events
L'iframe émet des postMessage vers la window parente à chaque transition de
parcours. Chaque message est signé avec votre webhook_secret afin que
vous puissiez vérifier côté serveur qu'il provient bien de Signlift (et n'a
pas été forgé depuis la console JS du parent).
| Event | Quand |
|---|---|
signlift:signature:ready | L'iframe a chargé la page de signature. |
signlift:signature:success | La signature a été finalisée avec succès. |
signlift:signature:error | Erreur (token expiré, signataire déjà signé, etc.). |
Chaque message est un objet JSON dont le type est porté par le champ type
(ex. event.data.type === "signlift:signature:success").
ready est émis immédiatement. success et error sont émis ~3 s après
l'affichage de l'écran de fin (le temps de laisser le signataire lire la
confirmation) ; si l'iframe est détruite ou rechargée avant, l'événement est
émis immédiatement plutôt que perdu. Ne dépendez donc pas d'un timing
exact : traitez l'événement dès sa réception.
Format et vérification du message
Chaque message est un objet JSON contenant un champ signature (HMAC-SHA256
au format sha256=<hex>), un issued_at (ISO 8601 UTC), un nonce, et le
payload métier.
Pour vérifier l'authenticité côté serveur, la chaîne canonique à signer suit ce format déterministe :
v1.<event>.<issued_at>.<nonce>.<k1>=<v1>;<k2>=<v2>;…Les clés du payload sont triées alphabétiquement, les valeurs vides sont
omises, et les valeurs sont sérialisées en string. Calculez le HMAC-SHA256 de
cette chaîne avec votre webhook_secret et comparez en temps constant au
champ signature reçu.
window.addEventListener("message", async (event) => {
if (event.origin !== "https://app.signlift.eu") return
const { type } = event.data
// Pour les transitions visuelles légères, le client peut se fier au type.
// Pour toute action engageante (mise à jour DB, génération de facture…),
// déclenchez-la sur le webhook serveur-à-serveur, pas sur postMessage.
if (type === "signlift:signature:success") {
showSuccessScreen()
}
})Pitfalls courants
- Attribut
sandbox:allow-scriptsetallow-same-originsont nécessaires pour le rendu PDF et la signature à la souris/au doigt. - Cookies tiers : Signlift ne dépend pas de cookies tiers — l'iframe fonctionne correctement avec Safari ITP / Chrome 3PCD.
- Mobile : l'interface est responsive. Allouez au moins 100vh de hauteur sur mobile pour éviter le scroll imbriqué.