API Marchand GeniusPay
Intégrez les paiements mobiles (Wave, Orange Money, MTN Money) et par carte dans vos applications en quelques minutes.
https://pay.genius.ci/api/v1/merchant
Sandbox
Testez votre intégration sans frais. Les transactions sont simulées.
Production
Transactions réelles. Activez le mode live dans vos paramètres.
Authentification
Toutes les requêtes doivent inclure vos clés API dans les headers HTTP.
| Header | Description |
|---|---|
X-API-Key |
Votre clé publique (pk_sandbox_... ou pk_live_...) |
X-API-Secret |
Votre clé secrète (sk_sandbox_... ou sk_live_...) |
Content-Type |
application/json |
Exemple avec cURL
curl -X POST https://pay.genius.ci/api/v1/merchant/payments \
-H "X-API-Key: pk_sandbox_xxxxxxxx" \
-H "X-API-Secret: sk_sandbox_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount": 5000, "customer": {"phone": "+221771234567"}}'
Démarrage rapide - 2 lignes de code
La façon la plus simple d'intégrer GeniusPay. Créez un paiement et redirigez votre client vers notre page de checkout sécurisée où il choisira son moyen de paiement.
✨ Intégration minimale
// 1. Créer le paiement (sans spécifier payment_method)
$response = Http::withHeaders([
'X-API-Key' => 'pk_live_xxx',
'X-API-Secret' => 'sk_live_xxx',
])->post('https://pay.genius.ci/api/v1/merchant/payments', [
'amount' => 15000,
'description' => 'Commande #123',
]);
// 2. Rediriger vers la page de checkout GeniusPay
return redirect($response['data']['checkout_url']);
Rapide
Intégration en 2 lignes, aucune logique de paiement à gérer
Sécurisé
Page de checkout hébergée et sécurisée par GeniusPay
Tous les moyens
Wave, Orange, MTN, Moov, Cartes bancaires
Comment ça marche ?
En omettant le paramètre payment_method, GeniusPay génère une
URL vers notre page de checkout personnalisée.
Votre client y choisira son moyen de paiement préféré. Une fois le paiement
effectué, il sera redirigé et vous recevrez un webhook.
Initier un paiement
Crée une nouvelle transaction et retourne une URL de paiement.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
amount |
number | ✓ | Montant en XOF (min: 200) |
currency |
string | - | Devise (défaut: XOF) |
payment_method |
string | - | wave, paystack, orange_money, mtn_money |
description |
string | - | Description du paiement (max 500 car.) |
customer.name |
string | - | Nom du client |
customer.email |
string | - | Email du client |
customer.phone |
string | - | Téléphone du client |
success_url |
string | - | URL de redirection après succès |
error_url |
string | - | URL de redirection après échec |
metadata |
object | - | Données personnalisées |
Requête
{
"amount": 15000,
"payment_method": "wave",
"description": "Commande #12345",
"customer": {
"name": "Amadou Diallo",
"email": "amadou@example.com",
"phone": "+221771234567"
},
"metadata": {
"order_id": "12345"
}
}
Réponse 201
{
"success": true,
"data": {
"id": 456,
"reference": "MTX-A1B2C3D4E5",
"amount": 15000,
"fees": 450,
"net_amount": 14550,
"status": "pending",
"payment_url": "https://wave.com/...",
"gateway": "wave",
"environment": "sandbox"
}
}
Page de Checkout GeniusPay
Quand vous initiez un paiement sans spécifier de payment_method,
l'API retourne une checkout_url vers notre page
de paiement hébergée.
Paiement sécurisé
Votre Boutique
Réponse API (mode checkout)
{
"success": true,
"data": {
"id": 123,
"reference": "MTX-A1B2C3D4E5",
"amount": 15000,
"currency": "XOF",
"status": "pending",
"checkout_url": "https://pay.genius.ci/checkout/MTX-A1B2C3D4E5",
"payment_url": "https://pay.genius.ci/checkout/MTX-A1B2C3D4E5",
"environment": "sandbox",
"expires_at": "2024-12-16T14:00:00.000000Z"
}
}
✅ Avantages
- • Aucune gestion des moyens de paiement côté client
- • Interface optimisée pour la conversion
- • Mise à jour automatique des providers
- • Design responsive (mobile/desktop)
📌 Bon à savoir
- • Le lien expire après 24 heures
- • Webhooks envoyés après paiement
- • Redirection vers success_url/error_url
- • Compatible sandbox et production
Lister les paiements
Paramètres de query
| Paramètre | Description |
|---|---|
status |
Filtrer par statut (pending, completed, failed) |
from |
Date de début (YYYY-MM-DD) |
to |
Date de fin (YYYY-MM-DD) |
per_page |
Résultats par page (défaut: 20, max: 100) |
Récupérer un paiement
Informations du compte
Solde du compte
{
"success": true,
"data": {
"available": 1250000,
"pending": 75000,
"total": 1325000,
"currency": "XOF"
}
}
Webhooks
Recevez des notifications en temps réel sur les événements de vos paiements. L'intégration webhook est identique pour Sandbox et Live, seules les clés changent.
🔑 Sandbox vs Live
| Aspect | Sandbox | Live |
|---|---|---|
| Secret Webhook | whsec_sandbox_xxx |
whsec_live_xxx |
| Header Environment | X-Webhook-Environment: sandbox |
X-Webhook-Environment: live |
| Payload Field | "environment": "sandbox" |
"environment": "live" |
| Code d'intégration | ✅ Identique | ✅ Identique |
/webhooks
Lister les webhooks
/webhooks
Créer un webhook
/webhooks/{id}
Modifier un webhook
/webhooks/{id}
Supprimer un webhook
/webhooks/{id}/test
Tester un webhook
Événements webhook
| Événement | Description |
|---|---|
payment.initiated
|
Paiement initié |
payment.success
|
Paiement réussi |
payment.failed |
Paiement échoué |
payment.cancelled
|
Paiement annulé |
payment.refunded
|
Paiement remboursé |
payment.expired
|
Paiement expiré |
cashout.requested
|
Demande de retrait |
cashout.approved
|
Retrait approuvé |
cashout.completed
|
Retrait complété |
cashout.failed |
Retrait échoué |
webhook.test
|
Test de webhook |
Configuration Webhook
✅ Créer un webhook
curl -X POST https://api.geniuspay.ci/merchant/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Mon webhook",
"url": "https://example.com/webhooks/geniuspay",
"events": ["payment.success", "payment.failed", "cashout.completed"]
}'
Le secret webhook sera retourné uniquement à la création. Conservez-le précieusement!
Payload webhook
Le payload est identique pour Sandbox et Live. Seul le champ "environment" change.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"event": "payment.success",
"timestamp": 1735587600,
"created_at": "2025-12-30T12:00:00.000000Z",
"data": {
"object": "transaction",
"id": 12345,
"reference": "TXN-2025-001",
"amount": 10000.00,
"currency": "XOF",
"fees": 250.00,
"net_amount": 9750.00,
"status": "completed",
"payment_method": "mobile_money",
"provider": "wave",
"customer_name": "Jean Kouassi",
"customer_phone": "+2250748123456",
"merchant_id": 25,
"metadata": {
"order_id": "ORD-2025-123",
"customer_email": "jean@example.com"
}
},
"environment": "live",
"api_version": "2024-01-01"
}
Sécurité des webhooks
Vérifiez toujours la signature des webhooks pour vous assurer qu'ils proviennent bien de GeniusPay.
Important
Ne traitez jamais un webhook sans vérifier sa signature.
Headers webhook
| Header | Description |
|---|---|
Content-Type |
application/json |
X-Webhook-Signature |
Signature HMAC-SHA256 |
X-Webhook-Timestamp |
Timestamp Unix de l'envoi |
X-Webhook-Event |
Type d'événement |
X-Webhook-Delivery |
ID unique de livraison (optionnel) |
X-Webhook-Environment |
sandbox ou live |
User-Agent |
GeniusPay-Webhook/1.0 |
Vérification de la signature
Format: signature = HMAC-SHA256(timestamp + "." + json_payload, secret)
// Récupérer les headers
$signature = $request->header('X-Webhook-Signature');
$timestamp = $request->header('X-Webhook-Timestamp');
$event = $request->header('X-Webhook-Event');
// Récupérer le payload JSON
$payload = $request->all();
// Construire la donnée à vérifier
$data = $timestamp . '.' . json_encode($payload);
// Calculer la signature attendue
$secret = 'whsec_xxxxxxxx'; // Votre clé secrète webhook
$expectedSignature = hash_hmac('sha256', $data, $secret);
// Vérifier la signature
if (!hash_equals($expectedSignature, $signature)) {
return response()->json([
'status' => 401,
'detail' => 'Invalid signature'
], 401);
}
// Vérifier le timestamp (protection replay attack)
if (abs(time() - (int)$timestamp) > 300) { // 5 minutes
return response()->json([
'status' => 400,
'detail' => 'Timestamp too old'
], 400);
}
// Traiter l'événement selon son type
switch ($event) {
case 'payment.success':
// Marquer la commande comme payée
break;
case 'payment.failed':
// Notifier le client
break;
}
📘 Documentation complète: Consultez le Guide d'Intégration Webhook pour des exemples en PHP, Node.js, Python et Java.
Statuts des paiements
En attente de paiement
En cours de traitement
Paiement réussi
Paiement échoué
Paiement annulé
Paiement remboursé
Méthodes de paiement
| Code | Nom | Pays |
|---|---|---|
wave |
Wave | SN, CI, ML, BF |
orange_money
|
Orange Money | SN, CI, ML, BF |
mtn_money
|
MTN Mobile Money | CI, BF |
card |
Carte bancaire (Visa, Mastercard) | International |
Conseil
Omettez le paramètre payment_method pour laisser
le client choisir sur la page de checkout GeniusPay.
C'est l'approche recommandée pour maximiser les conversions.
Codes d'erreur
| Code | HTTP | Description |
|---|---|---|
MISSING_API_KEY |
401 | Clé API manquante |
INVALID_API_KEY |
401 | Clé API invalide |
MERCHANT_INACTIVE |
403 | Compte désactivé |
PAYMENT_INIT_FAILED |
400 | Échec d'initialisation |
TRANSACTION_NOT_FOUND |
404 | Transaction introuvable |
VALIDATION_ERROR |
422 | Données invalides |
Exemples d'intégration
Mode Checkout (2 lignes)
Sans payment_method, le client choisit son
moyen de paiement sur la page GeniusPay.
// Intégration en 2 lignes avec le SDK Laravel
$payment = GeniusPay::checkout(15000, 'Commande #123');
return redirect($payment->checkoutUrl);
// Ou avec Http natif
$response = Http::withHeaders([
'X-API-Key' => 'pk_live_xxx',
'X-API-Secret' => 'sk_live_xxx',
])->post('https://pay.genius.ci/api/v1/merchant/payments', [
'amount' => 15000,
'description' => 'Commande #123',
// PAS de payment_method = Page checkout GeniusPay
]);
return redirect($response['data']['checkout_url']);
Mode Direct (méthode spécifiée)
Avec payment_method spécifié, redirection
directe vers le gateway.
$response = Http::withHeaders([
'X-API-Key' => 'pk_live_xxx',
'X-API-Secret' => 'sk_live_xxx',
])->post('https://pay.genius.ci/api/v1/merchant/payments', [
'amount' => 15000,
'payment_method' => 'wave', // Redirection directe vers Wave
'customer' => [
'phone' => '+221771234567',
],
]);
return redirect($response['data']['payment_url']);