Skip to content

Conformite Fiscale NF525/ISCA

Version: 1.0 Norme: NF525 / ISCA (Inalterabilite, Securisation, Conservation, Archivage) Base legale: Article 286-I-3 bis du Code General des Impots (Loi de Finances 2026)


Table des matieres

  1. Introduction
  2. Architecture Fiscale
  3. Immutabilite
  4. Integrite de la Chaine de Hachage
  5. Clotures
  6. Ancrage (Timestamping)
  7. Kill Switch
  8. Export FEC
  9. Regles Fiscales
  10. API Fiscale

1. Introduction

Qu'est-ce que NF525/ISCA ?

La norme NF525 (devenue ISCA dans sa version 2024+) definit les exigences de conformite pour les logiciels de caisse et de facturation en France. Elle impose quatre garanties fondamentales :

ExigenceDescriptionImplementation Scell.io
InalterabiliteLes donnees fiscales ne peuvent etre modifiees apres validationTriggers SQL, immutabilite Eloquent, audit log
SecurisationLes donnees sont protegees contre toute alterationChaine SHA-256, ancrage RFC 3161 TSA
ConservationLes donnees sont conservees pendant la duree legaleRetention 6 ans minimum, archivage S3
ArchivageLes donnees peuvent etre restituees a l'administrationExport FEC conforme, export forensique

Pourquoi c'est obligatoire en France ?

Depuis la Loi de Finances 2018 (renforcee en 2026), tout logiciel de facturation utilise par une entreprise assujettie a la TVA doit etre certifie conforme NF525 ou produire une attestation de conformite de son editeur. Le non-respect expose a une amende de 7 500 EUR par logiciel non conforme.

Ce que Scell.io implemente

Scell.io implemente l'integralite des exigences ISCA au niveau applicatif et base de donnees :

  • Grand livre fiscal (fiscal ledger) avec chaine de hachage SHA-256
  • Triggers PostgreSQL pour l'immutabilite des ecritures
  • Clotures journalieres et mensuelles automatiques
  • Ancrage RFC 3161 TSA pour preuve d'anteriorite
  • Export FEC conforme a l'article A.47 A-1 du LPF
  • Kill switch pour arret d'urgence
  • Piste d'audit complete de toute tentative de modification

2. Architecture Fiscale

Diagramme du flux complet

mermaid
graph TD
    subgraph "Evenements Source"
        INV["Facture creee/validee/transmise"]
        CN["Avoir cree/envoye"]
        PAY["Paiement recu"]
    end

    subgraph "Grand Livre Fiscal"
        FE["FiscalEntry<br/>Ecriture fiscale"]
        FS["FiscalSequence<br/>Compteur atomique"]
        HASH["Chaine SHA-256<br/>data_hash + previous_hash = chain_hash"]
    end

    subgraph "Clotures"
        DC["Cloture journaliere<br/>(00:05 UTC)"]
        MC["Cloture mensuelle<br/>(1er du mois)"]
        ATT["Attestation annuelle"]
    end

    subgraph "Preuves"
        TSA["Ancrage RFC 3161 TSA<br/>(Timestamp Authority)"]
        FEC["Export FEC<br/>(DGFIP)"]
        FOR["Export forensique"]
    end

    subgraph "Securite"
        KS["Kill Switch<br/>(arret d'urgence)"]
        IC["Verification d'integrite<br/>(02:00 UTC)"]
        AL["Audit Log<br/>(tentatives de modification)"]
    end

    INV --> FE
    CN --> FE
    PAY --> FE
    FE --> FS
    FS --> HASH
    HASH --> DC
    DC --> MC
    MC --> ATT
    DC --> TSA
    MC --> TSA
    FE --> IC
    IC --> AL
    FE --> FEC
    FE --> FOR
    KS -.->|"bloque"| FE

Modeles de donnees

Le systeme fiscal repose sur 9 modeles interconnectes :

