Egonix Cards — cartes de visite NFC

Des cartes de visite NFC : on touche la carte, le contact arrive dans un espace où il s’exporte, se segmente et se relance.

Egonix Cards — cartes de visite NFC
Rôle
CTO et co-fondateur
Stack
Laravel 13 · Livewire 3 · Filament 4
Produit
Cartes de visite NFC
Statut
En ligne

Contexte

Une carte de visite papier se perd, et le contact échangé sur un salon ne finit presque jamais dans un fichier exploitable. Egonix remplace la carte par une carte NFC : on la touche avec un téléphone ou on scanne son QR code, et le contact atterrit dans un espace où il peut être exporté, segmenté et relancé.

Défi métier

Transformer un contact pris en personne en prospect exploitable et exportable, sans perdre la carte papier.

Solution

Une seule application Laravel 13 : l’interface utilisateur en Livewire avec MaryUI, l’administration en Filament 4. Chaque carte est identifiée par un UUID qui sert à la fois d’URL publique et de cible de l’API de capture. Les règles métier vivent dans des services, les droits passent par des policies, et les quotas dépendent du forfait Free, Premium ou Entreprise.

Résultat

En ligne, en français et en anglais : profil public avec vCard et QR code, éditeur de carte en cinq phases, espace entreprise avec invitations, rôles et kit de marque, campagnes e-mail, clés API et webhooks signés. Sécurité, CI, Sentry et tests Playwright ont été livrés lors de la relance de mars 2026.

Mon rôle

CTO et co-fondateur

Architecture

Utilisateurs

  • Carte NFC et QR code
  • Tableau de bord personnel
  • Espace entreprise
  • Administration Filament
  • Intégrations (API, webhooks)

Application

  • Laravel 13 · Livewire 3 · MaryUI
  • Profil public /c/{uuid}
  • API de capture et clés API
  • Services contacts, facturation, webhooks
  • File en base de données
  • Policies et 2FA

Services externes

  • Stripe · Cashier
  • OAuth Google, Apple, LinkedIn
  • Sentry (données personnelles masquées)
  • MySQL (production)
  • Image Docker sur GHCR

Le parcours, étape par étape

  1. Contact

    Une personne touche la carte : la puce ouvre /c/{uuid}, qui affiche le profil, redirige vers une URL ou télécharge une vCard selon le réglage de la carte.

  2. Capture

    Elle laisse ses coordonnées dans le formulaire, ou une intégration appelle l’API de capture avec une clé API.

  3. Validation et quota

    La requête est validée, puis le quota du forfait est vérifié ; au-delà, l’API répond 422.

  4. Enregistrement

    Le contact est créé et rattaché au profil de la carte.

  5. Webhook

    L’événement contact.created part vers les URL du client, signé en HMAC, avec trois tentatives.

  6. Exploitation

    Le propriétaire retrouve le contact, l’exporte en CSV ou XLSX, ou l’ajoute à une campagne.

Modèle de données

Les entités principales, leurs champs clés et leurs relations.

User

  • role_id · society_id
  • colonnes Stripe
  • colonnes 2FA
  • langue
  • 1—n Nfc
  • 1—n Contact
  • 1—n Profile

Nfc (carte)

  • uuid (clé primaire)
  • profile_id · status_id
  • design (matériau, couleurs)
  • n—1 Profile
  • 1—n NfcDesignVersion

Profile

  • identité
  • theme_id · address_id
  • team_id
  • n—n Contact

Contact

  • email · phone
  • source · nfc_id
  • marketing_consent · locale
  • n—n Tag
  • n—1 Segment
  • 1—n Activity

Society (entreprise)

  • owner_id
  • logo · thème
  • kit de marque
  • n—n User (rôle)
  • 1—n SocietyInvitation

EmailCampaign

  • status
  • scheduled_at
  • segment
  • 1—n EmailCampaignRecipient

ApiKey

  • key_hash
  • last_used_at
  • revoked_at
  • n—1 User

OutgoingWebhook

  • secret chiffré
  • events
  • failure_count
  • 1—n WebhookDelivery

Fiche technique complète

