Manuel administration fiscale
Téléchargement de l'export
La gestion des exports se trouve dans la partie Préférences -> Comptabilité :
L’interface présente tous les exports générés depuis le début de l’utilisation du logiciel. L’utilisateur peut, via un bouton dédié, générer un nouvel export couvrant une période maximale d’un an. Cette page met également à disposition la clé publique nécessaire à la vérification des données, ainsi qu’un lien vers la documentation.
Utilisation de l'export
Cette documentation décrit la procédure de vérification de l’intégrité et de l’authenticité d’un export fiscal généré par le logiciel.
Chaque archive regroupe l’ensemble des factures et de leurs lignes sur une période maximale d’un an, accompagnée d’une signature Ed25519 assurant la non-altération des données.
La période couverte est précisée dans le nom de l’archive.
L’archive
Factures
[
{
"siret": "378534440",
"numero": "000000001",
"date": "2025-09-23",
"montant"nom" : "DUPUY",
"prenom" : "Jean",
"total_TTC": "1000.00",
"total_HT": "800.00",
"previous_signature": "",
"signature": "abc123...",
"lignes": [
{
"siret": "378534440",
"facture": "000000001",
"libelle": "Acte A",
"quantite": 1,
"montant"prix_unitaire_TTC": "1000.00",
"prix_unitaire_HT": "800.00",
"prix_total_HT": "800.00",
"tva": "20.00"
`}
]
}
]
Règlements
[
{
"siret": "378534440",
"user": "florian",
"facture": "000000001",
"dateCreation"date_creation": "2025-09-23",
"dateReglement"date_reglement": "2025-09-23",
"montant": "1000.00",
"mode": "CB",
"libelle": "Reglement M. ABC",
"signature": "abc123...",
"previous_signature": "poiuyt...",
},
]
Logs
{
"model": "activitylog.activitylog",
"pk": 291,
"fields": {
"timestamp": "2025-06-24T12:02:44.257Z",
"user": "florian",
"action": "Impression",
"model": "Facture",
"object_pk": 105,
"diff": {},
"object": {
"pdf_file": "/media/impressions/v2/factures_hors_teletrans/Facture-105.pdf"
},
"instance": "v2"2c987",
"commentaire": "Impression facture 250600077 du type facture_hors_teletrans avec le modèle : Facture",
"signature": "4c640482fc4253e4adab9a608513afa4717c1883c840fbfae1709f850d3f94e7",
"previous_signature": "00232eaa0365661e4827daadd6e019b0199956fa385f5470eac383544e04fec8"
}
},
{
"model": "activitylog.activitylog",
"pk": 292,
"fields": {
"timestamp": "2025-06-25T07:59:42.342Z",
"user": "florian",
"action": "Mise à jour",
"model": "LigneFacture",
"object_pk": 192,
"diff": { "quantite": [1, 2] },
"object": {
"code": "2110490",
"conditionnement": 1,
"dateActe": "2025-06-01",
"libelle": "CHUP, ADULTE NEUT, PODIABETES PARADIS, LA PAIRE",
"ligneParent": 0,
"lpp": 28075,
"montantRemboursementAMC": 0.0,
"montantRemboursementAMO": 0.0,
"nomCodeActe": "DVO",
"pcRO": null,
"prestaFse": null,
"prixSS": 55.02,
"prixUnitaireHT": 53.89,
"prixVente": 55.02,
...
},
"instance": "v2"2c987",
"commentaire": "Aperçu des modifications : {'quantite': [1, 2]}...",
"signature": "bc162eaaa1a018fa45d5b197633a25d7c7b0602bcfbd69628cc9a081f557607f",
"previous_signature": "c9460eb3b93bb34742e4774094a389f515d1255b6dd88f56a0376eea06146c94"
}
}
...
Vérification de l'archive et de la chaîne de factures
- Vérifier puis décompresser export_2024-01-01_2025-07-31.zip pour obtenir le fichier export.json.
- Charger le JSON et vérifier chaque facture et son chainage
Prérequis pour l'exécution du script
- Python 3.x
- Installer la librairie PyNaCl :
pip install pynacl
Aperçu du script pour analyse :
import json
import zipfile
from nacl.signing import VerifyKey
import hashlib
def compute_fiscal_hash(facture):
data = {
"numero": facture["numero"],
"date": facture["date"],
"montant": facture["montant"],
"type_client": facture["type_client"],
"lignes": sorted([
{"libelle": l["libelle"], "quantite": l["quantite"], "montant": l["montant"], "tva": l["tva"]}
for l in facture["lignes"]
], key=lambda x: x["libelle"])
}
json_data = json.dumps(data, sort_keys=True)
return hashlib.sha256(json_data.encode()).hexdigest()
def verify_archive_and_chain(zip_path, sig_path, verify_key_path):
# Charger clé publique
with open(verify_key_path, "r") as f:
verify_key = VerifyKey(bytes.fromhex(f.read()))
# Vérifier signature ZIP
with open(zip_path, "rb") as f:
zip_bytes = f.read()
with open(sig_path, "r") as f:
signature_hex = f.read()
try:
verify_key.verify(bytes.fromhex(signature_hex), zip_bytes)
print("✅ Signature ZIP valide")
except:
print("❌ Signature ZIP invalide")
return False
# Décompresser JSON
with zipfile.ZipFile(zip_path, "r") as zip_file:
with zip_file.open("factures.json") as f:
factures = json.load(f)
# Vérification de la chaîne
previous_sig = None
all_ok = True
for facture in factures:
fiscal_hash = compute_fiscal_hash(facture)
data_to_verify = fiscal_hash
if previous_sig:
data_to_verify += previous_sig
try:
verify_key.verify(bytes.fromhex(facture["signature"]), data_to_verify.encode())
print(f"✅ Facture {facture['numero']} OK")
except:
print(f"❌ Facture {facture['numero']} INVALIDE")
all_ok = False
previous_sig = facture["signature"]
if all_ok:
print("✅ La chaîne de factures est intacte")
else:
print("❌ La chaîne de factures est compromise")
return all_ok
# Exemple d'utilisation
if __name__ == "__main__":
verify_archive_and_chain("factures_archive.zip", "factures_archive.zip.sig", "verify_key.hex")
Interprétation des résultats
- ✅ Facture OK : intégrité de la facture et chainage valide.
- ❌ Facture INVALIDE : la facture a été modifiée ou la signature ne correspond pas.
- ✅ La chaîne de factures est intacte : toutes les factures sont conformes et la blockchain interne n’a pas été altérée.
- ❌ La chaîne de factures est compromise : au moins une facture a été modifiée, ce qui invalide toute la suite.

