Référence de l'API v1

Environnement Sandbox. Base : http://nabila.bconsultingsarl.com/api/v1. Authentification : Authorization: Bearer nabila_prv_test_…. Lire le guide.

Paiements (Pay-In)

POST/api/v1/paymentsCréer un paiementDroit : payments:write

Débite le client par mobile money. NabilaPay choisit la meilleure voie de traitement, sans jamais débiter deux fois, et crédite votre solde du net.

En-tête obligatoire : Idempotency-Key: commande-1001

ParamètreTypeRequisDescription
amountentierouiMontant en FCFA, 100 à 1 000 000. Pas de décimales.
currencytextenonXOF (seule devise disponible).
countrytexteouiBJ, TG, CI ou SN.
phonetexteouiNuméro du client, ex. +22961000000.
operatortextenonEx. MTN_BJ, MOOV_BJ, WAVE_CI…
descriptiontextenon120 caractères maximum.
external_reftextenonVotre référence de commande (64 car.). Filtrable dans la liste.
metadataobjetnon10 paires texte maximum.
sandbox_scenariotextenonSUCCESS (défaut), FAILED, PENDING, TIMEOUT, PRIMARY_DOWN, REJECTED_ALL.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/payments" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Idempotency-Key: commande-1001" \
  -H "Content-Type: application/json" \
  -d '{"amount":15000,"currency":"XOF","country":"BJ","phone":"+22961000000","description":"Commande 1001","external_ref":"CMD-1001","metadata":{"panier":"A-77"}}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payments');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Idempotency-Key: commande-1001',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 15000,
        'currency' => 'XOF',
        'country' => 'BJ',
        'phone' => '+22961000000',
        'description' => 'Commande 1001',
        'external_ref' => 'CMD-1001',
        'metadata' => [
            'panier' => 'A-77',
        ],
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payments', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Idempotency-Key': 'commande-1001',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "amount": 15000,
      "currency": "XOF",
      "country": "BJ",
      "phone": "+22961000000",
      "description": "Commande 1001",
      "external_ref": "CMD-1001",
      "metadata": {
          "panier": "A-77"
      }
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/payments',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
        'Idempotency-Key': 'commande-1001',
    },
    json={"amount":15000,"currency":"XOF","country":"BJ","phone":"+22961000000","description":"Commande 1001","external_ref":"CMD-1001","metadata":{"panier":"A-77"}},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "3f6d2b1e-8c1a-4e57-9d3b-6a1f0c2e7b11",
    "object": "payment",
    "reference": "PAY-9A41C7D2E05B",
    "external_ref": "CMD-1001",
    "status": "succeeded",
    "amount": 15000,
    "currency": "XOF",
    "fee": 425,
    "net": 14575,
    "refunded": 0,
    "country": "BJ",
    "customer": {
        "phone": "+22961000000",
        "email": null
    },
    "description": "Commande 1001",
    "provider": "nabilapay",
    "failure_reason": null,
    "metadata": {
        "panier": "A-77"
    },
    "livemode": false,
    "created_at": "2026-10-10T09:41:12Z"
}
GET/api/v1/payments/{id}Consulter un paiementDroit : payments:read

Par identifiant ou par référence (PAY-…).

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "3f6d2b1e-8c1a-4e57-9d3b-6a1f0c2e7b11",
    "object": "payment",
    "reference": "PAY-9A41C7D2E05B",
    "external_ref": "CMD-1001",
    "status": "succeeded",
    "amount": 15000,
    "currency": "XOF",
    "fee": 425,
    "net": 14575,
    "refunded": 0,
    "country": "BJ",
    "customer": {
        "phone": "+22961000000",
        "email": null
    },
    "description": "Commande 1001",
    "provider": "nabilapay",
    "failure_reason": null,
    "metadata": {
        "panier": "A-77"
    },
    "livemode": false,
    "created_at": "2026-10-10T09:41:12Z"
}
GET/api/v1/paymentsLister les paiementsDroit : payments:read

