Contrat API — Aligner un routeur / configurer une boutique (sans compte technicien agréé)
Date : 2026-10-26 · Pour : dev app mobile + dev PWA · API : https://live.jmoai.net
1. À quoi ça sert
Laisser un acteur authentifié (toi, un revendeur, un installateur — pas besoin d’être technicien agréé/validé) configurer la boutique TiketMOMO d’un client à partir de son email + les identifiants de son routeur. Le backend valide les identifiants en direct, les stocke, puis aligne la boutique (NAS, forfaits, stock, portail).
La clé d’autorisation réelle = la possession des identifiants du routeur (prouvée par un probe live), pas l’email. L’email ne fait que désigner la boutique cible.
2. Endpoint
POST /api/v1/technique/align-router
Authorization: Bearer <jeton d'un compte authentifié> (ou x-admin-token côté admin)
Content-Type: application/json
- Auth : tout compte authentifié. L’autorisation vient de la validation live des identifiants
- le serial doit appartenir à une allocation du client cible. Chaque appel est audité.
- Code HTTP :
200quand l’appel aboutit (le verdict est dansstatus/steps). Erreurs d’auth/validation/propriété →4xx. - Idempotent. Jamais de payout : aucun champ FedaPay/retrait n’est accepté ni écrit.
3. Requête
{
"email": "vendeur@exemple.com", // REQUIS — client propriétaire de la boutique
"router": {
"serial": "HEW0975P75W", // REQUIS
"allocation_id": "uuid", // optionnel
"model": "hAP ax lite",
"routeros_version": "7.x",
"identity": "…",
"mac": "…", // optionnels
},
"credentials": {
"username": "m1khm0n", // REQUIS — identifiant API/SSH du routeur
"password": "••••••", // REQUIS
"ssh_port": 22, // optionnel
},
"nas": { "declared_nas_name": "…", "hotspot_servers": ["…"], "walled_garden_present": true }, // optionnel
"profiles": [/* forfaits : nom, prix, durée */], // optionnel
"request_id": "…", // optionnel
}
⚠️ Tout champ lié au paiement (ex.
fedapay_public_key) est ignoré : retiré par la validation, jamais transmis à la logique boutique. Le pays, le compte de retrait et la clé FedaPay se gèrent par d’autres routes (voir §6).
4. Réponse 200
{
"success": true,
"status": "ACTIVE", // ACTIVE | ACTION_REQUIRED | REFUSED
"mode": "VPN", // VPN | APP_BRIDGE
"allocation_id": "uuid|null",
"store": { "slug": "…", "url": "https://….wifi.jmoai.net", "webhook_url": "https://…" },
"steps": [ { "key": "LICENCE", "ok": true, "code": "LICENCE_VALID", "message_fr": "…" }, … ],
"next_action": { "who": "NONE|APP|SELLER", "code": "…", "message_fr": "…" },
"green_light": { "green": true, "checks": 6, "warnings": 0 },
"aligned": { "by": "<id acteur>", "target_client_id": "<id client>", "serial": "…" }
}
Mêmes status / steps / next_action que activate-store — détail des étapes et boucle « un clic »
dans CONTRAT-API-ACTIVATION-BOUTIQUE-TIKETMOMO.
5. Erreurs (dans error.code)
| HTTP | error.code |
Sens | À afficher |
|---|---|---|---|
| 401 | UNAUTHORIZED |
Pas de jeton valide | « Reconnecte-toi. » |
| 404 | CLIENT_NOT_FOUND |
Email inconnu (générique, anti-énumération) | « Aucun client pour cet email. » |
| 4xx | AUTH_FAILED / INVALID_CREDENTIALS |
Identifiants routeur refusés | « Identifiants du routeur incorrects. » |
| 4xx | connectivité | Routeur injoignable | « Routeur injoignable — vérifie qu’il est en ligne. » |
| 4xx | propriété | Le serial n’appartient pas à ce client | « Ce routeur n’est pas rattaché à ce client. » |
Codes d’erreur dans
error.code({ "success":false, "error": { "code":"…" } }), pas à la racine.
6. Ce qui reste APRÈS l’alignement
La route prépare le technique (routeur, forfaits, stock, portail). Pour vendre ET encaisser, il reste des actions vendeur :
| À régler | Où | Qui |
|---|---|---|
| Pays de vente | payment.country |
configurateur ou vendeur (bouton dédié) |
| Compte de retrait | store_payout_accounts |
vendeur uniquement — sans lui, la boutique vend mais l’argent n’a nulle part où aller |
| Clé FedaPay (Bénin) | managers.fedapay_p_key |
vendeur uniquement |
Après un alignement réussi, inviter le vendeur à enregistrer son compte de retrait.