Wariguai Documentation
API v1 · mobile money · Burkina Faso

Intègre Wariguai
en quelques minutes.

Encaisse Orange Money, Moov Money, Telecel Money, Wave… avec une seule API REST en JSON. Paquet npm pour Node.js, bibliothèques PHP et Python, extension WooCommerce et liens de paiement sans code.

/
Node.js en 2 minutes npx wariguai init Paquet npm, clé vérifiée et exemple prêt à lancer. PHP et Python Un seul fichier à ajouter, aucune dépendance. WordPress (WooCommerce) Extension à installer, sans écrire de code. Sans code : liens de paiement WhatsApp, QR code au comptoir, demande par SMS.

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 :

  1. votre serveur crée un paiement (POST /api/v1/payments) ;
  2. vous redirigez le client vers checkout_url ;
  3. le client choisit son portefeuille et paie depuis son téléphone (code USSD, validation avec son code secret) ;
  4. Wariguai reconnaît le paiement, crédite votre solde et envoie un webhook signé à votre serveur ;
  5. 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.

1. Démarrer avec Wariguai1 min 45 · compte, questionnaire, niveaux, clés d'API
2. Le lien de paiement1 min 12 · encaisser sur WhatsApp, sans code
3. Intégration en Node.js2 min 08 · paiement, vérification, webhook (Express)
3. Intégration en PHP2 min 08 · paiement, vérification, webhook
3. Intégration en Python2 min 08 · paiement, vérification, webhook (Flask)
4. Les webhooks, simplement1 min 19 · signature, bonnes pratiques, renvoi

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.

1
Installer le paquet
npm install wariguai

Aucune dépendance, Node.js 18 ou plus récent. Les types TypeScript sont inclus.

2
Préparer le projet
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.

3
Lancer l'exemple et faire un paiement de test
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

CommandeCe qu'elle fait
npx wariguai initVérifie la clé, l'enregistre dans .env, crée l'exemple.
npx wariguai testCrée un paiement de test et le simule jusqu'à « réussi » (clé sk_test_).
npx wariguai soldeAffiche le solde du compte (test ou réel selon la clé).
npx wariguai lien --titre "Robe wax" --montant 5000Cré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.

  1. Dans WordPress : Extensions → Ajouter → Téléverser une extension, choisissez wariguai-woocommerce.zip, puis Installer et Activer.
  2. Dans WooCommerce → Réglages → Général : devise Franc CFA (XOF).
  3. Dans votre espace Wariguai, ouvrez votre application : copiez la clé secrète (sk_test_… pour essayer, sk_live_… une fois le compte validé).
  4. 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 secret whsec_….
  5. Dans WooCommerce → Réglages → Paiements → Wariguai : activez, collez les clés et le secret du webhook, enregistrez.
  6. 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"
La clé secrète ne doit jamais se trouver dans une appli mobile, dans du JavaScript de navigateur ou dans un dépôt de code. Gardez-la dans une variable d'environnement de votre serveur. Créer une nouvelle clé désactive immédiatement l'ancienne du même mode.

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

  1. Inscription avec votre numéro (code de vérification par SMS) et un mot de passe.
  2. Applications : créez une application par site ou appli ; sa clé de test est donnée tout de suite.
  3. Questionnaire (5 minutes) : type de compte, activité, projet, responsable et photo de la pièce d'identité. L'IFU et le RCCM sont facultatifs.
  4. Validation par l'équipe Wariguai, en général sous 48 h : les clés réelles sk_live_ s'ouvrent.
NiveauConditionsPar paiementPar moisRetraits / jour
Niveau 1Questionnaire et pièce d'identité, sans IFU ni RCCM (particulier, activité informelle)100 000 F1 500 000 F300 000 F
Niveau 2IFU et RCCM vérifiés1 000 000 F50 000 000 F5 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ètreTypeDescription
amountrequisentierMontant payé par le client, en F CFA (100 à 1 000 000).
referencetexte (64)Votre numéro de commande. Renvoyé partout (webhook, redirection).
descriptiontexte (200)Affiché au client sur la page de paiement.
customerobjetname, email, phone (facultatifs).
return_urlURL httpsOù renvoyer le client après le paiement.
cancel_urlURL httpsOù renvoyer le client s'il abandonne (sinon return_url).
metadataobjetVos données (20 clés, 2 000 caractères maximum), renvoyées telles quelles.
channeltextePaiement direct : moyen choisi (ORANGE_MONEY…). Voir Paiement direct.
payer_numbertextePaiement direct : numéro qui paie (8 chiffres).

Un paiement non réglé expire au bout de 30 minutes.

L'objet paiement

ChampDescription
idIdentifiant Wariguai (pay_…).
statuspending (créé), awaiting_payment (le client a choisi son portefeuille), succeeded, failed, expired, cancelled.
amount · fee · netMontant payé, commission Wariguai, montant crédité sur votre solde.
channel · payer_numberPortefeuille et numéro qui ont payé.
transaction_refID de transaction de l'opérateur (une fois payé).
instructionsPendant awaiting_payment : code USSD et numéro marchand à afficher.
checkout_urlPage de paiement hébergée.
paid_at · expires_at · created_atDates (UTC).
Seul 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).

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énementQuand
payment.succeededL'argent est reçu, votre solde est crédité.
payment.failedPaiement refusé.
payment.expiredDélai de paiement dépassé.
payment.cancelledAnnulé par vous ou par le client.
payout.succeededRetrait livré au bénéficiaire.
payout.failedRetrait é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/payouts

Envoie 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ètreDescription
amountrequisMontant reçu par le bénéficiaire.
channelrequisPortefeuille qui reçoit (ORANGE_MONEY, MOOV_MONEY, WAVE…).
numberrequisNuméro du bénéficiaire (8 chiffres).
referenceVotre 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/channels

Les 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).

channelNom
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)" } }
HTTPcodeSignification
400invalid_request, invalid_amount, invalid_url, invalid_channel, invalid_payer_number, payer_operator_mismatchParamètre manquant ou invalide.
401invalid_api_keyClé absente, inconnue ou désactivée.
402insufficient_balanceSolde insuffisant pour le retrait.
403account_not_live, account_suspended, payouts_disabled, payout_limit, level_limit, app_disabled, live_modeAction non autorisée pour ce compte, ce niveau ou ce mode.
404not_foundObjet introuvable (ou appartenant à un autre mode).
409payer_busy, idempotency_conflict, payment_not_payable, payment_not_cancellableConflit avec l'état actuel.
429rate_limitedPlus de 300 requêtes par minute : ralentissez.
5xxserver_errorProblè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 un GET /payments/{id}, jamais sur la seule redirection du client.
  • Comparez amount et reference avec votre commande avant de la valider.
  • Traitez chaque événement une seule fois (les webhooks peuvent arriver en double).
  • Utilisez une Idempotency-Key pour 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

  1. Intégrez et testez tout en mode test (paiement réussi, refusé, expiré, webhook).
  2. Dans votre espace, répondez au questionnaire (Ouvrir les paiements réels) et ajoutez la photo de votre pièce d'identité.
  3. L'équipe Wariguai vérifie votre compte (en général sous 48 h) et le valide au niveau 1 ou 2.
  4. Dans Applications & clés API, créez la clé sk_live_ de votre application et remplacez la clé de test sur votre serveur.
Une question ? Écrivez-nous depuis votre espace. Nous répondons en français, depuis Ouagadougou.