Les plus récents d'abord. Filtres : status (succeeded, failed, pending), external_ref ; pagination : limit (1 à 100), page.

ParamètreTypeRequisDescription
statustextenonsucceeded, failed ou pending.
external_reftextenonVotre référence.
limitentiernon20 par défaut.
pageentiernon1 par défaut.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/payments" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payments');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payments', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/payments',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "list",
    "data": [
        {
            "id": "3f6d2b1e-8c1a-4e57-9d3b-6a1f0c2e7b11",
            "object": "payment",
            "reference": "PAY-9A41C7D2E05B",
            "external_ref": "CMD-1001",
            "status": "succeeded",
            "amount": 15000,
            "currency": "XOF",
            "fee": 425,
            "net": 14575,
            "refunded": 0,
            "country": "BJ",
            "customer": {
                "phone": "+22961000000",
                "email": null
            },
            "description": "Commande 1001",
            "provider": "nabilapay",
            "failure_reason": null,
            "metadata": {
                "panier": "A-77"
            },
            "livemode": false,
            "created_at": "2026-10-10T09:41:12Z"
        }
    ],
    "page": 1,
    "limit": 20,
    "has_more": false
}
POST/api/v1/payments/{id}/refundsRembourserDroit : refunds:write

Total ou partiel, jamais au-delà du montant payé. Montant omis = solde restant.

En-tête obligatoire : Idempotency-Key: remb-1001-1

ParamètreTypeRequisDescription
amountentiernonFCFA. Par défaut : tout le reste.
reasontextenon120 caractères maximum.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B/refunds" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Idempotency-Key: remb-1001-1" \
  -H "Content-Type: application/json" \
  -d '{"amount":5000,"reason":"Article retourné"}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B/refunds');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Idempotency-Key: remb-1001-1',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 5000,
        'reason' => 'Article retourné',
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B/refunds', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Idempotency-Key': 'remb-1001-1',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "amount": 5000,
      "reason": "Article retourné"
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/payments/PAY-9A41C7D2E05B/refunds',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
        'Idempotency-Key': 'remb-1001-1',
    },
    json={"amount":5000,"reason":"Article retourné"},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "a7c0…",
    "object": "refund",
    "payment_id": "3f6d2b1e-8c1a-4e57-9d3b-6a1f0c2e7b11",
    "amount": 5000,
    "status": "succeeded",
    "reason": "Article retourné",
    "created_at": "2026-10-10T10:02:44Z"
}

Liens de paiement et factures

POST/api/v1/payment_linksCréer un lien de paiementDroit : payments:write

Crée une page de paiement hébergée (mobile money et carte) à partager ou vers laquelle rediriger votre client. Montant omis = le client le saisit. Avec la même external_ref et le même montant, le lien actif existant est renvoyé (pas de doublon si votre plugin réessaie).

ParamètreTypeRequisDescription
titletexteouiTitre affiché au client (160 car. max).
amountentiernonFCFA, 100 à 1 000 000. Omis = montant libre.
descriptiontextenon500 caractères maximum.
external_reftextenonVotre référence (n° de commande), renvoyée dans les webhooks.
single_usebooléennonSe désactive après un paiement réussi.
expires_in_daysentiernon1 à 365. Omis = sans limite.
success_urltextenonRedirection après succès (http/https). NabilaPay ajoute reference et status.
cancel_urltextenonRedirection en cas d'annulation ou d'échec.
customer_emailtextenonPré-remplit l'e-mail du reçu.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/payment_links" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Commande 1001","amount":15000,"external_ref":"CMD-1001","single_use":true,"success_url":"https://boutique.exemple/merci","cancel_url":"https://boutique.exemple/panier"}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payment_links');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'title' => 'Commande 1001',
        'amount' => 15000,
        'external_ref' => 'CMD-1001',
        'single_use' => true,
        'success_url' => 'https://boutique.exemple/merci',
        'cancel_url' => 'https://boutique.exemple/panier',
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payment_links', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "title": "Commande 1001",
      "amount": 15000,
      "external_ref": "CMD-1001",
      "single_use": true,
      "success_url": "https://boutique.exemple/merci",
      "cancel_url": "https://boutique.exemple/panier"
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/payment_links',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json={"title":"Commande 1001","amount":15000,"external_ref":"CMD-1001","single_use":True,"success_url":"https://boutique.exemple/merci","cancel_url":"https://boutique.exemple/panier"},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "9b1c…",
    "object": "payment_link",
    "url": "https://votre-domaine/pay/4f1e…",
    "title": "Commande 1001",
    "amount": 15000,
    "currency": "XOF",
    "status": "active",
    "single_use": true,
    "external_ref": "CMD-1001",
    "paid_count": 0,
    "livemode": false
}
GET/api/v1/payment_links/{id}Consulter un lienDroit : payments:read

