Baran

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

Base URL
https://api.getbaran.com

Sandbox : 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.

Headers
Content-Type: application/json
X-Baran-Key: baran_pk_test_…
X-Baran-Timestamp: <unix>
X-Baran-Signature: sha256=…
Idempotency-Key: <uuid>
Signature
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 sandbox dans la signature, pk_liveproduction).
  • Idempotency-Key obligatoire 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 :

Redirection
https://api.getbaran.com/checkout?session_id={SESSION_ID}#checkout_token={CHECKOUT_TOKEN}
Ne collectez pas le code secret client et ne placez pas la clé API dans un frontend.

Créer une session checkout

POST/api/v1/merchant/checkout-sessions

Crée une session de paiement valable 15 minutes.

Authentification : Clé API + signature + Idempotency-Key.

Paramètres

ChampTypePrésenceDescription
order_idstringObligatoireRéférence unique de commande.
amountnumberObligatoireMontant en FCFA.
return_urlstringObligatoireURL HTTPS de retour.
order_keystringOptionnelRéférence technique interne.
Idempotency-KeyheaderObligatoireIdentifiant unique de requête.
cURL
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
<?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);
JavaScript
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,
});
Réponse succès
{
  "status": "success",
  "request_id": "req_…",
  "data": {
    "checkout_session_id": "…",
    "checkout_token": "…",
    "expires_in": 900
  }
}

Erreurs

HTTPMessageAction
400Champs manquants / invalidesCorriger le payload.
401Authentication failedVérifier clé et signature.
403forbiddenValidation production ou IP.
409idempotency_key_reuseNouvelle clé ou même body.

Vérifier un paiement

GET/api/v1/merchant/orders/:order_id/payment

Confirme l’état d’un paiement après webhook, avant fulfillment.

Authentification : Clé API + signature (body vide). Alternative : GET /payments/:transaction_id

Paramètres

ChampTypePrésenceDescription
order_idpathObligatoireRéférence commande marchand.
cURL
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
<?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');
JavaScript
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');
Réponse succès
{
  "status": "success",
  "data": {
    "transaction_id": "txn_…",
    "order_id": "CMD-2026-0001",
    "amount": 50000,
    "status": "completed",
    "currency": "XOF"
  }
}

Erreurs

HTTPMessageAction
401Authentication failedVérifier la signature.
404payment_not_foundPaiement introuvable.

Simuler un événement sandbox

POST/api/v1/merchant/sandbox/simulate

Déclenche un webhook de test (clés test uniquement).

Authentification : Clés test + signature.

Paramètres

ChampTypePrésenceDescription
eventstringOptionnelpayment.completed, payment.failed, webhook.test
order_idstringOptionnelRéférence de test.
amountnumberOptionnelMontant simulé.
cURL
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
<?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');
JavaScript
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');
Réponse succès
{
  "status": "success",
  "data": {
    "status": "queued",
    "event": "payment.completed",
    "delivery_id": "whd_…"
  }
}

Erreurs

HTTPMessageAction
401Authentication failedUtiliser des clés test.
403sandbox_onlyRé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.

Headers
Content-Type: application/json
X-Baran-Delivery: whd_…
X-Baran-Timestamp: <unix>
X-Baran-Signature: sha256=…
payment.completed
{
  "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"
}
Vérification
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

HTTPMessageAction
400Requête invalideCorriger le JSON ou les champs.
401Non authentifiéVérifier clé, timestamp et signature.
403Accès refuséCompte, validation production ou IP whitelist.
404IntrouvableVérifier order_id ou session.
409ConflitCommande déjà payée ou Idempotency-Key réutilisée.
429Trop de requêtesRéessayer plus tard.
500Erreur serveurRé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_.