Projet Site Maison Crosnier · 21 juillet 2026
La Gateway est l'interface unique entre le site et la caisse. Le site ne parle jamais directement à la caisse : il passe par la Gateway, qui expose d'abord un simulateur, puis l'API réelle de la caisse, sans réécriture côté site (ADR-019). Ce contrat définit les opérations et les formats de données. Les parties dépendant de l'API réelle (non encore connue) sont marquées [provisoire] ; les parties que le site maîtrise entièrement sont [stable].
Format retenu : REST / JSON (neutre, exploitable directement pour le développement). Les identifiants, dates IS 8601 avec fuseau, montants en euros.
GET /catalogue — structure du catalogue
[provisoire]Renvoie les familles (avec leur politique de commande) et les produits.
{
"familles": [
{ "id": "pain", "libelle": "Pain", "politiqueCommande": { "type": "veille", "heureLimite": "10:00", "retraitAuPlusTot": "J+1" } },
{ "id": "viennoiserie", "libelle": "Viennoiserie", "politiqueCommande": { "type": "veille", "heureLimite": "12:00", "retraitAuPlusTot": "J+1", "retraitAvant": "09:00" } },
{ "id": "patisserie", "libelle": "Pâtisserie", "politiqueCommande": { "type": "delai", "delaiMinutes": 180, "retraitAuPlusTot": "J+0" } },
{ "id": "snacking", "libelle": "Snacking", "politiqueCommande": { "type": "delai", "delaiMinutes": 180, "retraitAuPlusTot": "J+0" } }
],
"produits": [
{
"id": "caisse-ref-123",
"familleId": "pain",
"libelle": "Baguette tradition",
"prix": 1.30,
"declinaisons": [],
"options": [],
"actif": true
}
]
}Notes :
produit + famille + prix + quelques déclinaisons pour
tester le tunnel.prix est le prix de référence
caisse. Les promotions sont appliquées côté site (ADR-020) et
ne transitent pas par la Gateway.La lecture du catalogue est déclenchée manuellement par l'admin (ADR-014) puis mise en cache côté site. La Gateway n'a pas besoin de mécanisme de push temps réel en V1.
POST /commandes — transmettre une commande payée
[stable]Envoyée une fois la commande validée et payée. C'est le format que le site maîtrise entièrement.
{
"commandeId": "site-8f3a…", // idempotence : rejouer le même id ne crée pas de doublon
"pointDeRetraitId": "boutique-1",
"creneau": { "debut": "2026-07-22T08:30:00+02:00", "dureeMinutes": 30 },
"client": { "nom": "…", "email": "…", "telephone": "…" },
"lignes": [
{ "produitId": "caisse-ref-123", "declinaisonId": null, "options": [], "quantite": 2, "prixUnitaire": 1.30 }
],
"montantTotal": 2.60,
"paiement": { "statut": "paye", "prestataire": "payplug", "reference": "pp_xxx" },
"creeLe": "2026-07-21T16:05:00+02:00"
}Réponse : { "accepte": true, "referenceCaisse": "…" } ou
{ "accepte": false, "raison": "…" }.
POST /commandes/{commandeId}/annulation — informer d'une
annulation [stable]Utilisé lorsqu'une commande annulée selon le barème (§9) doit être
signalée à la production. Corps :
{ "motif": "annulation_client" }.
Décision retenue (ADR-021) : on part du principe que la caisse ne remonte rien au site. L'usage physique d'un avoir passe donc par une édition auto-décrémentante côté site, sans aucun échange Gateway :
code en
code-barres / QR / code) ;edite_boutique) et affiche
l'avertissement « en éditant cet avoir vous n'y aurez plus accès
depuis le site » ;Aucune opération Gateway n'est requise pour cela → pas de dépendance à la caisse.
Évolutions optionnelles (uniquement si la caisse sait dialoguer, non nécessaires en V1) :
POST /avoirs (Site →
Caisse) à la création.GET /avoirs/{code} +
POST /avoirs/{code}/imputation (Caisse → Site) à
l'encaissement.Le format du code (EAN-13, QR, alphanumérique) reste à
aligner sur ce que la boutique/caisse sait scanner.
Le simulateur expose exactement les mêmes opérations que l'API réelle visée, pour permettre la bascule sans réécriture. Il doit :
POST /commandes (vérifier le tunnel de bout en bout) ;actif:false, créneau hors horaires ;produitId (base de l'appariement caisse ↔︎ fiche site
enrichie).POST) vers la caisse, ou la caisse
tire (pull/polling) les commandes ? — à confirmer selon
l'API.POST.