Ce guide raconte la commande client ordinaire, du catalogue à la livraison. Il s'adresse à l'application client, au frontend et à la QA.

  1. Le client lit GET /food/v1/restaurants puis GET /food/v1/restaurants/{restaurant_id}/menu.
  2. Avant de commander, il envoie POST /food/v1/restaurants/{restaurant_id}/quote avec les articles et les coordonnées. Food renvoie le sous-total, le frais de livraison configuré et le total XOF.
  3. Il crée une commande avec POST /food/v1/orders; le mode delivery est le parcours MVP et le paiement est cash_on_delivery ou online. Food fixe respond_by à cinq minutes par défaut; le worker annule une commande restée placed après cette échéance avec le motif restaurant_unresponsive.
  4. Pour online, le client prépare le paiement avec POST /food/v1/orders/{order_id}/payments/prepare pendant que la commande reste placed. Le restaurant accepte avec POST /food/v1/restaurants/{restaurant_id}/orders/{order_id}/accept seulement après confirmation DiddiPay succeeded; aucune préparation ne commence avant cette confirmation. Pour cash_on_delivery, l'acceptation peut commencer directement.
  5. Pour online, le client peut omettre customer_email. Food utilise l'e-mail fourni s'il existe, sinon le téléphone du compte authentifié pour produire une valeur technique comme 2250700112233@diddifree.com. Le téléphone du destinataire n'est jamais utilisé pour le paiement.
  6. Food crée la livraison auprès de DiddiSend. DiddiSend gère le livreur, la collecte cash, le trajet et la remise.
  7. Le client lit la projection avec GET /food/v1/orders/{order_id}/delivery/tracking (ou /delivery). Food vérifie la propriété de la commande, demande la donnée à DiddiSend et ne renvoie que le suivi public. DiddiSend reste propriétaire de l'ETA, de la position, du coursier, de la preuve et de la décision après un échec. Les états projetés sont requested, assigned, picked_up, in_transit, delivered et failed; un échec peut inclure failure_code et failure_reason.
  8. En cas de litige, le client crée une demande avec POST /food/v1/orders/{order_id}/refund-requests, puis la suit avec GET /food/v1/orders/{order_id}/refund-requests. Après approbation, Food demande le remboursement à DiddiPay, y compris pour une commande cash; DiddiPay choisit le compte mobile money ou le compte opérateur bénéficiaire.
  9. Le client peut relire sa note avec GET /food/v1/orders/{order_id}/rating après livraison. Une absence de note renvoie RATING_NOT_FOUND.
  10. Le client peut enregistrer son appareil avec /food/v1/devices/register et reçoit les notifications disponibles. Après reconnexion WebSocket, il relit la commande.
sequenceDiagram
    participant C as Client
    participant F as DiddiFood
    participant R as Restaurant
    participant S as DiddiSend
    C->>F: GET catalogue
    C->>F: POST /orders
    R->>F: accept puis ready
    F->>S: request delivery
    S-->>F: statut livraison
    F-->>C: commande et notification

Hors périmètre pour l'instant

Le retrait sur place et les substitutions restent désactivés par défaut (DIDDIFOOD_PICKUP_ENABLED=false, DIDDIFOOD_SUBSTITUTION_ENABLED=false).

Création de plat côté Pro

Le manager doit envoyer Idempotency-Key à POST /food/v1/restaurants/{restaurant_id}/dishes. Une nouvelle tentative avec la même clé et le même corps renvoie le même plat; la même clé avec un corps différent est rejetée en 409 IDEMPOTENCY_CONFLICT.