Par identifiant. Statuts : active, disabled, paid, expired.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "9b1c…",
    "object": "payment_link",
    "status": "paid",
    "paid_count": 1
}
GET/api/v1/payment_linksLister les liensDroit : payments:read

Les plus récents d'abord ; pagination limit et page.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/payment_links" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payment_links');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payment_links', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/payment_links',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "list",
    "data": [],
    "page": 1,
    "limit": 20
}
POST/api/v1/payment_links/{id}/disableDésactiver un lienDroit : payments:write

Le lien ne peut plus être payé. /enable le réactive.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B/disable" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '[]'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B/disable');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B/disable', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify([]),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/payment_links/PAY-9A41C7D2E05B/disable',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json=[],
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "9b1c…",
    "object": "payment_link",
    "status": "disabled"
}
POST/api/v1/invoicesCréer une factureDroit : payments:write

Facture numérotée (F-AAAA-0001…). Avec send=true elle est envoyée au client avec un bouton « Payer » ; elle passe à paid automatiquement.

ParamètreTypeRequisDescription
customerobjetouiname (obligatoire), email, phone, address.
itemslisteouiLignes : description, quantity, unit_amount (FCFA).
tax_percentnombrenonTVA en %, 0 à 50.
issue_datetextenonAAAA-MM-JJ (aujourd'hui par défaut).
due_datetextenonÉchéance AAAA-MM-JJ.
notestextenon500 caractères.
sendbooléennonEnvoyer tout de suite.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/invoices" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer":{"name":"Koffi Mensah","email":"koffi@exemple.com"},"items":[{"description":"Robe wax","quantity":2,"unit_amount":12000}],"tax_percent":18,"send":true}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/invoices');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'customer' => [
            'name' => 'Koffi Mensah',
            'email' => 'koffi@exemple.com',
        ],
        'items' => [
            [
                'description' => 'Robe wax',
                'quantity' => 2,
                'unit_amount' => 12000,
            ],
        ],
        'tax_percent' => 18,
        'send' => true,
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/invoices', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "customer": {
          "name": "Koffi Mensah",
          "email": "koffi@exemple.com"
      },
      "items": [
          {
              "description": "Robe wax",
              "quantity": 2,
              "unit_amount": 12000
          }
      ],
      "tax_percent": 18,
      "send": true
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/invoices',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json={"customer":{"name":"Koffi Mensah","email":"koffi@exemple.com"},"items":[{"description":"Robe wax","quantity":2,"unit_amount":12000}],"tax_percent":18,"send":True},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "7d2a…",
    "object": "invoice",
    "number": "F-2026-0001",
    "status": "sent",
    "subtotal": 24000,
    "tax": 4320,
    "total": 28320,
    "url": "https://votre-domaine/invoice/8c3f…",
    "livemode": false
}
GET/api/v1/invoices/{id}Consulter une factureDroit : payments:read

