Introduction
Le Driver MCF (Machine de Certification Fiscale) est un service local qui s'exécute sur le poste de travail et assure la communication entre votre logiciel de facturation et le terminal MCF Eltrade CC300. Il fonctionne en deux modes : mode local (API REST sur http://127.0.0.1:38917) et mode cloud (client WebSocket sortant vers le serveur SFE, pour les contextes SaaS multi-tenant où les opérateurs travaillent sur mobile ou tablette).
Nouveau : Binaire unifié v3.0
Le driver et la GUI sont maintenant regroupés dans un seul binaire e-mecef. La GUI ne démarre plus automatiquement le driver — celui-ci doit être lancé via le service système ou manuellement.
Sécurisé
JWT RS256 + HMAC-SHA256 pour l'intégrité des données
Léger
Binaire Rust autonome, aucune dépendance à installer
Multi-OS
Windows, macOS (Intel + Apple Silicon) et Linux
Architecture
Le système se compose de trois briques qui communiquent entre elles :
Le binaire unifié e-mecef contient le driver et la GUI. Mode local : le SFE appelle le driver en HTTP. Mode cloud : le driver se connecte au cloud SFE via WebSocket et reçoit les factures à certifier.
Installation du Driver
Téléchargez le binaire correspondant à votre système d'exploitation depuis la page de téléchargements. Le binaire unifié e-mecef contient à la fois le driver et la GUI.
WindowsInstallation Windows
- Téléchargez
e-mecef-windows-x64.exe - Placez le fichier dans un répertoire de votre choix (ex :
C:\eltrade\) - Double-cliquez pour lancer la GUI, ou installez comme service Windows (voir Tableau de bord)
- La GUI s'ouvre — utilisez la section Service système dans le tableau de bord pour installer le service
- Une fois le service installé et démarré, vérifiez :
http://127.0.0.1:38917/health
macOSInstallation macOS
- Téléchargez le bundle
e-mecef.app(recommandé) ou le binaire correspondant à votre architecture - Pour le bundle .app : glissez-le dans le dossier Applications
- Pour le binaire : rendez-le exécutable avec
chmod +x e-mecef-macos-arm64 - Au premier lancement, macOS peut demander une autorisation de sécurité (Préférences Système → Sécurité)
- Lancez la GUI et installez le service via le dashboard
LinuxInstallation Linux
# Téléchargement et installation
chmod +x e-mecef-linux-x64
sudo mv e-mecef-linux-x64 /usr/local/bin/e-mecef
# Lancement de la GUI
e-mecef
# Installation du service (depuis la GUI ou en ligne de commande)
e-mecef --driver-only # Mode driver seul (pour systemd)Pour un démarrage automatique, installez le service via la GUI ou créez manuellement un service systemd.
Configuration
La configuration du driver se fait via la GUI (onglet Paramètres) ou manuellement via un fichier .env. Le fichier est automatiquement créé par la GUI dans le répertoire de configuration de la plateforme.
| Variable | Défaut | Description |
|---|---|---|
DEVICE_PORT | (auto) | Port série du MCF. Vide = détection automatique par VID:PID. |
DEVICE_VID | 03EB | Vendor ID USB du MCF Eltrade. |
DEVICE_PID | 6119 | Product ID USB du MCF Eltrade. |
DEVICE_BAUD | 115200 | Vitesse de communication (bauds). |
DRIVER_PORT | 38917 | Port HTTP du serveur local du driver. |
DRIVER_HOST | 127.0.0.1 | Adresse d'écoute (ne pas modifier en prod). |
DRIVER_CORS_ORIGINS | (vide = Any) | Origines CORS autorisées, séparées par virgules. |
LICENSE_SERVER_URL | https://e-mecef.codarno.com | URL du serveur de licence E-MeCeF. |
LICENSE_FILE | ./license.json | Chemin vers le fichier de licence local. |
MCF_MOCK | false | true = simulateur MCF interne (pas de matériel requis) + vérification de licence désactivée. Réservé au développement — les factures générées ne sont pas fiscalement valides. |
DRIVER_MODE | local | Mode de fonctionnement : local (API HTTP 127.0.0.1 uniquement) ou cloud (client WebSocket sortant vers le serveur SFE). |
DRIVER_WSS_URL | (vide) | URL WSS du serveur SFE. Ex : wss://app.sfe.com/mcf/ws. Requis si DRIVER_MODE=cloud. |
DRIVER_API_KEY | (vide) | Clé d'API de l'organisation (= clé de licence) pour s'authentifier auprès du serveur SFE. Requis si DRIVER_MODE=cloud. |
Configuration recommandée
Utilisez la GUI pour configurer le driver. Les modifications sont automatiquement sauvegardées dans le fichier .env du répertoire de configuration.
Détection automatique du port série
Si DEVICE_PORT est vide, le driver recherche automatiquement le MCF par son identifiant USB (VID:PID). La route GET /ports retourne la liste des ports disponibles pour faciliter le diagnostic.

