Aller au contenu principal

Système de Commandes et Suivi de Statut

Ce document décrit le système de gestion des commandes de l'application e-commerce, incluant la création, le paiement, le suivi de statut et l'intégration avec les systèmes de logistique et fidélité.

Vue d'ensemble

Le système de commandes gère l'ensemble du cycle de vie d'une commande :

  1. Création : Génération d'un ordreId unique et enregistrement en base
  2. Paiement : Redirection vers le système de paiement et confirmation
  3. Transmission : Envoi vers la Logistique via RabbitMQ
  4. Suivi : Mise à jour du statut et affichage timeline visuelle
  5. Finalisation : Attribution de points de fidélité à la livraison

Statuts de commande

StatutDescriptionAffiché au client
EN_ATTENTEPaiement confirmé, en attente d'expéditionCommande reçue
EN_PREPARATIONLa commande est en cours de préparationCommande en préparation
EXPEDIEELa commande a été expédiéeCommande expédiée
LIVREELa commande a été livrée au clientCommande livrée
ANNULEELa commande a été annuléeCommande annulée

Composants impliqués

  • Frontend :
    • CheckoutPage.tsx : Page de paiement et création de commande
    • PaymentReturnPage.tsx : Page de retour après paiement
    • OrderConfirmationPage.tsx : Page de confirmation avec timeline
    • OrderStatusStepper.tsx : Composant visuel de suivi de statut
  • Backend :
    • commandes.service.ts : Logique métier des commandes
    • commandes.controller.ts : Endpoints REST
    • paiement.service.ts : Intégration avec le système de paiement
  • RabbitMQ : Communication asynchrone avec Logistique et Fidélité
  • Base de données : Table commandes avec historique de statut

Endpoints API

Créer une commande

POST /api/commandes

Crée une nouvelle commande et génère un ordreId unique.

Body :

{
"userId": 42,
"clientInfo": {
"prenom": "Jean",
"nom": "Dupont",
"email": "jean.dupont@example.com",
"telephone": "0612345678"
},
"adresseLivraison": {
"rue": "123 Rue de la Paix",
"codePostal": "75001",
"ville": "Paris",
"complementAdresse": "Bâtiment A, 2ème étage"
},
"articles": [
{
"id": "PROD_001",
"nom": "Pizza Margherita",
"prixUnitaireCents": 850,
"quantite": 2,
"categorie": "Pizzas"
},
{
"id": "PROD_002",
"nom": "Coca-Cola 33cl",
"prixUnitaireCents": 250,
"quantite": 1,
"categorie": "Boissons"
}
],
"montantTotalCents": 1950,
"commentaire": "Sonner à l'interphone avant de monter"
}

Champs :

  • userId (requis si authentifié) : ID de l'utilisateur connecté
  • clientInfo (requis) : Informations du client
  • adresseLivraison (requis) : Adresse de livraison complète
  • articles (requis) : Liste des articles commandés
  • montantTotalCents (requis) : Montant total en centimes
  • commentaire (optionnel) : Instructions de livraison

Réponse :

{
"ordreId": "ORD-20241115-A3B5C7",
"statut": "EN_ATTENTE",
"montantTotalCents": 1950,
"createdAt": "2024-11-15T14:30:00Z"
}

Format du ordreId : ORD-YYYYMMDD-XXXXXX où :

  • YYYYMMDD : Date de création
  • XXXXXX : 6 caractères hexadécimaux aléatoires

Codes de réponse :

  • 201 Created : Commande créée avec succès
  • 400 Bad Request : Données invalides
  • 401 Unauthorized : Token invalide (si userId fourni)

Récupérer une commande

GET /api/commandes/:ordreId

Récupère les détails complets d'une commande incluant son statut actuel.

Réponse :

{
"ordreId": "ORD-20241115-A3B5C7",
"userId": 42,
"statut": "EXPEDIEE",
"montantTotalCents": 1950,
"transactionId": "TXN-20241115-143045-12345",
"authorizationId": "CFM-20241115-143045-98765",
"clientInfo": {
"prenom": "Jean",
"nom": "Dupont",
"email": "jean.dupont@example.com",
"telephone": "0612345678"
},
"adresseLivraison": {
"rue": "123 Rue de la Paix",
"codePostal": "75001",
"ville": "Paris",
"complementAdresse": "Bâtiment A, 2ème étage"
},
"articles": [
{
"id": "PROD_001",
"nom": "Pizza Margherita",
"prixUnitaireCents": 850,
"quantite": 2,
"categorie": "Pizzas"
}
],
"commentaire": "Sonner à l'interphone avant de monter",
"createdAt": "2024-11-15T14:30:00Z",
"updatedAt": "2024-11-15T15:45:00Z"
}

Codes de réponse :

  • 200 OK : Commande trouvée
  • 404 Not Found : Commande inexistante

