SDK Python : bientôt disponible officiellement. Cette documentation présente l'API telle qu'elle sera disponible ; la publication officielle est en cours de finalisation.

Simulateur DGI: la plateforme nationale d'e-facturation de la DGI n'est pas encore ouverte aux intégrations. La clairance (statuts ACCEPTED / REJECTED, référence, QR code) est aujourd'hui assurée par notre simulateur, qui reproduit le flux officiel. Le basculement vers la plateforme officielle se fera sans changement côté client. En savoir plus

SDK Python

Version publiée de efact

SDK officiel EFact pour Python ≥ 3.9, typé avec Pydantic v2. Toutes les opérations sur les factures sont exposées via efact.invoices.*.

En bref

Le SDK Python officiel d'EFact (efact) permet de créer et suivre des factures électroniques conformes DGI depuis Python. Installez-le avec pip install efact, initialisez le client avec votre clé secrète efact_sk_ chargée depuis l'environnement, puis créez vos factures : le SDK gère la génération UBL 2.1, la signature XAdES et la transmission côté serveur.

Installation

Installation
pip install efact

Initialisation

Basique

Basic Initialization
import os
from efact import EFact

# La clé secrète identifie ET authentifie votre organisation.
# Ne la committez jamais : chargez-la depuis l'environnement.
efact = EFact(os.environ["EFACT_SECRET_KEY"])

efact.invoices.create(data)

Signature

Method Signature
efact.invoices.create(data: CreateInvoiceRequest | dict) -> InvoiceResponse

Exemple complet

Complete Example
invoice = efact.invoices.create({
    "invoiceNumber": "INV-2026-001",
    "invoiceDate": "2026-06-24",
    "currency": "MAD",
    "paymentMethod": "BANK_TRANSFER",
    "buyerIce": "001234567890123",
    "buyerName": "Client SARL",
    "buyerAddress": "Casablanca",
    "lines": [
        {
            "lineNumber": 1,
            "description": "Prestation de service",
            "quantity": 1,
            "unitPrice": 1000,
            "vatRate": 20,
        },
    ],
})

print(invoice.id, invoice.status)

efact.invoices.retrieve(invoice_id)

Retrieve Invoice
invoice = efact.invoices.retrieve("550e8400-e29b-41d4-a716-446655440000")
print(invoice.status, invoice.invoice_number)

Lève EFactNotFoundError (HTTP 404) si la facture n’existe pas ou n’appartient pas au tenant.

efact.invoices.retrieve_status(invoice_id)

Retrieve Status
status = efact.invoices.retrieve_status("550e8400-e29b-41d4-a716-446655440000")
print(status.status, status.dgi_reference)

efact.invoices.list(...)

List Invoices
page = efact.invoices.list(page=0, size=20, status="ACCEPTED")
for inv in page.content:
    print(inv.invoice_number, inv.status)

Pagination par page/size, pas par curseur.

efact.invoices.update(invoice_id, data)

Update Invoice
# Uniquement pour une facture au statut PENDING - sinon 409
updated = efact.invoices.update("550e8400-e29b-41d4-a716-446655440000", {
    "dueDate": "2026-07-31",
    "buyerAddress": "Nouvelle adresse, Casablanca",
})

efact.invoices.cancel(invoice_id)

Cancel Invoice
# Uniquement pour une facture au statut PENDING
cancelled = efact.invoices.cancel("550e8400-e29b-41d4-a716-446655440000")
print(cancelled.status)  # 'CANCELLED'

Gestion des erreurs

Le SDK lève des erreurs typées, toutes héritées de EFactError. Toujours envelopper les appels dans un try/except :

Error Handling
from efact import (
    EFactApiError,
    EFactAuthError,
    EFactValidationError,
    EFactNotFoundError,
    EFactConflictError,
    EFactConnectionError,
    EFactTimeoutError,
)

try:
    efact.invoices.create(data)
except EFactValidationError as e:
    print("Champs invalides :", e.errors)
except EFactAuthError:
    print("Clé API manquante ou invalide.")
except EFactConflictError:
    print("Facture non modifiable (statut ≠ PENDING).")
except EFactApiError as e:
    print(e.code, e.http_status, e)
except EFactTimeoutError:
    print("Délai dépassé.")
except EFactConnectionError:
    print("Échec réseau.")

Hiérarchie des erreurs

ClasseCode HTTPQuand
EFactConfigError-Mauvaise configuration (avant tout appel réseau)
EFactAuthError401 / 403Clé API manquante ou invalide
EFactNotFoundError404Ressource introuvable (y compris hors tenant)
EFactValidationError400 / 422Payload invalide
EFactConflictError409Ex. modification/annulation d’une facture non PENDING
EFactApiError5xxErreur côté EFact
EFactTimeoutError-Délai dépassé avant réponse
EFactConnectionError-Échec réseau

Les requêtes GET, PUT et DELETE sont rejouées automatiquement (back-off exponentiel) sur timeout, erreur réseau, ou statuts HTTP 408/425/429/500/502/503/504, jusqu’à max_retries fois. POST (création) n’est jamais rejoué.

Intégration Django

views.py
# views.py
import os
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from efact import EFact

efact = EFact(os.environ["EFACT_SECRET_KEY"])

@require_POST
def create_invoice(request):
    import json
    body = json.loads(request.body)

    invoice = efact.invoices.create({
        "invoiceNumber": body["invoiceNumber"],
        "invoiceDate": body["invoiceDate"],
        "currency": "MAD",
        "paymentMethod": "BANK_TRANSFER",
        "buyerIce": body.get("buyerIce"),
        "buyerName": body.get("buyerName"),
        "buyerAddress": body.get("buyerAddress"),
        "lines": body["lines"],
    })

    return JsonResponse({"id": invoice.id, "status": invoice.status})

Statuts de facture

Le statut reflète le cycle de vie complet, aligné avec le backend :

StatutSignification
PENDINGCréée, modifiable, pas encore transmise
SIGNEDSignée (XAdES), en attente de transmission
TRANSMITTEDEnvoyée à la plateforme DGI, en attente de clairance
ACCEPTEDValidée par la DGI - référence et QR code disponibles
REJECTEDRejetée par la DGI - voir errorCode / errorMessage
FAILEDÉchec technique de traitement
CANCELLEDAnnulée (uniquement possible depuis PENDING)

Questions fréquentes

Comment installer le SDK Python d'EFact ?

Installez le paquet officiel depuis PyPI avec pip install efact, puis importez le client (from efact import EFact). Initialisez-le avec votre clé secrète chargée depuis l'environnement, puis créez et suivez vos factures via ses méthodes. Le SDK gère la génération UBL 2.1, la signature et la transmission côté serveur EFact.

Le SDK Python EFact est-il compatible avec les frameworks web ?

Oui. Le SDK Python s'utilise dans n'importe quelle application, y compris les frameworks web comme Django ou FastAPI : instanciez le client au démarrage, chargez la clé API depuis une variable d'environnement, et appelez ses méthodes depuis vos vues ou tâches de fond pour créer et suivre les factures.

Comment suivre le statut d'une facture avec le SDK Python ?

Après la création, interrogez le statut de la facture via la méthode dédiée du client, avec un intervalle de polling de 2 à 5 secondes. Une fois le statut ACCEPTED, vous récupérez la référence DGI et les artefacts. En production, les webhooks remplaceront le polling pour être notifié du statut final.