Skip to content
StableAudienceDevAudit banqueComplianceOpsOwner@platform-teamDernière revue2026-05-22

Destruction de monnaie électronique

Procédure de destruction de monnaie électronique (réduction de la masse monétaire en circulation lors d'un virement sortant réel vers la banque). Pour la vue d'ensemble et les impacts comptables, voir Trésorerie & destruction — overview.

Feature 2 — Destruction de monnaie électronique

Description

Opération de sortie définitive de fonds hors du système, correspondant à un virement bancaire sortant réel. Réduit la masse monétaire électronique en circulation. La trésorerie est débitée au profit d'un compte black dédié (BLACK_ACCOUNT) qui accumule toutes les destructions — garantissant la traçabilité et l'intégrité comptable à partie double.

Pourquoi un compte black

AVANT (approche rejetée)       APRÈS (approche retenue)
DÉBIT  : TREASURY              DÉBIT  : TREASURY
CRÉDIT : ∅ (vide)              CRÉDIT : BLACK_ACCOUNT

Problème : double-entrée       Avantage : double-entrée
           incomplète                     parfaite

                               BLACK_ACCOUNT.balance
                               = total de toute la monnaie détruite
                               → indicateur clé pour compliance BEAC

Comptes système — Nouveau compte

typescript
// À ajouter dans system-accounts.constants.ts
export enum SystemAccountType {
  SUSPENSE       = 'suspense',
  TREASURY       = 'treasury',
  FEE_COLLECTION = 'fee_collection',
  BLACK_ACCOUNT  = 'black_account',   // NOUVEAU
}

export const SYSTEM_ACCOUNT_IDS = {
  SUSPENSE_XAF:       '00000000-0000-0000-0000-000000000201',
  TREASURY_XAF:       '00000000-0000-0000-0000-000000000202',
  FEE_COLLECTION_XAF: '00000000-0000-0000-0000-000000000203',
  BLACK_ACCOUNT_XAF:  '00000000-0000-0000-0000-000000000204',  // NOUVEAU
}

5 fichiers à modifier de façon cohérente :

  1. AccountType enum → BLACK_ACCOUNT = 'black_account'
  2. SystemAccountType enum → BLACK_ACCOUNT = 'black_account'
  3. SYSTEM_ACCOUNT_IDSBLACK_ACCOUNT_XAF
  4. SYSTEM_ACCOUNTS_CONFIG → entrée de configuration
  5. AccountTypesByEntity.system → ajouter AccountType.BLACK_ACCOUNT

Workflow

PENDING_APPROVAL
  (Backoffice initie : montant, motif, référence bancaire sortante, banque)

APPROVED
  (Backoffice différent approuve)

EXECUTED
  (Débit TREASURY → Crédit BLACK_ACCOUNT, écriture ledger standard)

  ↘ REJECTED (possible depuis PENDING_APPROVAL)

Flux comptable

text

Écriture ledger (double-entrée standard) :
  DÉBIT  : TREASURY_XAF       (X XAF)
  CRÉDIT : BLACK_ACCOUNT_XAF  (X XAF)
  Référence : externalBankReference (virement sortant réel)

Motifs (DestructionReason)

BANK_TRANSFER_OUT        — Virement bancaire sortant standard
REGULATORY_ADJUSTMENT    — Ajustement réglementaire (BEAC)
SETTLEMENT_PARTNER       — Règlement partenaire externe
END_OF_DAY_SETTLEMENT    — Règlement de fin de journée

Règles métier

  • externalBankReference obligatoire et unique dans le système
  • Initiateur ≠ approbateur (admin peut cumuler en phase initiale)
  • Re-vérification availableBalance >= amount à l'exécution
  • Une destruction EXECUTED est irréversible
  • Le BLACK_ACCOUNT n'est jamais débité (lecture + crédit uniquement)

Entité MoneyDestructionRecord

typescript
{
  id: string
  amount: number
  currencyCode: string
  reason: DestructionReason
  description?: string
  externalBankReference: string    // UNIQUE — référence virement sortant
  externalBankName: string
  status: MoneyDestructionStatus

  initiatedBy: string
  initiatedAt: Date
  approvedBy?: string
  approvedAt?: Date
  rejectedBy?: string
  rejectedAt?: Date
  rejectionReason?: string
  executedAt?: Date
  treasuryLedgerTransactionId?: string   // Pointe vers l'écriture TREASURY → BLACK_ACCOUNT

  metadata?: Record<string, unknown>
}

Architecture backend

services/ledger-wallets/src/destruction/
├── destruction.module.ts
├── destruction.service.ts
└── entities/
    └── money-destruction.entity.ts

services/orchestrator/src/application/use-cases/treasury/destruction/
├── initiate-money-destruction.use-case.ts
├── approve-money-destruction.use-case.ts
├── reject-money-destruction.use-case.ts
└── execute-money-destruction.use-case.ts

services/orchestrator/src/presentation/controllers/
└── destruction.controller.ts

Routes orchestrateur

POST   /treasury/destructions                     — Initier
GET    /treasury/destructions                     — Lister (filtres : status, dates, banque)
GET    /treasury/destructions/:id                 — Détail
POST   /treasury/destructions/:id/approve         — Approuver
POST   /treasury/destructions/:id/reject          — Rejeter
POST   /treasury/destructions/:id/execute         — Exécuter

Architecture CMMS

apps/cmms/app/pages/treasury/destructions.vue          — Nouvelle page
apps/cmms/app/stores/destruction.ts                    — Nouveau store
apps/cmms/app/components/treasury/
├── DestructionInitiateModal.vue
├── DestructionApproveModal.vue
└── DestructionRejectModal.vue
apps/cmms/app/utils/models/destruction.model.ts

Page system-accounts : le BLACK_ACCOUNT apparaît en lecture seule, badge "Monnaie détruite", sans action de distribution possible depuis ce compte.

Migration SQL (Feature 2)

sql
CREATE TABLE ledger_wallet.money_destructions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  amount DECIMAL(20, 4) NOT NULL,
  currency_code VARCHAR(3) NOT NULL,
  reason VARCHAR(50) NOT NULL,
  description TEXT,
  external_bank_reference VARCHAR(255) NOT NULL UNIQUE,
  external_bank_name VARCHAR(100) NOT NULL,
  status VARCHAR(30) NOT NULL DEFAULT 'pending_approval',
  initiated_by VARCHAR(255) NOT NULL,
  initiated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  approved_by VARCHAR(255),
  approved_at TIMESTAMPTZ,
  rejected_by VARCHAR(255),
  rejected_at TIMESTAMPTZ,
  rejection_reason TEXT,
  executed_at TIMESTAMPTZ,
  treasury_ledger_transaction_id UUID,
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE UNIQUE INDEX idx_destruction_bank_ref
  ON ledger_wallet.money_destructions (external_bank_reference);

Tickets de mise en œuvre

T6 — Initiation d'une destruction de monnaie électronique

Titre : Initiation d'une opération de destruction de monnaie électronique

Description

En tant que Responsable trésorerie

Je veux Pouvoir initier la sortie définitive d'un montant de la trésorerie hors du système, en y associant la référence du virement bancaire sortant réel

Afin de Assurer la conformité réglementaire lors du rachat de monnaie électronique, en maintenant à tout moment une correspondance entre les flux bancaires réels et la masse monétaire électronique en circulation


Règles de gestion

RG1 : Chaque destruction doit être associée à une référence de virement bancaire sortant unique — il est impossible d'utiliser deux fois la même référence

RG2 : La banque destinataire du virement doit être renseignée

RG3 : Après initiation, la destruction est en statut "En attente d'approbation" — aucun mouvement de fonds n'est effectué à ce stade

RG4 : Le responsable qui initie la destruction voit le solde disponible de la trésorerie au moment de la saisie

RG5 : Si le montant dépasse le solde disponible de la trésorerie, la création est refusée avec un message d'erreur

RG6 : L'historique de toutes les destructions (tous statuts confondus) est consultable, filtrable par période, statut et banque

RG7 : Le back-office peut consulter pour chaque destruction : montant, motif, référence bancaire, banque, initiateur, dates de chaque étape du workflow


Critères d'acceptation

  • [ ] Une section "Destructions" est accessible depuis le menu Trésorerie
  • [ ] Le formulaire affiche le solde disponible de la trésorerie en temps réel
  • [ ] La référence bancaire sortante est obligatoire et unique — un doublon est refusé immédiatement
  • [ ] La banque destinataire est obligatoire
  • [ ] Un montant supérieur au solde de la trésorerie est bloqué
  • [ ] Après création, le statut "En attente d'approbation" est visible dans la liste
  • [ ] L'historique complet est filtrable par statut, banque et période


T7 — Approbation et exécution d'une destruction de monnaie

Titre : Approbation et exécution d'une destruction de monnaie électronique

Description

En tant que Responsable conformité / Administrateur trésorerie (différent de l'initiateur)

Je veux Pouvoir approuver ou rejeter une destruction initiée, puis l'exécuter pour déclencher le mouvement définitif hors du système

Afin de Garantir un double contrôle sur toute opération irréversible affectant la masse monétaire électronique, conformément aux exigences de la réglementation BEAC


Règles de gestion

RG1 : L'opérateur qui approuve doit être différent de celui qui a initié la destruction

RG2 : En cas de rejet, un motif est obligatoire

RG3 : Entre l'approbation et l'exécution, le solde de la trésorerie est re-vérifié — si le solde est devenu insuffisant, l'exécution est bloquée

RG4 : L'exécution transfère définitivement les fonds de la trésorerie vers le compte de destruction (compte black), qui accumule l'ensemble de la monnaie électronique détruite depuis l'ouverture du système

RG5 : Le solde du compte black est consultable à tout moment et représente le total cumulé de toute la monnaie électronique sortie du système

RG6 : Une destruction exécutée est irréversible — aucune annulation possible

RG7 : Le compte black est affiché en lecture seule sur la page des comptes système — aucune distribution ne peut être initiée depuis ce compte


Critères d'acceptation

  • [ ] Les destructions en statut "En attente d'approbation" affichent les actions Approuver / Rejeter
  • [ ] L'approbation est bloquée si l'opérateur connecté est le même que l'initiateur
  • [ ] Le rejet nécessite un motif obligatoire
  • [ ] Les destructions approuvées affichent l'action "Exécuter"
  • [ ] Si le solde de la trésorerie est insuffisant à l'exécution, l'opération est annulée avec un message d'erreur
  • [ ] Après exécution, le solde de la trésorerie est réduit du montant détruit
  • [ ] Le compte black affiche le solde cumulé mis à jour
  • [ ] Le compte black est visible en lecture seule sur la page des comptes système, sans action possible
  • [ ] L'audit complet (qui a initié, approuvé, exécuté, quand) est consultable pour chaque destruction

Document créé le : 2026-03-13 Version : 2.0.0

Nex — Plateforme fintech CEMAC