Chaque cycle de paie dans un établissement saoudien se termine par le même moment critique : le fichier a-t-il été déposé sur Mudad ? Les enregistrements ont-ils été acceptés ? Le taux de conformité est-il suffisant pour protéger le certificat de saudisation ?
Le problème vient rarement de la paie elle-même. Il vient du fossé entre votre système RH ou comptable et la plateforme Mudad. Chaque établissement comble ce fossé à sa façon — Excel manuel, export CSV, copier-coller. Ces méthodes fonctionnent, jusqu'au jour où elles ne fonctionnent plus, et quelqu'un découvre que trois employés n'ont aucun enregistrement soumis depuis deux mois.
Ce guide explique comment construire une couche d'intégration fiable entre vos systèmes logiciels et Mudad, plutôt que de dépendre de processus manuels qui cèdent au pire moment.
Comment fonctionne Mudad
Mudad est une plateforme fintech agréée, soutenue par le ministère saoudien des Ressources humaines (HRSD), l'Organisation générale de l'assurance sociale (GOSI) et la Banque centrale saoudienne (SAMA). Elle se compose de deux systèmes interconnectés :
Mudad Business — Système de gestion de la paie pour les PME. Il permet les virements de salaires directs via l'intégration bancaire et dépose automatiquement le fichier WPS à la fin du virement.
Mudad Conformité — Système de dépôt de fichiers WPS pour les établissements utilisant des logiciels de paie ou ERP externes. Les fichiers sont déposés au format CSV selon les spécifications du HRSD, et Mudad les confronte aux registres GOSI et bancaires.
Le flux de conformité :
Système de paie → Génération fichier WPS → Mudad → Rapprochement GOSI + banques → Rapport de conformité
Les établissements qui transfèrent directement via Mudad Business contournent l'étape de dépôt. Tout établissement utilisant un ERP ou logiciel comptable externe doit passer par le chemin de dépôt de fichier — et c'est là que la majorité des erreurs se produisent.
Ce que l'intégration requiert concrètement
Mudad ne publie pas d'API publique. L'intégration programmatique directe est réservée aux partenaires technologiques certifiés (ZenHR, Jisr) via un accord de partenariat. Pour les autres systèmes, le chemin pratique est :
- Construire le fichier correct selon les spécifications Mudad
- Déposer le fichier via l'interface Mudad ou SFTP selon la taille de l'établissement
- Lire le rapport de conformité et retraiter les enregistrements rejetés
L'erreur la plus courante : des systèmes qui produisent un fichier correctement formaté, mais dont les données internes — numéros d'IQAMA, montants de salaires, IBAN — ne correspondent pas aux registres GOSI. Le fichier est accepté. Les enregistrements sont rejetés. Le résultat est une violation que vous découvrez seulement à la parution du rapport mensuel.
Construire une couche de validation avant le dépôt
Le vrai investissement n'est pas dans le dépôt du fichier — c'est dans sa validation avant qu'il n'atteigne Mudad. Voici une implémentation TypeScript de la logique de validation principale :
interface MudadEmployee {
iqamaOrNationalId: string; // exactement 10 chiffres
employeeName: string;
bankAccountIBAN: string; // SA + 22 chiffres
basicSalary: number;
allowances: number;
deductions: number;
netSalary: number;
paymentMonth: string; // YYYY-MM
}
interface ValidationResult {
isValid: boolean;
errors: string[];
employeeId: string;
}
function validateEmployee(emp: MudadEmployee): ValidationResult {
const errors: string[] = [];
if (!/^\d{10}$/.test(emp.iqamaOrNationalId)) {
errors.push(`Numéro ID invalide : ${emp.iqamaOrNationalId}`);
}
if (!/^SA\d{22}$/.test(emp.bankAccountIBAN)) {
errors.push(`Format IBAN invalide : ${emp.bankAccountIBAN}`);
}
const calculatedNet = emp.basicSalary + emp.allowances - emp.deductions;
if (Math.abs(calculatedNet - emp.netSalary) > 0.01) {
errors.push(
`Déséquilibre salarial : ${emp.basicSalary} + ${emp.allowances} - ${emp.deductions} = ${calculatedNet} ne correspond pas à ${emp.netSalary}`
);
}
if (emp.netSalary <= 0) {
errors.push(`Le salaire net doit être positif`);
}
return {
isValid: errors.length === 0,
errors,
employeeId: emp.iqamaOrNationalId,
};
}
function validatePayrollBatch(employees: MudadEmployee[]): {
valid: MudadEmployee[];
invalid: Array<{ employee: MudadEmployee; errors: string[] }>;
summary: string;
} {
const valid: MudadEmployee[] = [];
const invalid: Array<{ employee: MudadEmployee; errors: string[] }> = [];
for (const emp of employees) {
const result = validateEmployee(emp);
if (result.isValid) {
valid.push(emp);
} else {
invalid.push({ employee: emp, errors: result.errors });
}
}
const rate = ((valid.length / employees.length) * 100).toFixed(1);
const summary = `${valid.length}/${employees.length} enregistrements valides (${rate}%)`;
return { valid, invalid, summary };
}Cette couche intercepte les problèmes avant le dépôt — pas après.
Générer le fichier WPS selon les spécifications Mudad
Après validation, l'étape suivante est la génération du fichier dans le format attendu par Mudad :
import { createObjectCsvWriter } from 'csv-writer';
import * as path from 'path';
async function generateMudadWPSFile(
employees: MudadEmployee[],
establishmentId: string,
paymentMonth: string,
outputDir: string
): Promise<string> {
const fileName = `WPS_${establishmentId}_${paymentMonth.replace('-', '')}.csv`;
const filePath = path.join(outputDir, fileName);
const csvWriter = createObjectCsvWriter({
path: filePath,
header: [
{ id: 'EmployeeID', title: 'EmployeeID' },
{ id: 'EmployeeName', title: 'EmployeeName' },
{ id: 'IBAN', title: 'IBAN' },
{ id: 'BasicSalary', title: 'BasicSalary' },
{ id: 'HousingAllowance', title: 'HousingAllowance' },
{ id: 'OtherAllowances', title: 'OtherAllowances' },
{ id: 'Deductions', title: 'Deductions' },
{ id: 'NetSalary', title: 'NetSalary' },
{ id: 'PaymentDate', title: 'PaymentDate' },
],
encoding: 'utf8',
});
const records = employees.map((emp) => ({
EmployeeID: emp.iqamaOrNationalId,
EmployeeName: emp.employeeName,
IBAN: emp.bankAccountIBAN,
BasicSalary: emp.basicSalary.toFixed(2),
HousingAllowance: '0.00',
OtherAllowances: emp.allowances.toFixed(2),
Deductions: emp.deductions.toFixed(2),
NetSalary: emp.netSalary.toFixed(2),
PaymentDate: new Date().toISOString().split('T')[0],
}));
await csvWriter.writeRecords(records);
return filePath;
}Le mode d'échec silencieux le plus courant
Les établissements qui s'appuient sur le dépôt manuel tombent régulièrement dans le même piège : le système enregistre un dépôt réussi, mais le rapport de conformité affiche un taux inférieur aux attentes. Les causes suivent un schéma constant :
Numéros d'identification ne correspondant pas aux registres GOSI — Le numéro d'IQAMA d'un employé a été mis à jour dans le système RH, mais l'ancien numéro figure toujours dans le registre des assurances sociales. Cela nécessite d'abord une mise à jour des données GOSI, pas seulement du système interne.
IBAN stocké dans un format incorrect — Certains systèmes stockent les IBAN sans le préfixe "SA" ou avec des espaces. Le fichier est exporté avec la bonne structure de colonnes, mais les données sous-jacentes sont incorrectes.
Salaire net ne correspondant pas au virement bancaire effectif — Si l'établissement a absorbé les frais de virement bancaire et les a déduits du montant de l'employé, il y a un écart entre le fichier et ce que l'employé a reçu.
Ces trois situations produisent des enregistrements silencieusement rejetés — le fichier est accepté, le taux de conformité baisse, et aucune erreur n'apparaît avant le rapport mensuel. Pour une analyse approfondie de la logique de rapprochement appliquée par Mudad, consultez notre article sur pourquoi les violations WPS saoudiennes commencent dans vos données RH.
Surveiller la conformité après le dépôt
Après le dépôt, l'étape la plus importante est la lecture du rapport de conformité et le déclenchement d'alertes immédiates en cas de baisse du taux :
interface ComplianceReport {
establishmentId: string;
paymentMonth: string;
totalEmployees: number;
acceptedRecords: number;
rejectedRecords: number;
complianceRate: number;
violations: Array<{
employeeId: string;
reason: string;
correctionDeadline: string;
}>;
}
function analyzeComplianceReport(report: ComplianceReport): {
status: 'compliant' | 'at-risk' | 'violation';
message: string;
requiredAction: string;
} {
const { complianceRate, violations } = report;
// Seuil du programme WPS : 95% de conformité requis
if (complianceRate >= 95) {
return {
status: 'compliant',
message: `Taux de conformité ${complianceRate}% — aucune violation`,
requiredAction: "Aucune action requise",
};
}
if (complianceRate >= 80) {
const deadline = violations[0]?.correctionDeadline ?? 'non spécifié';
return {
status: 'at-risk',
message: `Taux de conformité ${complianceRate}% — ${violations.length} enregistrements à réviser`,
requiredAction: `Corriger les enregistrements rejetés avant le ${deadline}`,
};
}
return {
status: 'violation',
message: `Taux de conformité ${complianceRate}% — violation active`,
requiredAction: "Alerter la direction RH immédiatement et déposer une correction ou un recours",
};
}Connecter Mudad à l'ensemble de la conformité saoudienne
Mudad n'est pas la seule plateforme dans l'équation de conformité saoudienne. Si vous construisez une couche d'intégration complète, vous devez la connecter à :
- Qiwa / Nitaqat — pour le suivi des taux de saudisation et leur corrélation avec les données WPS. Consultez notre guide sur l'intégration de Qiwa avec les systèmes RH pour la conformité Nitaqat.
- ZATCA / Fatoorah — pour synchroniser les données de paie avec la facturation électronique dans les établissements qui suivent la répartition des coûts de main-d'oeuvre. Voir notre guide d'intégration Fatoorah.
- Calcul des indemnités de fin de service — des enregistrements de paie mensuels incomplets affectent le calcul des droits de fin de service lors des audits.
Le schéma d'intégration recommandé
Sur la base de ce que nous observons dans les établissements saoudiens, l'architecture la plus fiable :
ERP / Système RH
↓ export données de paie (JSON ou base de données)
Couche de validation
↓ filtrage enregistrements invalides + notification immédiate
Générateur de fichier WPS
↓ fichier CSV selon spécifications Mudad
Dépôt vers Mudad (manuel ou SFTP)
↓ confirmation de réception
Moniteur de conformité
↓ lecture du rapport de conformité périodiquement
Tableau de bord interne
↓ alerte immédiate en cas de baisse du taux
L'élément critique : la couche de validation s'exécute avant le dépôt, pas après. Chaque enregistrement rejeté après le dépôt signifie du temps perdu en corrections et soumissions répétées — du temps dont vous ne disposez pas toujours avant la fermeture de la fenêtre de conformité.
Si vous êtes un partenaire technologique qui construit un produit
Si vous construisez un système RH ou comptable ciblant le marché saoudien, l'intégration Mudad n'est pas une fonctionnalité optionnelle — c'est un prérequis pour acquérir des clients sur ce marché. ZenHR et Jisr commercialisent tous deux leur intégration Mudad comme argument de vente principal.
La voie de partenariat officielle commence par un contact direct avec l'équipe technique Mudad pour obtenir des identifiants API partenaires. En dehors de ce programme, la voie pratique pour la plupart des systèmes est un générateur de fichiers WPS de haute qualité avec une interface de dépôt propre et un suivi de conformité.
Conclusion
Mudad n'est pas techniquement complexe. Les établissements qui rencontrent des difficultés avec cette plateforme souffrent généralement non pas de Mudad lui-même, mais du fossé entre leur système interne et le fichier qu'il produit. Construire une couche de validation solide avant le dépôt, et une vraie surveillance des rapports de conformité après, élimine la plupart des problèmes avant qu'ils ne deviennent des violations.
Si vous construisez une intégration programmatique avec Mudad ou l'ensemble de la conformité saoudienne, parlez avec l'équipe Noqta — nous concevons l'architecture et construisons les couches qui préviennent les violations avant qu'elles ne surviennent.