Contrat API — Connexion Google et candidature partenaire
Statut : implémenté dans le code local, non déployé et non vérifié en production.
Routes serveur disponibles sous les deux préfixes existants : /resellers/auth/google/... (appel direct du BFF portail) et /api/resellers/auth/google/... (alias du routeur API). Le portail client utilise la base configurée par PARTNER_API_URL et le préfixe /resellers.
Les opérations exigent Authorization: Bearer <Firebase ID token> issu de Firebase, avec firebase.sign_in_provider = google.com et une adresse email vérifiée. Le backend vérifie le jeton auprès de Firebase Admin. Le client ne transmet jamais l’email de référence à la création du dossier : il est tiré de l’identité vérifiée.
Consulter l’état
GET /resellers/auth/google/application (alias /api/resellers/auth/google/application)
Réponse 200 :
{
"success": true,
"data": {
"email": "personne@example.com",
"name": "Nom Google",
"status": "NOT_APPLIED",
"access_ready": false,
"application": null
}
}
status vaut NOT_APPLIED, PENDING, APPROVED, REJECTED ou APPLICATION_INCOMPLETE. access_ready n’est vrai que si le dossier est APPROVED et lié à un revendeur dont le statut est ACTIVE et dont l’email correspond à l’identité Google. Une ancienne approbation sans ce lien actif est exposée comme APPLICATION_INCOMPLETE; elle ne donne aucun accès.
Envoyer la candidature
POST /resellers/auth/google/application (alias /api/resellers/auth/google/application)
{
"phone": "01 97 00 00 06",
"country_code": "BJ",
"country_name": "Benin",
"company_name": "Ma société",
"notes": "Présentation facultative"
}
Réponse 201 : { "success": true, "data": { "id": "…", "status": "PENDING", "company_name": "Ma société", "created_at": "…" }, "status": "PENDING" }. Une demande en attente est mise à jour au lieu d’être dupliquée. Une ancienne approbation non liée peut être réouverte en PENDING, en conservant sa décision dans metadata.decision_history. Une candidature approuvée déjà liée à un compte actif renvoie 200 sans créer de doublon. Un compte déjà lié mais inactif ou incohérent est refusé avec PARTNER_ACCOUNT_LINK_INVALID et doit être traité par le support.
Échanger l’approbation contre une session
POST /resellers/auth/google/session (alias /api/resellers/auth/google/session) avec le même Bearer Firebase Google vérifié. L’API répond 200 et pose le cookie HTTP-only partner_token uniquement si le dossier est approuvé, lié à un revendeur ACTIVE, et que les emails correspondent. Le JSON ne contient jamais le JWT.
Une demande PENDING retourne 403 PARTNER_APPLICATION_PENDING; une absence de demande ou un dossier non approuvé retourne 403 PARTNER_APPLICATION_REQUIRED. Le portail client appelle d’abord l’endpoint d’état; si l’accès est prêt, son BFF appelle cet endpoint, relaie le JWT dans le cookie first-party HTTP-only partner_session, puis navigue vers /reseller. Le navigateur ne reçoit jamais le JWT dans le JSON.
Erreurs : 401 session absente/invalide ou email non vérifié; 400 données invalides/pays non pris en charge; 429 limite d’action; 500 erreur technique.
Garanties et limites
- Un jeton Firebase dont le fournisseur est Google, valide, et une email vérifiée sont requis; les valeurs d’email du formulaire sont ignorées par cette route.
- La soumission répond
201lors d’une création et200lors d’une mise à jour/idempotence. Après une soumission, le client relit toujoursGETpour afficher l’état autoritaire; il ne suppose pas que chaque réponse200est encorePENDING. - La candidature est enregistrée
PENDING; aucune ligneresellers/compte revendeur ni accès aux fonctions partenaires n’est créé à cette étape. - L’approbation demeure une action admin. Elle doit créer ou lier un revendeur actif; seule cette relation permet ensuite l’échange de session Google.
- Le client garde le jeton Firebase en session pour relire l’état et envoyer le formulaire.
- Déviation par rapport au formulaire public historique : pas de code promo ni de mot de passe provisoire émis à la candidature. Le formulaire public historique n’accorde désormais lui aussi qu’une candidature
PENDING; un nouveau compte revendeur n’est créé qu’à l’approbation. - Les comptes affiliés historiques et les autres flux de connexion ne sont pas globalement bloqués par cette règle, car le registre
resellersinclut aussi des affiliés/clients historiques. L’échange Firebase Google est explicitement soumis à l’approbation.
Preuve
Prouvé dans le code après implémentation locale. Le contrat OpenAPI généré doit être régénéré et vérifié. Aucun test runtime ni déploiement n’est revendiqué.