Introduction
Présentation de la plateforme et de ses capacités
L'API UnitechPay permet d'intégrer les paiements Wave et Orange Money dans vos applications web, mobiles ou e-commerce. Elle gère l'encaissement, les retraits automatiques, les commissions et les webhooks pour une expérience marchande complète.
URL de base
https://api.unitech.sn/api.php
Fonctionnalités
sold_wave) et Orange (sold_om)Authentification
Toutes les requêtes nécessitent une clé API valide
Incluez votre clé API dans le header Authorization de chaque requête.
Authorization: Bearer VOTRE_CLE_API
Obtenir une clé API
Créez un compte marchand sur la plateforme, puis générez votre clé depuis le tableau de bord dans la section Paramètres → API.
Important : Ne partagez jamais votre clé API publiquement. Elle donne accès à vos fonds et données de transactions.
Endpoints
Liste complète des endpoints disponibles
| Méthode | Endpoint | Description |
|---|---|---|
| POST | /api.php?action=create_wave_payment | Créer un paiement Wave |
| POST | /api.php?action=create_orange_qr | Générer un QR Code Orange Money |
| POST | /api.php?action=create_orange_maxit | Paiement Max It Orange |
| POST | /api.php?action=create_orange_om | Paiement Orange Money standard |
| POST | /api.php?action=withdraw_funds | Retrait automatique MàJ |
| POST | /api.php?action=configure_webhook | Configurer les webhooks |
| GET | /api.php?action=balance | Consulter les soldes Wave / Orange MàJ |
| GET | /api.php?action=transactions | Lister les transactions |
| GET | /api.php?action=withdrawals | Lister les retraits |
| GET | /api.php?action=commissions | Lister les commissions |
Solde marchand MàJ v1.1
Les fonds sont répartis sur deux soldes distincts
Depuis la v1.1, les fonds encaissés sont crédités sur deux soldes distincts selon le moyen
de paiement utilisé par le client : sold_wave pour les paiements Wave et
sold_om pour les paiements Orange Money.
Fonds issus des paiements Wave. Retirable uniquement via method=wave.
Fonds issus des paiements Orange Money. Retirable via method=orange.
/api.php?action=balance
Réponse
{
"success": true,
"data": {
"sold_wave": 45000,
"sold_om": 12500,
"total": 57500,
"currency": "XOF"
}
}
Paiements Wave
Créer une session de paiement Wave
/api.php?action=create_wave_payment
Paramètres
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
amount | number | ✅ Oui | Montant en XOF |
customer_number | string | ✅ Oui | Numéro de téléphone du client |
description | string | Non | Description du paiement |
callback_success | string | Non | URL de redirection après succès |
callback_cancel | string | Non | URL de redirection après annulation |
Exemple de requête
{
"amount": 5000,
"customer_number": "771234567",
"description": "Commande #123",
"callback_success": "https://monsite.com/payment/success",
"callback_cancel": "https://monsite.com/payment/cancel"
}
Réponse
{
"success": true,
"data": {
"transaction_id": 1,
"reference": "wave_66a1b2c3d4e5f_1716542100",
"payment_url": "https://pay.wave.com/c/cos-1xxxxx",
"amount": 5000,
"status": "pending",
"callback_urls": {
"success": "https://monsite.com/payment/success",
"error": "https://monsite.com/payment/cancel"
}
}
}
Après paiement réussi, le montant net (après commission) est automatiquement crédité sur
sold_wave du marchand. La confirmation arrive via webhook.
Paiements Orange Money
Trois modes de paiement disponibles
QR Code
Image base64 à afficher, liens deep MAXIT et OM inclus.
create_orange_qr
Max It
Redirection vers l'app Max It avec lien deep link.
create_orange_maxit
Orange Money
Paiement OM standard avec redirection.
create_orange_om
1. QR Code Orange Money
/api.php?action=create_orange_qrParamètres
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
amount | number | ✅ Oui | Montant en XOF |
reference | string | Non | Référence personnalisée |
description | string | Non | Description |
callback_success | string | Non | URL succès |
callback_cancel | string | Non | URL annulation |
Réponse
{
"success": true,
"data": {
"transaction_id": 1,
"reference": "commande_123",
"qr_code": "data:image/png;base64,iVBORw0KGgo...",
"deep_links": {
"MAXIT": "https://sugu.orange-sonatel.com/np/dgjuu_xxx",
"OM": "https://orangenonevsn.page.link/zzz"
},
"amount": 5000,
"status": "pending",
"type": "qr_code",
"validity": 300,
"callback_urls": {
"success": "https://monsite.com/success",
"cancel": "https://monsite.com/cancel"
}
}
}
2. Paiement Max It
/api.php?action=create_orange_maxitParamètres
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
amount | number | ✅ Oui | Montant en XOF |
customer_number | string | ✅ Oui | Numéro du client |
description | string | Non | Description |
callback_success | string | Non | URL succès |
callback_cancel | string | Non | URL annulation |
Réponse
{
"success": true,
"data": {
"transaction_id": 2,
"reference": "orange_maxit_123456",
"payment_url": "https://sugu.orange-sonatel.com/np/dgjuu_xxx",
"deep_links": {
"MAXIT": "https://sugu.orange-sonatel.com/np/dgjuu_xxx",
"OM": "https://orangenonevsn.page.link/zzz"
},
"amount": 5000,
"status": "pending",
"type": "maxit"
}
}
3. Orange Money standard
/api.php?action=create_orange_omMêmes paramètres que Max It. La payment_url retournée est le deep link OM.
{
"success": true,
"data": {
"transaction_id": 3,
"reference": "orange_om_123456",
"payment_url": "https://orangenonevsn.page.link/zzz",
"amount": 5000,
"status": "pending",
"type": "orange_money"
}
}
Après paiement Orange Money réussi, le montant net est crédité sur sold_om du marchand.
Retraits automatiques MàJ v1.1
Transfert des fonds vers Wave, Orange Money ou compte bancaire
Les retraits Wave et Orange Money sont traités automatiquement en temps réel. Chaque méthode débite le solde correspondant. En cas d'échec du payout, les fonds sont automatiquement restitués au marchand.
method=wave
Débite sold_wave. Payout automatique instantané via l'API Wave Payout.
method=orange
Débite sold_om. Cash-in automatique instantané via l'API Orange eWallet.
method=bank
Débite sold_wave + sold_om au prorata. Traitement manuel 3-5 jours.
/api.php?action=withdraw_funds
Paramètres
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
amount | number | ✅ Oui | Montant à retirer en XOF. Doit être ≤ au solde disponible de la méthode choisie. |
method | string | ✅ Oui |
wave → débite sold_waveorange → débite sold_ombank → débite les deux au prorata
|
account | string | ✅ Oui | Numéro Wave / Orange destinataire, ou numéro de compte bancaire. |
Exemple — retrait Wave
{
"amount": 10000,
"method": "wave",
"account": "771234567"
}
Réponse — succès (Wave / Orange)
{
"success": true,
"data": {
"withdrawal_id": 42,
"reference": "WDR_7_1716542100_3829",
"amount": 10000,
"commission": 150,
"commission_rate": 0.015,
"net_amount": 9850,
"method": "wave",
"status": "processed",
"note": "Payout automatique effectue"
}
}
Réponse — virement bancaire
{
"success": true,
"data": {
"withdrawal_id": 43,
"reference": "WDR_7_1716542200_4912",
"amount": 25000,
"commission": 375,
"commission_rate": 0.015,
"net_amount": 24625,
"method": "bank",
"status": "pending",
"note": "Virement bancaire : traitement sous 3-5 jours ouvres"
}
}
Réponse — payout échoué (fonds restitués)
{
"success": false,
"message": "Payout echoue, fonds restitues. Ref : WDR_7_1716542100_3829. Detail : Configuration Wave invalide"
}
Délais de traitement
• Wave & Orange Money : payout automatique instantané
• Virement bancaire : 3 à 5 jours ouvrés (traitement manuel)
Webhooks
Notifications en temps réel sur les événements de votre compte
Configurer un webhook
/api.php?action=configure_webhookParamètres
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
webhook_url | string | ✅ Oui | URL HTTPS de votre endpoint webhook |
events | array | Non | Événements à écouter (tous par défaut) |
Événements disponibles
payment_completed — Paiement réussipayment_failed — Paiement échouépayment_expired — Paiement expiréwithdrawal_processed — Retrait traitéwithdrawal_failed — Retrait échouéExemple de payload webhook
{
"event": "payment_completed",
"transaction_id": 18,
"reference": "wave_66a1b2_1716540000",
"amount": 5000,
"status": "completed",
"method": "wave",
"commission": 75,
"net_amount": 4925,
"timestamp": 1716540300,
"signature": "hmac_sha256_de_la_payload"
}
Vérification de signature (PHP)
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_UNITECHPAY_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, VOTRE_CLE_API);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Signature invalide');
}
$data = json_decode($payload, true);
// Traiter l'événement...
Sécurité : Vérifiez toujours la signature HMAC-SHA256 avant de traiter un webhook. Votre clé API est utilisée comme secret de signature.
Plugins & Intégrations
Solutions prêtes à l'emploi pour vos projets
Plugin WordPress Officiel
Intégrez Wave et Orange Money dans votre site WordPress ou boutique WooCommerce en quelques minutes.
Guide d'installation WordPress
Installation
Depuis votre admin WordPress : Extensions → Ajouter → Rechercher "UnitechPay" → Installer & Activer.
Configuration
Allez dans UnitechPay Settings et renseignez vos numéros Wave et Orange Money.
WooCommerce
Activez UnitechPay comme méthode de paiement dans WooCommerce → Réglages → Paiements.
Codes d'erreur
Réponses HTTP retournées par l'API
| Code HTTP | Message | Description |
|---|---|---|
| 200 | Success | Requête traitée avec succès |
| 400 | Bad Request | Paramètres manquants, invalides ou solde insuffisant |
| 401 | Unauthorized | Clé API manquante ou invalide |
| 404 | Not Found | Action inconnue ou ressource introuvable |
| 500 | Internal Server Error | Erreur serveur ou échec payout (fonds restitués) |
Format des erreurs
{
"success": false,
"message": "Description de l'erreur",
"code": 400
}
Exemples d'intégration
Code prêt à l'emploi dans différents langages
PHP — Paiement Wave + Consultation des soldes
<?php
$api_url = 'https://api.unitech.sn/api.php';
$api_key = 'VOTRE_CLE_API';
function unitechRequest($action, $data = [], $method = 'POST') {
global $api_url, $api_key;
$url = $api_url . '?action=' . $action;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json'
],
]);
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// Consulter les soldes (sold_wave + sold_om)
$balance = unitechRequest('balance', [], 'GET');
echo "Wave : " . $balance['data']['sold_wave'] . " XOF\n";
echo "Orange : " . $balance['data']['sold_om'] . " XOF\n";
echo "Total : " . $balance['data']['total'] . " XOF\n";
// Créer un paiement Wave
$result = unitechRequest('create_wave_payment', [
'amount' => 5000,
'customer_number' => '771234567',
'description' => 'Commande #123',
'callback_success' => 'https://monsite.com/success',
'callback_cancel' => 'https://monsite.com/cancel',
]);
if ($result['success']) {
header('Location: ' . $result['data']['payment_url']);
exit;
}
// Retrait Wave automatique
$withdrawal = unitechRequest('withdraw_funds', [
'amount' => 10000,
'method' => 'wave',
'account' => '771234567',
]);
if ($withdrawal['success']) {
echo "Retrait traité : " . $withdrawal['data']['net_amount'] . " XOF net\n";
echo "Statut : " . $withdrawal['data']['status'] . "\n";
}
?>
PHP — QR Code Orange Money
<?php
$result = unitechRequest('create_orange_qr', [
'amount' => 2500,
'reference' => 'cmd_' . uniqid(),
'description' => 'Paiement QR Code',
'callback_success' => 'https://monsite.com/success',
'callback_cancel' => 'https://monsite.com/cancel',
]);
if ($result['success']) {
$qr = $result['data']['qr_code']; // data:image/png;base64,...
$ref = $result['data']['reference'];
echo '<img src="' . $qr . '" alt="QR Code" />';
echo '<p>Référence : ' . $ref . '</p>';
}
?>
Node.js — Classe UnitechPay complète
const axios = require('axios');
class UnitechPay {
constructor(apiKey) {
this.client = axios.create({
baseURL: 'https://api.unitech.sn/api.php',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
timeout: 30000,
});
}
async _post(action, data) {
const res = await this.client.post(`?action=${action}`, data);
return res.data;
}
async _get(action, params = {}) {
const res = await this.client.get(`?action=${action}`, { params });
return res.data;
}
// Soldes Wave + Orange
async getBalance() {
return this._get('balance');
}
// Paiement Wave
async wavePayment(amount, phone, description, callbacks = {}) {
return this._post('create_wave_payment', {
amount, customer_number: phone, description,
callback_success: callbacks.success,
callback_cancel: callbacks.cancel,
});
}
// QR Code Orange Money
async orangeQR(amount, reference, description, callbacks = {}) {
return this._post('create_orange_qr', {
amount, reference, description,
callback_success: callbacks.success,
callback_cancel: callbacks.cancel,
});
}
// Retrait automatique
async withdraw(amount, method, account) {
return this._post('withdraw_funds', { amount, method, account });
}
}
// Utilisation
(async () => {
const pay = new UnitechPay('VOTRE_CLE_API');
// Soldes
const bal = await pay.getBalance();
console.log(`Wave: ${bal.data.sold_wave} XOF — Orange: ${bal.data.sold_om} XOF`);
// Paiement Wave
const wave = await pay.wavePayment(5000, '771234567', 'Commande #123', {
success: 'https://monapp.com/success',
cancel: 'https://monapp.com/cancel',
});
console.log('URL de paiement:', wave.data.payment_url);
// Retrait Wave
const wd = await pay.withdraw(10000, 'wave', '771234567');
console.log(`Retrait: ${wd.data.net_amount} XOF — ${wd.data.status}`);
})();
Python — Classe UnitechPay
import requests
class UnitechPay:
BASE_URL = "https://api.unitech.sn/api.php"
def __init__(self, api_key: str):
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
})
def _post(self, action: str, data: dict) -> dict:
r = self.session.post(f"{self.BASE_URL}?action={action}", json=data, timeout=30)
r.raise_for_status()
return r.json()
def _get(self, action: str, params: dict = {}) -> dict:
r = self.session.get(f"{self.BASE_URL}?action={action}", params=params, timeout=30)
r.raise_for_status()
return r.json()
def get_balance(self) -> dict:
return self._get("balance")
def wave_payment(self, amount, phone, description="", success_url="", cancel_url=""):
return self._post("create_wave_payment", {
"amount": amount, "customer_number": phone,
"description": description,
"callback_success": success_url, "callback_cancel": cancel_url,
})
def orange_qr(self, amount, reference="", description="", success_url="", cancel_url=""):
return self._post("create_orange_qr", {
"amount": amount, "reference": reference,
"description": description,
"callback_success": success_url, "callback_cancel": cancel_url,
})
def withdraw(self, amount: float, method: str, account: str) -> dict:
return self._post("withdraw_funds", {
"amount": amount, "method": method, "account": account,
})
# Utilisation
if __name__ == "__main__":
api = UnitechPay("VOTRE_CLE_API")
# Soldes
bal = api.get_balance()
print(f"Wave: {bal['data']['sold_wave']} XOF")
print(f"Orange: {bal['data']['sold_om']} XOF")
print(f"Total: {bal['data']['total']} XOF")
# Paiement Wave
w = api.wave_payment(5000, "771234567", "Test",
"https://monsite.com/success",
"https://monsite.com/cancel")
print("URL:", w["data"]["payment_url"])
# Retrait Orange Money
r = api.withdraw(8000, "orange", "771234567")
print(f"Retrait: {r['data']['net_amount']} XOF — {r['data']['status']}")
Flutter/Dart — Intégration complète
import 'package:http/http.dart' as http;
import 'dart:convert';
class UnitechPay {
static const String _base = 'https://api.unitech.sn/api.php';
final String _apiKey;
UnitechPay(this._apiKey);
Future<Map<String, dynamic>> _post(String action, Map<String, dynamic> body) async {
final res = await http.post(
Uri.parse('$_base?action=$action'),
headers: {
'Authorization': 'Bearer $_apiKey',
'Content-Type': 'application/json',
},
body: json.encode(body),
).timeout(const Duration(seconds: 30));
return json.decode(res.body);
}
Future<Map<String, dynamic>> _get(String action) async {
final res = await http.get(
Uri.parse('$_base?action=$action'),
headers: {'Authorization': 'Bearer $_apiKey'},
).timeout(const Duration(seconds: 30));
return json.decode(res.body);
}
Future<Map<String, dynamic>> getBalance() => _get('balance');
Future<Map<String, dynamic>> wavePayment({
required double amount,
required String phone,
String description = '',
String successUrl = '',
String cancelUrl = '',
}) => _post('create_wave_payment', {
'amount': amount,
'customer_number': phone,
'description': description,
'callback_success': successUrl,
'callback_cancel': cancelUrl,
});
Future<Map<String, dynamic>> orangeQR({
required double amount,
String reference = '',
String description = '',
String successUrl = '',
String cancelUrl = '',
}) => _post('create_orange_qr', {
'amount': amount,
'reference': reference,
'description': description,
'callback_success': successUrl,
'callback_cancel': cancelUrl,
});
Future<Map<String, dynamic>> withdraw({
required double amount,
required String method, // 'wave' | 'orange' | 'bank'
required String account,
}) => _post('withdraw_funds', {
'amount': amount,
'method': method,
'account': account,
});
}
// Utilisation dans un widget
void _example() async {
final api = UnitechPay('VOTRE_CLE_API');
// Soldes
final bal = await api.getBalance();
print('Wave: ${bal['data']['sold_wave']} XOF');
print('Orange: ${bal['data']['sold_om']} XOF');
// Paiement Wave
final wave = await api.wavePayment(
amount: 5000,
phone: '771234567',
description: 'Commande Flutter',
successUrl: 'https://monapp.com/success',
cancelUrl: 'https://monapp.com/cancel',
);
print('URL: ${wave['data']['payment_url']}');
// Retrait automatique
final wd = await api.withdraw(
amount: 10000,
method: 'wave',
account: '771234567',
);
print('Net: ${wd['data']['net_amount']} XOF — ${wd['data']['status']}');
}