Aller au contenu principal

Passerelle de paiement

Encaissez des paiements de vos utilisateurs — mobile money (Orange Money, MTN MoMo, KULU…) et carte — directement depuis les applications que vous déployez sur Kuploy. Choisissez « Payment Gateway » dans le menu + Create Service et votre projet reçoit un point de paiement hébergé, ainsi que des API que vos applications peuvent appeler.

Disponibilité

Le service de passerelle de paiement n'est proposé que si votre hébergeur Kuploy l'a activé. Si Payment Gateway n'apparaît pas dans le choix des types de service, adressez-vous à votre administrateur de plateforme : son offre ne le comprend peut-être pas, ou il n'a pas encore terminé de le configurer.

La référence marchand complète

La référence d'intégration marchand complète — POST /api/pay, le contenu des webhooks, la correspondance des champs, les liens de paiement, les abonnements, les tests en environnement de test — se trouve sur docs.epay.kuploy.app/merchant. L'accès à ce site est restreint : demandez une invitation à votre administrateur de plateforme une fois votre passerelle en service.

Ce que vous obtenez​

Lorsque vous ajoutez une passerelle de paiement à un projet, le panneau de réglages du service affiche :

ÉlémentÀ quoi il sert
Merchant codeL'identifiant unique de votre organisation au sein de la passerelle. À transmettre à chaque appel d'API. Copiable d'un clic depuis le panneau. Affiche Provisioning… un court instant après la création du service — rafraîchissez un peu plus tard.
Webhook signing keyLe secret HMAC-SHA256 qui signe l'en-tête x-epay-signature de chaque événement de paiement livré à votre webhook. Affichez-le et copiez-le depuis le panneau pour vérifier les événements entrants. Gardez-le secret.
Checkout URLLe point d'accès canonique POST /api/pay de la passerelle de votre plateforme. Votre serveur y redirige les clients pour qu'ils règlent.
Payment methodsLes moyens de paiement activés pour votre compte marchand (Orange Money, MoMo, carte, KULU…). La liste dépend de ce que votre administrateur de plateforme a configuré sur la passerelle : les nouveaux moyens apparaissent donc tout seuls à mesure que votre plateforme en ajoute.
Webhook URLL'adresse à laquelle les événements de paiement de votre application sont livrés. Modifiable à tout moment.

Tout se règle depuis le panneau du service : une fois celui-ci créé, vous n'avez plus besoin de l'administrateur de la plateforme.

Un seul compte marchand par organisation

Votre organisation possède une seule identité marchand. Si vous ajoutez la passerelle de paiement à plusieurs projets, tous partagent le même code marchand et la même clé de signature — et les événements de paiement de l'organisation sont livrés à toutes les adresses de webhook que vous avez configurées sur ces services.

Créer un service de passerelle de paiement​

  1. Ouvrez votre projet dans le tableau de bord Kuploy.
  2. Cliquez sur + Create Service et choisissez Payment Gateway.
  3. Donnez au service un nom parlant (il apparaît dans les tableaux de bord ; en général, celui de l'application qu'il servira).
  4. Choisissez les moyens de paiement à activer. Vous pourrez y revenir.
  5. Renseignez éventuellement une adresse de webhook — un point d'accès sur l'une de vos applications déployées, auquel la passerelle enverra ses notifications (paiement réussi, abonnement renouvelé…).
  6. Cliquez sur Create. Votre plateforme crée une identité marchand pour votre organisation et câble le tout. Le code marchand peut afficher Provisioning… quelques instants à la première création : rafraîchissez le panneau et il apparaît.

Encaisser un paiement ponctuel​

Depuis le serveur de votre application, redirigez le client vers le paiement hébergé :

POST https://<hote-passerelle>/api/pay?merchantCode=<votre-code-marchand>
amount=1000
currency=XOF
reference=commande-12345
returnUrl=https://votreapp.example/merci

La passerelle affiche un guichet, le client choisit son moyen de paiement (Orange Money, MoMo, carte…), et en cas de succès votre application est prévenue par le webhook configuré plus haut. La référence complète des champs se trouve dans la documentation d'intégration de la passerelle.

Votre référence externe est votre meilleure alliée

Transmettez toujours votre propre reference — un identifiant de commande, de facture, ce qui rattache le paiement à votre propre système. Elle revient dans chaque webhook et permet à votre application de rapprocher les paiements de vos enregistrements sans analyser quoi que ce soit de fragile.

Abonnements récurrents​