Activation de la licence
Pour émettre des factures certifiées, le driver doit être activé avec une clé de licence valide. L'activation lie la licence à la machine (via son NIM — Numéro d'Identification de la Machine).
Procédure d'activation
Obtenez une clé de licence
Achetez une licence depuis votre espace client E-MeCeF et récupérez la clé au format XXXXX-XXXXX-XXXXX-XXXXX.
Installez et démarrez le service
Lancez la GUI e-mecef, allez dans le dashboard et installez le service système. Démarrez le service.
Activez via l'interface GUI
Dans le dashboard, si la licence est invalide, un formulaire d'activation apparaît. Entrez votre clé et le NIM, puis cliquez sur Activer.
Vérification
L'activation est confirmée par un message de succès. La licence est sauvegardée localement dans license.json.

Activation via l'API
Vous pouvez également activer la licence directement via l'API REST :
POST http://127.0.0.1:38917/license/activate
Content-Type: application/json
{
"key": "ABCDE-FGHIJ-KLMNO-PQRST",
"nim": "NIM-de-la-machine"
}Interface graphique (GUI)
La GUI est une application de bureau native intégrée au binaire unifié. Elle comporte deux onglets : Tableau de bord et Paramètres.
Important : Démarrage du driver
La GUI ne démarre plus automatiquement le driver. Vous devez installer et démarrer le service système via le dashboard, ou lancer manuellement le driver avec e-mecef --driver-only.
Tableau de bord
L'onglet Tableau de bord est l'interface principale. Il regroupe le monitoring en temps réel et la gestion du service système :
Monitoring
- Driver — état En cours / Arrêté et numéro de version.
- Appareil MCF — Connecté, Non connecté, ou Mode mock (simulé) si MCF_MOCK=true.
- Licence — validité, plan, NIM, quota de factures (émises / max / restantes) et date d'expiration.
Service système
Le dashboard intègre la gestion du service système pour un démarrage automatique au boot :
- macOS — LaunchAgent launchd (flag --driver-only).
- Linux — service utilisateur systemd (flag --driver-only).
- Windows — Service Control Manager (flag --service).
Actions disponibles : Installer, Désinstaller, Démarrer et Arrêter le service.
Sur Windows, l'installation nécessite les droits administrateur. Un bouton "Relancer en admin" est proposé si nécessaire.
Activation de licence
Lorsque la licence est absente ou invalide, un formulaire d'activation apparaît directement dans le tableau de bord (champs clé de licence et NIM).

Paramètres
L'onglet Paramètres permet de configurer tous les aspects du driver :
- Port série MCF (ex. COM3 ou /dev/ttyUSB0), VID, PID et vitesse de communication (baudrate).
- Adresse et port HTTP du serveur local (hôte + port).
- URL du serveur de licence et chemin vers le fichier license.json.
- Mode mock MCF — case à cocher pour activer le simulateur sans matériel.
- Mode cloud (WebSocket) — sélecteur Local / Cloud, URL WSS et clé API (voir section dédiée ci-dessous).
Après enregistrement, les modifications prendront effet au prochain démarrage du driver. Redémarrez le service via le tableau de bord pour appliquer les changements.

