Reçu public

Ce que `GET /v1/transactions/:orderId` montre, et pourquoi ce n'est pas un endpoint de polling.

GET /v1/transactions/{orderId} renvoie un reçu destiné au payeur, sans authentification. C'est de quoi afficher une page de confirmation, pas de quoi piloter une intégration.

Ce n'est pas une stratégie de production

Sur GET /v1/transactions/{orderId}, trois plafonds s'appliquent, cumulativement :

  • 10 requêtes par minute par orderId ;
  • 20 requêtes par minute par IP ;
  • un plafond global, commun à tous les appelants de la route.

Les deux derniers sont le point bloquant : le second borne chaque IP, le troisième met votre trafic de polling en concurrence avec celui de tout le monde. Ce n'est pas un réglage à négocier, c'est une défense contre l'énumération des orderId — sans elle, l'endpoint étant adressable par orderId seul, un tiers pourrait balayer les identifiants d'autrui.

Avec une clé d'API, l'issue se lit sur GET /v1/transactions/by-id/{transactionId} ou GET /v1/transactions?orderId=…, qui relèvent du quota général et portent le détail complet — c'est là qu'il faut poller, pas ici. Voir Réconciliation.

Les données sont partielles et masquées

  • phoneNumber est masqué : +225***0707.
  • email est masqué, et absent si le payeur n'en a pas fourni.
  • payerName n'est servi que pour un lien de paiement, où le payeur saisit lui-même son nom. Celui que vous transmettez à POST /v1/pay-in n'y figure jamais.
  • Le reçu ne porte ni la cause de l'échec, ni les frais.

description est en revanche renvoyé en entier : il est destiné à être lu par le payeur sur son reçu. N'y mettez rien que le porteur de l'orderId ne devrait pas voir.

Le 404 sur orderId ambigu est volontaire

Un orderId est unique par organisation, pas globalement. Deux marchands peuvent donc porter le même. Quand c'est le cas, cet endpoint — qui n'a qu'un orderId en main et aucune organisation à laquelle se rattacher — répond 404 NOT_FOUND plutôt que de choisir.

Ce n'est ni un bug, ni un état transitoire : servir un premier match exposerait les données d'une organisation à un tiers. Le comportement ne changera pas.

Pour lever l'ambiguïté, adressez le reçu par l'identifiant az54 de la transaction (transactionId dans la réponse de POST /v1/pay-in) : GET /v1/transactions/receipt/{transactionId}. Cet identifiant est unique toutes organisations confondues, donc jamais refusé pour ambiguïté. Même reçu, mêmes données masquées, même absence d'authentification ; seul s'applique un plafond de 30 requêtes par minute par transactionId, sans seau par IP ni plafond global : un UUID ne s'énumère pas. C'est l'adresse vers laquelle certains prestataires (Wave, Dalapay) renvoient le payeur.

C'est aussi la raison de choisir un orderId non devinable : voir Idempotence.

On this page