Flux caisse (API native)
L’API native du moteur est servie par chaque moteur de workspace sur son port public (en local : http://localhost:47500
pour le workspace demo, slot 0). Elle est authentifiée par clé d’API (X-Api-Key, voir
Authentification). Le ticket suit le schéma ticket.schema.json ; la réponse suit
evaluation-result.schema.json.
Vue d’ensemble
Section intitulée « Vue d’ensemble »Caisse Moteur du workspace │ 1. (option) carte scannée │ ├── POST /v1/customers/lookup ─────────────▶│ soldes + offres disponibles │ 2. fin de saisie du ticket │ ├── POST /v1/transactions/evaluate ────────▶│ ticket en attente (pending), coupons réservés │◀──────────── remises par ligne, points, coupons, messages │ 3. paiement encaissé │ ├── POST /v1/transactions/{id}/commit ─────▶│ points postés, coupons utilisés/émis │ (ou) POST /v1/transactions/{id}/cancel ──▶│ libérationUne caisse qui ne peut pas faire deux appels utilise POST /v1/transactions/commit (évaluation et validation en une fois).
Le ticket
Section intitulée « Le ticket »{ "header": { "ticketNumber": "000123", "storeCode": "S042", "posId": "03", "businessDate": "2026-11-09", "timestamp": "2026-11-09T10:42:13+01:00", "channel": "pos", "currency": "EUR", "totals": { "grossCents": 5490, "itemCount": 3 } }, "customer": { "identifiers": [{ "type": "card", "value": "2600000012345" }] }, "lines": [ { "lineNo": 1, "ean": "3017620422003", "ref": "NUT750", "univers": "ALIM", "qty": 2, "unitPriceCents": 495, "lineTotalCents": 990 }, { "lineNo": 2, "ean": "4006381333931", "ref": "STB001", "univers": "MAISON", "qty": 1, "unitPriceCents": 4500, "lineTotalCents": 4500 } ], "payments": []}Règles :
- montants en centimes ;
lineTotalCents= quantité × prix unitaire − remise caisse, calculé par la caisse ; totals.grossCentsest le total avant offres Remizo ; le moteur ne le recalcule pas (avertissement si incohérent) ;lineNoest unique dans le ticket : c’est lui qui adresse les remises dans la réponse ;- les drapeaux de ligne
no_promo,no_points,gift_card,deposit,fee,serviceexcluent la ligne des remises ou des points ; - la clé de ticket est
storeCode:posId:businessDate:ticketNumber(S042:03:2026-11-09:000123) : c’est l’identité métier du ticket.
1. Simuler
Section intitulée « 1. Simuler »POST /v1/transactions/simulate évalue sans rien écrire (limites lues mais pas consommées, coupons vérifiés mais pas réservés).
Utile pour afficher les avantages au client avant la fin du ticket.
curl -s http://localhost:47500/v1/transactions/simulate \ -H "X-Api-Key: $RMZ_KEY" -H 'Content-Type: application/json' \ -d "$(jq .ticket docs-site/src/content/docs/fr/integration/examples/ticket-simple.json)"2. Évaluer (ticket en attente)
Section intitulée « 2. Évaluer (ticket en attente) »POST /v1/transactions/evaluate enregistre un ticket pending (durée de vie 24 h par défaut) et renvoie transactionId.
Les coupons présentés sont réservés, les budgets d’offres sont pré-réservés. Rien n’est encore posté dans le registre des points.
Extrait de réponse :
{ "mode": "evaluate", "status": "ok", "transactionId": "6f1c2a9e-3b7d-4e0a-9c1f-2d3e4f5a6b7c", "ticketKey": "S042:03:2026-11-09:000123", "transactionState": "pending", "totals": { "grossCents": 5490, "discountCents": 549, "netCents": 4941 }, "lines": [ { "lineNo": 1, "discountCents": 99 }, { "lineNo": 2, "discountCents": 450 } ], "applied": [ { "offerCode": "WELCOME10", "valueCents": 549, "level": 0, "mode": "cumulative" } ], "pointsMovements": [ { "counterTypeCode": "POINTS", "kind": "earn", "amount": 49, "state": "projected" } ], "messages": [], "warnings": []}La caisse applique les remises ligne par ligne (lines[].discountCents) ; la part non attribuable à une ligne est donnée par
totals.ticketDiscountCents. Les lignes à ajouter (produit offert) sont dans addedLines.
3. Valider
Section intitulée « 3. Valider »POST /v1/transactions/{transactionId}/commit, avec si besoin les paiements définitifs et la réservation de points à confirmer :
{ "payments": [ { "method": "card", "amountCents": 4941 } ], "pointsReservationId": null }En une seule transaction de base de données : points crédités, coupons consommés ou émis, budgets d’offres consommés,
statuts et étiquettes client appliqués, événements publiés vers le hub. La réponse est le même résultat, avec les identifiants
réels (movementId, couponId, lien de rendu du coupon). Une validation répétée renvoie le même résultat (Idempotent-Replay: true).
4. Annuler
Section intitulée « 4. Annuler »POST /v1/transactions/{transactionId}/cancel :
- sur un ticket en attente : libère coupons et budgets ;
- sur un ticket validé depuis moins de
transactions.cancelWindowSeconds(24 h par défaut) et sans remboursement : annule tous les effets par des mouvements de compensation. Au-delà, utilisez le remboursement.
À la fermeture de caisse ou après un incident : POST /v1/transactions/cancel-pending avec storeCode (et posId) annule tous
les tickets restés en attente. Les tickets oubliés expirent aussi automatiquement (tâche transactions.expire_pending).
5. Rembourser
Section intitulée « 5. Rembourser »POST /v1/transactions/{transactionId}/refund crée une transaction fille de type refund :
{ "refundTicketNumber": "000187", "lines": [ { "lineNo": 1, "qty": 1 } ], "clawbackPoints": true, "cancelIssuedCoupons": true }- sans
lines, le remboursement est total ; plusieurs remboursements partiels sont possibles jusqu’à épuisement des quantités ; - les remises sont recalculées sur les unités restantes : la réponse indique, par ligne, la remise à restituer ;
- les points sont repris au prorata (sans solde négatif si le compteur l’interdit, avec un avertissement) ;
- les coupons émis par le ticket d’origine et encore disponibles sont annulés.
Lire une transaction
Section intitulée « Lire une transaction »GET /v1/transactions/{id} ou GET /v1/transactions/by-key/{ticketKey} renvoient le ticket, le résultat, l’état et les remboursements.
Performances
Section intitulée « Performances »Objectif : p99 < 30 ms par appel (moins de 10 ms de calcul). Gardez des connexions HTTP persistantes, envoyez un
X-Request-Id pour corréler vos journaux, et prévoyez un délai d’attente côté caisse de l’ordre de 2 s avec repli « vente sans
avantage » : le ticket pourra être régularisé plus tard.