API de statut de lien de paiement
Relit un lien de paiement par votre référence, avec le statut du lien et l'issue du paiement effectué via ce lien. Utilisez-la pour récupérer le résultat d'un paiement lorsqu'une notification ne vous est pas parvenue, et pour vérifier l'état d'un lien avant d'en émettre un nouveau.
Endpoint
GET https://app.papi.mg/engine/api/payment-links/{merchantPaymentReference}
| Élément | Valeur |
|---|---|
| URL de base | https://app.papi.mg/engine/api |
| Chemin | /payment-links/{merchantPaymentReference} |
| Méthode | GET |
| Corps de la requête | Aucun |
| Corps de la réponse | JSON |
Cet endpoint existe uniquement sur l'URL du moteur. L'URL historique https://app.papi.mg/dashboard/api/payment-links prend en charge uniquement la création de lien (POST). Elle ne prend pas en charge ce GET.
Authentification
Chaque requête doit porter la clé API de votre boutique dans l'en-tête Token. La référence est résolue uniquement dans la boutique à laquelle appartient la clé API.
En-têtes de la requête
| En-tête | Requis | Valeur | Description |
|---|---|---|---|
Token | ✓ | <YOUR_API_KEY> | Clé API de votre boutique. |
Aucun autre en-tête n'est lu par cet endpoint. L'en-tête LinkToken utilisé par la page de paiement n'est pas accepté ici comme méthode d'authentification.
Paramètres de chemin
| Paramètre | Type | Requis | Contraintes | Description |
|---|---|---|---|---|
merchantPaymentReference | string | ✓ | Comparée exactement (sensible à la casse). Peut contenir des points. Encodez les caractères réservés pour l'URL. | Votre référence : le champ reference envoyé lors de la création du lien. C'est la même valeur que merchantPaymentReference dans les notifications. Ce n'est pas la référence de paiement de Papi. |
N'utilisez que des lettres, des chiffres, -, _ et . dans les références. Les caractères comme ?, # ou l'espace doivent être encodés pour l'URL (%3F, %23, %20). Une référence contenant / ne peut pas être relue via cet endpoint, même encodée : le serveur refuse une barre oblique encodée dans un chemin.
Quel lien est retourné
Une référence n'est pas toujours unique : vous pouvez créer un nouveau lien avec la même référence après que le précédent a été payé, a expiré ou a été désactivé. Lorsque plusieurs liens de votre boutique partagent la référence, l'endpoint retourne exactement un lien, choisi dans cet ordre :
- Un lien payé, s'il en existe un, quel que soit son âge. Si plusieurs sont payés, le lien payé le plus récent.
- Sinon, le lien le plus récent.
Ainsi, si une commande a été payée et qu'un nouveau lien a été émis pour elle plus tard, cet endpoint signale toujours le lien payé. Vous êtes toujours informé que l'argent est arrivé.
Cette recherche prend en compte tous les liens de votre boutique ayant cette référence, y compris les liens créés à la main depuis le tableau de bord.
Exemple de requête
curl -X GET "https://app.papi.mg/engine/api/payment-links/ORDER-123" \
-H "Token: <YOUR_API_KEY>"
Réponse en cas de succès
Statut : 200 OK
{
"data": {
"linkStatus": "PAID",
"paymentStatus": "SUCCESS",
"paymentMethod": "MVOLA",
"currency": "MGA",
"displayCurrency": "MGA",
"amount": 15000.0,
"clientName": "Client Name",
"description": "Payment for Order #123",
"merchantPaymentReference": "ORDER-123",
"papiPaymentReference": "c1f4a5b0-6f5e-4e1b-9f0e-2b7d8a9c3d21",
"notificationToken": "5b8f0c3e-2a7d-4f61-9e0b-7c4d1a2e9f38",
"message": null,
"payerEmail": "customer@example.com",
"payerPhone": "+261 34 00 000 00",
"paymentLink": "https://payment-form.papi.mg/yourshop/payments/eyJhbGciOiJIUzI1NiJ9...",
"shortLink": "https://link.papi.mg/8NW7R",
"linkCreationDateTime": 1788065989011,
"linkExpirationDateTime": 1788281989011,
"isTestMode": false
}
}
Champs de la réponse
Tous les champs sont présents dans la réponse. Un champ sans valeur vaut null.
Les champs portent les mêmes noms et la même signification que dans le corps de la notification, à une exception près : la référence de Papi s'appelle ici papiPaymentReference (elle s'appelle paymentReference dans la notification). Cela évite toute confusion avec votre merchantPaymentReference.
| Champ | Type | Description |
|---|---|---|
linkStatus | string | État du lien : ACTIVE, EXPIRED, PAID ou DISABLED. Voir Statut du lien. |
paymentStatus | string | Issue de la tentative de paiement décrite par cette réponse : SUCCESS, PENDING ou FAILED (les mêmes valeurs que la notification). null lorsque personne n'a tenté de payer. |
paymentMethod | string | Prestataire de cette tentative de paiement (MVOLA, AIRTEL_MONEY, ORANGE_MONEY, BRED). null lorsque personne n'a tenté de payer. |
currency | string | Devise du lien (MGA). |
displayCurrency | string | Devise affichée au client (MGA). |
amount | number | Montant du lien. |
clientName | string | Nom du client, tel qu'envoyé à la création. |
description | string | Description, telle qu'envoyée à la création. |
merchantPaymentReference | string | Votre reference, telle qu'envoyée à la création. |
papiPaymentReference | string | La référence de Papi pour la tentative de paiement (un UUID). C'est le paymentReference de la notification. null lorsque personne n'a tenté de payer. |
notificationToken | string | Le jeton retourné à la création du lien. |
message | string | Motif d'échec de la tentative de paiement, s'il y en a un. null sinon. |
payerEmail | string | Email du client, tel qu'envoyé à la création, ou null. |
payerPhone | string | Numéro de téléphone du client au format international, tel qu'envoyé à la création, ou null. |
paymentLink | string | L'URL de paiement, telle que retournée à la création. |
shortLink | string | Forme courte de l'URL de paiement, ou null lorsqu'aucune n'a été générée. |
linkCreationDateTime | integer | Date de création, en millisecondes epoch. |
linkExpirationDateTime | integer | Date d'expiration, en millisecondes epoch. |
isTestMode | boolean | Indique si le lien est marqué comme test. |
Statut du lien
linkStatus est évalué dans cet ordre. La première règle qui correspond donne le statut :
| Ordre | Condition | linkStatus |
|---|---|---|
| 1 | Le lien est payé. | PAID |
| 2 | La date d'expiration est passée. | EXPIRED |
| 3 | Le lien est activé. | ACTIVE |
| 4 | Aucune des conditions ci-dessus : le lien a été désactivé. | DISABLED |
PAID l'emporte toujours : un lien payé est signalé comme PAID même après avoir expiré ou avoir été désactivé. Un lien désactivé dont la date d'expiration est passée est signalé comme EXPIRED.
Quelle tentative de paiement est décrite
Un client peut tenter de payer plusieurs fois sur le même lien (par exemple, une première tentative échoue et une seconde réussit). Les champs de paiement (paymentStatus, paymentMethod, papiPaymentReference, message) décrivent une seule tentative :
- pour un lien
PAID: la tentative réussie, même si une autre tentative a été faite après elle ; - pour tout autre lien : la tentative la plus récente.
Lire les deux statuts ensemble
linkStatus | paymentStatus | Signification | Que faire |
|---|---|---|---|
ACTIVE | null | Personne n'a encore tenté de payer. | Attendez, ou envoyez à nouveau le lien au client. |
ACTIVE | FAILED | La dernière tentative a été refusée ou abandonnée. Le client peut réessayer sur le même lien. | Lisez message pour connaître le motif. Attendez. |
ACTIVE | PENDING | Une tentative est en cours chez le prestataire. | Revérifiez sous peu. |
PAID | SUCCESS | Le paiement est passé. | Confirmez la commande. |
EXPIRED | null / FAILED / PENDING | Le lien a expiré avant un paiement réussi. | Créez un nouveau lien. |
DISABLED | null / FAILED / PENDING | Le lien a été désactivé depuis le tableau de bord. | Créez un nouveau lien si la commande doit encore être payée. |
Erreurs
Format du corps d'erreur :
{
"error": {
"code": "<ERROR_CODE>",
"message": "<Human-readable message, in French>"
}
}
| Statut HTTP | Code d'erreur | Signification | Exemple de message |
|---|---|---|---|
401 | CORE_PERM_0001 | L'en-tête Token est absent, ou la clé API est inconnue. | API key invalide |
404 | CORE_404 | Aucun lien avec cette référence n'existe dans votre boutique. Une référence qui n'existe que dans une autre boutique donne aussi 404. | Aucun lien de paiement pour la référence ORDER-123 |
Exemple de corps 404 :
{
"error": {
"code": "CORE_404",
"message": "Aucun lien de paiement pour la référence ORDER-123"
}
}
Notes pratiques
Récupérer une notification manquée
Une notification n'est envoyée qu'une fois. Si votre endpoint était indisponible ou si l'appel s'est perdu :
- Appelez cet endpoint avec votre
reference. - Si
linkStatusvautPAIDetpaymentStatusvautSUCCESS, confirmez la commande. - Si
paymentStatusvautPENDING, rappelez l'endpoint plus tard. - Sinon, laissez la commande impayée.
Vous pouvez aussi renvoyer la notification depuis le tableau de bord : voir Notifications en échec.
Vérifier avant de réémettre un lien
Avant de créer un nouveau lien pour une commande qui en avait déjà un, appelez cet endpoint :
PAID: n'émettez pas de nouveau lien. La commande est payée.ACTIVE: envoyez à nouveau le même lien au client, ou renvoyez la même requête de création (elle retourne le même lien, voir Idempotence).EXPIREDouDISABLED: créez un nouveau lien. Vous pouvez utiliser la mêmereference.
Interrogation périodique (polling)
Cet endpoint est destiné à la récupération et aux vérifications, pas à remplacer les notifications. Si vous interrogez périodiquement, espacez les appels (par exemple, toutes les quelques secondes tant que paymentStatus vaut PENDING) et arrêtez lorsque le lien est PAID, EXPIRED ou DISABLED.
Mode test
L'endpoint lit les liens de test et les liens réels de la même façon. Utilisez isTestMode dans la réponse pour les distinguer.