Langages
PHP 8.4, JavaScript, TypeScript (Playwright)
Framework
Laravel 13
Front
Livewire 3, MaryUI 2, Tailwind 3, DaisyUI 4, Vite 8, Chart.js, design system interne
Administration
Filament 4, 8 ressources
Base de données
MySQL en production, SQLite en développement et en CI
Files
Pilote base de données : livraison des webhooks (3 tentatives) et envoi des campagnes
Authentification
Sessions, OAuth Google, Apple et LinkedIn, 2FA TOTP, vérification d’e-mail obligatoire, Sanctum
Paiement
Stripe Checkout et Cashier 16, changement de forfait, essais et codes promo
NFC
La puce porte l’URL /c/{uuid} ; QR code généré ; vCard construite côté serveur
API
Spécification OpenAPI lintée par Spectral, documentation Swagger désactivée par défaut en production
Hébergement
Image Docker multi-étapes publiée sur GHCR à chaque tag ; Apache en production
CI/CD
GitHub Actions sur runner auto-hébergé : Pint, PHPUnit, build, E2E planifiés, audits Composer et npm
Tests
PHPUnit 12 (117 tests), Playwright (environ 65 tests)
Observabilité
Sentry côté serveur et navigateur, avec masquage des données personnelles
Langues
Français et anglais, langue enregistrée par contact
Sécurité
En-têtes de sécurité, garde anti-SSRF sur les webhooks, clés API hachées, débit limité par forfait, protection contre l’injection de formules dans les CSV, journal d’audit

Fonctionnalités clés

  • Éditeur de carte

    Modèles, palette, placement libre, annuler et rétablir, matériau, historique des versions.

  • Profil public

    vCard, redirection ou profil, et QR code.

  • Contacts

    Import CSV guidé avec dédoublonnage, export CSV et XLSX, tags et segments.

  • Espace entreprise

    Invitations, rôles, kit de marque verrouillé, statistiques et commandes en volume.

  • Campagnes

    E-mails et séquences, avec gestion du consentement.

  • Intégrations

    Clés API et webhooks sortants signés.

Problèmes résolus

  1. Erreur 500 sur l’espace entreprise

    ProblèmeLe mode strict de MySQL refusait un GROUP BY sur une expression ; SQLite ne le contrôle pas, les tests passaient.

    SolutionRegroupement sur l’alias, corrigé en production le jour même.

  2. Toutes les icônes cassées en production

    ProblèmeL’alias global /icons/ d’Apache interceptait les requêtes du sprite.

    SolutionSprite déplacé dans un dossier qui n’entre pas en conflit.

  3. Requêtes Livewire falsifiables

    ProblèmeLa sauvegarde du design acceptait des identifiants modifiés côté navigateur.

    SolutionContrôle de propriété et identifiants verrouillés côté serveur.

  4. Authentifier l’API sans casser les intégrations

    ProblèmeDes intégrations existantes appelaient l’API de capture sans clé.

    SolutionActivation par phases, en-têtes Deprecation et Link, et une date limite configurable.

  5. Domaine disparu

    ProblèmeLes cartes pointaient vers un ancien domaine qui ne résolvait plus.

    SolutionLe domaine des cartes est dérivé de APP_URL.

Choix techniques

Choix Pourquoi
File, cache et session en base Aucun Redis à faire tourner, en développement comme en production.
UUID comme identifiant public L’URL de la carte ne révèle ni le nombre de cartes ni leur ordre.
Filament pour l’administration seulement L’interface client garde son design system ; l’administration profite des ressources prêtes à l’emploi.
Documentation OpenAPI coupée en production Elle s’active par une variable quand c’est utile.

Chronologie

  1. Avril 2024 Premier commit, modèles et migrations
  2. Mars 2026 Relance : site, tableaux de bord et cartes NFC
  3. Mars 2026 Stripe, 2FA, webhooks, CI, Sentry et Playwright
  4. Juin 2026 Version 2.0.18
  5. Août 2026 Design system v3 et refonte
  6. Septembre 2026 Éditeur de carte en cinq phases

En chiffres

160
commits, dont 145 de ma main
66
modèles
65
migrations
~180
tests (PHPUnit et Playwright)

Relevé dans le code source et l’historique Git du projet le 8 octobre 2026. Aucun chiffre d’usage ou de revenu n’est publié.

Projets similaires

SaaS
janv. 2024 — présent
Finnexus — projet Laravel Finance
SaaS finance entreprise : analytics, prévisions et trésorerie.
Laravel, Livewire, TailwindCSS, Stripe
Voir le projet
SaaS
oct. 2024 — présent
Vetzy — projet Laravel SaaS
Plateforme SaaS vétérinaire de prise de rendez-vous pour cliniques et propriétaires d’animaux.
PHP, Laravel, Livewire, TailwindCSS, SaaS
Voir le projet
SaaS
janv. 2024 — présent
StreamCrea — tableau de bord des créateurs
Synchro Twitch, YouTube et Kick, publication multi-réseaux et blog pour abonnés.
PHP, Laravel, Livewire, Stripe
Voir le projet
SaaS
janv. 2022 — déc. 2022
MissionsCMS — projet Web App
Système de gestion de missions avec suivi et tableaux de bord.
Laravel, Livewire, Alpine.js, TailwindCSS
Voir le projet

Disponible pour missions PHP / Laravel / WordPress / Silverstripe en Belgique et remote EU.