
API Reference
Baran Business APIs
Créez un checkout, acceptez 1x et 3x/4x, recevez des webhooks, puis vérifiez chaque paiement avant de livrer.
Base URL
https://api.getbaran.comSandbox : baran_pk_test_… / baran_sk_test_…. Production : baran_pk_live_… / baran_sk_live_…. HTTPS obligatoire.
Authentification
Appels depuis votre serveur uniquement. Clés disponibles dans le portail marchand.
Content-Type: application/json
X-Baran-Key: baran_pk_test_…
X-Baran-Timestamp: <unix>
X-Baran-Signature: sha256=…
Idempotency-Key: <uuid>canonical =
METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + ENVIRONMENT + "\n" + sha256(raw_body)
signature = "sha256=" + HMAC_SHA256(baran_sk_…, canonical)- Timestamp valide ± 5 minutes.
- Environnement déduit du préfixe de clé (
pk_test→sandboxdans la signature,pk_live→production). Idempotency-Keyobligatoire sur les POST de paiement / simulation.- Production : whitelist IP de vos backends obligatoire.
- Environ 100 req/h (paiements) et 500 req/h (général).
Checkout hébergé
Le client paie sur Baran. Vous créez une session, puis redirigez :
https://api.getbaran.com/checkout?session_id={SESSION_ID}#checkout_token={CHECKOUT_TOKEN}Créer une session checkout
Crée une session de paiement valable 15 minutes.
Authentification : Clé API + signature + Idempotency-Key.
Paramètres
| Champ | Type | Présence | Description |
|---|---|---|---|
| order_id | string | Obligatoire | Référence unique de commande. |
| amount | number | Obligatoire | Montant en FCFA. |
| return_url | string | Obligatoire | URL HTTPS de retour. |
| order_key | string | Optionnel | Référence technique interne. |
| Idempotency-Key | header | Obligatoire | Identifiant unique de requête. |
curl -X POST https://api.getbaran.com/api/v1/merchant/checkout-sessions \
-H "Content-Type: application/json" \
-H "X-Baran-Key: baran_pk_test_VOTRE_CLE" \
-H "X-Baran-Timestamp: <unix_timestamp>" \
-H "X-Baran-Signature: sha256=SIGNATURE" \
-H "Idempotency-Key: 4f5c8a2e-9b1d-4c3a-8e7f-0123456789ab" \
-d '{
"order_id": "CMD-2026-0001",
"amount": 50000,
"return_url": "https://boutique.example/merci"
}'<?php
$payload = [
'order_id' => 'CMD-2026-0001',
'amount' => 50000,
'return_url' => 'https://boutique.example/merci',
];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES);
$timestamp = (string) time();
$environment = 'sandbox';
$path = '/api/v1/merchant/checkout-sessions';
$canonical = "POST\n{$path}\n{$timestamp}\n{$environment}\n" . hash('sha256', $body);
$signature = 'sha256=' . hash_hmac('sha256', $canonical, 'baran_sk_test_VOTRE_SECRET');
$ch = curl_init('https://api.getbaran.com/api/v1/merchant/checkout-sessions');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Baran-Key: baran_pk_test_VOTRE_CLE',
'X-Baran-Timestamp: ' . $timestamp,
'X-Baran-Signature: ' . $signature,
'Idempotency-Key: 4f5c8a2e-9b1d-4c3a-8e7f-0123456789ab',
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);const payload = {
order_id: 'CMD-2026-0001',
amount: 50000,
return_url: 'https://boutique.example/merci',
};
const body = JSON.stringify(payload);
const timestamp = Math.floor(Date.now() / 1000).toString();
const environment = 'sandbox';
const path = '/api/v1/merchant/checkout-sessions';
const bodyHash = await sha256Hex(body);
const canonical = ['POST', path, timestamp, environment, bodyHash].join('\n');
const signature = 'sha256=' + hmacSha256Hex(canonical, 'baran_sk_test_VOTRE_SECRET');
const response = await fetch('https://api.getbaran.com/api/v1/merchant/checkout-sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Baran-Key': 'baran_pk_test_VOTRE_CLE',
'X-Baran-Timestamp': timestamp,
'X-Baran-Signature': signature,
'Idempotency-Key': crypto.randomUUID(),
},
body,
});{
"status": "success",
"request_id": "req_…",
"data": {
"checkout_session_id": "…",
"checkout_token": "…",
"expires_in": 900
}
}Erreurs
| HTTP | Message | Action |
|---|---|---|
| 400 | Champs manquants / invalides | Corriger le payload. |
| 401 | Authentication failed | Vérifier clé et signature. |
| 403 | forbidden | Validation production ou IP. |
| 409 | idempotency_key_reuse | Nouvelle clé ou même body. |
Vérifier un paiement
Confirme l’état d’un paiement après webhook, avant fulfillment.
Authentification : Clé API + signature (body vide). Alternative : GET /payments/:transaction_id
Paramètres
| Champ | Type | Présence | Description |
|---|---|---|---|
| order_id | path | Obligatoire | Référence commande marchand. |
curl "https://api.getbaran.com/api/v1/merchant/orders/CMD-2026-0001/payment" \
-H "X-Baran-Key: baran_pk_test_VOTRE_CLE" \
-H "X-Baran-Timestamp: <unix_timestamp>" \
-H "X-Baran-Signature: sha256=SIGNATURE"<?php
$body = '';
$timestamp = (string) time();
$path = '/api/v1/merchant/orders/CMD-2026-0001/payment';
$canonical = "GET\n{$path}\n{$timestamp}\nsandbox\n" . hash('sha256', $body);
$signature = 'sha256=' . hash_hmac('sha256', $canonical, 'baran_sk_test_VOTRE_SECRET');const path = '/api/v1/merchant/orders/CMD-2026-0001/payment';
const timestamp = Math.floor(Date.now() / 1000).toString();
const bodyHash = await sha256Hex('');
const canonical = ['GET', path, timestamp, 'sandbox', bodyHash].join('\n');
const signature = 'sha256=' + hmacSha256Hex(canonical, 'baran_sk_test_VOTRE_SECRET');{
"status": "success",
"data": {
"transaction_id": "txn_…",
"order_id": "CMD-2026-0001",
"amount": 50000,
"status": "completed",
"currency": "XOF"
}
}Erreurs
| HTTP | Message | Action |
|---|---|---|
| 401 | Authentication failed | Vérifier la signature. |
| 404 | payment_not_found | Paiement introuvable. |
Simuler un événement sandbox
Déclenche un webhook de test (clés test uniquement).
Authentification : Clés test + signature.
Paramètres
| Champ | Type | Présence | Description |
|---|---|---|---|
| event | string | Optionnel | payment.completed, payment.failed, webhook.test |
| order_id | string | Optionnel | Référence de test. |
| amount | number | Optionnel | Montant simulé. |
curl -X POST https://api.getbaran.com/api/v1/merchant/sandbox/simulate \
-H "Content-Type: application/json" \
-H "X-Baran-Key: baran_pk_test_VOTRE_CLE" \
-H "X-Baran-Timestamp: <unix_timestamp>" \
-H "X-Baran-Signature: sha256=SIGNATURE" \
-H "Idempotency-Key: sim-001" \
-d '{"event":"payment.completed","order_id":"SIM-001","amount":50000}'<?php
$payload = ['event' => 'payment.completed', 'order_id' => 'SIM-001', 'amount' => 50000];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES);
$timestamp = (string) time();
$path = '/api/v1/merchant/sandbox/simulate';
$canonical = "POST\n{$path}\n{$timestamp}\nsandbox\n" . hash('sha256', $body);
$signature = 'sha256=' . hash_hmac('sha256', $canonical, 'baran_sk_test_VOTRE_SECRET');const payload = { event: 'payment.completed', order_id: 'SIM-001', amount: 50000 };
const body = JSON.stringify(payload);
const timestamp = Math.floor(Date.now() / 1000).toString();
const path = '/api/v1/merchant/sandbox/simulate';
const bodyHash = await sha256Hex(body);
const canonical = ['POST', path, timestamp, 'sandbox', bodyHash].join('\n');
const signature = 'sha256=' + hmacSha256Hex(canonical, 'baran_sk_test_VOTRE_SECRET');{
"status": "success",
"data": {
"status": "queued",
"event": "payment.completed",
"delivery_id": "whd_…"
}
}Erreurs
| HTTP | Message | Action |
|---|---|---|
| 401 | Authentication failed | Utiliser des clés test. |
| 403 | sandbox_only | Réservé au sandbox. |
Paiements 1x et 3x/4x
Le mode de paiement et l’authentification client se font sur le checkout Baran. Après succès : webhook, puis GET …/payment avant fulfillment.
Webhooks
URL configurée dans le portail. Répondez `2xx` rapidement.
Content-Type: application/json
X-Baran-Delivery: whd_…
X-Baran-Timestamp: <unix>
X-Baran-Signature: sha256=…{
"event": "payment.completed",
"transaction_id": "txn_…",
"order_id": "CMD-2026-0001",
"amount": 50000,
"amount_paid": 49000,
"status": "completed",
"payment_method": "1x",
"timestamp": "2026-06-12T00:00:00+00:00"
}expected = "sha256=" + HMAC_SHA256(webhook_secret, timestamp + "." + raw_body)Traitez X-Baran-Delivery de façon idempotente, puis confirmez avec GET …/payment.
Codes d’erreur
| HTTP | Message | Action |
|---|---|---|
| 400 | Requête invalide | Corriger le JSON ou les champs. |
| 401 | Non authentifié | Vérifier clé, timestamp et signature. |
| 403 | Accès refusé | Compte, validation production ou IP whitelist. |
| 404 | Introuvable | Vérifier order_id ou session. |
| 409 | Conflit | Commande déjà payée ou Idempotency-Key réutilisée. |
| 429 | Trop de requêtes | Réessayer plus tard. |
| 500 | Erreur serveur | Réessayer ; conserver request_id pour le support. |
Guide de test
- Créer une session et rediriger vers le checkout
- Recevoir et vérifier un webhook
- Confirmer via
GET …/payment - Tester le retry avec la même Idempotency-Key
Production : déclarer site + IP → validation → clés baran_pk_live_ / baran_sk_live_.