Par identifiant ou numéro (F-…).

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "7d2a…",
    "object": "invoice",
    "number": "F-2026-0001",
    "status": "paid",
    "total": 28320
}
POST/api/v1/invoices/{id}/sendEnvoyer une factureDroit : payments:write

Envoie (ou renvoie) la facture au client par e-mail.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B/send" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '[]'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B/send');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify([]),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/invoices/PAY-9A41C7D2E05B/send',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json=[],
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "7d2a…",
    "object": "invoice",
    "status": "sent"
}

Décaissements (Pay-Out)

POST/api/v1/payoutsCréer un payoutDroit : payouts:write

Envoie de l'argent à un bénéficiaire mobile money. Le montant plus les frais est réservé sur votre solde. À partir de 500 000 FCFA, une approbation (double validation) est requise.

En-tête obligatoire : Idempotency-Key: paie-2026-10-001

ParamètreTypeRequisDescription
amountentierouiFCFA, 500 à 5 000 000.
nametexteouiNom du bénéficiaire.
phonetexteouiNuméro mobile money.
operatortextenonOpérateur du bénéficiaire.
sandbox_scenariotextenonSUCCESS (défaut) ou autre valeur pour simuler un échec.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/payouts" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Idempotency-Key: paie-2026-10-001" \
  -H "Content-Type: application/json" \
  -d '{"amount":25000,"name":"Awa Koné","phone":"+22507000000","operator":"ORANGE_CI"}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payouts');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Idempotency-Key: paie-2026-10-001',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 25000,
        'name' => 'Awa Koné',
        'phone' => '+22507000000',
        'operator' => 'ORANGE_CI',
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payouts', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Idempotency-Key': 'paie-2026-10-001',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "amount": 25000,
      "name": "Awa Koné",
      "phone": "+22507000000",
      "operator": "ORANGE_CI"
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/payouts',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
        'Idempotency-Key': 'paie-2026-10-001',
    },
    json={"amount":25000,"name":"Awa Koné","phone":"+22507000000","operator":"ORANGE_CI"},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "c1d2…",
    "object": "payout",
    "reference": "OUT-4B7E19A0C3D2",
    "status": "succeeded",
    "amount": 25000,
    "fee": 225,
    "currency": "XOF",
    "requires_approval": false,
    "failure_reason": null,
    "beneficiary": {
        "name": "Awa Koné",
        "phone": "+22507000000"
    },
    "livemode": false,
    "created_at": "2026-10-10T10:15:00Z"
}
GET/api/v1/payouts/{id}Consulter un payoutDroit : payouts:read

Par identifiant ou référence (OUT-…).

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/payouts/PAY-9A41C7D2E05B" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/payouts/PAY-9A41C7D2E05B');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/payouts/PAY-9A41C7D2E05B', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/payouts/PAY-9A41C7D2E05B',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "id": "c1d2…",
    "object": "payout",
    "reference": "OUT-4B7E19A0C3D2",
    "status": "succeeded",
    "amount": 25000
}

Compte

GET/api/v1/balanceSoldeDroit : balance:read

Trois compartiments : disponible, en attente, réservé (payouts en cours).

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/balance" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/balance');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/balance', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/balance',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "balance",
    "currency": "XOF",
    "available": 1989575,
    "pending": 0,
    "reserved": 0,
    "livemode": false
}
GET/api/v1/feesEstimer les fraisDroit : payments:read

Frais marchand pour un montant et un pays, selon votre grille.

ParamètreTypeRequisDescription
amountentierouiFCFA.
countrytexteouiBJ, TG, CI, SN.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/fees" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/fees');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/fees', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/fees',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "fee_quote",
    "amount": 15000,
    "currency": "XOF",
    "country": "BJ",
    "fee": 425,
    "net": 14575
}
GET/api/v1/meQui suis-je ?Droit : toute clé valide