Mode cloud (WebSocket)
Par défaut, le driver expose une API REST sur http://127.0.0.1:38917 (mode local). En activant le mode cloud, il initie lui-même une connexion WebSocket permanente vers le serveur SFE. Cette connexion est sortante — aucun port à ouvrir, fonctionne derrière n'importe quel NAT ou firewall.
DRIVER_MODE=localMode LOCAL (défaut)
API REST sur 127.0.0.1:38917 — le SFE appelle le driver directement depuis le même réseau local.
DRIVER_MODE=cloudMode CLOUD (nouveau)
Le driver se connecte au serveur SFE via WebSocket. Les factures sont poussées depuis le cloud et traitées localement.
Pourquoi le mode cloud ?
En mode cloud, les opérateurs peuvent être sur mobile, tablette ou un browser distant — ils ne peuvent jamais atteindre 127.0.0.1 d'un autre réseau. Le mode cloud résout ce problème : le driver établit lui-même la connexion vers le serveur SFE, qui peut ensuite pousser des factures à certifier depuis n'importe quel appareil connecté à Internet.
Flux de certification
Mobile / Browser
L'opérateur valide une facture dans l'interface SFE.
Cloud SFE
Le serveur stocke le payload MCF pré-calculé et pousse un message BILL vers le driver via WebSocket.
Driver MCF (local)
Le driver reçoit le message, appelle le terminal MCF via le port série et obtient le QR code + numéro DGI.
Cloud SFE
Le driver répond BILL_RESULT (status: success) avec le QR code. Le serveur met à jour la facture et notifie le client.
Mobile / Browser
L'opérateur voit la facture certifiée (QR code affiché), 1 à 3 secondes après validation.
Configuration
Activez le mode cloud via la GUI → Paramètres → Mode cloud (WebSocket) : sélecteur Local / Cloud, champs URL WSS et Clé API. Enregistrez puis redémarrez le service via le dashboard.
Ou manuellement dans le fichier .env :
DRIVER_MODE=cloud
DRIVER_WSS_URL=wss://app.sfe.com/mcf/ws
DRIVER_API_KEY=sk_org_xxxxxxxxxxxx # clé API fournie par l'admin SFEAuthentification
La clé API (DRIVER_API_KEY) est transmise lors de la poignée de main WebSocket (handshake HTTP/1.1 Upgrade), dans l'en-tête standard Authorization :
GET /mcf/ws HTTP/1.1
Host: app.sfe.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: <clé générée automatiquement>
Sec-WebSocket-Version: 13
Authorization: Bearer sk_org_xxxxxxxxxxxxLe serveur SFE doit vérifier cet en-tête avant d'accepter l'upgrade (répondre 401 Unauthorized si absent ou invalide). Une fois la connexion établie, aucun header supplémentaire n'est nécessaire — les messages JSON circulent librement sur le canal ouvert.
Reconnexion automatique
En cas de déconnexion, le driver se reconnecte automatiquement avec un exponential backoff (1 s → 2 s → 4 s → … → 60 s). Les factures reçues pendant la déconnexion restent en statut PENDING_MCF côté cloud et sont traitées dès que le driver se reconnecte.
Protocole de messages
Le WebSocket expose exactement les mêmes opérations que l'API HTTP. Tous les messages suivent le format uniforme { type, status, data|error }.
| Message entrant (Cloud → Driver) | Équivalent HTTP | Réponse (type) |
|---|---|---|
BILL | POST /bill | BILL_RESULT |
CHECK | GET /check | CHECK_RESULT |
INFO | GET /info | INFO_RESULT |
PORTS | GET /ports | PORTS_RESULT |
LICENSE_STATUS | GET /license/status | LICENSE_STATUS_RESULT |
LICENSE_ACTIVATE | POST /license/activate | LICENSE_ACTIVATE_RESULT |
LICENSE_RENEW | POST /license/renew | LICENSE_RENEW_RESULT |
Serveur → Driver (facture)
{ "type": "BILL", "invoiceId": "uuid", "payload": { ...BillInput... } }
{ "type": "PONG" }Driver → Serveur (succès)
{
"type": "BILL_RESULT",
"invoiceId": "uuid",
"status": "success",
"data": {
"qr_code": "BFSECEF01;...",
"security_code": "MOCKSIG000001",
"nim": "XX01000001-1",
"ifu": "0000000000001",
"invoice_number": "SFEMOCK001/1",
"datetime": "20260512210432",
"bill_counter": "1",
"total_counter": "1",
"bill_type": "FV",
"mcf_reference": "XX01000001-1-1"
}
}Driver → Serveur (erreur)
{ "type": "BILL_RESULT", "invoiceId": "uuid", "status": "error", "error": "Licence invalide" }
{ "type": "PING" } // heartbeat toutes les 30 sLe driver envoie un PING JSON toutes les 30 s. Le serveur doit répondre PONG. Si la connexion est perdue, le driver se reconnecte automatiquement (exponential backoff).
Référence API
Le driver expose une API REST sur http://127.0.0.1:38917. Les routes protégées nécessitent une licence valide.
| Méthode | Route | Auth. | Description |
|---|---|---|---|
| GET | /health | Non | Statut du driver, version, infos licence et device. |
| GET | /check | Non | Teste la connexion avec le MCF (port série). |
| GET | /ports | Non | Liste les ports série disponibles sur le système. |
| POST | /license/activate | Non | Active une licence avec clé + NIM de la machine. |
| POST | /license/renew | Non | Renouvelle le token JWT de la licence active. |
| GET | /license/status | Non | Retourne le statut de la licence courante. |
| GET | /info | Oui¹ | Informations du device MCF et contribuable. |
| POST | /bill | Oui¹ | Crée et certifie une facture sur le MCF. |
¹ En mode MCF_MOCK=true, la vérification de licence est désactivée pour toutes les routes protégées.
Exemple : créer une facture
Requête minimale avec un article et un paiement en espèces :
POST http://127.0.0.1:38917/bill
Content-Type: application/json
{
"isf": "SFE-2026-000042",
"invoice_number": "FAC-2026-000042",
"client_type": "PM",
"client_ifu": "1234567890123",
"client_name": "Entreprise ACME SARL",
"price_mode": "TTC",
"vt": "FV",
"products": [
{
"label": "Prestation de service informatique",
"tax": "B",
"price": 150000,
"quantity": 1,
"itype": "LOCSER"
}
],
"payments": [
{
"mode": "V",
"amount": 150000
}
]
}Réponse en cas de succès :
HTTP/1.1 200 OK
{
"qr_code": "BFSECEF01;XX01000001-1;MOCKSIG000001;0000000000001;20260511143000",
"security_code": "MOCKSIG000001",
"nim": "XX01000001-1",
"ifu": "0000000000001",
"invoice_number": "SFE-2026-000042",
"datetime": "20260511143000",
"bill_counter": "1",
"total_counter": "1",
"bill_type": "FV",
"mcf_reference": "XX01000001-1-1"
}Exemple : créer une facture d'avoir
Pour émettre un avoir sur une facture déjà certifiée, utilisez la valeur mcf_reference retournée par le POST /bill original comme champ rn. Le format attendu est {NIM}-{TC} (ex : AB01000001-1-50). Ne pas utiliser invoice_number — le MCF stocke sa propre référence interne et rejettera tout autre valeur.
POST http://127.0.0.1:38917/bill
Content-Type: application/json
{
"isf": "SFE-2026-000043",
"invoice_number": "AV-2026-000001",
"rt": "FA",
"receipt_nature": "RAN",
"rn": "XX01000001-1-1",
"price_mode": "TTC",
"products": [
{
"label": "Prestation de service informatique",
"tax": "B",
"price": 150000,
"quantity": 1,
"itype": "LOCSER"
}
],
"payments": [
{
"mode": "E",
"amount": 150000
}
]
}Modèles
BillInput — Corps de la requête POST /bill
| Champ | Type | Requis | Description |
|---|---|---|---|
isf | string | Oui | Identifiant Système de Facturation (ISF) — référence interne unique de la facture dans le SFE. |
invoice_number | string | Oui | Numéro de facture interne (affiché sur le ticket). |
products | ProductInput[] | Oui | Liste des articles de la facture (minimum 1). |
payments | PaymentInput[] | Oui | Liste des paiements (minimum 1). |
operator_id | string | Non | Identifiant de l'opérateur/caissier (OPID). Défaut : "1". |
operator_name | string | Non | Nom de l'opérateur/caissier (OPNOM). Défaut : "Caisse". |
client_type | "CC"|"PM"|"PP"|"PC" | Non | Type de client. CC = Client comptant (défaut), PM = Personne morale, PP = Personne physique, PC = Personne physique commerçant. |
client_ifu | string | Non | IFU du client (obligatoire si client_type = PM ou PP). |
client_name | string | Non | Nom ou raison sociale du client. |
client_address | string | Non | Adresse du client. |
client_phone | string | Non | Numéro de téléphone du client. |
client_email | string | Non | Adresse e-mail du client. |
client_rccm | string | Non | Numéro RCCM (Registre du Commerce) du client. |
price_mode | "TTC"|"HT" | Non | Mode de saisie des prix. TTC = toutes taxes comprises (défaut), HT = hors taxes. |
vt | "FV"|"FT"|"EV"|"ET" | Non | Type de facture vente. FV = Facture de vente (défaut), FT = Facture d'acompte, EV = Facture de vente à l'exportation, ET = Facture d'acompte à l'exportation. |
rt | "FA"|"EA" | Non | Type de facture d'avoir. FA = Facture d'avoir, EA = Facture d'avoir à l'exportation. Nécessite rn et receipt_nature. |
rn | string | Non | Référence MCF de la facture d'origine (obligatoire si rt est défini). Doit être la valeur mcf_reference retournée par le POST /bill de la facture originale. Format : {NIM}-{TC} (ex : "AB01000001-1-50"). Ne pas utiliser invoice_number — le MCF ne le reconnaîtra pas. |
receipt_nature | "COR"|"RAN"|"RAM"|"RRR" | Non | Nature de la facture d'avoir (obligatoire si rt défini). COR = Correction, RAN = Annulation, RAM = Avoir suite reprise de biens/services, RRR = Remise, ristourne, rabais. |
psvb | string | Non | Groupe PSVB (Prélèvement Sécurité Ventes Boissons) applicable : A | B | C | D. Vide ou absent = aucun précompte PSVB. Non applicable aux factures d'avoir. |
supplementary_info | AdditionalInfoEntry[] | Non | Informations supplémentaires libres (commentaires, régime fiscal, compte bancaire…) envoyées via la commande 36h. |
BillResponse — Réponse de POST /bill
| Champ | Type | Requis | Description |
|---|---|---|---|
qr_code | string | Oui | Code QR à imprimer sur la facture certifiée. Format : BFSECEF01;{NIM};{SIG};{IFU};{DT}. |
security_code | string | Oui | Code SECeF/DGI (SIG) — élément de sécurité à imprimer sur la facture. |
nim | string | Oui | Numéro d'Identification de la Machine (NIM) au format NIM-ACNT. |
ifu | string | Oui | Identifiant Fiscal Unique du contribuable. |
invoice_number | string | Oui | Numéro de facture SFE confirmé par le MCF. |
datetime | string | Oui | Date et heure de certification au format AAAAMMJJHHmmss. |
bill_counter | string | Oui | FC — compteur par type de facture. |
total_counter | string | Oui | TC — compteur total de factures (utilisé dans mcf_reference). |
bill_type | string | Oui | Type de facture certifiée (FV, FA, EV…). |
mcf_reference | string | Oui | Référence MCF de cette facture, à conserver et passer comme champ rn pour tout avoir ultérieur. Format : {NIM}-{TC} (ex : "AB01000001-1-50"). |
ProductInput — Article de facture
| Champ | Type | Requis | Description |
|---|---|---|---|
label | string | Oui | Désignation de l'article (1–64 caractères). |
tax | "A".."P" | Oui | Groupe de taxe MCF (16 groupes A à P selon la configuration du terminal). |
price | number | Oui | Prix unitaire (TTC ou HT selon price_mode), doit être positif. |
quantity | number | Non | Quantité (défaut : 1). |
itype | "LOCBIE"|"LOCSER"|"IMPBIE"|"IMPSER" | Non | Type d'article. LOCBIE = Bien local, LOCSER = Service local, IMPBIE = Bien importé, IMPSER = Service importé. |
internal_code | string | Non | Code interne / référence article (max 24 caractères). |
specific_tax_rate | string | Non | Taux de taxe spécifique (ex. "0.05" pour 5 %). À fournir avec specific_tax_total. |
specific_tax_total | number | Non | Montant total de la taxe spécifique calculé pour cette ligne. |
specific_tax_desc | string | Non | Libellé de la taxe spécifique. |
original_price | number | Non | Prix d'origine avant remise ou modification. |
price_change_explanation | string | Non | Motif du changement de prix. |
PaymentInput — Paiement
| Champ | Type | Requis | Description |
|---|---|---|---|
mode | "V"|"C"|"M"|"D"|"E"|"A" | Oui | Mode : V = Virement, C = Carte bancaire, M = Mobile Money, D = Chèque, E = Espèces, A = Autre. |
amount | number | Oui | Montant du paiement, doit être positif. |
AdditionalInfoEntry — Champ d'information supplémentaire (36h)
| Champ | Type | Requis | Description |
|---|---|---|---|
lid | string | Oui | Identifiant du champ. A..H = Lignes de commentaire A–H, REGIMP = Régime d'imposition, COMBAN = Comptes bancaires, SERIMP = Centre d'impôts. |
content | string | Non | Contenu du champ (texte libre, optionnel selon le LID). |
FAQ & Dépannage
Besoin d'aide supplémentaire ?
Contactez notre support ou consultez votre espace client.