Manuel administration fiscale
Téléchargement de l'export
fiscale
La gestion des exports fiscaux se trouve dans la partie Préférences -> Comptabilité :
L’interface présente tous les exportsexport 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.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 regroupecontient l’ensembletoutes desles factures et de leurs ligneslignes, surles règlements et les journaux d’activité pour une période maximale d’un an,an. accompagnée d’uneUne signature Ed25519 assurantgarantit la non-altérationl’intégrité des données.
La période couverte est précisée dans le nom de l’archive.
L’Contenu de l'archive
Fichiers de données
export_2024-01-01_2025-07-31.export_20251101_20251130.zip :archive ZIPArchive contenant lesfichiersdonnées JSONfactures-20251101-20251130.json: Factures de la période avec signatures blockchainreglements-20251101-20251130.json: Règlements de la période avec signatures blockchainlogs-20251101-20251130.json: Journaux d'export.
Fichiers de sécurité
export_2024-01-01_2025-07-31.export_20251101_20251130.zip.sig :signatureSignature cryptographique Ed25519 del’l'archive
Documentation
- README.md : l'équivalent de cette documentation au format markdown
- verifier_archive.html : Interface web de vérification
Structure des données.
Factures
factures-YYYYMMDD-YYYYMMDD.json
Tableau fichierd'objets factures.json contient toutescontenant les factures etavec leurs lignes enfants sous cette structure :
[
{
"siret": "378534440"12345678901234",
"numero": "000000001"251100001",
"date": "2025-09-23",
"nom" : "DUPUY",
"prenom" : "Jean",
"total_TTC": "1000.01-15T10:30:00",
"total_HT": "800.1250.00",
"total_TTC": "1500.00",
"signature": "aca7aaf2e5c93b0ee377...",
"previous_signature": "",
"signature": "abc123...",
"lignes": [
{
"siret": "378534440"12345678901234",
"facture": "000000001"251100001",
"code": "2159815",
"libelle": "ActeSemelle A"orthopédique",
"prixVente": "125.00",
"prixUnitaireHT": "104.17",
"totalHT": "104.17",
"quantite": 1,
"prix_unitaire_TTC": "1000.00",
"prix_unitaire_HT": "800.00",
"prix_total_HT": "800.00",
"tva": "20.00"
}
]
}
]
siret: Numéro SIRET de l'établissementnumero: Numéro unique de la facturedate: Date de création (ISO 8601)total_HT: Montant total hors taxestotal_TTC: Montant total toutes taxes comprisessignature: Signature blockchain de cette factureprevious_signature: Signature de la facture précédente (vide pourmaintenirlal’intégritépremière)lignes: Tableau des lignes delafacturation
reglements-YYYYMMDD-YYYYMMDD.json
Tableau signatured'objets Ed25519 de la facture.
Règlements
[
{
"siret": "378534440"12345678901234",
"facture": "251100001",
"user": "florian"Dr. Martin",
"facture"libelle": "000000001"Règlement Carte Bancaire",
"date_creation": "2025-09-23"01-15T10:35:00",
"date_reglement": "2025-09-23"01-15T10:35:00",
"montant": "1000.1500.00",
"mode": "CB",
"libelle": "Reglement M. ABC",
"signature": "abc123.ff187b00e19af92136bd...",
"previous_signature": "poiuyt.aca7aaf2e5c93b0ee377...",
},
]
siretla:signatureNuméro SIRET de l'établissementfacture: Numéro de la factureprécédenteassociéeusermaintenir:l’intégritéUtilisateur ayant enregistré le règlementlibelle: Description du règlementdate_creation: Date d'enregistrement du règlement (ISO 8601)date_reglement: Date effective du règlement (ISO 8601)montant: Montant du règlementmode: Mode delarèglementblockchain.
signature : previous_signature : Signature du règlement précédentlogs-YYYYMMDD-YYYYMMDD.json
Logs
Tableau
d'objets {
"model": "activitylog.activitylog",
"pk": 291,
"fields":[
{
"timestamp": "2025-06-24T12:02:44.257Z"01-15T10:30:00",
"user": "florian"Dr. Martin",
"action": "Impression"UPDATE",
"model": "Facture",
"object_pk"instance": 105,"251100001",
"diff": "{}\"status\": [\"brouillon\", \"object": {
validée\"pdf_file": ]}"/media/impressions/v2/factures_hors_teletrans/Facture-105.pdf"
},
"instance": "2c987",
"commentaire": "ImpressionValidation facturede 250600077la du type facture_hors_teletrans avec le modèle : Facture"facture",
"signature": "4c640482fc4253e4adab9a608513afa4717c1883c840fbfae1709f850d3f94e7"209e9cc27d6ebd9ccfbb...",
"previous_signature": "00232eaa0365661e4827daadd6e019b0199956fa385f5470eac383544e04fec8"ff187b00e19af92136bd..."
}
},]
timestamp:"activitylog.activitylog",Date"pk"et heure de l'action (ISO 8601)user:292,Utilisateur"fields"ayant effectué l'actionaction:{Type"timestamp"d'actionmodel:"2025-06-25T07:59:42.342Z",Type"user"d'objet modifié (Facture, Reglement, Patient, etc.)instance:"florian",Identifiant"action"de l'objet modifiédiff:"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": "2c987", "commentaire": "AperçuDétail des modifications (format JSON)commentaire:{'quantite'Commentaire optionnelsignature:[1,Signature2]}...",blockchain"signature"de ce logprevious_signature:"bc162eaaa1a018fa45d5b197633a25d7c7b0602bcfbd69628cc9a081f557607f",Signature"previous_signature"du log précédent
signature et previous_signature vides ou null.Système de sécurité
Signature cryptographique
L'archive utilise l'algorithme Ed25519 (courbes elliptiques) pour garantir :
- L'authenticité :
"c9460eb3b93bb34742e4774094a389f515d1255b6dd88f56a0376eea06146c94"L'archive}provient}bien...de votre système - L'intégrité : Aucune modification n'a été effectuée après génération
Blockchain
Chaque enregistrement (facture, règlement, log) contient :
signature: Hash cryptographique des données + signature précédenteprevious_signature: Signature de l'enregistrement précédent
Ce chaînage garantit :
- L'inaltérabilité : Impossible de modifier un enregistrement sans casser la chaîne
- La non-répudiation : Impossible de supprimer ou insérer un enregistrement
Vérification de l'exportarchive
Méthode de1 la: chaîneInterface deweb factures(recommandée - aucune installation requise)
VérifierModepuisautomatiquedécompresser: Si vous utilisez un serveur HTTP local (voir ci-dessous), les fichiers se chargent automatiquementexport_2024-01-01_2025-07-31.zipMode manuel : Sinon, un bouton apparaît pour sélectionner les 3 fichiers
Pour le JSONmode etautomatique vérifier(optionnel) chaque:
# règlementDans etle logdossier de Prérequisl'archive extraite
python3 -m http.server 8080
# Puis ouvrir: http://localhost:8080/verifier_archive.html
Méthode 2 : Vérification manuelle (pour l'exécutionexperts)
1. script
Python 3.x
InstallerVérifier la librairiesignature PyNaCl :
pip install pynacl
Aperçu du script pour analyse :
Ed25519
Python 3.xInstallerVérifier lalibrairiesignaturePyNaCl :
pip install pynaclimport 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):nacl.encoding
# Charger la clé publique
with open(verify_key_path,'export_20251101_20251130.zip.verify_key.pub', "r"'r') as f:
verify_key = VerifyKey(bytes.fromhex(f.read()))
# Vérifier signature ZIP
with open(zip_path, "rb") as f:
zip_bytesverify_key_hex = f.read()
verify_key = nacl.signing.VerifyKey(verify_key_hex, encoder=nacl.encoding.HexEncoder)
# Charger les données
with open(sig_path,'export_20251101_20251130.zip', "r"'rb') as f:
data = f.read()
# Charger la signature
with open('export_20251101_20251130.zip.sig', 'r') as f:
signature_hex = f.read()
signature = bytes.fromhex(signature_hex)
# Vérifier
try:
verify_key.verify(bytes.fromhex(signature_hex),data, zip_bytes)signature)
print("✅✓ Signature ZIP valide")
except:
print("❌✗ Signature ZIPinvalide invalide"- Archive compromise")
2. FalseVérifier #la Décompresserblockchain
Pour withchaque zipfile.ZipFile(zip_path,type "r")de asdonnées zip_file:(factures, withrèglements, zip_file.open("factures.json")logs), asvérifier f:que factures:
signature_N = json.load(f)Hash(données_N #+ Vérificationsignature_N-1)
Consultez le fichier verifier_archive.html (source JavaScript) pour l'implémentation complète 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înevérification de facturesblockchain.
Support
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 invalidePour toute
laquestionsuite.concernant
Notescontactez importantes
Présence Informatique.





