Enrôler vos clients
Inviter un client, ouvrir son dossier, le suivre, et recetter le tout sans conséquence.
Ce que votre intégration doit traiter
Deux voies mènent un client jusqu'à son compte de paiement. Vous l'invitez, et il constitue lui-même son dossier. Ou vous ouvrez son dossier à sa place, vous le constituez, puis vous le lui transmettez pour qu'il le relise. Dans les deux cas, Mobupay l'instruit avec son partenaire bancaire, et un compte s'ouvre.
Entre les deux bouts, l'enrôlement traverse onze états, contractuels, rendus dans enrollmentStatus : les mêmes que ceux d'une plateforme. Le champ actionRequired dit qui doit agir (client, agency, mobupay ou none), et hand qui écrit dans le dossier. Branchez vos relances sur le premier.
IN_REVIEW : la liste ne peut que s'allonger, et aucune valeur ne change de sens.Inviter un client
POST /api/v1/agency/clients/invitations avec sa seule adresse suffit. deliveryMode choisit qui envoie l'invitation : email (Mobupay envoie le courriel, avec un seul bouton : « Choisir mon mot de passe » pour un client qui n'a pas encore de compte, « Ouvrir mon compte » sinon), redirect (vous transmettez vous-même le lien url) ou both.
Quand l'invitation porte son adresse, le premier dossier que votre client ouvre vous est rattaché, quel que soit son chemin : le lien du courriel, ou une connexion plus tard, depuis un autre appareil. Un lien transmis sans adresse, lui, doit être suivi pour rattacher. L'invitation passe LINK_OPENED dès qu'il ouvre le lien ou choisit son mot de passe, puis DRAFT quand il commence son dossier.
POST /api/v1/agency/clients/invitations
Authorization: Bearer sk_agy_live_…
{
"email": "gerant@lebonplat.nc",
"deliveryMode": "email",
"redirectUrl": "https://app.votre-agence.nc/clients/retour",
"prefill": { "brandName": "Le Bon Plat", "registrationNumber": "1234567001", "iban": "FR76…" },
"externalRef": "client_00412",
"requestedScope": ["view_kpis", "dev_access"]
}Le préremplissage porte la dénomination, l'enseigne, le RIDET, l'IBAN et le BIC. L'IBAN est contrôlé à l'entrée, et vérifié au nom de l'entreprise lors de l'instruction.
Le RIDET (registrationNumber, 10 chiffres pour l'établissement, 7 pour l'entreprise) est cherché par Mobupay dans l'annuaire de l'ISEE dès l'appel. La réponse dit ce qui a été trouvé dans registry : avec found, l'établissement attend votre client présélectionné à l'étape d'identité, et le valider remplit l'identité de l'entreprise et récupère l'avis RIDET ; avec not_listed (un entrepreneur individuel, le plus souvent), l'étape d'identité le recherche auprès de l'ISEE. Un RID à 7 chiffres qui compte plusieurs établissements est refusé (422 ESTABLISHMENT_AMBIGUOUS), comme un établissement qui a déjà un dossier ou un compte Mobupay (409 ESTABLISHMENT_ALREADY_LINKED).
Une externalRef déjà portée par une invitation en cours est refusée (409 DUPLICATE_INVITATION, avec existingId) : vous avez sans doute rejoué un appel. Une adresse déjà invitée rend l'invitation existante. Pour relancer, employez /resend (même lien) ou /resume-link (nouveau lien, l'ancien cesse de fonctionner).
Ouvrir le dossier de votre client
POST /api/v1/agency/dossiers ouvre le dossier en nommant le courriel du futur titulaire, avec un motif. Si l'adresse n'a pas de compte Mobupay, un compte sans mot de passe est préparé : votre client choisira le sien, vous ne le connaîtrez jamais. Le dossier naît prérempli, et la main est à vous.
Si l'adresse a déjà un compte, rien n'est ouvert sans son accord : une invitation lui est envoyée, la réponse porte consentRequired: true, et le dossier naît quand il l'accepte.
# Un lien d'écriture : il ouvre notre parcours sur ce dossier, au nom du client
POST /api/v1/agency/dossiers/{obsId}/write-link
{ "reason": "Saisie des pièces après appel du gérant", "expiresInMinutes": 15 }
# Transmettre au client : la main passe, il reçoit son courriel
POST /api/v1/agency/dossiers/{obsId}/releaseexpiresInMinutes. Il se ferme après quinze minutes d'inactivité. Un lien neuf ferme le précédent : il n'en vit jamais qu'un par dossier. Chaque lien est journalisé avec son motif, et votre client voit ce que votre agence a fait en son nom.Suivre les dossiers
GET /api/v1/agency/clients/invitations suit vos invitations (filtres status, enrollmentStatus, externalRef, updatedSince). GET /api/v1/agency/dossiers liste les dossiers, et GET /api/v1/agency/dossiers/{obsId} dit ce qui manque à l'un d'eux : le même verdict que lit votre espace agence, jamais le contenu d'une pièce.
Une fois le compte ouvert, le client entre dans GET /api/v1/agency/clients, et se lit dès ce moment, sans attendre son premier paiement. Les pièces que votre client devra réunir sont listées dans le guide Pièces justificatives.
Recevoir les événements
Déclarez une adresse de réception par POST /api/v1/agency/webhooks. Elle appartient à votre agence, et non à l'un de vos clients. Chaque événement arrive signé, au format { id, type, createdAt, data }, comme les autres webhooks Mobupay (vérifier la signature).
agency.invitation.created- Une invitation est créée, ou un dossier ouvert par votre agence.
agency.invitation.expired- Une invitation a expiré sans qu'aucun dossier ne soit ouvert.
agency.invitation.cancelled- Vous avez annulé une invitation.
agency.client.onboarding.updated- L'état public du dossier a changé : lien ouvert, dossier commencé, déposé, en instruction, à corriger, ouvert, refusé.
agency.client.opened- Le compte de paiement de votre client vient d'ouvrir.
agency.mandate.created- Un client entre dans votre portefeuille.
agency.mandate.updated- Le périmètre de votre mandat a changé, ou la propriété du compte a été transmise.
agency.mandate.revoked- Votre mandat a été révoqué : vos appels sur ce client vont être refusés.
Un événement réel part vers vos adresses de test et de production : l'ouverture d'un compte n'existe qu'en production, et une intégration se développe en test. Un événement simulé ne part que vers vos adresses de test. Aucune charge ne porte de pièce, de personne ni de motif.
Recetter sans conséquence
Avec une clé sk_agy_test_, une invitation est simulée : aucun courriel ne part, aucun dossier ni compte ne naît, et rien n'est transmis à notre partenaire bancaire. Vous pilotez son avancement, état par état, et chaque transition émet les vraies notifications, de forme identique à la production, vers vos adresses de test. Une clé de test ne voit que les simulations, une clé de production jamais.
X-Mobupay-Merchant-Id, et GET /api/v1/agency/dossiers/{obsId} rend diagnostic: null, faute de pièces à attendre.Simuler un enrôlement
Collez une clé sk_agy_test_ de votre agence, ou connectez-vous pour choisir parmi les vôtres. Son secret n'est lisible qu'au moment de sa création, depuis les réglages de votre espace agence : il est haché en base et ne se relit pas.
Les appels de la simulation
La console ne fait rien que votre outillage ne puisse faire. C'est le serveur qui dit, à chaque instant, quelles transitions sont possibles.
# Les transitions possibles depuis l'état courant, et la frise
GET /api/v1/agency/clients/invitations/{id}/simulation
# Faire avancer l'enrôlement d'un état
POST /api/v1/agency/clients/invitations/{id}/simulation
{ "transition": "submit" }
# Effacer une simulation
DELETE /api/v1/agency/clients/invitations/{id}Pour un dossier ouvert par votre agence en test, deux transitions de plus, hand_release et hand_return, font passer la main au client et la lui reprennent : actionRequired suit. Une transition impossible est refusée en 409 ILLEGAL_TRANSITION avec la liste de celles qui sont acceptées ; en rejouer une déjà faite rend 200 sans rien réémettre.
Le lien d'une invitation simulée, de la forme /sandbox/agency-enrollment/…, mène à une page de bac à sable qui annonce l'environnement de test et porte les mêmes boutons que la console : vous pouvez la confier à qui recette votre parcours.