welloo-payment-sdk
v0.1.8
Published
SDK Node.js pour effectuer un paiement ou un transfert via welloo
Maintainers
Readme
welloo-payment-sdk
SDK Node.js/TypeScript pour :
- accepter un paiement (page de sélection ou lien direct pour un opérateur) et obtenir une URL de paiement hébergée vers laquelle rediriger le client,
- transfert Mobile Money via Welloo
- liste des transactions
- consultation du solde
- vérifier la signature d'un webhook de confirmation.
⚠️ Sécurité — à lire avant tout
Ce SDK manipule apiKey et serviceToken, des credentials secrets.
Il ne doit jamais être importé ni instancié dans du code qui s'exécute dans le
navigateur (Angular, React, Vue...). Utilise-le uniquement côté serveur :
Express, NestJS, Fastify, script Node, etc. Ne mets jamais ces valeurs en dur
dans ton code ou ta documentation — passe-les toujours par des variables
d'environnement.
Le frontend doit appeler ton propre backend, qui utilise ce SDK pour parler au prestataire de paiement.
[Frontend] --(HTTP, sans secret)--> [Ton backend Express/NestJS] --(SDK, avec secrets)--> [Welloo]Procédure d'installation
1. Prérequis
- Node.js >= 18
2. Installer le package
npm install welloo-payment-sdk3. Configurer les identifiants
Récupère apiKey et serviceToken auprès de Welloo, puis expose-les en
variables d'environnement (ex: fichier .env, jamais commité) :
API_KEY=...
SERVICE_TOKEN=...
WEBHOOK_SECRET=...4. Instancier le SDK
import { PaymentSDK } from "welloo-payment-sdk";
// Le SDK est instancié UNE FOIS, côté serveur, avec les secrets pris depuis .env
const sdk = new PaymentSDK({
apiKey: process.env.API_KEY,
serviceToken: process.env.SERVICE_TOKEN,
webhookSecret: process.env.WEBHOOK_SECRET,
});PaymentSDK lève une PaymentSDKError si apiKey ou serviceToken est
manquant — instancie-le une seule fois au démarrage de l'application, pas à
chaque requête.
Utilisation du SDK avec initPayment
initPayment crée une session de paiement auprès de Welloo et retourne
checkoutUrl : l'URL vers laquelle rediriger le navigateur du client.
Son comportement dépend du champ optionnel operator :
operatorabsent : retourne la page de paiement hébergée par Welloo, où le client choisit lui-même son opérateur Mobile Money et son numéro.operatorfourni ("welloo"ou"wave") : génère directement un lien de paiement pour cet opérateur (endpointPOST /api/v1/payment-link-sdk), sans passer par l'écran de sélection.
// Sans opérateur -> page de sélection hébergée par Welloo
app.get("/api/v1/init-payment", async (req, res) => {
try {
const payment = await sdk.initPayment({
amount: 5, // montant en unité mineure du prestataire
operator: req.query.operator, // optionnel : "welloo" | "wave"
returnUrl: "https://monsite.com/panier", // lien de retour
metadata: {},
});
res.redirect(payment.checkoutUrl);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Impossible de lancer le paiement" });
}
});Exemple complet :
examples/express-backend/server.js.
Champs de InitPaymentPayload
| Champ | Requis | Description |
| --- | --- | --- |
| amount | oui | Montant en unité mineure (ex: centimes) selon le prestataire |
| returnUrl | oui | Cible du bouton "Retour" sur la page de paiement |
| operator | non | "welloo" ou "wave" — génère un lien direct pour cet opérateur au lieu de la page de sélection |
| description | non | Description du paiement (usage actuellement informatif côté Welloo) |
| metadata | non | Objet libre transmis au prestataire (ignoré si operator est fourni) |
initPayment retourne un InitPaymentResult :
| Champ | Description |
| --- | --- |
| checkoutUrl | URL vers laquelle rediriger (page de sélection ou lien direct selon operator) |
| status | Statut initial de la session (ex: "active", "pending") |
Utilisation du SDK avec initTransfer
initTransfer initie un transfert et retourne l'URL de paiement hébergée
vers laquelle rediriger le client (endpoint POST /api/v1/init).
app.get("/api/v1/init-transfer", async (req, res) => {
try {
const transfer = await sdk.initTransfer({
returnUrl: "https://merchant.example.com/success",
});
res.redirect(transfer.checkoutUrl);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Impossible d'initier le transfert" });
}
});Champs de InitTransferPayload
| Champ | Description |
| --- | --- |
| returnUrl | URL de retour après paiement |
initTransfer retourne un InitTransferResult avec un seul champ :
checkoutUrl (URL vers laquelle rediriger, à rediriger).
initPaymentrejette unamountinférieur à 5 (PaymentSDKError), avant même d'appeler l'API.
Utilisation du SDK avec getTransactions et getPaymentStatus
getTransactions liste les transactions du service authentifié (endpoint
GET /api/v1/payments). getPaymentStatus(reference) vérifie le statut
réel d'une transaction précise (endpoint GET /api/v1/payments/{reference}) —
la reference est le session_reference renvoyé dans chaque transaction.
// Sans ?reference= -> liste complète. Avec ?reference= -> statut d'une transaction.
app.get("/api/v1/transactions", async (req, res) => {
try {
if (req.query.reference) {
const status = await sdk.getPaymentStatus(req.query.reference);
return res.json(status);
}
const transactions = await sdk.getTransactions();
res.json(transactions);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Impossible de récupérer les transactions" });
}
});getTransactions retourne un tableau des transactions brutes renvoyées par
Welloo (montant, devise, statut, opérateur, dates, etc.). getPaymentStatus
retourne un GetPaymentStatusResult :
| Champ | Description |
| --- | --- |
| reference | La référence passée en paramètre |
| status | Statut réel de la transaction (ex: "active", "completed", "expire") |
| raw | Réponse brute complète du prestataire |
Ne te fie jamais uniquement à une URL de retour (returnUrl) pour
valider un paiement : revérifie toujours via getPaymentStatus() ou un
webhook signé.
Utilisation du SDK avec getSolde
getSolde récupère le solde du compte Welloo (endpoint GET /api/v1/solde).
app.get("/api/v1/solde", async (req, res) => {
try {
const solde = await sdk.getSolde();
res.json(solde);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Impossible de récupérer le solde" });
}
});getSolde retourne un GetSoldeResult :
| Champ | Description |
| --- | --- |
| currency | Devise du solde (ex: "XOF") |
| solde | Montant disponible sur le compte |
| raw | Réponse brute complète du prestataire |
Gérer les erreurs
Toutes les méthodes qui appellent l'API rejettent avec une PaymentSDKError
en cas d'échec, avec deux champs utiles pour distinguer une erreur
actionnable par l'appelant (ex: opérateur invalide) d'une vraie panne :
| Champ | Description |
| --- | --- |
| statusCode | Code HTTP renvoyé par Welloo (ex: 400, 401) — absent pour une erreur réseau |
| details | Corps JSON brut de la réponse d'erreur Welloo ({ message, errors }) |
Un pattern courant : exposer le vrai message pour les erreurs 4xx (actionnables), et rester générique pour les 5xx (pour ne pas fuiter de détail interne que l'appelant ne peut de toute façon pas corriger) :
function sendSdkError(res, err, fallbackMessage) {
console.error(err); // détail complet toujours loggé côté serveur
if (err instanceof PaymentSDKError && err.statusCode && err.statusCode < 500) {
const details = err.details && err.details.errors;
const message = (err.details && err.details.message) || err.message;
return res.status(err.statusCode).json({ error: message, details });
}
res.status(500).json({ error: fallbackMessage });
}Exemple complet :
examples/express-backend/server.js.
Vérifier un webhook
⚠️ Important : la route webhook doit utiliser
express.raw()(pasexpress.json()) pour garder le corps brut exact, nécessaire au calcul HMAC — et elle doit être déclarée avant un éventuelapp.use(express.json())global, sinon le corps serait déjà parsé/reformaté avant d'atteindre la vérification de signature, cassant la comparaison.
app.post("/api/v1/webhook", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.header("X-Webhook-Signature");
const isValid = signature && sdk.verifyWebhookSignature(req.body, signature);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}
const event = JSON.parse(req.body.toString());
// event.status === "paid" -> mettre à jour la commande en base
res.sendStatus(200);
});API complète
| Méthode | Description |
| --- | --- |
| initPayment(payload) | Crée une session de paiement et retourne checkoutUrl (page de sélection, ou lien direct si operator est fourni). |
| initTransfer(payload) | Initie un transfert et retourne checkoutUrl. |
| getTransactions() | Liste les transactions du service authentifié. |
| getPaymentStatus(reference) | Vérifie le statut réel d'une transaction précise. |
| getSolde() | Récupère le solde du compte Welloo. |
| verifyWebhookSignature(rawBody, signature) | Vérifie la signature HMAC-SHA256 d'un webhook. |
Build
npm install
npm run build