Comment ça marche
Encaissez Orange Money, Moov Money, Telecel Money, Wave et les autres portefeuilles du Burkina Faso depuis votre site ou votre application, avec une seule API REST en JSON.
Le parcours le plus simple :
- votre serveur crée un paiement (
POST /api/v1/payments) ; - vous redirigez le client vers
checkout_url; - le client choisit son portefeuille et paie depuis son téléphone (code USSD, validation avec son code secret) ;
- Wariguai reconnaît le paiement, crédite votre solde et envoie un webhook signé à votre serveur ;
- le client revient sur votre
return_url.
Adresse de base de l'API : https://wariguai.mikpilot.com/api/v1. Montants en francs CFA (XOF), nombres entiers. Dates au format ISO 8601 (UTC).
Vidéos tutoriels
Tout comprendre en quelques minutes, du compte jusqu'au webhook. Choisissez la vidéo de votre langage pour l'intégration.
Node.js : npm et npx
Le paquet officiel wariguai s'installe avec npm. Une seule commande vérifie ta clé et prépare tout le projet.
npm install wariguai
Aucune dépendance, Node.js 18 ou plus récent. Les types TypeScript sont inclus.
npx wariguai init
La commande demande ta clé secrète (sk_test_…), vérifie qu'elle marche, l'enregistre dans .env (ajouté à .gitignore) et crée wariguai-exemple.js : une petite boutique Express avec le paiement, la page de retour et le webhook.
npm install express node wariguai-exemple.js npx wariguai test
Ouvre http://localhost:3000 : le bouton « Payer » t'envoie sur la vraie page de paiement Wariguai, en mode test.
Dans ton code
const Wariguai = require('wariguai');
const wariguai = new Wariguai(process.env.WARIGUAI_SECRET_KEY);
const paiement = await wariguai.payments.create({ amount: 5000, reference: 'CMD-1001', return_url: 'https://maboutique.bf/merci' });
res.redirect(paiement.checkout_url);
import Wariguai from 'wariguai';
const wariguai = new Wariguai(process.env.WARIGUAI_SECRET_KEY);
const lien = await wariguai.links.create({ title: 'Robe wax', amount: 5000 });
console.log(lien.url, lien.qr_url);
import Wariguai, { type Payment, WariguaiError } from 'wariguai';
const wariguai = new Wariguai(process.env.WARIGUAI_SECRET_KEY!);
try {
const paiement: Payment = await wariguai.payments.create({ amount: 5000 });
} catch (e) {
if (e instanceof WariguaiError) console.error(e.code, e.message);
}
La commande wariguai
| Commande | Ce qu'elle fait |
|---|---|
npx wariguai init | Vérifie la clé, l'enregistre dans .env, crée l'exemple. |
npx wariguai test | Crée un paiement de test et le simule jusqu'à « réussi » (clé sk_test_). |
npx wariguai solde | Affiche le solde du compte (test ou réel selon la clé). |
npx wariguai lien --titre "Robe wax" --montant 5000 | Crée un lien de paiement (sans montant : le client tape le montant). |
La clé est lue dans --cle, la variable WARIGUAI_SECRET_KEY ou le fichier .env. Toutes les fonctions : payments (create, retrieve, list, cancel, isPaid, simulate), links (create, retrieve, list, disable, enable), payouts, balance, channels, webhooks.verify. Tu préfères un seul fichier sans npm ? wariguai.cjs contient la même bibliothèque.
Bibliothèques officielles
Node.js : le paquet npm (voir Node.js : npm et npx). PHP et Python : un seul fichier à ajouter à votre projet, sans aucune dépendance. Chaque bibliothèque crée les paiements, vérifie qu'ils sont payés et contrôle la signature des webhooks à votre place.
1. Créer le paiement et envoyer le client vers la page de paiement
const Wariguai = require('wariguai'); // installé avec npm (voir « Node.js : npm et npx »)
const wariguai = new Wariguai(process.env.WARIGUAI_SECRET_KEY);
app.post('/payer', async (req, res) => {
const paiement = await wariguai.payments.create({
amount: 5000,
reference: 'CMD-1001',
return_url: 'https://maboutique.bf/merci?commande=CMD-1001',
});
res.redirect(paiement.checkout_url);
});
<?php
require __DIR__ . '/Wariguai.php';
$wariguai = new Wariguai\Client(getenv('WARIGUAI_SECRET_KEY'));
$paiement = $wariguai->createPayment([
'amount' => 5000,
'reference' => 'CMD-1001',
'return_url' => 'https://maboutique.bf/merci.php?commande=CMD-1001',
]);
header('Location: ' . $paiement['checkout_url']);
import os, wariguai
client = wariguai.Client(os.environ['WARIGUAI_SECRET_KEY'])
paiement = client.create_payment(
amount=5000,
reference='CMD-1001',
return_url='https://maboutique.bf/merci?commande=CMD-1001',
)
return redirect(paiement['checkout_url']) # Flask / Django
2. Au retour du client : vérifier que c'est payé
if (await wariguai.payments.isPaid(paymentId)) {
// livrer la commande
}
if ($wariguai->isPaid($paymentId)) {
// livrer la commande
}
if client.is_paid(payment_id):
pass # livrer la commande
Gardez l'identifiant paiement.id avec votre commande au moment de la création.
3. Le webhook en 3 lignes (recommandé)
app.post('/webhooks/wariguai', express.raw({ type: 'application/json' }), (req, res) => {
const evenement = wariguai.webhooks.verify(req.body, req.get('Wariguai-Signature'), process.env.WARIGUAI_WEBHOOK_SECRET);
if (evenement.type === 'payment.succeeded') {
// marquer la commande evenement.data.reference comme payée
}
res.sendStatus(200);
});
<?php
require __DIR__ . '/Wariguai.php';
$evenement = Wariguai\Webhook::verify(file_get_contents('php://input'), $_SERVER['HTTP_WARIGUAI_SIGNATURE'] ?? '', getenv('WARIGUAI_WEBHOOK_SECRET'));
if ($evenement['type'] === 'payment.succeeded') {
// marquer la commande $evenement['data']['reference'] comme payée
}
http_response_code(200);
@app.post('/webhooks/wariguai')
def webhook():
evenement = wariguai.verify_webhook(request.get_data(), request.headers.get('Wariguai-Signature', ''), os.environ['WARIGUAI_WEBHOOK_SECRET'])
if evenement['type'] == 'payment.succeeded':
pass # marquer la commande evenement['data']['reference'] comme payée
return '', 200
Une signature fausse ou trop ancienne déclenche une erreur (invalid_signature) : répondez alors 400. Pas encore de webhook ? Le contrôle de l'étape 2 suffit pour démarrer.
Toutes les fonctions : Node.js payments.create / retrieve / list / cancel / isPaid / simulate, payouts.create, balance.retrieve · PHP createPayment, getPayment, listPayments, cancelPayment, isPaid, simulatePayment, createPayout, getBalance · Python create_payment, get_payment, list_payments, cancel_payment, is_paid, simulate_payment, create_payout, get_balance. Les erreurs sont des WariguaiError (PHP : WariguaiException) avec status et code.
WooCommerce (WordPress)
Votre boutique tourne sur WordPress avec WooCommerce ? Installez l'extension Wariguai : aucun code à écrire. Le client choisit « Mobile money » à la commande, paie sur la page Wariguai, et la commande passe toute seule « En cours » dès que l'argent est reçu.
- Dans WordPress : Extensions → Ajouter → Téléverser une extension, choisissez
wariguai-woocommerce.zip, puis Installer et Activer. - Dans WooCommerce → Réglages → Général : devise Franc CFA (XOF).
- Dans votre espace Wariguai, ouvrez votre application : copiez la clé secrète (
sk_test_…pour essayer,sk_live_…une fois le compte validé). - Toujours dans l'application, mettez l'adresse du webhook
https://votre-boutique.bf/?wc-api=wariguai(l'adresse exacte est affichée dans les réglages de l'extension) et copiez le secretwhsec_…. - Dans WooCommerce → Réglages → Paiements → Wariguai : activez, collez les clés et le secret du webhook, enregistrez.
- Essayez en mode test : passez une commande puis touchez « Simuler un paiement réussi » sur la page de paiement. Décochez ensuite le mode test.
L'extension fonctionne avec la page de commande classique et la page de commande en blocs (WooCommerce 8.3 et plus), et avec le stockage des commandes HPOS. Sécurité : le webhook est vérifié par sa signature, et la commande n'est validée que si la commande, le mode et le montant correspondent. Si le webhook n'est pas configuré, la commande est vérifiée quand le client revient sur la page « Merci ».
Authentification
Chaque appel porte votre clé secrète dans l'en-tête Authorization. Chaque application (un site, une appli) a ses propres clés : créez-les dans votre espace › Applications & clés API.
| Clé | Usage |
|---|---|
sk_test_… | Mode test : paiements simulés, aucun argent réel. Disponible dès l'inscription. |
sk_live_… | Mode réel : disponible quand l'équipe Wariguai a activé votre compte. |
curl https://wariguai.mikpilot.com/api/v1/balance \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
Démarrage rapide
Créez un paiement de 5 000 F et redirigez votre client :
curl https://wariguai.mikpilot.com/api/v1/payments \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: commande-1001" \
-d '{
"amount": 5000,
"reference": "CMD-1001",
"description": "Pagne Faso Dan Fani",
"customer": { "name": "Awa Ouédraogo", "phone": "70123456" },
"return_url": "https://maboutique.bf/paiement/retour",
"cancel_url": "https://maboutique.bf/panier",
"metadata": { "panier_id": 42 }
}'
// Node 18+ (fetch intégré)
const res = await fetch('https://wariguai.mikpilot.com/api/v1/payments', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.WARIGUAI_SECRET_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': 'commande-1001',
},
body: JSON.stringify({
amount: 5000,
reference: 'CMD-1001',
description: 'Pagne Faso Dan Fani',
return_url: 'https://maboutique.bf/paiement/retour',
cancel_url: 'https://maboutique.bf/panier',
metadata: { panier_id: 42 },
}),
});
const payment = await res.json();
if (!res.ok) throw new Error(payment.error.message);
// Express : res.redirect(payment.checkout_url)
<?php
$ch = curl_init('https://wariguai.mikpilot.com/api/v1/payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WARIGUAI_SECRET_KEY'),
'Content-Type: application/json',
'Idempotency-Key: commande-1001',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 5000,
'reference' => 'CMD-1001',
'description' => 'Pagne Faso Dan Fani',
'return_url' => 'https://maboutique.bf/paiement/retour',
'cancel_url' => 'https://maboutique.bf/panier',
]),
]);
$payment = json_decode(curl_exec($ch), true);
header('Location: ' . $payment['checkout_url']);
exit;
import os
import requests
res = requests.post(
'https://wariguai.mikpilot.com/api/v1/payments',
headers={
'Authorization': 'Bearer ' + os.environ['WARIGUAI_SECRET_KEY'],
'Idempotency-Key': 'commande-1001',
},
json={
'amount': 5000,
'reference': 'CMD-1001',
'description': 'Pagne Faso Dan Fani',
'return_url': 'https://maboutique.bf/paiement/retour',
'cancel_url': 'https://maboutique.bf/panier',
},
timeout=15,
)
res.raise_for_status()
payment = res.json()
# Django : return redirect(payment['checkout_url'])
Réponse (201 Created) :
{
"id": "pay_8fK2mQx7LpR4vNs1TbYc",
"object": "payment",
"mode": "test",
"status": "pending",
"amount": 5000,
"fee": 50,
"net": 4950,
"currency": "XOF",
"reference": "CMD-1001",
"checkout_url": "https://wariguai.mikpilot.com/checkout/Xa81…",
"expires_at": "2026-10-02T10:30:00.000Z",
…
}
Mode test
Avec une clé sk_test_, tout fonctionne comme en réel (page de paiement, webhooks, solde, retraits) sauf que l'argent est fictif. Pour conclure un paiement de test :
- sur la page de paiement, utilisez les boutons « Simuler un paiement réussi » ou « Simuler un refus » ;
- ou depuis votre code : POST/api/v1/payments/{id}/simulate avec
{"outcome": "succeeded"}ou{"outcome": "failed"}.
Les retraits de test réussissent immédiatement et sont débités de votre solde de test.
Compte, niveaux et plafonds
- Inscription avec votre numéro (code de vérification par SMS) et un mot de passe.
- Applications : créez une application par site ou appli ; sa clé de test est donnée tout de suite.
- Questionnaire (5 minutes) : type de compte, activité, projet, responsable et photo de la pièce d'identité. L'IFU et le RCCM sont facultatifs.
- Validation par l'équipe Wariguai, en général sous 48 h : les clés réelles
sk_live_s'ouvrent.
| Niveau | Conditions | Par paiement | Par mois | Retraits / jour |
|---|---|---|---|---|
| Niveau 1 | Questionnaire et pièce d'identité, sans IFU ni RCCM (particulier, activité informelle) | 100 000 F | 1 500 000 F | 300 000 F |
| Niveau 2 | IFU et RCCM vérifiés | 1 000 000 F | 50 000 000 F | 5 000 000 F |
Au-delà d'un plafond, l'API répond 403 level_limit. Ajoutez votre IFU et votre RCCM depuis votre espace › Vérification du compte pour passer au niveau 2.
Créer un paiement
POST/api/v1/payments| Paramètre | Type | Description |
|---|---|---|
amountrequis | entier | Montant payé par le client, en F CFA (100 à 1 000 000). |
reference | texte (64) | Votre numéro de commande. Renvoyé partout (webhook, redirection). |
description | texte (200) | Affiché au client sur la page de paiement. |
customer | objet | name, email, phone (facultatifs). |
return_url | URL https | Où renvoyer le client après le paiement. |
cancel_url | URL https | Où renvoyer le client s'il abandonne (sinon return_url). |
metadata | objet | Vos données (20 clés, 2 000 caractères maximum), renvoyées telles quelles. |
channel | texte | Paiement direct : moyen choisi (ORANGE_MONEY…). Voir Paiement direct. |
payer_number | texte | Paiement direct : numéro qui paie (8 chiffres). |
Un paiement non réglé expire au bout de 30 minutes.
L'objet paiement
| Champ | Description |
|---|---|
id | Identifiant Wariguai (pay_…). |
status | pending (créé), awaiting_payment (le client a choisi son portefeuille), succeeded, failed, expired, cancelled. |
amount · fee · net | Montant payé, commission Wariguai, montant crédité sur votre solde. |
channel · payer_number | Portefeuille et numéro qui ont payé. |
transaction_ref | ID de transaction de l'opérateur (une fois payé). |
instructions | Pendant awaiting_payment : code USSD et numéro marchand à afficher. |
checkout_url | Page de paiement hébergée. |
paid_at · expires_at · created_at | Dates (UTC). |
succeeded signifie que l'argent est arrivé. Livrez la commande sur réception du webhook payment.succeeded (ou après avoir vérifié le statut par l'API), jamais sur le simple retour du client sur votre site.Page de paiement
La page checkout_url affiche votre nom commercial, le montant et la description. Le client y choisit son portefeuille, saisit son numéro, puis reçoit le code USSD à composer. Elle se met à jour toute seule dès que le paiement est reconnu.
À la fin, le client est renvoyé vers votre adresse avec ces paramètres :
https://maboutique.bf/paiement/retour?payment_id=pay_8fK2…&reference=CMD-1001&status=succeeded
Si le paiement n'a pas été reconnu automatiquement (payé depuis un autre numéro…), le client peut saisir l'ID de transaction reçu par SMS de son opérateur.
Paiement direct (votre propre interface)
Vous préférez garder le client dans votre appli ? Passez channel et payer_number à la création : le paiement passe directement en awaiting_payment et instructions contient ce qu'il faut afficher.
"instructions": {
"channel": "ORANGE_MONEY",
"channelName": "Orange Money",
"merchantNumber": "7XXXXXXX",
"amount": 5000,
"payerNumber": "76112233",
"ussd": "*144*2*1*7XXXXXXX*5000#",
"text": "Compose *144*2*1*7XXXXXXX*5000# puis valide avec ton code secret Orange Money."
}
Le paiement est reconnu grâce au trio portefeuille + numéro qui paie + montant. Un même numéro ne peut donc pas avoir deux paiements du même montant en attente sur le même portefeuille : l'API répond alors 409 payer_busy.
Consulter, lister, annuler
GET/api/v1/payments/{id}
GET/api/v1/payments?status=succeeded&limit=20&starting_after=pay_…
Liste paginée, du plus récent au plus ancien : {"object":"list","data":[…],"has_more":true}. Pour la page suivante, passez l'id du dernier élément dans starting_after. Filtre reference disponible.
POST/api/v1/payments/{id}/cancel
Annule un paiement pas encore réglé (statut pending ou awaiting_payment).
Liens de paiement
Un lien de paiement est une adresse durable https://wariguai.mikpilot.com/p/CODE à partager sur WhatsApp, Facebook ou par SMS, ou à imprimer en QR code pour votre comptoir. Le client l'ouvre, confirme (et tape le montant si le lien est à montant libre), puis paie sur la page de paiement habituelle. Chaque paiement est un paiement normal : même commission, même solde, mêmes webhooks, avec link_id rempli.
Pas besoin de code : vous pouvez tout faire depuis votre espace, page Liens de paiement. L'API sert à les créer depuis votre logiciel.
POST/api/v1/links| Paramètre | Type | Description |
|---|---|---|
titlerequis | texte (80) | Nom affiché au client : « Robe wax », « Caisse de la boutique »… |
kind | texte | fixed (montant fixé, par défaut si amount est donné) ou open (le client tape le montant). |
amount | entier | Montant en F CFA, requis pour fixed. |
description | texte (200) | Détail affiché sous le nom. |
reference | texte (64) | Votre référence, reprise sur chaque paiement (sinon le code du lien). |
single_use | booléen | Un seul paiement possible (demande de paiement). Le lien passe ensuite à paid. |
customer_phone | texte | Numéro du client (8 chiffres), pour une demande de paiement. |
send_sms | booléen | Envoie au client un SMS avec le montant et le lien (en réel seulement, nombre limité par jour). |
expires_in_days | entier | Durée de validité (1 à 365 jours). Par défaut : sans fin, ou 7 jours pour un lien à usage unique. |
{
"id": "lnk_Hk3T9vQw2LmZpA",
"object": "payment_link",
"mode": "live",
"code": "A2V8BV6S",
"url": "https://wariguai.mikpilot.com/p/A2V8BV6S",
"qr_url": "https://wariguai.mikpilot.com/p/A2V8BV6S/qr.svg",
"poster_url": "https://wariguai.mikpilot.com/p/A2V8BV6S/affiche",
"kind": "fixed",
"title": "Robe wax",
"amount": 5000,
"single_use": false,
"status": "active",
"payments_count": 3,
"total_received": 15000
}
GET/api/v1/links · GET/api/v1/links/{id}
POST/api/v1/links/{id}/disable · POST/api/v1/links/{id}/enable
Statuts : active, disabled, paid (lien à usage unique réglé), expired. qr_url donne le QR code (SVG) et poster_url une affiche prête à imprimer.
Webhooks
Indiquez l'adresse de votre webhook (https) dans votre espace › Applications › Webhook (un webhook par application). Wariguai y envoie un POST JSON à chaque événement :
| Événement | Quand |
|---|---|
payment.succeeded | L'argent est reçu, votre solde est crédité. |
payment.failed | Paiement refusé. |
payment.expired | Délai de paiement dépassé. |
payment.cancelled | Annulé par vous ou par le client. |
payout.succeeded | Retrait livré au bénéficiaire. |
payout.failed | Retrait échoué, montant recrédité sur votre solde. |
{
"id": "evt_Qm3s9…",
"type": "payment.succeeded",
"mode": "live",
"created": 1790000000,
"data": { "id": "pay_8fK2…", "object": "payment", "status": "succeeded", "amount": 5000, … }
}
Répondez par un code 2xx en moins de 10 secondes. Sinon, Wariguai réessaie après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h. Un même événement peut arriver deux fois : utilisez data.id pour ne traiter chaque paiement qu'une seule fois. Vous pouvez relancer un envoi depuis votre espace.
Vérifier la signature
Chaque webhook porte l'en-tête Wariguai-Signature: t=1790000000,v1=5257a8…. v1 est le HMAC-SHA256, avec votre secret whsec_…, de la chaîne t + "." + corps brut. Refusez les signatures fausses et les horodatages de plus de 5 minutes.
import crypto from 'node:crypto';
import express from 'express';
const app = express();
// Corps BRUT : la signature porte sur les octets reçus.
app.post('/webhooks/wariguai', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.get('Wariguai-Signature') ?? '';
const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')));
const expected = crypto
.createHmac('sha256', process.env.WARIGUAI_WEBHOOK_SECRET)
.update(`${parts.t}.${req.body}`)
.digest('hex');
const valid = parts.v1 && expected.length === parts.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
if (!valid || Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return res.sendStatus(400);
const event = JSON.parse(req.body);
if (event.type === 'payment.succeeded') {
// marquer la commande event.data.reference comme payée (une seule fois)
}
res.sendStatus(200);
});
<?php
$payload = file_get_contents('php://input');
$header = $_SERVER['HTTP_WARIGUAI_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $parts);
$expected = hash_hmac('sha256', $parts['t'] . '.' . $payload, getenv('WARIGUAI_WEBHOOK_SECRET'));
if (!hash_equals($expected, $parts['v1'] ?? '') || abs(time() - (int) $parts['t']) > 300) {
http_response_code(400);
exit;
}
$event = json_decode($payload, true);
if ($event['type'] === 'payment.succeeded') {
// marquer la commande $event['data']['reference'] comme payée (une seule fois)
}
http_response_code(200);
import hashlib, hmac, json, os, time
from flask import Flask, request, abort
app = Flask(__name__)
@app.post('/webhooks/wariguai')
def wariguai_webhook():
payload = request.get_data()
parts = dict(kv.split('=', 1) for kv in request.headers.get('Wariguai-Signature', '').split(',') if '=' in kv)
expected = hmac.new(os.environ['WARIGUAI_WEBHOOK_SECRET'].encode(),
parts.get('t', '').encode() + b'.' + payload, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, parts.get('v1', '')) or abs(time.time() - int(parts.get('t', 0))) > 300:
abort(400)
event = json.loads(payload)
if event['type'] == 'payment.succeeded':
pass # marquer la commande event['data']['reference'] comme payée (une seule fois)
return '', 200
Solde
GET/api/v1/balance{ "object": "balance", "mode": "live", "available": 124500, "currency": "XOF" }
Chaque paiement réussi crédite le montant net (montant − commission). Les retraits débitent le montant envoyé plus leur commission. Le détail des mouvements est dans votre espace (Retraits › Mouvements du solde). Le solde est commun à toutes vos applications.
Retraits
POST/api/v1/payoutsEnvoie de l'argent de votre solde vers un portefeuille mobile money (remboursement d'un client, paiement d'un fournisseur, virement vers vous-même).
| Paramètre | Description |
|---|---|
amountrequis | Montant reçu par le bénéficiaire. |
channelrequis | Portefeuille qui reçoit (ORANGE_MONEY, MOOV_MONEY, WAVE…). |
numberrequis | Numéro du bénéficiaire (8 chiffres). |
reference | Votre référence. |
curl https://wariguai.mikpilot.com/api/v1/payouts \
-H "Authorization: Bearer sk_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: remboursement-1001" \
-d '{ "amount": 5000, "channel": "ORANGE_MONEY", "number": "76112233", "reference": "REMB-1001" }'
Statuts : processing → succeeded ou failed (montant recrédité). En réel, les retraits doivent être autorisés par l'équipe Wariguai pour votre compte et sont plafonnés par jour. GET/api/v1/payouts/{id} GET/api/v1/payouts
Moyens de paiement
GET/api/v1/channelsLes portefeuilles actuellement acceptés. Dans votre espace développeur (Paramètres → « Opérateurs de ta page de paiement »), vous pouvez choisir ceux que vos clients voient : GET /api/v1/channels renvoie alors seulement votre choix, et un autre channel est refusé (invalid_channel).
| channel | Nom |
|---|---|
| Chargement… | |
Idempotence
Ajoutez l'en-tête Idempotency-Key (100 caractères maximum, par exemple votre numéro de commande) aux créations de paiements et de retraits. Si la requête est rejouée (coupure réseau, nouvel essai), Wariguai renvoie l'objet déjà créé avec le code 200 au lieu d'en créer un second.
Erreurs
Les erreurs ont toujours la même forme :
{ "error": { "code": "invalid_amount", "message": "amount : nombre entier entre 100 et 1000000 (F CFA)" } }
| HTTP | code | Signification |
|---|---|---|
| 400 | invalid_request, invalid_amount, invalid_url, invalid_channel, invalid_payer_number, payer_operator_mismatch | Paramètre manquant ou invalide. |
| 401 | invalid_api_key | Clé absente, inconnue ou désactivée. |
| 402 | insufficient_balance | Solde insuffisant pour le retrait. |
| 403 | account_not_live, account_suspended, payouts_disabled, payout_limit, level_limit, app_disabled, live_mode | Action non autorisée pour ce compte, ce niveau ou ce mode. |
| 404 | not_found | Objet introuvable (ou appartenant à un autre mode). |
| 409 | payer_busy, idempotency_conflict, payment_not_payable, payment_not_cancellable | Conflit avec l'état actuel. |
| 429 | rate_limited | Plus de 300 requêtes par minute : ralentissez. |
| 5xx | server_error | Problème chez Wariguai : réessayez avec la même Idempotency-Key. |
Bonnes pratiques
- Clé secrète et secret de webhook uniquement côté serveur, dans des variables d'environnement.
- Livrez sur
payment.succeeded(signature vérifiée) ou après unGET /payments/{id}, jamais sur la seule redirection du client. - Comparez
amountetreferenceavec votre commande avant de la valider. - Traitez chaque événement une seule fois (les webhooks peuvent arriver en double).
- Utilisez une
Idempotency-Keypour chaque création. - Si une clé a fuité, créez-en une nouvelle tout de suite : l'ancienne cesse de marcher.
Passer en réel
- Intégrez et testez tout en mode test (paiement réussi, refusé, expiré, webhook).
- Dans votre espace, répondez au questionnaire (Ouvrir les paiements réels) et ajoutez la photo de votre pièce d'identité.
- L'équipe Wariguai vérifie votre compte (en général sous 48 h) et le valide au niveau 1 ou 2.
- Dans Applications & clés API, créez la clé
sk_live_de votre application et remplacez la clé de test sur votre serveur.