Confirmer le paiement d'une commande

POST /api/commandes/:ordreId/confirmer-paiement

Confirme le paiement d'une commande et déclenche l'envoi vers la logistique.

Body :

{
"transactionId": "TXN-20241115-143045-12345",
"authorizationId": "CFM-20241115-143045-98765",
"amount": "19.50"
}

Réponse :

{
"ordreId": "ORD-20241115-A3B5C7",
"statut": "EN_ATTENTE",
"message": "Paiement confirmé, commande envoyée aux systèmes"
}

Actions déclenchées :

  1. Mise à jour de la commande avec transactionId et authorizationId
  2. Envoi vers RabbitMQ (queue logistique.nouvelle-commande)
  3. Notification au client par email (future fonctionnalité)

Codes de réponse :

  • 200 OK : Paiement confirmé
  • 404 Not Found : Commande inexistante
  • 400 Bad Request : Paiement déjà confirmé

Mettre à jour le statut d'une commande

PATCH /api/commandes/:ordreId/statut

Met à jour le statut d'une commande (généralement appelé par le système de logistique).

Body :

{
"nouveauStatut": "EXPEDIEE",
"trackingNumber": "FR123456789",
"commentaire": "Expédié via Colissimo"
}

Valeurs acceptées pour nouveauStatut :

  • EN_PREPARATION
  • EXPEDIEE
  • LIVREE
  • ANNULEE

Réponse :

{
"ordreId": "ORD-20241115-A3B5C7",
"statut": "EXPEDIEE",
"message": "Statut mis à jour avec succès"
}

Actions déclenchées :

  • Si statut = LIVREE : Envoi vers RabbitMQ (queue fidelite.commande-livree) pour attribution des points

Codes de réponse :

  • 200 OK : Statut mis à jour
  • 404 Not Found : Commande inexistante
  • 400 Bad Request : Transition de statut invalide

Récupérer les commandes d'un utilisateur

GET /api/commandes/user/:userId

Récupère toutes les commandes d'un utilisateur authentifié.

Headers :

Authorization: Bearer <accessToken>

Réponse :

{
"commandes": [
{
"ordreId": "ORD-20241115-A3B5C7",
"statut": "EXPEDIEE",
"montantTotalCents": 1950,
"createdAt": "2024-11-15T14:30:00Z"
},
{
"ordreId": "ORD-20241110-B8C2D4",
"statut": "LIVREE",
"montantTotalCents": 3200,
"createdAt": "2024-11-10T18:20:00Z"
}
],
"total": 2
}

Paramètres de requête optionnels :

  • ?statut=EXPEDIEE : Filtrer par statut
  • ?limit=10 : Limiter le nombre de résultats
  • ?offset=0 : Pagination

Codes de réponse :

  • 200 OK : Liste retournée (peut être vide)
  • 401 Unauthorized : Token invalide

Intégration RabbitMQ

Queue : logistique.nouvelle-commande

Déclenchement : Après confirmation du paiement

Message envoyé :

{
"ordreId": "ORD-20241115-A3B5C7",
"userId": 42,
"clientInfo": {
"prenom": "Jean",
"nom": "Dupont",
"email": "jean.dupont@example.com",
"telephone": "0612345678"
},
"adresseLivraison": {
"rue": "123 Rue de la Paix",
"codePostal": "75001",
"ville": "Paris",
"complementAdresse": "Bâtiment A, 2ème étage"
},
"articles": [
{
"id": "PROD_001",
"nom": "Pizza Margherita",
"quantite": 2,
"prixUnitaireCents": 850
}
],
"montantTotalCents": 1950,
"commentaire": "Sonner à l'interphone avant de monter",
"createdAt": "2024-11-15T14:30:00Z"
}

Action attendue de la Logistique :

  1. Réceptionner le message
  2. Préparer la commande
  3. Mettre à jour le statut via PATCH /api/commandes/:ordreId/statut

Queue : fidelite.commande-livree

Déclenchement : Lorsque le statut passe à LIVREE

Message envoyé :

{
"ordreId": "ORD-20241115-A3B5C7",
"userId": 42,
"clientId": "CLI_A3B5C7D9",
"montantTotalCents": 1950,
"pointsGagnes": 19,
"livreLe": "2024-11-15T18:30:00Z"
}

Calcul des points : pointsGagnes = Math.floor(montantTotalCents / 100) (1 point par euro dépensé)

Action attendue de Fidélité :

  1. Réceptionner le message
  2. Créditer les points sur le compte client
  3. Mettre à jour le niveau de fidélisation si nécessaire

Composant de suivi de statut (Frontend)

OrderStatusStepper

Le composant OrderStatusStepper affiche une timeline visuelle du statut de la commande.

Props :

