Aller au contenu principal

3. Intégrez Papi à votre application web

Intégrez Papi dans votre application, notamment la gestion des flux de paiement, des notifications et des paramètres spécifiques à l'environnement.


Environnements

Papi fournit un seul endpoint de production. Pour les tests, utilisez les indicateurs mode test décrits ci-dessous.

  • Production (transactions en direct) : https://app.papi.mg/dashboard/api/payment-links

Vue d'ensemble du flux de paiement

Le processus de paiement se compose des étapes suivantes :

  1. Obtenez votre clé API depuis le tableau de bord.
  2. Créez un lien de paiement : Envoyez une requête API pour générer un lien de paiement unique pour le client.
  3. Redirigez le client : Utilisez le paymentLink retourné pour envoyer le client vers la page de paiement sécurisée.
  4. Traitement du paiement : Le client finalise le paiement sur la page sécurisée.
  5. Recevez une notification : Après le paiement, Papi appelle votre notificationUrl avec le statut final.
  6. Vérifiez et gérez le résultat : Contrôlez le notificationToken et le paymentReference pour confirmer l'authenticité et mettre à jour votre application.

Guide pas à pas pour implémenter l'intégration des paiements

Ce guide vous accompagne pas à pas pour intégrer l'API de paiement, depuis la création des pages de redirection jusqu'à la gestion des notifications.

1
Créez des pages de redirection

Vous devez configurer deux pages sur votre site web vers lesquelles les clients seront redirigés après le paiement :

  • URL de succès – La page affichée après un paiement réussi (ex. : confirmation de commande).
  • URL d'échec – La page affichée après un paiement échoué (ex. : message d'erreur avec option de réessai).

Notez ces deux URLs – vous en aurez besoin lors de la création du lien de paiement.

2
Créez l'endpoint de notification (API de callback)

L'endpoint de notification est une API que vous implémentez pour recevoir les mises à jour automatiques de statut de Papi.
Il doit accepter les requêtes POST.

Exemple de corps de notification envoyé par Papi

{
"paymentStatus": "SUCCESS",
"paymentMethod": "MVOLA",
"currency": "MGA",
"amount": 15000,
"fee": 500,
"clientName": "Nom du client",
"description": "Paiement pour la commande #123",
"merchantPaymentReference": "MERCHANT-0001",
"paymentReference": "ORDER-123",
"notificationToken": "xyz789",
"message": "Paiement effectué avec succès.",
"payerEmail": "client@example.com",
"payerPhone": "+261340000000"
}

Explication des champs de notification

ChampTypeDescription
paymentStatusstringSUCCESS, PENDING ou FAILED.
paymentMethodstringLa méthode utilisée (MVOLA, ARTEL_MONEY, ORANGE_MONEY, BRED).
currencystringCode de la devise (toujours MGA).
amountintegerMontant payé.
feeintegerFrais de transaction déduits.
clientNamestringNom du client tel que fourni.
descriptionstringLa description du paiement que vous avez envoyée.
merchantPaymentReferencestringRéférence interne du prestataire de paiement.
paymentReferencestringVotre référence unique pour ce paiement (depuis le champ reference).
notificationTokenstringJeton retourné lors de la création du lien de paiement – utilisez-le pour vérifier l'authenticité.
messagestringInformations supplémentaires lisibles par l'humain.
payerEmailstringAdresse email du client (si fournie).
payerPhonestringNuméro de téléphone du client (si fourni).

Vérification de la notification

Pour s'assurer que la notification est authentique, vérifiez que :

  • paymentReference correspond à la référence que vous avez envoyée.
  • notificationToken correspond à celui que vous avez reçu dans la réponse de création du lien de paiement.

Si les deux correspondent, la notification est authentique et vous pouvez mettre à jour votre base de données en toute sécurité.

3
Préparez le corps et les en-têtes pour la création d'un lien de paiement

Vous enverrez une requête POST pour générer un lien de paiement.
Le corps doit inclure les URLs créées aux étapes 1 et 2, ainsi que les détails du paiement.

Endpoint

POST https://app.papi.mg/dashboard/api/payment-links

En-têtes

{
"Content-Type": "application/json",
"Token": "<VOTRE_CLÉ_API>"
}

Exemple de corps de requête

