Aller au contenu

Intégration paiement MyPVit (Mobile Money)

Objectif : intégrer les paiements Mobile Money via MyPVit dans un SaaS et valider l'intégration jusqu'au passage en production. Quand l'utiliser : à chaque nouveau projet SaaS qui encaisse via MyPVit. Doc officielle : https://docs.mypvit.pro/fr/intro/integration-guide

Prérequis

  • Un compte MyPVit avec un compte d'opération (en mode Test pour l'intégration).
  • Le Code URL (aussi appelé API Secret) de ton compte — depuis https://mypvit.pro/settings/apis.
  • Un mot de passe fort défini pour l'API Secret (à créer sur la même page, à conserver dans ton gestionnaire de secrets).
  • Une URL de callback publique (pas de localhost ni 127.0.0.1, ils sont refusés) capable de recevoir des POST.
  • L'IP de ton serveur autorisée côté MyPVit (menu autorisation d'IP).

Préparation (console MyPVit)

  1. Mot de passe API + Code URL : dans Settings → APIs, définis le mot de passe de l'API Secret et récupère ton Code URL.
  2. URL de callback : dans Settings → Urls, bouton +Url, type Callback, renseigne ton URL publique de notification, puis récupère le code du callback généré (callback_url_code).

⚠️ Ne jamais committer les secrets (mot de passe API, sk_test_..., codes) dans la base. Placeholders ici, vraies valeurs dans un vault.

Étapes

1. Authentification — obtenir la clé d'accès

La clé récupérée devra être envoyée dans le header X-Secret de tous les appels suivants.

curl --location 'https://api.mypvit.pro/v2/{YOUR_URL_CODE}/renew-secret' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'operationAccountCode={YOUR_OPERATION_ACCOUNT_CODE}' \
  --data-urlencode 'password={YOUR_API_SECRET_PASSWORD}'

Réponse :

{
  "operation_account_code": "ACC_XXXXXXXXXXXX",
  "secret": "sk_test_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "expires_in": 3600
}

La clé expire au bout de 3600 s (1 h). Prévoir un cron / routine qui la renouvelle avant expiration et la met en cache côté serveur.

2. Initier un paiement (scénario succès)

Montant < 1000 XAF pour un succès. Header X-Secret = la clé de l'étape 1.

curl --location 'https://api.mypvit.pro/v2/{YOUR_URL_CODE}/rest' \
  --header 'X-Secret: {SECRET_KEY}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"agent":"AGENT-1","amount":150,"callback_url_code":"{CALLBACK_URL_CODE}","customer_account_number":"{MSISDN}","merchant_operation_account_code":"{ACCOUNT_CODE}","transaction_type":"PAYMENT","owner_charge":"CUSTOMER","owner_charge_operator":"CUSTOMER","free_info":"INFORMATION","product":"PRODUIT TEL","operator_code":"AIRTEL_MONEY","reference":"{TA_REFERENCE}","service":"RESTFUL"}'

Réponse (statut initial) :

{
  "status": "PENDING",
  "status_code": "200",
  "operator": "AIRTEL_MONEY",
  "reference_id": "PAY...",
  "merchant_reference_id": "{TA_REFERENCE}",
  "merchant_operation_account_code": "ACC_...",
  "message": "Demande de paiement initiée, en cours de traitement"
}

Le PENDING ne vaut pas confirmation. Le statut définitif arrive par le webhook (étape 3).

3. Recevoir le webhook (callback) — le point critique

MyPVit envoie un POST à ton URL de callback avec le statut final (SUCCESS ou FAILED) :

{
  "transactionId": "PAY...",
  "merchantReferenceId": "{TA_REFERENCE}",
  "status": "SUCCESS",
  "amount": 150,
  "customerID": "0770XXXXXX",
  "fees": 3.5,
  "totalAmount": 163.5,
  "operator": "AIRTEL_MONEY",
  "amountCredited": 150
}

Ton serveur DOIT répondre HTTP 200 avec un écho dynamique du transactionId et du code reçus :

{
  "transactionId": "PAY...",
  "responseCode": 200
}

Règles strictes de l'accusé de réception : - Écho dynamique : renvoie les valeurs transactionId et code extraites du payload entrant. Ne code jamais 200 en dur — renvoie la valeur reçue, elle peut changer. - Boucle obligatoire : un test n'est validé que si ce callback est correctement traité. Une simple initiation réussie ne suffit pas.

4. Simuler un échec

Pour forcer un échec, initie un paiement avec un montant strictement > 1000 XAF (même requête que l'étape 2, amount à 1500 par ex.). Il faut aussi traiter le callback d'échec avec le même accusé de réception dynamique.

5. APIs complémentaires obligatoires

  • KYC (Know Your Customer) : vérifier l'identité du client avant toute transaction sensible (anti-fraude).
  • Check Status (vérification d'état) : récupérer l'état définitif d'une transaction. C'est le fallback indispensable si le webhook n'arrive pas.

Bonnes pratiques (à ne pas zapper)

  • Asynchrone d'abord : la vérité, c'est le webhook (SUCCESS/FAILED), pas la réponse d'initiation.
  • Idempotence : ta route de callback doit pouvoir recevoir la même notification plusieurs fois sans créditer le client en double. Utilise merchantReferenceId pour vérifier si la transaction est déjà traitée.
  • Pas de callback reçu ? N'en déduis rien. Après un délai raisonnable (~3 min sans notification), le statut est incertain → interroge Check Status pour trancher.

Vérification — checklist avant production

  • [ ] ≥ 2 simulations de succès (montant < 1000 XAF) réalisées et validées
  • [ ] ≥ 2 simulations d'échec (montant > 1000 XAF) réalisées et validées
  • [ ] Webhook géré pour chaque transaction, avec accusé de réception dynamique (HTTP 200 + écho transactionId et code)
  • [ ] API KYC implémentée et fonctionnelle
  • [ ] API Check Status implémentée et fonctionnelle

Dépannage / pièges

  • Callback jamais reçu → URL en localhost/127.0.0.1 (refusée), IP serveur non autorisée, ou URL non publique. Vérifie les 3.
  • Tests refusés côté PVit → l'accusé de réception n'est pas conforme (code en dur au lieu de l'écho dynamique, ou pas de HTTP 200).
  • 401 / clé invalide → clé expirée (durée 3600 s) : renouvelle via renew-secret.
  • Double crédit client → idempotence manquante sur la route callback.

Ressources

  • Guide d'intégration : https://docs.mypvit.pro/fr/intro/integration-guide
  • Guide post-production : https://docs.mypvit.pro/fr/intro/production-guide
  • Console APIs / clés : https://mypvit.pro/settings/apis

Dernière mise à jour : 2026-07-02