Aller au contenu
Journal
databricksmedallion-architectureorange-moneydelta-lakesenegalmobile-moneycdp-compliancedata-engineering

Architecture Medallion pour Orange Money : Pipeline de Données sur Azure Databricks

Comment ingérer, normaliser et analyser des millions de transactions Orange Money avec une architecture Medallion (Bronze → Silver → Gold) conforme à la CDP du Sénégal.

16 juin 20258 minPar Ibrahim Faye

Le vrai problème n'est pas l'API

Orange Money fournit une API REST pour les partenaires. Obtenir les transactions n'est pas le défi. Le défi, c'est ce qui vient après :

  1. Idempotence : La même transaction peut apparaître deux fois dans deux appels API successifs. Sans déduplication, vos agrégats sont faux.
  2. Qualité : 2 à 5% des transactions ont des montants nuls, des statuts invalides, ou des timestamps manquants. Sans contrôle qualité, votre Gold Layer est contaminé.
  3. Conformité CDP: Les numéros de téléphone sont des données personnelles au sens de l'Article 4 de la loi sénégalaise. Les stocker en clair dans un Data Lake, c'est une non-conformité immédiate.
  4. Volume : 5 000+ transactions/jour pour un commerçant moyen, 500 000+ pour une banque. Sans partitionnement, vos requêtes Gold mettent 30 secondes au lieu de 2.

L'Architecture Medallion : Pourquoi trois couches ?

L'architecture Medallion (Bronze → Silver → Gold), popularisée par Databricks, n'est pas un buzzword. C'est une réponse directe aux quatre problèmes ci-dessus.

┌──────────────────────────────────────────────┐
│           ORANGE MONEY API                   │
│      (ou Mock Generator pour le dev)         │
└─────────────────┬────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────┐
│ 🥉 BRONZE — raw_transactions                │
│ • Append-only, jamais modifié               │
│ • Tokenisation PII à l'ingestion (CDP)      │
│ • Format : Delta Lake                       │
└─────────────────┬────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────┐
│ 🥈 SILVER — normalized_transactions         │
│ • Déduplication (ROW_NUMBER)                │
│ • 7 règles de qualité automatiques          │
│ • Enrichissement : buckets, heures de pointe │
└─────────────────┬────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────┐
│ 🥇 GOLD — daily_summary, fraud_patterns     │
│ • KPIs prêts pour dashboards                │
│ • Détection d'anomalies                     │
│ • Partitionné, aggregé, documenté           │
└──────────────────────────────────────────────┘
📐
La règle d'or : Bronze est immuable. Silver est fiable. Gold est actionnable.

Bronze : L'ingestion qui protège les données personnelles

La couche Bronze reçoit les transactions brutes de l'API Orange Money. Mais avant d'écrire la moindre ligne dans Delta Lake, une étape critique se produit : la tokenisation des numéros de téléphone.

Python
# Tokenisation CDP à l'ingestion — Art. 44
class PhoneTokenizer:
    """HMAC-SHA256 pour conformité CDP."""

    def tokenize(self, phone: str) -> str:
        return hmac.new(
            self.secret, phone.encode(), hashlib.sha256
        ).hexdigest()[:16]

# Avant écriture dans Bronze
if self._tokenizer:
    tx.sender_phone = self._tokenizer.tokenize(tx.sender_phone)
    tx.recipient_phone = self._tokenizer.tokenize(tx.recipient_phone)

Pourquoi c'est important : la CDP sénégalaise (Article 44) exige la pseudonymisation des données personnelles. En tokenisant à l'ingestion — avant que les données n'atteignent le stockage — vous éliminez le risque de PII en clair dans votre Data Lake. Même un accès non autorisé à la table Bronze ne révèle aucun numéro de téléphone réel.

ColonneRôle
_ingested_atHorodatage d'ingestion (UTC)
_source_fileFichier source ou endpoint API
_batch_idIdentifiant de lot pour la traçabilité

Silver : La normalisation qui fait la différence

C'est ici que la plupart des projets échouent. On passe de Bronze à Gold directement — et on obtient des dashboards qui affichent des totaux inexacts à cause de doublons et de données corrompues.

1. Déduplication

Python
# Déduplication par transaction_id
window = Window.partitionBy("transaction_id") \
    .orderBy(F.col("_ingested_at").desc())

deduped = bronze \
    .withColumn("_row_num", F.row_number().over(window)) \
    .filter(F.col("_row_num") == 1) \
    .drop("_row_num")

2. Contrôles qualité

