Brief frontend DiddiFood — v2026.10.27

Ce brief complète le contrat OpenAPI généré le 27 octobre 2026.

Paiement en ligne

POST /food/v1/orders/{order_id}/payments/prepare accepte un corps vide ou {"customer_email":"..."}. Le client n'a pas à demander une adresse e-mail. Food transmet à DiddiPay l'adresse fournie; si elle manque, Food dérive une valeur à partir du téléphone du payeur authentifié, par exemple 2250700112233@diddifree.com. Le téléphone du destinataire ne doit jamais être utilisé pour cette dérivation.

Réponse du restaurant

Une commande créée à 12:00 contient respond_by à 12:05 par défaut. Si le restaurant ne l'accepte ni ne la refuse avant cette échéance, Food l'annule et renvoie cancellation_reason=restaurant_unresponsive. Le frontend doit afficher la date limite et traiter cette annulation comme une commande annulée.

Suivi et échec de livraison

Utiliser GET /food/v1/orders/{order_id}/delivery/tracking. Food vérifie que le client possède la commande et renvoie une projection de DiddiSend : statut, coursier public, position, ETA, failure_code et failure_reason. DiddiSend reste propriétaire du coursier, de la position, de l'ETA réelle, de la preuve de remise et de la décision métier après un échec. Food ne doit pas afficher de bouton qui déclenche une nouvelle tentative ou un remboursement automatique.

Images et plats Pro

Les lignes de commande et la file cuisine peuvent contenir image_url. L'URL vient de DiddiFiles et peut être null; le frontend doit fournir un fallback. Pour POST /food/v1/restaurants/{restaurant_id}/dishes, envoyer une Idempotency-Key stable pendant toute la tentative. La répétition avec le même corps renvoie le même plat; un corps différent avec la même clé renvoie 409.

Note et remboursements

Après livraison, lire GET /food/v1/orders/{order_id}/rating pour distinguer une note existante de l'absence de note (404 RATING_NOT_FOUND). Les remboursements approuvés, y compris ceux d'une commande cash, sont exécutés par DiddiPay vers le bénéficiaire approprié; Food ne propose pas de règlement cash manuel.

Catalogue, pagination et recherche

GET /food/v1/restaurants est paginé avec limit (1–100), offset et total. Le MVP accepte aussi q (nom, adresse ou catégorie), category et is_open. Les filtres ne renvoient que les restaurants actifs. La file Pro/Cuisine accepte déjà le filtre de statut répétable status sur GET /food/v1/restaurants/{restaurant_id}/orders (par exemple ?status=placed&status=preparing).

En V1, ajouter latitude, longitude et radius_km pour limiter les restaurants autour d'une position. Les trois paramètres sont liés : les coordonnées vont ensemble, et radius_km ne peut être fourni sans elles. Food applique ensuite le rayon configuré du restaurant et ses horaires hebdomadaires dans Africa/Abidjan.

Ventilation financière Pilotage

Pilotage peut lire une commande sans données personnelles avec : GET /food/v1/internal/pilotage/orders/{order_id}/financial-breakdown et le scope food:pilotage:read. La réponse détaille le total client, les frais de livraison, le revenu restaurant, le gain coursier, les commissions Food/Send, le cash à collecter et les remboursements agrégés. diddipay_fee_xof reste null tant que DiddiPay ne fournit pas ce frais dans son contrat de paiement; Food n'invente pas cette valeur.

Limites restantes

Les filtres avancés restent hors MVP. La ventilation expose les montants connus de Food et marque explicitement les frais externes encore absents.