Le service gère aussi la facturation récurrente, pratique si votre application a ses propres offres payantes. Depuis votre serveur :

  1. créez une offre, avec son prix et sa périodicité, via l'API du service ;
  2. à l'inscription, appelez l'API d'abonnement avec l'identifiant du client et celui de votre offre ;
  3. réagissez aux événements customer.subscription.* et invoice.* sur votre point d'accès de webhook.

La forme de l'API de gestion — y compris tous les événements du cycle de vie d'un abonnement — est documentée sur docs.epay.kuploy.app/merchant/subscriptions. L'accès se fait sur invitation : demandez vos identifiants à votre administrateur de plateforme.

Réagir aux événements de webhook​

La passerelle émet des événements à la forme de ceux de Stripe, de sorte que le même code de traitement vaut pour les abonnements par carte et pour ceux en mobile money. Ceux qui vous intéresseront le plus souvent :

ÉvénementCe qu'il signifie pour votre application
customer.subscription.createdLe nouvel abonnement est actif : ouvrez l'accès aux fonctionnalités payantes.
customer.subscription.updatedChangement d'offre, renouvellement ou changement d'état — revérifiez ce à quoi le client a droit.
customer.subscription.deletedL'abonnement a été résilié : retirez l'accès aux fonctionnalités payantes en fin de période.
invoice.payment_succeededL'argent est arrivé : effacez tout impayé de votre côté.
invoice.payment_failedLe paiement a échoué : décidez s'il faut relancer le client.

Chaque événement porte un metadata.externalReference : renseignez-y votre propre identifiant de client ou d'abonnement à la création, et vous pourrez ignorer le reste du contenu si vous le souhaitez.

Vérifier la signature d'un événement​

Chaque événement livré à votre webhook porte un en-tête x-epay-signature : un HMAC-SHA256 du corps brut exact de la requête, en hexadécimal minuscule, calculé avec votre clé de signature de webhook (le secret affiché dans le panneau du service). Il n'y a pas d'enveloppe horodatée.

Vérifiez-la avant d'accorder la moindre confiance au contenu : calculez le HMAC sur le corps brut et comparez en temps constant.

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, signatureHeader, signingKey) {
const expected = createHmac("sha256", signingKey).update(rawBody).digest("hex");
if (!signatureHeader || expected.length !== signatureHeader.length) return false;
return timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}
Vérifiez contre le corps brut

Calculez le HMAC sur le corps non analysé de la requête : resérialiser un JSON déjà analysé peut en changer les octets — ordre des clés, espaces — et faire échouer la vérification. Lisez le corps brut, vérifiez, puis analysez. Rejetez toute requête dont la signature ne correspond pas.

Comment se passe la livraison

Kuploy reçoit chaque événement de la passerelle, le vérifie, puis le relaie tel quel — même corps, même x-epay-signature — vers la ou les adresses de webhook que vous avez configurées. Comme la signature est calculée avec votre clé, vous la vérifiez directement, exactement comme si la passerelle vous livrait l'événement elle-même.

La Webhook URL de vos réglages de service est l'adresse de livraison qui vous appartient, et la seule que vous ayez à renseigner. Vous n'enregistrez pas vous-même de point d'accès auprès de la passerelle : ce versant est configuré pour vous.

La livraison est tentée une fois

Votre point d'accès est appelé une seule fois par événement, avec un délai de 10 secondes, et un appel qui échoue n'est pas réessayé. Un événement manqué est perdu, et non mis en file.

C'est le point le plus important à prendre en compte dans votre conception — voir Rapprocher les paiements.

Rapprocher les paiements​

Considérez le webhook comme le chemin rapide, jamais comme le seul.

Si votre application est en cours de redéploiement, redémarre, devient brièvement injoignable, ou met simplement du temps à répondre, l'événement est perdu. Rien ne le réémet. Le paiement, lui, a bien abouti — le client a été débité et la passerelle l'a enregistré ; seule votre notification s'est égarée.

La conséquence à retenir : une commande encore marquée impayée dans votre base n'est pas la preuve que le client n'a pas payé.

Construisez donc le chemin lent à côté du chemin rapide :

  1. Enregistrez la commande comme en attente au moment où vous engagez le paiement, indexée par la reference que vous avez transmise au comptoir.
  2. Dénouez-la sur réception du webhook. C'est le cas courant, et il est immédiat.
  3. Interrogez la passerelle pour tout ce qui reste en attente — périodiquement, et de nouveau chaque fois qu'un client ouvre sa commande. Demandez l'état courant de ce paiement et dénouez d'après la réponse. L'appel d'état figure dans la référence marchand.
  4. Rendez les deux chemins idempotents. Ils se feront la course : un événement peut arriver pendant que votre interrogation est en vol. Dénouer deux fois la même reference doit être sans effet — ni seconde livraison, ni second reçu.

