Plateforme événementielle
VotArena
Plateforme événementielle pour l'Afrique francophone : compétitions à votes payants avec classement public en direct, billetterie QR livrée sur WhatsApp et reversements aux organisateurs, le tout réglé par Mobile Money. Conçue, développée et exploitée par un seul ingénieur, en ligne depuis mars 2026 avec une traction initiale vérifiable.
- Client
- Produit propre — Fingers Technologies
- Rôle
- Fondateur, CEO & CTO — unique ingénieur
- Période
- Mars 2026 – aujourd'hui
- Statut
- En production

Le problème
Au Cameroun, les concours — élections de miss, tremplins, galas — vendent du soutien payant, mais le décompte reste opaque. Les votes sont notés dans un cahier ou un tableur, et l'argent arrive sur le numéro personnel de quelqu'un, sans reçu. Quand un résultat est contesté, l'organisateur n'a aucune preuve à présenter et les acheteurs n'ont aucune raison de faire confiance à l'édition suivante.
Les outils de billetterie existants ne font que de la billetterie. Aucun ne réunit votes, billets, inscriptions, stands partenaires et ventes d'artistes sur un même compte, ne publie sa grille de répartition ni ne vérifie chaque événement avant sa mise en vente. Le Mobile Money est le moyen de paiement dominant, et les deux principaux opérateurs camerounais s'atteignent par des prestataires différents, aux contraintes différentes.
La contrainte technique découlait du produit : la plateforme devait encaisser de l'argent réel dès le premier jour, sur des connexions 3G et des écrans de 360 px, avec un seul ingénieur pour la construire, l'exploiter et assurer le support.
Le produit
VotArena fait tourner quatre lignes de produit sur un même code. Les compétitions à votes payants : votes réglés par Mobile Money, classement en direct, sessions de vote avec éliminations et kit de campagne WhatsApp par candidat. La billetterie : billet QR et code à 5 caractères envoyés sur WhatsApp, achat sans compte, rôle d'approbateur par événement et billet brûlé une seule fois à l'entrée. Un espace artistes avec vente de musique, boutique, tournées et liste de fans opt-in, ainsi que des inscriptions payantes et des stands partenaires.
Le socle commun est une PWA installable, en français et en anglais, avec connexion sans mot de passe par numéro WhatsApp. Les paiements passent par NOKASH pour MTN et Orange Cameroun, et par Tara Money pour les autres opérateurs, les autres pays, la carte bancaire et les liens de paiement. Les organisateurs consultent leur solde et demandent un retrait, versé sur leur numéro Mobile Money.
Le back-office couvre la super-administration, la modération, le support avec recherches journalisées, le suivi des dossiers de paiement partagé entre administrateurs et organisateurs, l'approbation des retraits et un journal d'audit des actions admin en écriture seule. La grille de commission est publique : 20 % sur les votes, 10 % sur les billets, 15 % sur la musique, 10 % sur la boutique, 0 % sur les inscriptions et les stands.
Mon rôle
J'ai fondé VotArena et je le dirige comme CEO et CTO au sein de Fingers Technologies. Je suis l'unique ingénieur : les 457 commits réalisés entre le 14 mars et le 25 septembre 2026 sont tous de moi, des spécifications produit et de l'architecture jusqu'au code, aux tests, au déploiement, à la supervision et au support.
En dehors du code, j'ai rédigé les contrats organisateurs, la tarification et le pitch deck, et je coordonne les volets commercial, financier et juridique.
Les défis
Router chaque paiement Mobile Money vers le bon prestataire sans rien demander à l'utilisateur
Le problème
NOKASH exige de connaître l'opérateur (MTN ou Orange) à l'avance et refuse les montants inférieurs à 200 FCFA. Tara Money accepte tout et détecte l'opérateur lui-même, mais coûte plus cher par transaction. Demander à un acheteur quel opérateur il utilise au moment d'un vote à 100 FCFA fait perdre la vente.
Ce que j'ai construit
Un PaymentRouter derrière un port déduit l'opérateur camerounais du préfixe du numéro, envoie MTN et Orange vers NOKASH et tout le reste — autres pays, Wave, montants sous le minimum — vers Tara. Une MobileMoneyGateway normalise l'initiation pour que le cas d'usage de vote ignore quel prestataire traite le paiement. La billetterie utilise une route NOKASH seule, sans repli.
Rendre chaque franc traçable sans jamais faire échouer un paiement réel
Le problème
Organisateurs et administrateurs doivent savoir où en est chaque paiement : initié, confirmé par le prestataire, crédité, reversé. Mais une panne de journalisation ou de projection ne doit jamais bloquer un client en train de payer.
Ce que j'ai construit
Un journal PaymentEvent en écriture seule, avec un contrat « au mieux » : les implémentations avalent leurs propres erreurs et les remontent à Sentry. Un décorateur du port projette chaque événement dans un dossier de paiement (client, numéro WhatsApp, billets, événement) dans un budget de 2,5 secondes, et un cas d'usage de reconstruction par lots rejoue le journal pour rattraper toute projection manquée. Les actions admin sont journalisées sous le même contrat.
Reverser les organisateurs sans double décaissement — et sans transactions en base
Le problème
Les reversements passent par l'API de décaissement NOKASH. Un callback perdu figeait une demande, un callback PENDING était traité comme un échec, et deux administrateurs cliquant sur « Approuver » pouvaient payer deux fois la même demande. L'offre d'hébergement n'exécute le cron qu'une fois par jour : la réconciliation ne peut pas reposer sur lui seul.
Ce que j'ai construit
Une machine à états WithdrawalRequest persistée par écritures conditionnelles : chaque mise à jour est filtrée sur le statut, la référence de paiement et le numéro lus auparavant, vérifie qu'exactement un document correspond, et ne fait jamais d'upsert. Le code ne contient aucune transaction MongoDB ; l'atomicité vient des mises à jour conditionnelles et des index uniques. La resynchronisation des statuts se déclenche de façon opportuniste au rafraîchissement de la file admin, un cron quotidien rattrape le reste, et les callbacks PENDING sont acquittés sans faire échouer la demande.
Connexion sans mot de passe par WhatsApp après le refus du modèle sortant par Meta
Le problème
Le plan initial était d'envoyer un code de connexion par WhatsApp. Meta a refusé le modèle Utility porteur du code : les codes sortants sont réservés à la catégorie Authentification, ouverte aux entreprises vérifiées. Le produit avait pourtant besoin d'une connexion sans mot de passe et sans e-mail.
Ce que j'ai construit
Le flux a été inversé : l'utilisateur envoie un court message de confirmation via un lien wa.me, et le webhook Meta signé attribue l'action au numéro expéditeur attesté par WhatsApp. Le même geste confirme un numéro, connecte et crée un compte. Un parcours OTP sortant, avec codes salés, fenêtres de validité et plafonds de tentatives, est prêt pour le jour où les modèles Authentification seront approuvés.
Une observabilité par cas d'usage qui ne met pas l'API en panne
Le problème
Les builds Turbopack ne bénéficient pas de l'auto-instrumentation Sentry à la compilation : il fallait instrumenter les cas d'usage à la main. Un premier essai a enveloppé chaque entrée du conteneur de dépendances dans un Proxy, y compris un booléen, et a mis toute l'API en panne le 24 septembre 2026.
Ce que j'ai construit
Un point d'instrumentation unique : à la construction du conteneur, une fonction générique enveloppe une seule fois chaque entrée qui passe un type guard sur sa méthode execute dans un Proxy qui ouvre un span de cas d'usage et capture les exceptions. Les dépôts reçoivent le même traitement. Le nettoyage des données personnelles est centralisé et l'envoi par défaut des PII est désactivé. C'est le type guard qui empêche l'incident de se reproduire.
Le résultat
- Votes payés
- 3 472381 920 FCFA, une compétition
- Commandes de billets
- 52259 242 FCFA confirmés
- Reversements payés
- 22466 352 FCFA
- Comptes utilisateurs
- 214
- Tests automatisés
- 6 087tous verts, 25 septembre 2026
au 23 septembre 2026
VotArena est en ligne sur votarena.com et encaisse des paiements réels. Lecture de la base de production le 23 septembre 2026 : 3 472 votes payés (381 920 FCFA), tous issus d'une seule compétition tenue en mars et avril 2026 ; 52 commandes de billets confirmées (259 242 FCFA) ; 22 reversements effectivement payés aux organisateurs (466 352 FCFA) ; 214 comptes utilisateurs. Le pitch deck du 3 septembre 2026 comptait 5 organisateurs.
Ce sont des chiffres de démarrage, pas une histoire de croissance : la vente terrain commence à peine. Ce qu'ils montrent, c'est un circuit de paiement qui fonctionne de bout en bout — achat d'un vote ou d'un billet, callback du prestataire, solde de l'organisateur, reversement — avec une piste d'audit à chaque étape.
Côté ingénierie : environ 120 000 lignes de TypeScript hors tests, 32 sous-domaines, 46 ports, 228 cas d'usage, 188 routes API, 62 pages et 3 596 clés de traduction en français et en anglais. La suite exécutée le 25 septembre 2026 fait tourner 6 087 tests répartis en 1 843 suites, tous verts ; une campagne de tests en juillet 2026 a révélé 15 bugs de production, tous corrigés. Une application Android (TWA) est construite mais pas encore publiée sur le Play Store.
Stack technique
- Frontend
- Next.js 16 (App Router)
- React 19
- TypeScript 5 strict
- Tailwind CSS 4 + shadcn/ui
- next-intl 4 (FR/EN)
- SWR
- PWA installable (service worker, manifeste web)
- Backend & architecture
- Route Handlers Next.js (188 routes API)
- Architecture hexagonale : domaine, ports, application, infrastructure, présentation
- Conteneur de dépendances typé
- Result<T, E> pour les erreurs métier plutôt que des exceptions
- Validation zod 4
- next-auth v5
- Données
- MongoDB Atlas via Mongoose 9 (44 schémas, 42 dépôts)
- Mises à jour conditionnelles et index uniques (sans transactions)
- Cache Redis en mode fail-open
- Cloudinary (images, URL audio signées)
- Paiements & messagerie
- NOKASH (encaissement MTN et Orange Cameroun, reversements aux organisateurs)
- Tara Money (autres opérateurs et pays, carte bancaire, liens de paiement)
- Webhooks authentifiés par comparaison en temps constant
- WhatsApp Cloud API (envoi des billets, webhook entrant signé)
- Infrastructure & observabilité
- Vercel (hébergement, cron quotidien)
- Sentry (spans par cas d'usage, nettoyage des PII, tunnel)
- docker-compose pour le développement local
- TWA Android construite avec Bubblewrap
- Tests & outillage
- Vitest 4 + jsdom : 6 087 tests, 1 843 suites
- Hook pre-commit qui exécute la suite
- ESLint 9 + Prettier
- Test d'alignement des catalogues de traduction


