Skip to Content
Enregistrement de produits par USSD (vendeurs en zone mal couverte)

Enregistrement de produits par USSD (vendeurs en zone mal couverte)

Statut : brouillon / proposition d’architecture — non implémenté. Aucun code n’existe encore dans apps/api pour ce module ; ce document sert de base de réflexion avant développement.


1. Contexte & Objectif

Une partie des vendeurs (agriculteurs, coopératives) opèrent dans des zones agricoles où la couverture internet (3G/4G) est faible ou absente, alors que la couverture réseau GSM voix/SMS/USSD y est quasi systématiquement meilleure. L’objectif est de leur permettre d’enregistrer un produit (nom, catégorie, prix, stock) via un menu USSD (*XXX#), sans connexion data, directement depuis un téléphone basique.

Ce que ce n’est pas : un remplacement du Dashboard vendeur. C’est un canal complémentaire, à minima fonctionnel, pour les cas où la connexion data n’est pas disponible.


2. Faisabilité technique

Oui, c’est faisable — c’est un pattern éprouvé sur d’autres plateformes agri-tech en Afrique (Esoko, Twiga Foods, iCow). Mais la plateforme ne “parle” pas directement au réseau GSM : il faut passer par un intermédiaire.

  • Opérateur / Agrégateur : on ne loue pas directement un short code auprès de MTN/Orange sans volume — en pratique on passe par un agrégateur (Africa’s Talking, Nsano, etc.) qui gère la relation avec les deux opérateurs camerounais et expose une API HTTP + un sandbox de test.
  • Intégration côté code : un nouveau contrôleur POST /ussd/callback dans apps/api (module ussd isolé, comme orders ou payments). Le protocole est simple (texte brut, code retour CON pour continuer la session / END pour la terminer) — pas de SDK complexe requis.

3. Impact sur l’architecture actuelle

AspectExistantBesoin USSD
AuthJWT + login email/passwordIdentification par numéro de téléphone (User.phone existe déjà) + PIN USSD dédié à créer
État de requêteAPI REST statelessSession conversationnelle multi-étapes, avec état à conserver entre chaque frappe (timeout ~2 min par écran)
Stockage de session—Aucun store éphémère dans la stack actuelle (pas de Redis, pas de table à TTL) — à ajouter
Données produit capturéesNom, description, prix, stock, catégorie, images, certificationsNom, prix, stock, catégorie uniquement — pas d’image possible en USSD (texte pur, ~180 caractères/écran)
RésultatProduit actif immédiatementProduit créé isActive: false (incomplet), à finaliser plus tard (photo ajoutée via Dashboard/app une fois connecté, ou par un agent terrain)

Conséquence sur le schéma Prisma :

  • Un modèle UssdSession (ou équivalent) : sessionId, phoneNumber, step, data (JSON partiel du produit en cours de saisie), expiresAt.
  • Un champ ussdPin (hashé) sur User, à définir par le vendeur une première fois via le Dashboard (avant de pouvoir utiliser l’USSD).
  • Un produit créé par ce canal doit être identifiable (createdVia: 'USSD' | 'WEB' ou équivalent) pour traçabilité/support.

4. Flux USSD proposé (brouillon)

Points à trancher plus tard : ordre des étapes, limite de caractères par écran selon l’agrégateur retenu, gestion du “retour” (0) et “menu principal” (00), langue (français uniquement au départ ou aussi langues locales ?).


5. Sécurité

  • PIN USSD distinct du mot de passe Dashboard (numérique, 4-6 chiffres, hashé comme le mot de passe).
  • Blocage après N tentatives échouées (protection brute-force — un short code est plus exposé qu’un formulaire web classique).
  • Le numéro de téléphone doit déjà être associé à un compte vendeur existant, actif (isActive: true) et validé (vendorStatus: APPROVED — voir Validation des comptes vendeur) — l’USSD n’est pas un canal d’inscription initiale, seulement de gestion produit pour un compte déjà créé et approuvé (via Dashboard ou un agent terrain). Un module ussd devra réutiliser (ou dupliquer) le même contrôle que ProductsService.create() avant d’insérer un Product.
  • Rate-limiting sur le endpoint webhook (/ussd/callback) — c’est un endpoint public exposé à l’agrégateur, pas derrière JWT classique ; l’authentification de la requête agrégateur→API se fait généralement par IP whitelisting + clé partagée fournie par l’agrégateur.

6. Logistique & partenariats (hors code)

  1. Choix du partenaire : agrégateur (Africa’s Talking, Nsano…) vs contrat direct MTN Cameroon / Orange Cameroon. L’agrégateur est plus rapide à mettre en place mais ajoute un intermédiaire (coût, dépendance).
  2. Obtention d’un short code : délai de plusieurs semaines, dossier administratif (souvent nécessite une entité enregistrée au Cameroun), coût de location récurrent.
  3. Modèle de facturation de la session : à la charge du vendeur (frein à l’adoption, l’objectif étant justement de faciliter l’accès) ou reverse-billed (pris en charge par la plateforme — coût opérationnel proportionnel à l’usage, à budgéter).
  4. Environnement de test : sandbox fourni par l’agrégateur, indispensable pour développer/valider les menus sans dépendre du réseau réel.
  5. Support : qui gère un vendeur bloqué (PIN oublié, session qui échoue) ? Prévoir une procédure (ex. réinitialisation du PIN par un admin depuis le Dashboard).

7. Phasage suggéré

PhaseContenuDépend de
0Choix de l’agrégateur + accès sandboxDécision business
1Module ussd (API) : session store, flux “ajouter un produit” en sandbox, sans short code réelPhase 0
2PIN USSD (création/reset depuis le Dashboard vendeur)— (peut démarrer en parallèle de la phase 1)
3Tests avec de vrais vendeurs pilotes sur le sandboxPhase 1 + 2
4Obtention du short code + mise en productionPhase 3 validée + accord commercial signé

8. Risques & points ouverts

  • Produits incomplets : un produit sans photo est-il affiché dans le catalogue (avec image par défaut) ou reste-t-il masqué jusqu’à complétion ? Impact direct sur l’expérience acheteur si trop de produits “sans photo” apparaissent.
  • Volume réel du besoin : combien de vendeurs actuels/ciblés sont réellement en zone non couverte data ? À valider avant d’investir dans un short code (coût récurrent même à faible usage).
  • Alternative moins coûteuse à considérer : un flux SMS (au lieu d’USSD) pourrait couvrir une partie du besoin à moindre coût d’intégration (pas de session temps réel à gérer), au prix d’une UX plus rigide (format de message strict). À évaluer comme option de repli ou complément — voir Notifications SMS (Passerelle légère) pour l’approche déjà envisagée pour l’envoi de SMS sortants.
  • Maintenance des menus : toute évolution du catalogue de catégories doit rester synchronisée avec les choix numérotés du menu USSD (texte statique côté agrégateur vs données dynamiques côté DB).

9. Ce qui n’est PAS dans ce plan (hors périmètre)

  • Paiement / retrait d’argent par USSD (Mobile Money) — déjà couvert par l’intégration MTN MoMo / Orange Money existante côté web, pas de besoin identifié de le dupliquer en USSD pour l’instant.
  • Consultation des commandes/statistiques de vente par USSD — pourrait être une itération future si le canal “ajout produit” fonctionne bien.
Last updated on