Aller au contenu

Verrouiller des champs

Un champ verrouillé s’affiche sans contrôle d’édition, accompagné de votre motif. À utiliser lorsqu’une valeur a déjà été décidée ailleurs et que la rechoisir dans le widget offrirait une seconde occasion, déroutante, de se contredire.

Il existe deux façons de verrouiller un champ, et elles diffèrent sur un point qui compte plus que tous les autres : le serveur refuse-t-il une réservation qui les contredit ?

Où cela se règleLe client le voit fixeLe serveur refuse une réservation contradictoire
Non signésetLocks(), data-locked, ?locked=OuiNon
Signélocked dans l’assertion d’identitéOuiOui

Les deux s’affichent à l’identique. Le client ne peut pas les distinguer, et n’a pas à le faire.

Le cas courant. Rien à signer, aucun serveur impliqué.

<script
src="…/widget.js"
data-slug="chez-marie"
data-locked="date,party_size"
data-lock-reason="Bon cadeau BC-4471"
async
></script>
widget.setLocks({ fields: ["date", "partySize"], reason: "Bon cadeau BC-4471" });
https://book.useservice.app/r/chez-marie?date=2026-09-03&locked=date&lock_reason=Bon%20cadeau

reason est le pourquoi, pas une phrase complète — le widget ajoute son propre suffixe localisé « · date fixée » par champ, de sorte que « Bon cadeau BC-4471 » se lit correctement dans les onze langues.

Les noms de champs acceptent les deux graphies : party_size ou partySize, section_key ou sectionKey, shift_id ou shiftId. Les noms inconnus sont ignorés.

Ces verrous circulent dans votre HTML ou dans une chaîne de requête : n’importe quoi peut donc les modifier. Le point de terminaison de réservation ne peut pas distinguer un verrou non signé d’une absence de verrou, et accepte une réservation qui le contredit.

C’est un arbitrage délibéré. Exiger un jeton signé pour simplement griser un champ serait disproportionné dans le cas courant, qui consiste seulement à refléter un choix que le client a déjà fait sur votre propre page.

Le risque à nommer n’est pas un client qui modifie une URL — c’est le cas que tout le monde imagine, et il n’a guère d’importance. C’est de lire le mot « verrouillé » et d’en conclure que la réservation ne peut pas atterrir ailleurs. Elle le peut.

Lorsque la valeur doit réellement tenir — un bon cadeau valable un seul jour, un créneau prépayé, une table que votre propre système a déjà engagée — placez le champ dans locked à l’intérieur du jeton signé :

{
"iss": "ivk_…",
"reservation": { "date": "2026-09-03", "party_size": 4 },
"locked": ["date", "party_size"]
}

Le serveur dispose alors des valeurs et de la contrainte depuis une source que le navigateur ne peut pas falsifier, et il refuse une création qui les contredit. Le widget positionne également le tunnel à partir de ces mêmes valeurs signées : ce que le client voit et ce que le serveur acceptera ne peuvent donc pas diverger.

Voir Identifier le client pour la génération.

Ils se combinent, et c’est l’union qui est verrouillée. Une page peut épingler le nombre de couverts sans signature pendant que le jeton épingle la date : le client voit les deux fixes, et seule la date est appliquée.

Un jeton refusé (expiré, ou mal signé) n’apporte rien, et vos verrous non signés n’en sont pas affectés : ils n’en dépendaient pas.

date, time, party_size, section_key, shift_id.

Les coordonnées ne sont pas verrouillables. Un client doit toujours pouvoir corriger son nom, son e-mail et son téléphone — voir Identifier le client pour comprendre pourquoi un champ affirmé cesse de l’être dès qu’il est modifié.

Verrouiller une date où le restaurant n’a plus rien de libre produit une impasse par construction : le client ne peut pas changer la date, et il n’y a rien à réserver. Le widget le dit clairement plutôt que d’afficher un calendrier vide, et propose votre return_url comme issue si vous en avez fourni une. C’est précisément pour cela qu’il vaut la peine d’en fournir une.