interface OrderStatusStepperProps {
currentStatus:
| 'EN_ATTENTE'
| 'EN_PREPARATION'
| 'EXPEDIEE'
| 'LIVREE'
| 'ANNULEE';
createdAt?: string;
shippedAt?: string;
deliveredAt?: string;
}

Affichage :

<OrderStatusStepper
currentStatus="EXPEDIEE"
createdAt="2024-11-15T14:30:00Z"
shippedAt="2024-11-15T15:45:00Z"
/>

Rendu visuel :

  • Étapes complétées : Fond orange (#ff8803), icône SVG, texte en gras
  • Étape actuelle : Bordure orange animée (pulse)
  • Étapes futures : Fond gris clair, icône grise

Icônes utilisées :

  1. Commande reçue : Icône de carton/paquet (SVG)
  2. En préparation : Icône d'horloge (SVG)
  3. Expédiée : Icône de camion (SVG)
  4. Livrée : Icône de check/validation (SVG)

Responsive :

  • Desktop : Timeline horizontale
  • Mobile : Timeline verticale

Flux de création de commande

Flux de mise à jour de statut

Schéma de la table commandes

CREATE TABLE commandes (
id SERIAL PRIMARY KEY,
ordre_id VARCHAR(50) UNIQUE NOT NULL,
user_id INTEGER REFERENCES users(id),
statut VARCHAR(50) NOT NULL DEFAULT 'EN_ATTENTE',
montant_total_cents INTEGER NOT NULL,
transaction_id VARCHAR(100),
authorization_id VARCHAR(100),
client_info JSONB NOT NULL,
adresse_livraison JSONB NOT NULL,
articles JSONB NOT NULL,
commentaire TEXT,
tracking_number VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
shipped_at TIMESTAMP,
delivered_at TIMESTAMP
);

Index recommandés :

  • ordre_id (unique) : Pour recherche rapide
  • user_id : Pour récupérer les commandes d'un utilisateur
  • statut : Pour filtrage par statut
  • created_at : Pour tri chronologique

Bonnes pratiques d'intégration

Pour l'équipe Logistique

Endpoints à appeler :

  1. Consommer la queue logistique.nouvelle-commande pour recevoir les nouvelles commandes
  2. Mettre à jour le statut via PATCH /api/commandes/:ordreId/statut

Transitions de statut attendues :

EN_ATTENTE → EN_PREPARATION → EXPEDIEE → LIVREE

ANNULEE (si problème)

Informations à fournir :

  • trackingNumber lors du passage à EXPEDIEE
  • commentaire en cas d'annulation

Pour l'équipe Fidélité

Queue à consommer : fidelite.commande-livree

Action attendue :

  1. Récupérer clientId et pointsGagnes du message
  2. Créditer les points sur le compte client via votre API
  3. Recalculer le niveau de fidélisation si nécessaire

Important : Le message n'est envoyé QUE lorsque la commande passe à LIVREE, pas avant.

Pour l'équipe Paiement

Endpoint à appeler : POST /api/commandes/:ordreId/confirmer-paiement

Quand l'appeler : Après validation du paiement par votre système

Données à fournir :

  • transactionId : ID de la transaction chez vous
  • authorizationId : ID d'autorisation bancaire
  • amount : Montant payé (pour vérification)

Pour l'équipe Frontend

Composants disponibles :

  • OrderStatusStepper : Timeline visuelle du statut
  • useOrder hook : Pour récupérer les données d'une commande

Polling de statut : Pour afficher le statut en temps réel, implémenter un polling toutes les 30 secondes :

useEffect(() => {
const interval = setInterval(() => {
fetchOrderStatus(ordreId);
}, 30000); // 30 secondes

return () => clearInterval(interval);
}, [ordreId]);

Surveillance et logs

Logs disponibles

Création de commande :

[CommandesService] 📦 Création d'une nouvelle commande
[CommandesService] ✅ Commande créée: ORD-20241115-A3B5C7

Confirmation de paiement :

[CommandesService] 💳 Confirmation du paiement pour: ORD-20241115-A3B5C7
[CommandesService] 📤 Envoi de la commande vers la logistique
[CommandesService] ✅ Commande envoyée à RabbitMQ (logistique.nouvelle-commande)

Mise à jour de statut :

[CommandesService] 🔄 Mise à jour du statut: ORD-20241115-A3B5C7 → EXPEDIEE
[CommandesService] ✅ Statut mis à jour avec succès

Livraison et points :

[CommandesService] 🔄 Mise à jour du statut: ORD-20241115-A3B5C7 → LIVREE
[CommandesService] 🎁 Attribution de 19 points de fidélité
[CommandesService] 📤 Envoi vers Fidélité (RabbitMQ)

Métriques à surveiller

  • Nombre de commandes créées par jour
  • Taux de conversion (commandes créées vs paiements confirmés)
  • Durée moyenne entre statuts
  • Taux d'annulation
  • Délai moyen de livraison

Liens utiles