ModeleTableRole
FiscalEntryfiscal_entriesEcriture fiscale unitaire (append-only)
FiscalSequencefiscal_sequencesCompteur de sequence atomique par tenant
FiscalClosingfiscal_closingsCloture journaliere/mensuelle/annuelle
FiscalAttestationfiscal_attestationsAttestation de conformite annuelle
FiscalAnchorfiscal_anchorsAncrage TSA (preuve d'anteriorite)
FiscalKillSwitchfiscal_kill_switchesHistorique des arrets d'urgence
FiscalIntegrityCheckfiscal_integrity_checksResultats des verifications d'integrite
FiscalRulefiscal_rulesRegles fiscales configurables par tenant
FiscalRuleApplicationfiscal_rule_applicationsJournal d'application des regles

Services

ServiceFichierResponsabilite
FiscalLedgerServiceServices/Fiscal/FiscalLedgerService.phpGrand livre, enregistrement, verification
FiscalAnchoringServiceServices/Fiscal/FiscalAnchoringService.phpAncrage TSA, attestations
FecExportServiceServices/Fiscal/FecExportService.phpExport FEC conforme DGFIP
FiscalForensicExportServiceServices/Fiscal/FiscalForensicExportService.phpExport forensique complet
FiscalVersionChangeDetectorServices/Fiscal/FiscalVersionChangeDetector.phpDetection de changement de version logicielle

3. Immutabilite

L'immutabilite est la pierre angulaire de la conformite NF525. Scell.io l'implemente a trois niveaux.

Niveau 1 : Modele Eloquent

Les modeles Invoice et CreditNote definissent des champs fiscaux immutables :

php
// Invoice.php
const IMMUTABLE_FISCAL_FIELDS = [
    'total_ht', 'total_ttc', 'total_tax', 'invoice_number',
    'issue_date', 'seller_name', 'seller_siret', 'seller_address',
    'buyer_name', 'buyer_siret', 'buyer_address', 'currency',
    'user_id', 'company_id',
];

Des qu'une facture quitte le statut draft, toute tentative de modification de ces champs :

  1. Est bloquee par un RuntimeException
  2. Est enregistree dans FiscalAuditLog avec la severite critical
  3. Inclut l'identifiant de l'acteur, l'adresse IP et le user-agent
php
// Protection dans le modele Invoice (booting)
protected static function booting(): void
{
    static::updating(function (Invoice $invoice) {
        if ($invoice->status !== 'draft') {
            $changedFiscalFields = array_intersect(
                array_keys($invoice->getDirty()),
                self::IMMUTABLE_FISCAL_FIELDS
            );
            if (!empty($changedFiscalFields)) {
                FiscalAuditLog::record([
                    'event_type' => 'modification_attempt',
                    'target_table' => 'invoices',
                    'target_id' => $invoice->id,
                    'severity' => 'critical',
                    'details' => ['fields' => $changedFiscalFields],
                ]);
                throw new \RuntimeException(
                    'Modification interdite : champs fiscaux immutables.'
                );
            }
        }
    });
}

Niveau 2 : Triggers PostgreSQL

La migration 2026_02_10_000005_add_fiscal_immutability_triggers installe des triggers SQL qui protegent les donnees directement au niveau de la base de donnees, meme en cas de contournement de l'application :

sql
-- Empecher la modification des ecritures fiscales
CREATE OR REPLACE FUNCTION prevent_fiscal_entry_update()
RETURNS TRIGGER AS $$
BEGIN
    RAISE EXCEPTION 'Les ecritures fiscales sont immutables (NF525)';
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tr_fiscal_entries_immutable
BEFORE UPDATE ON fiscal_entries
FOR EACH ROW
EXECUTE FUNCTION prevent_fiscal_entry_update();

-- Empecher la suppression des ecritures fiscales
CREATE TRIGGER tr_fiscal_entries_no_delete
BEFORE DELETE ON fiscal_entries
FOR EACH ROW
EXECUTE FUNCTION prevent_fiscal_entry_delete();

Niveau 3 : Journal d'audit

Le trait LogsImmutabilityViolation est applique aux modeles fiscaux. Toute tentative de modification est tracee :

php
FiscalAuditLog::record([
    'event_type' => 'modification_attempt',  // ou deletion_attempt, deletion_blocked
    'event_source' => 'eloquent',            // ou sql_trigger, api
    'target_table' => 'fiscal_entries',
    'target_id' => $entry->id,
    'severity' => 'critical',
    'actor_type' => 'user',                  // ou api_key, system
    'actor_id' => auth()->id(),
    'ip_address' => request()->ip(),
    'user_agent' => request()->userAgent(),
    'details' => ['attempted_changes' => $dirty],
]);

Suppression interdite

Les factures et avoirs valides (statut != draft) ne peuvent pas etre supprimes. Les soft deletes sont desactivees sur les ecritures fiscales (FiscalEntry n'utilise pas SoftDeletes). Le grand livre est strictement en mode append-only.


4. Integrite de la Chaine de Hachage

Principe

Chaque ecriture fiscale (FiscalEntry) est liee a la precedente par un hash cryptographique SHA-256, formant une chaine inalterable :

Entry #1: chain_hash = SHA256(data_hash_1 + "0000...0000")
Entry #2: chain_hash = SHA256(data_hash_2 + chain_hash_1)
Entry #3: chain_hash = SHA256(data_hash_3 + chain_hash_2)
...
Entry #N: chain_hash = SHA256(data_hash_N + chain_hash_N-1)

Calcul du hash

php
// FiscalEntry::record() - methode statique, seul point de creation
public static function record(
    ?string $tenantId,
    string $entryType,
    string $entityType,
    string $entityId,
    string $fiscalDate,
    array $dataSnapshot,
    string $environment,
    string $legalStatus,
    string $actorType,
    ?string $actorId,
    ?string $ipAddress,
    ?string $userAgent,
): self {
    return DB::transaction(function () use (...) {
        // 1. Obtenir le prochain numero de sequence (atomique)
        $sequence = FiscalSequence::lockForUpdate()
            ->where('tenant_id', $tenantId)
            ->first();
        $sequenceNumber = $sequence->last_sequence_number + 1;

        // 2. Calculer le hash des donnees
        $dataHash = hash('sha256', json_encode($dataSnapshot, JSON_UNESCAPED_UNICODE));

        // 3. Recuperer le hash precedent
        $previousEntry = self::where('tenant_id', $tenantId)
            ->orderBy('sequence_number', 'desc')
            ->first();
        $previousHash = $previousEntry?->chain_hash ?? str_repeat('0', 64);

        // 4. Calculer le hash de chaine
        $chainHash = hash('sha256', $dataHash . $previousHash);

        // 5. Creer l'ecriture (append-only)
        $entry = self::create([
            'tenant_id' => $tenantId,
            'sequence_number' => $sequenceNumber,
            'entry_type' => $entryType,
            'data_hash' => $dataHash,
            'previous_hash' => $previousHash,
            'chain_hash' => $chainHash,
            'data_snapshot' => $dataSnapshot,
            // ...
        ]);

        // 6. Mettre a jour la sequence
        $sequence->increment('last_sequence_number');

        return $entry;
    });
}

Verification d'integrite

Le FiscalLedgerService::verifyChainIntegrity() rejoue l'integralite de la chaine pour detecter toute falsification :

php
public function verifyChainIntegrity(Tenant $tenant, ?Carbon $from, ?Carbon $to): array
{
    $query = FiscalEntry::forTenant($tenant->id)
        ->orderBy('sequence_number', 'asc');

    if ($from) $query->where('fiscal_date', '>=', $from);
    if ($to) $query->where('fiscal_date', '<=', $to);

    $entries = $query->get();
    $discrepancies = [];
    $previousHash = str_repeat('0', 64);

    foreach ($entries as $entry) {
        // Recalculer le hash des donnees
        $expectedDataHash = hash('sha256', json_encode($entry->data_snapshot));
        if ($expectedDataHash !== $entry->data_hash) {
            $discrepancies[] = [
                'type' => 'data_hash_mismatch',
                'sequence' => $entry->sequence_number,
            ];
        }

        // Verifier la chaine
        $expectedChainHash = hash('sha256', $entry->data_hash . $previousHash);
        if ($expectedChainHash !== $entry->chain_hash) {
            $discrepancies[] = [
                'type' => 'chain_break',
                'sequence' => $entry->sequence_number,
            ];
        }

        $previousHash = $entry->chain_hash;
    }

    return [
        'result' => empty($discrepancies) ? 'valid' : 'invalid',
        'entries_checked' => $entries->count(),
        'discrepancies' => $discrepancies,
    ];
}

Verification automatique

La commande FiscalIntegrityCheckCommand s'execute automatiquement chaque jour a 02:00 UTC :

bash
# Configuration dans le scheduler Laravel
$schedule->command('fiscal:integrity-check')->dailyAt('02:00');

Le resultat est enregistre dans la table fiscal_integrity_checks avec le nombre d'entrees verifiees, le nombre d'anomalies trouvees et le chemin du rapport.


5. Clotures

Cloture journaliere

La cloture journaliere s'execute automatiquement a 00:05 UTC via la commande FiscalDailyClosingCommand :

bash
php artisan fiscal:daily-closing

Elle produit un enregistrement FiscalClosing contenant :

ChampDescription
closing_dateDate cloturee
closing_typedaily
entries_countNombre d'ecritures de la journee
opening_balanceSolde d'ouverture
closing_balanceSolde de cloture
total_operationsSomme des operations de la journee
fec_export_pathChemin du FEC journalier (optionnel)
closed_atHorodatage de la cloture

La cloture est elle-meme enregistree comme une ecriture fiscale dans le grand livre (entry_type: closing), garantissant son inclusion dans la chaine de hachage.

Cloture mensuelle

La cloture mensuelle s'execute le 1er de chaque mois via FiscalMonthlyClosingCommand :

bash
php artisan fiscal:monthly-closing

Elle agrege les clotures journalieres du mois et genere un enregistrement FiscalClosing de type monthly.

Attestation annuelle

A la fin de chaque exercice fiscal, une FiscalAttestation est generee automatiquement :

php
FiscalAttestation::create([
    'tenant_id' => $tenant->id,
    'year' => 2025,
    'attestation_type' => 'annual',
    'software_name' => 'Scell.io',                     // config('fiscal.attestation.software_name')
    'software_version' => '1.2.0',                      // config('fiscal.attestation.software_version')
    'editor_name' => 'QR Communication SAS',            // config('fiscal.attestation.editor')
    'editor_siret' => '...',                             // config('fiscal.attestation.editor_siret')
    'license_number' => '...',                           // config('fiscal.attestation.license_number')
    'market_release_date' => '2026-01-01',
    'attestation_date' => now(),
]);

L'attestation est disponible en PDF via l'API : GET /v1/tenant/fiscal/attestation/{year}/download.


6. Ancrage (Timestamping)

Principe RFC 3161 TSA

L'ancrage temporel (timestamping) fournit une preuve d'anteriorite legalement reconnue. Scell.io utilise le standard RFC 3161 avec une Time Stamp Authority (TSA) pour ancrer les clotures fiscales.

Flux d'ancrage

mermaid
sequenceDiagram
    participant S as Scell.io
    participant TSA as Time Stamp Authority<br/>(freetsa.org)

    S->>S: Cloture journaliere generee
    S->>S: Calcul du hash de la cloture
    S->>TSA: TimeStampReq (hash SHA-256)
    TSA->>TSA: Signe avec certificat TSA
    TSA->>S: TimeStampResp (token signe)
    S->>S: Stocke FiscalAnchor (proof_path)
    S->>S: Enregistre dans le grand livre

Implementation

Le FiscalAnchoringService gere l'ancrage via un provider pluggable :

php
// FiscalAnchoringService.php
public function anchorClosing(FiscalClosing $closing): FiscalAnchor
{
    $dataToAnchor = json_encode([
        'closing_id' => $closing->id,
        'closing_date' => $closing->closing_date,
        'entries_count' => $closing->entries_count,
        'closing_balance' => $closing->closing_balance,
    ]);

    $hash = hash('sha256', $dataToAnchor);
    $tsaResponse = $this->tsaProvider->requestTimestamp($hash);

    return FiscalAnchor::create([
        'tenant_id' => $closing->tenant_id,
        'entry_id' => $closing->fiscal_entry_id,
        'anchor_type' => 'rfc3161_tsa',
        'anchor_timestamp' => now(),
        'anchor_reference' => $tsaResponse['reference'],
        'proof_path' => $tsaResponse['proof_path'],
        'status' => 'anchored',
    ]);
}

Provider RFC 3161

Le provider par defaut utilise freetsa.org (configurable) :

php
// config/fiscal.php
'anchoring' => [
    'provider' => env('FISCAL_ANCHOR_PROVIDER', 'none'),  // none, rfc3161_tsa
    'auto_anchor' => env('FISCAL_AUTO_ANCHOR', false),
    'tsa_url' => env('FISCAL_TSA_URL', 'https://freetsa.org/tsr'),
    'tsa_cert_path' => env('FISCAL_TSA_CERT_PATH'),
],

Le provider Rfc3161TsaProvider envoie une TimeStampReq HTTP et stocke le token signe comme preuve.

Verification d'ancrage

php
// Verifier qu'un ancrage est valide
$isValid = $anchoringService->verifyAnchor($anchor);
// Rejoue la requete TSA et compare avec le token stocke

7. Kill Switch

Mecanisme d'arret d'urgence

Le kill switch fiscal est un mecanisme de securite extreme permettant de bloquer toutes les operations fiscales d'un tenant en cas d'urgence (fraude detectee, faille de securite, incoherence comptable grave).

Fonctionnement

mermaid
stateDiagram-v2
    [*] --> Inactif
    Inactif --> Actif: activate_kill_switch<br/>(raison obligatoire)
    Actif --> Inactif: deactivate_kill_switch<br/>(raison obligatoire)

    state Actif {
        [*] --> Bloquer_Factures
        [*] --> Bloquer_Avoirs
        [*] --> Bloquer_Clotures
    }

Lorsque le kill switch est actif :

  • Creation de factures : bloquee (HTTP 423 Locked)
  • Creation d'avoirs : bloquee
  • Clotures : bloquees
  • Consultation : autorisee (lecture seule)
  • Export FEC : autorise

Middleware FiscalKillSwitchGuard

Le middleware FiscalKillSwitchGuard intercepte les operations d'ecriture fiscale :

php
// Applique aux routes : tenant.balance:invoice, tenant.balance:credit_note
// Verifie le statut du kill switch avant toute creation
public function handle(Request $request, Closure $next): Response
{
    $tenant = $request->attributes->get('tenant');

    $killSwitch = FiscalKillSwitch::where('tenant_id', $tenant->id)
        ->where('status', 'active')
        ->first();

    if ($killSwitch) {
        return response()->json([
            'error' => 'Operations fiscales suspendues',
            'code' => 'FISCAL_KILL_SWITCH_ACTIVE',
            'reason' => $killSwitch->activation_reason,
            'activated_at' => $killSwitch->activated_at,
        ], 423);
    }

    return $next($request);
}

API Kill Switch

EndpointMethodeScope requisDescription
/v1/tenant/fiscal/kill-switch/statusGETfiscal:readStatut actuel
/v1/tenant/fiscal/kill-switch/activatePOSTfiscal:adminActiver
/v1/tenant/fiscal/kill-switch/deactivatePOSTfiscal:adminDesactiver

Chaque activation/desactivation est enregistree dans :

  • Le modele FiscalKillSwitch (historique complet)
  • Le FiscalAuditLog (piste d'audit)

8. Export FEC

Format FEC (Fichier des Ecritures Comptables)

Le FEC est le format standardise par la DGFIP pour le controle fiscal informatise. Scell.io genere un fichier conforme a l'article A.47 A-1 du Livre des Procedures Fiscales.

Structure du fichier

Le fichier FEC contient 18 colonnes obligatoires, separees par un pipe (|) ou une tabulation :

#ColonneDescriptionExemple
1JournalCodeCode du journalVE (ventes)
2JournalLibLibelle du journalJournal des ventes
3EcritureNumNumero de l'ecritureVE-2026-001
4EcritureDateDate de l'ecriture20260303
5CompteNumNumero de compte411000
6CompteLibLibelle du compteClients
7CompAuxNumCompte auxiliaireCLI-ACME
8CompAuxLibLibelle auxiliaireACME SAS
9PieceRefReference de la pieceFA-2026-001
10PieceDateDate de la piece20260303
11EcritureLibLibelle de l'ecritureFacture ACME SAS
12DebitMontant debit600.00
13CreditMontant credit0.00
14EcritureLetLettrage
15DateLetDate de lettrage
16ValidDateDate de validation20260303
17MontantdeviseMontant en devise600.00
18IdeviseCode deviseEUR

Comptabilisation en partie double

Le FecExportService genere les ecritures en partie double :

Facture (500 EUR HT, TVA 20%) :

CompteNumCompteLibDebitCredit
411000Clients600.000.00
701000Ventes de produits0.00500.00
44571TVA collectee0.00100.00

Avoir (extourne) :

CompteNumCompteLibDebitCredit
411000Clients0.00600.00
701000Ventes de produits500.000.00
44571TVA collectee100.000.00

Nommage du fichier

Le fichier FEC suit la convention de nommage DGFIP :

{SIREN}FEC{AAAAMMJJ}.txt

Exemple : 123456789FEC20261231.txt

API d'export

bash
# Export FEC pour l'exercice 2025
curl -X GET "https://api.scell.io/api/v1/tenant/fiscal/fec?year=2025&format=pipe" \
  -H "X-API-Key: sk_live_..." \
  -o 123456789FEC20251231.txt

Export forensique

L'export forensique est un export complet incluant :

  • Toutes les ecritures fiscales avec snapshots
  • Les clotures et attestations
  • Le journal d'audit complet
  • Les resultats de verification d'integrite
bash
curl -X GET "https://api.scell.io/api/v1/tenant/fiscal/forensic-export?date_from=2025-01-01&date_to=2025-12-31" \
  -H "X-API-Key: sk_live_..."

9. Regles Fiscales

Regles configurables par tenant

Le systeme de regles fiscales permet aux tenants de definir des alertes et validations personnalisees :

Type de regleDescriptionExemple
alertNotification sans blocage"Alerte si facture > 10 000 EUR"
validationBlocage si condition non remplie"Refuser si SIRET invalide"
correctionApplication automatique"Arrondir a 2 decimales"

Structure d'une regle

json
{
  "rule_key": "max_invoice_amount",
  "rule_name": "Montant maximum de facture",
  "rule_type": "alert",
  "condition_json": {
    "field": "total_ttc",
    "operator": "greater_than",
    "value": 10000
  },
  "action_json": {
    "type": "notify",
    "channel": "email",
    "message": "Facture de montant eleve detectee"
  },
  "enabled": true
}

API Regles

EndpointMethodeDescription
/v1/tenant/fiscal/rulesGETLister les regles
/v1/tenant/fiscal/rulesPOSTCreer une regle
/v1/tenant/fiscal/rules/{id}PUTModifier une regle
/v1/tenant/fiscal/rules/{key}GETDetail d'une regle
/v1/tenant/fiscal/rules/{key}/historyGETHistorique d'application
/v1/tenant/fiscal/rules/replayPOSTRejouer les regles
/v1/tenant/fiscal/rules/exportGETExporter en JSON

10. API Fiscale

Endpoints complets

Tous les endpoints fiscaux sont sous le prefixe /api/v1/tenant/fiscal/ et necessitent une cle tenant (X-API-Key: tk_*).

EndpointMethodeScopeDescription
/fiscal/complianceGETfiscal:readStatut de conformite
/fiscal/entriesGETfiscal:readEcritures fiscales
/fiscal/closingsGETfiscal:readListe des clotures
/fiscal/closings/dailyPOSTfiscal:writeCloture journaliere manuelle
/fiscal/integrityGETfiscal:readVerification d'integrite
/fiscal/integrity/historyGETfiscal:readHistorique des verifications
/fiscal/integrity/{date}GETfiscal:readVerification pour une date
/fiscal/attestation/{year}GETfiscal:readAttestation annuelle
/fiscal/attestation/{year}/downloadGETfiscal:readTelecharger PDF
/fiscal/fecGETfiscal:readExport FEC
/fiscal/forensic-exportGETfiscal:readExport forensique
/fiscal/anchorsGETfiscal:readListe des ancrages TSA
/fiscal/rulesGETfiscal:readRegles fiscales
/fiscal/rulesPOSTfiscal:writeCreer une regle
/fiscal/rules/{id}PUTfiscal:writeModifier une regle
/fiscal/rules/replayPOSTfiscal:writeRejouer les regles
/fiscal/kill-switch/statusGETfiscal:readStatut kill switch
/fiscal/kill-switch/activatePOSTfiscal:adminActiver
/fiscal/kill-switch/deactivatePOSTfiscal:adminDesactiver

Scopes de permission

Le systeme fiscal utilise 3 niveaux de permission (configurable par tenant dans settings.fiscal_permissions) :

ScopePermissions
fiscal:readConsultation du grand livre, clotures, FEC, attestation, integrite, regles
fiscal:writeDeclenchement de clotures, creation/modification de regles
fiscal:adminActivation/desactivation du kill switch

Configuration

env
# .env
FISCAL_COMPLIANCE_ENABLED=true
FISCAL_EDITOR_NAME="QR Communication SAS"
FISCAL_EDITOR_SIRET="12345678900001"
FISCAL_LICENSE_NUMBER="NF525-2026-001"
FISCAL_MARKET_RELEASE_DATE="2026-01-01"
FISCAL_ANCHOR_PROVIDER=rfc3161_tsa       # none | rfc3161_tsa
FISCAL_AUTO_ANCHOR=false
FISCAL_TSA_URL=https://freetsa.org/tsr
FISCAL_RETENTION_YEARS=6

Commandes Artisan

bash
# Cloture journaliere (normalement automatique a 00:05 UTC)
php artisan fiscal:daily-closing

# Cloture mensuelle (normalement automatique le 1er du mois)
php artisan fiscal:monthly-closing

# Verification d'integrite (normalement automatique a 02:00 UTC)
php artisan fiscal:integrity-check

# Detection de changement de version logicielle
php artisan fiscal:check-version-change

Documentation Scell.io