Compte, environnement et droits de la clé.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/me" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/me');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/me', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/me',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "account",
    "name": "Ma Boutique",
    "country": "BJ",
    "kyb_status": "SANDBOX_ONLY",
    "environment": "sandbox",
    "livemode": false,
    "scopes": [
        "payments:read",
        "payments:write"
    ]
}

Webhooks

POST/api/v1/webhooksAjouter un point de réceptionDroit : webhooks:manage

Le secret de signature n'est affiché qu'à la création.

ParamètreTypeRequisDescription
urltexteouihttps:// (http://localhost accepté en développement).
eventslistenonPar défaut tous : payment.succeeded, payment.failed, payment.pending, refund.created, payout.created, payout.succeeded, payout.failed.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/webhooks" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://exemple.com/webhooks/nabila","events":["payment.succeeded","payment.failed"]}'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/webhooks');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'url' => 'https://exemple.com/webhooks/nabila',
        'events' => [
            'payment.succeeded',
            'payment.failed',
        ],
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/webhooks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "url": "https://exemple.com/webhooks/nabila",
      "events": [
          "payment.succeeded",
          "payment.failed"
      ]
  }),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/webhooks',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json={"url":"https://exemple.com/webhooks/nabila","events":["payment.succeeded","payment.failed"]},
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "webhook_endpoint",
    "id": "e5f6…",
    "url": "https://exemple.com/webhooks/nabila",
    "secret": "whsec_••••",
    "note": "Le secret n'est affiché qu'une fois."
}
POST/api/v1/webhooks/testEnvoyer un événement de testDroit : webhooks:manage

Envoie webhook.test à tous vos points de réception.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/webhooks/test" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '[]'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/webhooks/test');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/webhooks/test', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify([]),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/webhooks/test',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json=[],
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "webhook_test",
    "deliveries_attempted": 1
}

Outils Sandbox

POST/api/v1/sandbox/payouts/{id}/approveApprouver un payoutDroit : payouts:write

Simule la double validation de NabilaPay pour un payout ≥ 500 000 FCFA, puis l'exécute.

Exemple

curl -X POST "http://nabila.bconsultingsarl.com//api/v1/sandbox/payouts/PAY-9A41C7D2E05B/approve" \
  -H "Authorization: Bearer $NABILA_KEY" \
  -H "Content-Type: application/json" \
  -d '[]'
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/sandbox/payouts/PAY-9A41C7D2E05B/approve');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    ]),
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/sandbox/payouts/PAY-9A41C7D2E05B/approve', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify([]),
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'POST', 'http://nabila.bconsultingsarl.com//api/v1/sandbox/payouts/PAY-9A41C7D2E05B/approve',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    json=[],
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "object": "payout",
    "status": "succeeded"
}
GET/api/v1/sandbox/statusÉtat de la SandboxDroit : aucun (public)

Disponibilité de la Sandbox.

Exemple

curl -X GET "http://nabila.bconsultingsarl.com//api/v1/sandbox/status" \
  -H "Authorization: Bearer $NABILA_KEY"
<?php
$ch = curl_init('http://nabila.bconsultingsarl.com//api/v1/sandbox/status');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('NABILA_KEY'),
    ],
]);
$reponse = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
var_dump($code, $reponse);
const res = await fetch('http://nabila.bconsultingsarl.com//api/v1/sandbox/status', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.NABILA_KEY}`,
  },
});
console.log(res.status, await res.json());
import os, requests

r = requests.request(
    'GET', 'http://nabila.bconsultingsarl.com//api/v1/sandbox/status',
    headers={
        'Authorization': 'Bearer ' + os.environ['NABILA_KEY'],
    },
    timeout=10,
)
print(r.status_code, r.json())

Réponse

{
    "sandbox": {
        "active": true
    },
    "production": {
        "available": false
    }
}

Testez votre intégration aujourd'hui.

Compte gratuit, clé API Sandbox générée automatiquement, aucun argent réel.

Ouvrir un compte Sandbox