Architecture .NET 8 complète pour une plateforme FinTech couvrant Banking, Wallet et Paiements avec séparation stricte des domaines, sécurité enterprise-grade et conformité réglementaire.
| Raison | Détail |
|---|---|
| Cohérence transactionnelle | Le ledger immuable nécessite des transactions ACID strictes |
| Performance | Pas de latence réseau des appels inter-services |
| Simplicité opérationnelle | Un seul déploiement, un seul monitoring |
| Migration progressive | Décomposable en microservices si nécessaire |
┌─────────────────────────────────────────────────────────────────┐
│ API HOST │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌─────────────┐│
│ │ Banking │ │ Wallet │ │ WalletFMCG │ │ Ledger ││
│ │ 🟢 │ │ 🟢 │ │ 🟠 │ │ 🟢 ││
│ └────┬─────┘ └────┬─────┘ └──────┬───────┘ └──────┬──────┘│
│ └─────────────┴───────────────┴──────────────────┘ │
│ │ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │Payments │ │ FX │ │Statements│ │MerchantPay │ │
│ │ 🟡 │ │ 🟡 │ │ 🟠 │ │ 🟡 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│ └─────────────┴─────────────┘ │ │
│ │ │ │
│ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌────┴─────┐ │
│ │PartyReg. │ │ Identity │ │Compliance│ │Disputes │ │
│ │ 🟢 │ │ 🟢 │ │ 🟠 │ │ 🟡 │ │
│ └──────────┘ └────────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │Notifs │ │Budgeting │ │ Audit │ │ Documents │ │
│ │ 🟡 │ │ 🟡 │ │ 🟠 │ │ 🟠 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ BuildingBlocks │ │
│ │ Domain · Application · Infrastructure · SharedKernel │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
🟢 Implemented 🟡 Service Layer 🟠 Contracts ⚪ Scaffold
Règles de dépendances strictes :
- ❌ Banking ne référence JAMAIS Wallet ou WalletFMCG
- ❌ Wallet ne référence JAMAIS Banking
- ✅ Les deux référencent les modules communs (Ledger, Payments, FX, PartyRegistry)
- ✅ Communication inter-modules uniquement via Contracts (interfaces + DTOs)
- ✅ Domain ne dépend jamais d'Infrastructure (Clean Architecture)
| Module | Rôle | Fonctionnalités |
|---|---|---|
| Ledger | Source de vérité financière | Double-entry bookkeeping, multi-devise, outbox pattern, historique immutable |
| Identity | Authentification | JWT RSA-2048, refresh tokens avec rotation, MFA/TOTP, sessions |
| Banking | Comptes bancaires | Comptes épargne, prêts, découvert, calcul d'intérêts, cartes |
| Wallet | Portefeuille digital | P2P, split payments, loyalty, Orange Money/Inwi Money, paiement factures, KYC 4 niveaux, offres/promotions, détection fraude |
| PartyRegistry | Référentiel clients | Parties (Individual/Organization), rôles multi-domaines |
| Module | Rôle | Fonctionnalités |
|---|---|---|
| Payments | Virements | Intra-devise, cross-devise via FX, ordres permanents |
| FX | Change | Taux de change temps réel (simulé), quotes 5min, conversion MAD/EUR/USD |
| MerchantPayments | Paiement marchand | QR EMVCo dynamique, paiement par scan, ISO 4217 |
| Disputes | Litiges | Remboursements partiels/totaux, chargebacks |
| Notifications | Alertes | Routing SMS/Email/Push, templates |
| Budgeting | Gestion budget | Catégorisation, budgets mensuels, analytics de dépenses, alertes seuil |
| Module | Rôle |
|---|---|
| IdentityCompliance | eKYC, KYB, AML, détection fraude, freeze/unfreeze |
| Statements | Relevés comptables périodiques |
| WalletFMCG | Distribution agents, cash-in/cash-out, commissions |
| Audit | Audit trail pour compliance |
| Documents | Stockage documents (S3 compatible) |
| BranchNetwork | Gestion des agences |
| Scheduler | Jobs planifiés (Quartz.NET) |
| Composant | Technologie |
|---|---|
| Runtime | .NET 8.0 |
| Database | PostgreSQL 2022 |
| ORM | Entity Framework Core + Migrations |
| Auth | JWT RSA-2048 signing |
| Passwords | Argon2id (OWASP recommended) |
| Encryption | AES-256-GCM pour PII |
| MFA | TOTP (Google/Microsoft Authenticator) |
| Cards | Tokenization PCI-compliant |
| Background Jobs | Quartz.NET |
| API Docs | OpenAPI / Swagger |
| Tests | xUnit + NetArchTest.Rules |
| Observabilité | OpenTelemetry + Prometheus |
| Containers | Docker + Docker Compose |
| Orchestration | Kubernetes (Kustomize) |
| CI/CD | GitHub Actions |
- Docker Desktop
- .NET 8 SDK
docker-compose up -d postgresdotnet run --project src/ApiHost/Finitech.ApiHost/Finitech.ApiHost.csproj→ API : http://localhost:5000
→ Swagger : http://localhost:5000/swagger
docker-compose up --buildcurl -X POST http://localhost:5000/api/partyregistry \
-H "Content-Type: application/json" \
-d '{
"partyType": "Individual",
"firstName": "Ahmed",
"lastName": "Benali",
"email": "ahmed@example.com",
"phoneNumber": "+212612345678",
"initialRoles": ["Consumer", "RetailCustomer"]
}'curl -X POST http://localhost:5000/api/fx/rate \
-H "Content-Type: application/json" \
-d '{"fromCurrencyCode": "MAD", "toCurrencyCode": "EUR"}'curl -X POST http://localhost:5000/api/wallet/p2p/send \
-H "Content-Type: application/json" \
-d '{
"fromWalletId": "{walletId}",
"toIdentifier": "+212612345679",
"identifierType": "Phone",
"currencyCode": "MAD",
"amountMinorUnits": 25000,
"idempotencyKey": "p2p-001"
}'curl -X POST http://localhost:5000/api/merchantpayments/qr/generate \
-H "Content-Type: application/json" \
-d '{
"merchantId": "{merchantId}",
"currencyCode": "MAD",
"amountMinorUnits": 15000,
"reference": "CMD-001"
}'→ Tous les endpoints : docs/API-REFERENCE.md
| Protection | Implémentation |
|---|---|
| Authentication | JWT RSA-2048, access token 15min, refresh 7j avec rotation |
| Passwords | Argon2id (OWASP) |
| Data | AES-256-GCM encryption pour PII |
| Cards | Tokenization PCI-compliant |
| MFA | TOTP compatible Google/Microsoft Authenticator |
| Rate Limiting | 100 req/min global, 5 req/5min auth |
| Headers | CSP, HSTS, X-Frame-Options, X-Content-Type-Options |
→ Détails : SECURITY.md
Le système supporte MAD, EUR, USD nativement :
- Stockage en minor units (long) + CurrencyCode (string)
- Conversion via module FX avec taux simulés (provider-ready pour production)
- Ledger : une écriture par devise, pas de conversion implicite
- QR EMVCo : devise numérique ISO 4217 (504=MAD, 978=EUR, 840=USD)
# Tests unitaires (FX, Disputes, MerchantPayments, Budgeting, Money, Outbox)
dotnet test tests/Finitech.UnitTests
# Tests d'architecture (vérifie les dépendances inter-modules)
dotnet test tests/Finitech.ArchitectureTests
# Tests d'intégration (nécessite PostgreSQL)
docker-compose up -d postgres
dotnet test tests/Finitech.IntegrationTestsLes tests d'architecture vérifient automatiquement :
- ❌ Banking ne référence pas Wallet
- ❌ Wallet ne référence pas Banking
- ✅ Modules communiquent via Contracts uniquement
- ✅ Domain ne dépend pas d'Infrastructure
# Staging
kubectl apply -k k8s/overlays/staging
# Production
kubectl apply -k k8s/overlays/productionInclut : Deployment, Service, Ingress, ConfigMap, NetworkPolicy, ServiceAccount.
Finitech/
├── src/
│ ├── ApiHost/ # ASP.NET Core host (controllers, config)
│ ├── BuildingBlocks/ # Shared kernel (Domain, Application, Infrastructure)
│ │ ├── Domain/ # Interfaces, repositories, Result pattern
│ │ ├── Application/ # CQRS patterns
│ │ ├── Infrastructure/ # EF Core, JWT, Argon2, AES, Outbox
│ │ ├── SharedKernel/ # Money, Entity, ValueObject, AggregateRoot
│ │ └── Contracts/ # DTOs partagés
│ └── Modules/ # 18 modules métier
│ ├── Banking/ # Comptes, prêts, cartes, intérêts
│ ├── Wallet/ # P2P, loyalty, paiements programmés
│ ├── Ledger/ # Double-entry bookkeeping
│ ├── Payments/ # Virements intra/cross-devise
│ ├── FX/ # Change, quotes, conversion
│ ├── MerchantPayments/ # QR EMVCo
│ ├── PartyRegistry/ # Référentiel clients
│ ├── Identity*/ # Auth JWT + MFA
│ ├── IdentityCompliance/ # eKYC, AML
│ └── ... # Notifications, Budgeting, Disputes, etc.
├── tests/
│ ├── UnitTests/ # 9 fichiers de tests
│ ├── ArchitectureTests/ # Tests de dépendances
│ └── IntegrationTests/ # Tests avec PostgreSQL
├── k8s/ # Kubernetes (Kustomize)
├── docs/ # API Reference
├── docker-compose.yml
├── CONTRIBUTING.md
├── SECURITY.md
└── LICENSE
Le module Wallet intègre désormais toutes les fonctionnalités de ZOUZ.Wallet :
| Méthode | Provider |
|---|---|
| Carte bancaire | Payment Gateway |
| Virement bancaire | Bank Transfer API |
| Orange Money | api.orangemoney.ma |
| Inwi Money | api.inwimoney.ma |
| Cash (via agent) | En agence |
| Type | Fournisseurs |
|---|---|
| Télécom | Maroc Telecom, Inwi, Orange |
| Eau | REDAL, LYDEC |
| Électricité | ONEE |
| Taxes | Direction Générale des Impôts |
| Niveau | Vérification | Limite/jour | Limite/mois |
|---|---|---|---|
| None | Aucune | 0 MAD | 0 MAD |
| Basic | Téléphone + Email | 2,000 MAD | 10,000 MAD |
| Standard | CIN (Carte d'Identité Nationale) | 10,000 MAD | 50,000 MAD |
| Advanced | Vérification complète | 20,000 MAD | 100,000 MAD |
Cashback · Réduction de frais · Bonus recharge · Programme fidélité · Promotions spéciales
Règles basées sur les seuils Bank Al-Maghrib : dépôts >10,000 MAD, retraits >5,000 MAD, transferts >7,000 MAD, cash >5,000 MAD.
- Modular monolith avec 18 modules
- Ledger double-entry immutable
- JWT RSA-2048 + MFA/TOTP + refresh rotation
- Argon2id + AES-256-GCM
- Multi-devise MAD/EUR/USD
- QR EMVCo dynamique
- Background jobs (Quartz.NET)
- 9 Application Services
- Tests unitaires + architecture
- CI/CD GitHub Actions
- Docker + Kubernetes
- Event sourcing pour le Ledger (append-only event store, jsonb)
- RabbitMQ pour outbox distribué (Transactional Outbox Pattern)
- API Gateway Traefik v3 (rate limiting, CORS, security headers)
- Multi-région
- Fusion ZOUZ.Wallet — KYC, factures, offres, fraude, Orange/Inwi Money
- Dashboard admin React
| Document | Contenu |
|---|---|
| API Reference | Tous les endpoints (30+ routes) |
| Security | Politique de sécurité et features |
| Contributing | Setup, conventions, PR process |
| Architecture | Décisions techniques détaillées |
MIT — Khalil Benazzouz
Le module Ledger utilise l'Event Sourcing pour garantir une traçabilité complète :
Domain Event → Outbox Table (même transaction) → RabbitMQ → Consumers
Chaque opération financière est un événement immutable stocké en PostgreSQL jsonb :
| Event Type | Description |
|---|---|
AccountOpened |
Ouverture de compte |
MoneyDeposited |
Dépôt |
MoneyWithdrawn |
Retrait |
TransferExecuted |
Virement |
InterestAccrued |
Intérêts calculés |
FxConversionExecuted |
Conversion de devise |
RefundProcessed |
Remboursement |
ChargebackInitiated |
Chargeback |
L'état d'un compte peut être reconstruit à tout moment en rejouant ses événements.
# Lancer avec le gateway
docker-compose -f docker-compose.yml -f gateway/docker-compose.gateway.yml upFonctionnalités :
- Rate limiting (100 req/min)
- CORS configuré
- Security headers (HSTS, CSP, X-Frame-Options)
- Dashboard :
http://localhost:8080
Le Transactional Outbox Pattern garantit la livraison fiable des événements :
- L'événement est écrit dans la table
outboxdans la même transaction que le changement - Le
OutboxProcessor(background job) lit les messages pending - Publication vers RabbitMQ avec retry automatique (max 5 tentatives)
- Marquage comme
Publishedaprès succès
Dashboard RabbitMQ : http://localhost:15672 (finitech/finitech)