Dépannage / FAQ
Les problèmes les plus fréquents lors d'une intégration MCM, regroupés par symptôme.
Authentification
401 Unauthorized à chaque appel
Causes habituelles :
- Clé API manquante —
McmApi:ApiKeynon configuré. Vérifiezappsettings.json, secrets utilisateurs, variables d'environnement. - Clé pour le mauvais environnement — la clé
devne fonctionne pas contreprodet vice-versa. - Clé révoquée ou expirée — contactez l'admin MCM.
- En-tête mal écrit —
x-api-key(avec tiret, minuscules). Le SDK le fait pour vous, mais si vous appelez l'API en HTTP brut, soyez précis.
var result = await employesClient.GetAllEmployes();
if (result.IsError && result.FirstError.Type == ErrorType.Unauthorized)
{
logger.LogError("Clé API invalide ou pour le mauvais environnement");
}
403 Forbidden sur certains endpoints
Le client MCM associé à votre clé n'a pas le module activé. Les endpoints sont protégés par [RequireModule] :
- Endpoints
/b2b/v1/employe,/employeur,/syndicat,/courriel,/conciliation, etc. → moduleMaCarteDeMembre - Endpoints
/b2b/v1/campagnes,/votants,/questions,/liste-electorale→ moduleVotez
Contactez l'admin MCM pour activer le module.
Multi-tenant : changer de clé en cours d'exécution
Voir Authentification — surcharge par client.
Synchronisation
B2BSyncResult.Erreurs non vide mais result.IsError == false
C'est normal : Sync est partiellement tolérant. Une erreur sur un employé n'annule pas le batch. Inspectez :
foreach (var err in result.Value.Employes.Erreurs)
logger.LogWarning("{IdExterne}: {Msg}", err.IdUnique, err.Message);
Emploi rejeté avec Employeur.NotFound
L'IdentifiantExterneEmployeur ne correspond à aucun employeur :
- existant côté MCM, ni
- présent dans la même charge utile
Sync(sousSyndicats[].Employeurs).
Solution : incluez tous les syndicats / employeurs référencés dans le même appel, ou créez-les d'abord.
Adhesion dupliquée à chaque sync
La clé est (EmployeIdExterne, SyndicatIdExterne). Vérifiez :
- Casse / espaces dans
IdExterne. - Vous ne mélangez pas
B2BUpdateEmployeDto(V1, sansAdhesions[]) avecB2BUpsertEmployeDtoV2(V2, avecAdhesions[]).
Sync de 50 000+ employés expire
Tronçonnez :
foreach (var batch in employes.Chunk(5000))
await syncClient.Sync(syndicats, batch.ToList(), []);
Voir Limites de débit.
Suppressions silencieuses : « mes employés disparaissent »
DeleteEmploye est logique : l'employé est désactivé, pas effacé. Ses adhésions historiques restent. Si vous voyez disparaître des employés sans appel Delete de votre part :
- vérifiez que vos imports ne marquent pas par erreur certains employés
EstActif=false, - vérifiez les logs côté MCM (admin) pour des suppressions manuelles.
Webhooks
Aucun webhook ne déclenche
- Webhook configuré côté administration MCM ? Demandez confirmation.
- URL accessible publiquement ? Pas derrière un VPN / firewall ?
- Endpoint mappé :
app.MapMcmWebhooks("/webhooks/mcm")présent dansProgram.cs? - Le secret partagé correspond-il à
McmApi:WebhookSecret? - Les handlers sont-ils enregistrés via
.AddHandler<THandler, TData>(WebhookEventTypes.X)?
Tous les webhooks renvoient 401
La signature ne valide pas. Vérifiez :
- Secret identique côté MCM et
appsettings.json. - Horloge serveur synchronisée (NTP). La fenêtre par défaut est 5 min via
MaxTimestampAgeSeconds.
Webhook reçu deux fois
C'est attendu — MCM réessaie en cas d'échec ou de timeout. Toujours dédoublonner par payload.DeliveryId de votre côté (table d'idempotence). Voir Idempotence et retries.
Comment tester localement ?
Utilisez ngrok ou cloudflared pour exposer votre service local :
ngrok http 5050
# Donnez l'URL HTTPS https://abc123.ngrok.io/webhooks/mcm à l'admin MCM
Erreurs courantes par client
| Code | Client | Cause | Action |
|---|---|---|---|
Courriel.NotAssociatedWithEmployee | ICourrielClient | Adresse passée ≠ courriel principal/alternatif de l'employé | Synchroniser les courriels avant l'envoi |
Employe.CourrielDuplique | IEmployesClient, ISyncClient | Deux employés avec le même courriel | MCM impose l'unicité — corrigez de votre côté |
Employe.Validation (Matricule) | IEmployesClient | Matricule vide ou non unique au sein de l'employeur | Imposer une règle du côté de votre SIRH |
DemandeAdhesion.StatutInvalidePourAccepter | IConciliationClient | Confirmer sur une demande déjà traitée | Marquer comme traitée de votre côté (idempotence) |
ChampUtilisateur.NomDuplique | IChampUtilisateurClient | Nom de champ déjà utilisé | Le Nom est unique par client MCM |
Campagne.EtatInvalidePourPublier | ICampagnesClient | Publier sur une campagne pas en Brouillon | Vérifier Etat avant l'appel |
Votant.DroitDeVoteVerrouille | IVotantsClient | La campagne est ouverte / les droits sont figés | Bloquer ces appels après l'ouverture |
Voir le catalogue complet des erreurs.
Performance
Mes appels prennent plus de 10 secondes
GetAll*sur 100k+ enregistrements : ces endpoints ne sont pas paginés. Préférez :ISignatureClient.SearchSignaturesV2avec filtreApres/Avantpour un flux temporel.- Synchronisation incrémentale : stockez
LastSyncedUtcet lisez parIdExterneuniquement les nouveaux.
- Sync trop gros : tronçonner par 5 000 (voir plus haut).
- Latence réseau : utilisez l'URL régionale la plus proche (vérifiez
BaseUrl).
Combien de requêtes parallèles ?
Pas de limite formelle, ~10 en parallèle est le seuil idéal empirique. Au-delà, vous saturez les pools EF Core du côté MCM. Voir Limites de débit.
Configuration
BaseUrl à utiliser
| Environnement | BaseUrl |
|---|---|
| Développement | https://mcm-dev.neosapiens.com/ |
| Staging | https://mcm-staging.neosapiens.com/ |
| Production | https://app.macartedemembre.com/ |
(Confirmez avec l'admin MCM ; ces valeurs peuvent évoluer.)
L'injection de dépendances échoue au démarrage
No service for type 'IEmployesClient' has been registered
→ builder.Services.AddMcmApiClient(builder.Configuration); manque dans Program.cs. Cet appel enregistre tous les clients d'un coup par réflexion.
Section 'McmApi' is missing
→ Ajoutez le bloc dans appsettings.json :
{
"McmApi": {
"BaseUrl": "https://mcm-dev.neosapiens.com/",
"ApiKey": "votre-cle"
}
}
Sandbox / test
Vous pouvez créer un client MCM jetable pour vos tests d'intégration via l'endpoint POST /test. Voir Sandbox / client de test.
Versions et compatibilité
V1 vs V2 — quelle version utiliser ?
Voir V1 vs V2 — aide-mémoire.
Règle simple :
- Lecture d'adhésions et imports en lot → V2.
- CRUD unitaire (un employé à la fois, intégration legacy) → V1 reste fonctionnelle.
- Nouveau projet → ne mélangez pas, partez sur V2 partout où c'est disponible.
Quelle version de .NET le SDK prend-il en charge ?
MCM.ApiProxy cible net10.0. Pour des cibles antérieures (net8.0), ouvrez un ticket — ce n'est pas planifié mais c'est un effort modéré.
Diagnostic réseau
Activer les logs HTTP du SDK
Le SDK utilise HttpClient standard. Pour voir les requêtes/réponses :
builder.Services.AddHttpClient<IEmployesClient>()
.AddHttpMessageHandler(() => new LoggingHandler());
Ou plus simple, niveau Information sur System.Net.Http.HttpClient :
{
"Logging": {
"LogLevel": {
"System.Net.Http.HttpClient": "Information"
}
}
}
Capturer un appel pour ouvrir un ticket
Journalisez :
- L'URL appelée (sans la clé).
result.FirstError.Code,Description, etMetadata(StatusName, RawBody, Url).- Le
traceIdretourné dans leProblemDetailsHTTP — c'est la clé de recherche côté MCM.