Conciliation
Quand un client MCM est configuré avec un système de mission externe (HRIS, base syndicale, etc.), les demandes d'adhésion publiques signées via un formulaire web ne créent pas immédiatement un employé MCM. Elles passent à l'état ATransferer et attendent que votre système les traite.
IConciliationClient est le pont entre MCM et votre système : vous récupérez la liste, créez le membre de votre côté, puis confirmez à MCM qui crée l'Employe final.
Module requis : MaCarteDeMembre.
Activation : ce flux n'est actif que si l'admin MCM a coché « Système de mission externe » sur votre client. Sinon, les demandes signées créent un Employe directement et GetDemandesATransferer retourne toujours une liste vide.
Client SDK : IConciliationClient.
1. Diagramme d'état
┌──────────────────────────────────────────────────────────────────┐
│ Formulaire public signé par un non-membre │
│ │ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ En attente (admin) │ ── rejetée (admin) ──┐ │
│ └────────────────────────┘ │ │
│ │ admin accepte │ │
│ ▼ │ │
│ ┌────────────────────────┐ │ │
│ ┌─────► │ ATransferer │ ◄── visible via │ │
│ │ └────────────────────────┘ GetDemandesATransferer
│ │ │ │ │
│ │ Confirmer() │ Rejeter() │ │
│ │ ▼ ▼ │
│ │ ┌────────────────────────┐ ┌──────────────────────┐
│ │ │ Employe MCM créé + │ │ Rejetée │
│ │ │ webhook adhesion.signee│ └──────────────────────┘
│ │ └────────────────────────┘ │
│ │ │
│ └── (idempotent : Confirmer sur déjà confirmée → 4xx) ── │
└──────────────────────────────────────────────────────────────────┘
2. Cycle complet
// 1. Récupérer les demandes en attente
var demandes = await conciliationClient.GetDemandesATransferer();
if (demandes.IsError)
{
logger.LogError("Récupération impossible: {Err}", demandes.FirstError.Description);
return;
}
foreach (var d in demandes.Value)
{
using var scope = logger.BeginScope(new { IdUnique = d.IdUnique });
try
{
// 2. Vérifier dans votre système (doublon, liste noire, employeur valide)
var existing = await missionSystem.RechercherMembre(d.Courriel, d.DateNaissance);
if (existing is { Statut: "Actif" })
{
// Doublon connu — rejeter
await conciliationClient.Rejeter(d.IdUnique);
logger.LogInformation("Demande rejetée (doublon)");
continue;
}
// 3. Créer le membre de votre côté
var noMembre = await missionSystem.CreerMembre(d);
// 4. Confirmer à MCM avec le matricule attribué
var confirme = await conciliationClient.Confirmer(d.IdUnique,
new B2BConfirmerDemandeAdhesionDto
{
Matricule = noMembre,
// Surcharger n'importe quel champ que vous corrigez :
// CodePostal = d.CodePostal?.ToUpperInvariant(),
});
if (confirme.IsError)
{
logger.LogError("Confirmation échouée: {Err}", confirme.FirstError.Description);
continue;
}
logger.LogInformation("Membre créé. IdExterne MCM: {Id}", confirme.Value);
}
catch (Exception ex)
{
logger.LogError(ex, "Échec traitement");
// NE PAS rejeter sur exception — laisser réessayer au prochain cycle
}
}
3. Données reçues — B2BDemandeAdhesionConciliationItem
| Champ | Type | Note |
|---|---|---|
IdUnique | Guid | Clé de la demande. À passer à Confirmer/Rejeter. |
Prenom, Nom | string | Requis. |
Courriel | string | Requis (sera courriel principal de l'Employe créé). |
CourrielAlternatif | string? | Optionnel. |
Adresse1 / Adresse2 / Ville / Province / CodePostal | string? | Optionnel selon le formulaire. |
TelephonePrincipal / TelephoneAlternatif | string? | Optionnel. |
DateNaissance | DateOnly? | Optionnel. |
Matricule | string? | Saisi par le signataire si demandé — souvent null, à compléter via Confirmer. |
DateSignature | DateTime | UTC. Date de signature du formulaire. |
EmployeurIdentifiantExterne | string | À matcher contre votre référentiel d'employeurs. |
EmployeurNom | string | Affichage uniquement. |
4. Confirmer avec surcharges
Tous les champs de B2BConfirmerDemandeAdhesionDto sont optionnels. Tout champ non-null remplace la valeur de la demande avant la création de l'Employe :
await conciliationClient.Confirmer(d.IdUnique,
new B2BConfirmerDemandeAdhesionDto
{
Matricule = "M-2026-0042", // attribution interne
CodePostal = NormalizeCodePostal(d.CodePostal),
Prenom = ToTitleCase(d.Prenom) // correction de casse
});
Passer null ou ne pas appeler le second paramètre garde toutes les valeurs de la demande :
// Acceptation telle quelle
await conciliationClient.Confirmer(d.IdUnique);
La méthode retourne ErrorOr<Guid> — le Guid étant l'IdUnique interne MCM. Notez que ce n'est pas l'IdExterne ; l'IdExterne est typiquement le Matricule que vous avez passé. Récupérez l'Employe complet ensuite si nécessaire :
var employe = await employesClient.GetEmployeById("M-2026-0042");
5. Erreurs spécifiques
| Code | Signification | Action |
|---|---|---|
DemandeAdhesion.NotFound | L'IdUnique n'existe pas, ou n'appartient pas au client de la clé API | Vérifier que la clé API a accès à ce client MCM |
DemandeAdhesion.StatutInvalidePourAccepter | Confirmer appelé sur une demande qui n'est plus ATransferer (déjà traitée, fusionnée) | Idempotence : marquer comme déjà traité de votre côté |
DemandeAdhesion.StatutInvalidePourRejet | Rejeter sur une demande déjà acceptée | Idem |
Employe.CourrielDuplique | Lors de Confirmer, le courriel est déjà associé à un autre employé | Renvoyer un courriel de fusion à l'admin MCM, ou surcharger via Confirmer({Courriel = ...}) |
Validation.* (codes postaux, téléphones) | La demande contient des données invalides | Surcharger via Confirmer ou Rejeter |
6. Webhook adhesion.signee
Lorsque Confirmer réussit, MCM crée l'Employe, l'adhésion correspondante, transfère les paiements éventuels déjà attachés à la demande, et déclenche le webhook adhesion.signee avec un payload B2BAdhesionItemV2.
Si vous écoutez ce webhook, n'appelez pas IEmployesClient.GetEmployeById derrière Confirmer — vous recevrez la donnée fraîche par push :
public class AdhesionSigneeHandler : IMcmWebhookHandler<B2BAdhesionItemV2>
{
public Task HandleAsync(B2BWebhookPayload<B2BAdhesionItemV2> p, CancellationToken ct)
{
// p.Data contient l'adhésion finale
return missionSystem.MarquerAdhesionSignee(p.Data);
}
}
Voir le guide webhooks.
7. Bonnes pratiques
- Cadence :
GetDemandesATransferern'est pas paginé. Faites tourner le job aussi souvent que vous voulez (toutes les 5–15 min) — la liste est généralement courte. - Idempotence de votre côté : avant de créer le membre, vérifiez les doublons (
Courriel,DateNaissance). MCM ne dédoublonne pas pour vous. - Erreur transitoire vs erreur métier : laissez les exceptions réseau réessayer. Ne
Rejeterque sur décision métier explicite (doublon, inéligible, liste noire). - Ordre Confirmer → de votre côté : créez d'abord de votre côté, puis
Confirmer. SiConfirmeréchoue, vous avez quand même votre membre — corrigez et réessayez. L'inverse (Confirmer puis créer de votre côté) laisse MCM créer un employé orphelin. - Ne pas mélanger avec sync : si vous utilisez la conciliation, ne synchronisez pas ces employés via
ISyncClient.Sync(l'IdExterneest géré par le flux conciliation). Une sync ultérieure peut écraser des champs. - Webhook + interrogation périodique combinés : redondance saine. Le webhook peut être perdu (réseau, redéploiement). Un appel quotidien à
GetDemandesATransferervide la file résiduelle.
8. Dépannage
| Symptôme | Cause |
|---|---|
GetDemandesATransferer retourne toujours [] | Le client MCM n'a pas activé le système de mission externe |
| Demandes accumulées sans être consommées | Job d'interrogation périodique arrêté de votre côté, ou Confirmer échoue silencieusement (vérifier result.IsError) |
Employe créé sans Matricule | Confirmer appelé sans B2BConfirmerDemandeAdhesionDto.Matricule ; la demande n'en avait pas |
| Paiement perdu | Bug pré-2026.04 — fixé ; vérifier la date de la demande et le ticket support |
Voir aussi
IConciliationClient(référence)- Guide — synchronisation des employés (alternative directe sans conciliation)
- Guide — webhooks (
adhesion.signee) - Endpoints HTTP —
ConciliationController