Sans l'étape 3, chaque événement perdu est une commande qui reste en attente jusqu'à ce qu'un humain le remarque — en général le client, qui a été débité et n'a rien reçu en échange.

Rapprochez avant de redemander un paiement

Un « paiement échoué, veuillez réessayer » affiché à cause d'un webhook manquant, c'est un double débit en puissance. Vérifiez d'abord l'état réel du paiement.

Gérer les moyens de paiement​

Dans les réglages du service, la section Payment Methods liste tous les moyens que votre plateforme prend en charge. Activez-les ou désactivez-les un à un pour votre compte marchand — pratique si vous souhaitez, par exemple, démarrer avec Orange Money et MoMo, puis ouvrir la carte plus tard.

Les changements s'appliquent au paiement suivant : les paiements déjà entamés conservent la liste de moyens avec laquelle ils ont commencé.

Démonter le service​

Pour retirer la passerelle de paiement d'un projet, ouvrez ses réglages et cliquez sur Delete Service. Le rattachement local est effacé immédiatement. Comme votre organisation ne possède qu'un seul compte marchand partagé, celui-ci n'est libéré qu'à la suppression de votre dernier service de passerelle : jusque-là, vos autres services continuent d'utiliser le même code marchand et la même clé de signature. Les paiements en cours et les abonnements actifs rattachés au compte marchand s'arrêtent à sa libération — migrez vos clients d'abord si vous avez de la facturation récurrente en cours.

Limites connues​

Les éléments ci-dessous existent sur le principe, mais ne sont pas encore pleinement exposés dans l'interface. Les chemins d'intégration décrits plus haut permettent tous de s'en passer aujourd'hui.

  • Factures en PDF — l'historique des paiements s'affiche sous forme de liste de transactions. Les factures téléchargeables en PDF — avec lignes de détail, ventilation des taxes et reçu hébergé — arriveront avec le moteur de facturation de votre passerelle ; elles apparaîtront alors d'elles-mêmes dans les réglages du service, sans aucune modification de votre code.
  • Espace client en libre-service pour vos utilisateurs finaux — aujourd'hui, c'est à votre application de proposer ses propres écrans « changer de carte » et « résilier l'abonnement », en appelant l'API de gestion de la passerelle. Une page hébergée que vos clients pourront visiter directement est en cours de développement ; une fois disponible, elle le sera par marchand, à une adresse que le panneau du service affichera.
  • Remboursements, litiges, taxes — pas encore exposés dans l'API de gestion. Si vous en avez besoin avant leur sortie, adressez-vous à votre administrateur de plateforme : il peut agir pour votre compte depuis la console d'administration de la passerelle.

Pour connaître l'état exact de ce que la passerelle prend en charge, consultez la référence sur docs.epay.kuploy.app/merchant. L'accès se fait sur invitation ; demandez-le à votre administrateur de plateforme.

Pièges courants​

  • « Payment Gateway » n'apparaît pas dans + Create Service — soit votre hébergeur ne propose pas encore cette fonctionnalité dans son offre, soit l'administrateur de la plateforme n'a pas fini de la configurer. Demandez-lui.
  • L'URL de paiement renvoie une erreur — vérifiez que le paramètre merchantCode correspond exactement à ce qu'affiche le panneau du service ; les codes sont sensibles à la casse.
  • Aucun webhook ne vous parvient — renseignez une Webhook URL dans les réglages du service (les événements ne sont relayés qu'une fois celle-ci configurée) et assurez-vous qu'elle est joignable depuis l'Internet public. Testez-la avec curl depuis l'extérieur de votre réseau. Les adresses internes, de bouclage ou de réseau privé (localhost, 10.x, 192.168.x, 172.16–31.x, 169.254.x, *.internal, *.local…) sont refusées par précaution — et une cible refusée compte comme une livraison échouée, donc non réessayée, comme l'explique Rapprocher les paiements. Un nom de service interne au cluster ne fonctionnera jamais ici, si joignable qu'il paraisse depuis votre application. https:// est fortement recommandé : le corps décrit un paiement.
  • La vérification de signature échoue — vérifiez contre le corps brut de la requête, avec la clé de signature de webhook du panneau (et non le code marchand), comme montré dans Vérifier la signature d'un événement.