Python
QUALITY_RULES = {
    "amount_positive": F.col("amount") > 0,
    "amount_reasonable": F.col("amount") < 50_000_000,
    "valid_status": F.col("status").isin(
        "SUCCESS", "PENDING", "FAILED", "REVERSED"
    ),
    "has_sender": F.col("sender_phone").isNotNull(),
    "fee_non_negative": F.col("fee") >= 0,
}

Les lignes qui échouent ne sont pas rejetées — elles sont conservées avec le flag FAIL, ce qui permet un audit sans perte de données.

3. Enrichissement

Colonne enrichieExempleUtilité
_date2025-01-15Partitionnement
_hour14Analyse horaire
_is_peak_hourTrueHeures de pointe (9h-12h, 15h-18h)
_is_weekendFalsePatterns week-end vs semaine
_amount_bucketMEDIUMSegmentation (MICRO → XLARGE)
_is_merchant_txnTrueTransaction commerçant vs P2P
_processing_latency_seconds3Délai initiation → complétion

Gold : Les agrégats qui parlent aux décideurs

daily_summary — Le pouls quotidien

SQL
-- Volume par région et canal (7 derniers jours)
SELECT
    _date, region,
    SUM(transaction_count)     AS total_txns,
    SUM(total_volume_xof)      AS volume_fcfa,
    ROUND(AVG(success_rate), 1) AS success_pct
FROM orange_money.gold.daily_summary
WHERE _date >= CURRENT_DATE() - INTERVAL 7 DAYS
GROUP BY _date, region
ORDER BY _date DESC, volume_fcfa DESC;

Détection de fraude

La couche Gold exécute quatre patterns de détection d'anomalies à chaque exécution :

PatternRègleExemple
VELOCITY_ANOMALY> 20 transactions/jour par émetteurCompte émet 45 transferts en une journée
AMOUNT_SPIKETransaction > 5× la moyenne 7 joursTransaction de 500K FCFA (moy: 45K)
RAPID_TRANSFERTransferts multiples même destinataire < 10 min3 transferts de 50K en 4 minutes
OFF_HOURS_LARGETransaction > 100K hors heures de pointePaiement de 200K à 3h du matin

Infrastructure-as-Code : Terraform pour la reproductibilité

HCL
# Azure Databricks Workspace (Premium — Unity Catalog)
resource "azurerm_databricks_workspace" "this" {
  name                = "orange-money-databricks"
  sku                 = "premium"
}

# ADLS Gen2 — un container par couche Medallion
resource "azurerm_storage_container" "bronze" { ... }
resource "azurerm_storage_container" "silver" { ... }
resource "azurerm_storage_container" "gold"  { ... }

Mode Mock : Développer sans credentials API

Python
from src.ingestion import OrangeMoneyClient

# Aucun credential requis — mode mock par défaut
client = OrangeMoneyClient()

for page in client.fetch_transactions(
    datetime(2025, 1, 15), datetime(2025, 1, 17)
):
    for tx in page.transactions:
        print(f"{tx.amount:,.0f} FCFA — {tx.region}")

Le générateur respecte :

  • Distribution régionale : Dakar ~45%, Thiès ~15%
  • Heures de pointe : 9h-12h et 15h-18h GMT
  • Canaux : USSD 65%, APP 25%, WEB 5%, AGENT 5%
  • Montants : Clusters autour de 500, 1 000, 2 000, 5 000, 10 000 FCFA

Ce que cette architecture apporte concrètement

AvantAprès
Scripts Python ad-hoc par employéPipeline unique, versionné, testé
Numéros de téléphone en clair dans les logsTokenisation HMAC-SHA256 à l'ingestion
Doublons non détectés → KPIs erronésDéduplication déterministe dans Silver
2-5% de données corrompuesQuality flag sur chaque ligne, audit trail
Dashboard = 30 secondesPartitionnement → 2 secondes
Pas de détection de fraude4 patterns d'anomalies automatiques
Déploiement manuelterraform apply → infra complète

Code source

L'intégralité du code est open-source (MIT) :

Le dépôt contient le pipeline Python complet (Bronze → Silver → Gold), les modèles dbt alternatifs (SQL), les modules Terraform, quatre notebooks Databricks exécutables, une suite de tests complète et une CI/CD GitHub Actions.

Vous avez un projet Orange Money, Wave, ou Free Money ?

XamXam Graph déploie des architectures Medallion clé-en-main pour les données de mobile money en Afrique de l'Ouest — avec conformité CDP intégrée.

Planifier un Diagnostic