{
"amount": 15000.0,
"clientName": "Nom du client",
"reference": "ORDER-123",
"description": "Paiement pour la commande #123",
"successUrl": "https://votreapp.com/paiement-succes",
"failureUrl": "https://votreapp.com/paiement-echec",
"notificationUrl": "https://votreapp.com/paiement-notif",
"validDuration": 60,
"provider": "MVOLA",
"payerEmail": "client@example.com",
"payerPhone": "+261340000000",
"testReason": "QA interne",
"isTestMode": false
}

Explication des champs de la requête

ChampTypeRequisDescription
clientNamestringNom du client.
amountnumberMontant du paiement (minimum 300).
referencestringVotre identifiant unique pour ce paiement (ex. : ID de commande).
descriptionstringDescription courte (max 255 caractères).
successUrlstringURL de redirection après le succès (doit commencer par http(s)://).
failureUrlstringURL de redirection après l'échec (doit commencer par http(s)://).
notificationUrlstringVotre endpoint qui reçoit les notifications de paiement (http(s)://).
validDurationintegerDurée de validité du lien en minutes (défaut : 1, doit être > 0).
providerstringRestreindre à un seul prestataire : MVOLA, ARTEL_MONEY, ORANGE_MONEY, BRED.
payerEmailstringAdresse email du client.
payerPhonestringNuméro de téléphone du client.
testReasonstringRaison de l'utilisation du mode test (apparaît dans le tableau de bord).
isTestModebooleanDéfinir à true pour activer le mode test (voir la section « Mode Test » ci-dessous).
4
Envoyez la requête POST pour récupérer le lien de paiement

Effectuez la requête avec le corps et les en-têtes de l'étape 3.
En cas de succès, vous recevez une réponse comme celle-ci :

{
"data": {
"amount": 15000.0,
"currency": "MGA",
"linkCreationDateTime": 1723850012,
"linkExpirationDateTime": 1723853612,
"paymentLink": "https://pay.papi.mg/payment/abc123",
"clientName": "Nom du client",
"paymentReference": "ORDER-123",
"description": "Paiement pour la commande #123",
"successUrl": "https://votreapp.com/paiement-succes",
"failureUrl": "https://votreapp.com/paiement-echec",
"notificationUrl": "https://votreapp.com/paiement-notif",
"payerEmail": "client@example.com",
"payerPhone": "+261340000000",
"notificationToken": "xyz789",
"testReason": "QA interne",
"isTestMode": false
}
}

Champs importants de la réponse

ChampDescription
paymentLinkL'URL vers laquelle le client doit être redirigé pour payer.
notificationTokenConservez-le – vous en aurez besoin pour vérifier les futures notifications.
5
Redirigez l'utilisateur vers l'URL de paiement

Choisissez comment envoyer le client vers la page de paiement. Deux flux sont pris en charge – choisissez celui qui correspond à votre UX.

Option A — Redirection standard

Extrayez le paymentLink de la réponse et redirigez le client :

  • Applications web : Ouvrez le lien dans un nouvel onglet de navigateur ou effectuez une redirection HTTP.
  • Applications mobiles : Utilisez une WebView ou le navigateur par défaut de l'appareil.
    Conseil : Certaines plateformes réinitialisent les WebViews lorsque l'application passe en arrière-plan – gérez cela avec soin pour éviter la perte d'état.

Une fois redirigé, le client finalise le paiement sur la page sécurisée de Papi. Après la transaction, il est renvoyé vers votre successUrl ou failureUrl, et votre notificationUrl reçoit le statut final.

Écran de choix du paiement


Option B — Fenêtre pop-up intégrée à l'application

Gardez le client sur votre site en ouvrant le paymentLink dans une fenêtre pop-up et en écoutant un événement postMessage envoyé par Papi lorsque le paiement est confirmé.

1. Ouvrir la pop-up de paiement

Ouvrez l'URL retournée par le serveur dans une nouvelle fenêtre pop-up. Cela doit se produire à l'intérieur d'un gestionnaire d'événement utilisateur (ex. un événement submit de formulaire) — sinon le navigateur bloquera la pop-up. Nous utilisons JavaScript pour la démonstration, mais la même logique s'applique dans n'importe quel framework frontend.

var paymentWindow = window.open(
paymentLink, // URL de l'étape précédente
'payment-form-window', // nom de fenêtre réutilisable
'width=500,height=700' // dimensions de la pop-up
);

Conservez une référence à paymentWindow — vous en aurez besoin pour vérifier que le message provient bien de cette pop-up.

2. Écouter le succès du paiement

Une fois la pop-up ouverte, enregistrez un écouteur message sur la fenêtre parente. Papi publiera { type: 'PAYMENT_STATUS' } lorsque le paiement est confirmé.

let PAPI_ORIGIN  = 'https://payment-form.papi.mg';

let paymentMessageHandler = null;
let paymentSuccess = false;

function teardownPaymentMessageListener() {
if (paymentMessageHandler) {
window.removeEventListener('message', paymentMessageHandler);
paymentMessageHandler = null;
}
}

function onPaymentSuccessMessage () {
// Votre logique de gestion du succès ici
}

function setupPaymentMessageListener() {
teardownPaymentMessageListener();

paymentMessageHandler = function (event) {
// 1. Rejeter tout ce qui ne vient pas de l'origine Papi
if (event.origin !== PAPI_ORIGIN) return;
// 2. Rejeter tout ce qui ne vient pas de la pop-up ouverte
if (event.source !== paymentWindow) return;
// 3. Ne réagir qu'aux charges utiles PAYMENT_STATUS
if (!event.data || event.data.type !== 'PAYMENT_STATUS') return;
// 4. Éviter le double traitement
if (paymentSuccess) return;

paymentSuccess = true;
teardownPaymentMessageListener();
onPaymentSuccessMessage();
};

window.addEventListener('message', paymentMessageHandler);
}

Appelez setupPaymentMessageListener() immédiatement après window.open() afin de ne manquer aucun message entre les deux appels :

paymentWindow = window.open(paymentLink, 'payment-form-window', 'width=500,height=700');
setupPaymentMessageListener();

3. Garde-fous de sécurité

Trois vérifications doivent toutes passer avant d'agir sur un message :

VérificationPourquoi c'est important
event.origin === PAPI_ORIGINRejette les messages provenant de tout autre domaine. Doit correspondre exactement — schéma + hôte, sans barre oblique finale.
event.source === paymentWindowRejette les messages des iframes ou onglets non liés qui partagent la même origine.
event.data.type === 'PAYMENT_STATUS'Ignore les autres trafics postMessage sur la même page (analytics, widgets, etc.).

4. Nettoyage

Retirez toujours l'écouteur une fois terminé — en cas de succès, d'annulation ou lorsque l'utilisateur ferme la pop-up :

// En cas de succès → géré automatiquement dans l'écouteur ci-dessus

// En cas d'annulation (l'utilisateur clique sur « Annuler »)
teardownPaymentMessageListener();
if (paymentWindow && !paymentWindow.closed) { paymentWindow.close(); }
paymentWindow = null;

Pièges courants

SymptômeCause
L'écouteur ne se déclenche jamaisMauvaise correspondance de PAPI_ORIGIN (http vs https, barre oblique finale, port).
L'écouteur se déclenche pour des messages non liésGarde-fou event.source === paymentWindow manquant.
La redirection se produit deux foisIndicateur paymentSuccess manquant ou écouteur non retiré après le premier déclenchement.
event.source est nullPop-up fermée avant l'envoi du message — assurez-vous que le message est envoyé avant window.close().

Mode Test

Papi propose deux façons de tester votre intégration :

1. Indicateur isTestMode dans la requête

  • Définissez "isTestMode": true dans le corps de la requête.
  • La transaction est marquée comme test dans votre tableau de bord, mais de l'argent réel est quand même déplacé.
  • Utile pour les tests de bout en bout avec de vrais prestataires (sauf pour le mobile money, qui ne prend pas en charge les transactions de test non réelles).

2. Mode Test de l'application (cartes uniquement)

  • Dans les paramètres de votre boutique dans le tableau de bord, activez le Mode Test.
  • Utilisez les informations de la carte de test suivante :
    • Numéro de carte : 4000 0000 0000 5126
    • Date d'expiration : 01/2028
    • CVV : 123
  • Cela simule un paiement par carte sans mouvement de fonds réels.

Récapitulatif du flux de travail

  1. Obtenez votre clé API depuis le tableau de bord (Icône avatar → Boutiques → sélectionnez la boutique → onglet Développeur).
  2. Créez un lien de paiement en envoyant une requête POST avec les champs requis.
  3. Redirigez le client vers le paymentLink retourné.
  4. Recevez une notification sur votre notificationUrl lorsque le statut du paiement change.
  5. Vérifiez la notification à l'aide de paymentReference et notificationToken.
  6. Mettez à jour vos enregistrements et informez le client.

En suivant ces étapes, vous pouvez accepter des paiements en ligne de manière sécurisée avec Papi. Testez toujours minutieusement en mode test avant de passer en production.