API prête à l'intégration

REST v1, OpenAPI 3.1, authentification Bearer, webhooks signés HMAC-SHA256, attestations KYC Ed25519 vérifiables offline. Sandbox en libre-service depuis votre dashboard SGI.

Production : https://api.getinopay.com · Sandbox indistinguable avec clés inopay_test_*
Quickstart · 4 étapes

De zéro à production en quelques heures

Parcours type d'une SGI qui intègre Inopay dans son système d'information.

1

Créer votre clé

Dans Dashboard SGI → Intégration, générez une clé sandbox. Choisissez le label et les permissions (read / write / admin).

2

Appeler l'API

Header Authorization: Bearer inopay_test_…. Commencez par GET /v1/sgi/portfolio/connections pour voir les investisseurs consentants.

3

Recevoir les webhooks

Configurez votre URL HTTPS + vérifiez la signature X-Inopay-Signature avec votre secret HMAC. Testez avec le bouton « Envoyer un ping » du dashboard.

4

Passer en production

Signez l'accord pilote, nous activons vos clés inopay_live_*. Même API, même latence, mêmes SLA — uniquement l'environnement change.

Endpoints

Trois surfaces, une seule API

Préfixe base : https://api.getinopay.com. Tous les endpoints SGI utilisent Authorization: Bearer inopay_….

KYC unifié

POST/v1/kyc/sessions
GET/v1/kyc/:id
GET/v1/kyc/:id/audit-trail
POST/v1/kyc/verify-attestation

Ordres & portefeuilles

GET/v1/sgi/portfolio/orders
PATCH/v1/sgi/portfolio/orders/:id/execute
PATCH/v1/sgi/portfolio/orders/:id/cancel
GET/v1/sgi/portfolio/connections
POST/v1/sgi/portfolio/sync-callback
GET/v1/sgi/portfolio/billing/commissions

Données publiques

GET/v1/instruments
GET/v1/portfolio/fx-rates
GET/v1/portfolio/sgi-directory
GET/.well-known/inopay-kyc-pubkey.pem
Exemple curl

Votre premier appel en 30 secondes

# 1. Lister les investisseurs consentants pour votre SGI
curl "https://api.getinopay.com/v1/sgi/portfolio/connections" \
  -H "Authorization: Bearer inopay_test_abc123..."

# 2. Créer une session KYC hébergée pour un investisseur
curl -X POST "https://api.getinopay.com/v1/kyc/sessions" \
  -H "Authorization: Bearer inopay_test_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "amadou@example.com",
    "full_name": "Amadou Diallo",
    "phone": "+33612345678",
    "requested_level": "KYC2"
  }'

# 3. Confirmer l'exécution d'un ordre routé vers votre SGI
curl -X PATCH "https://api.getinopay.com/v1/sgi/portfolio/orders/ORDER_ID/execute" \
  -H "Authorization: Bearer inopay_test_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "execution_ref": "EXEC-20260423-001",
    "executed_at": "2026-04-23T10:30:00Z",
    "gross_amount_fcfa": 1500000
  }'
// npm install node-fetch (Node 18+ : fetch natif)
const API = "https://api.getinopay.com";
const KEY = process.env.INOPAY_API_KEY;

// Lister les investisseurs consentants
const res = await fetch(`${API}/v1/sgi/portfolio/connections`, {
  headers: { Authorization: `Bearer ${KEY}` }
});
const { connections } = await res.json();

// Vérifier une attestation KYC signée Ed25519 offline (sans réseau)
import { createPublicKey, verify } from "crypto";
const inopayPubKey = createPublicKey(fs.readFileSync("./inopay-kyc-pubkey.pem"));
function verifyAttestation(attestationJwt) {
  const [header, payload, sig] = attestationJwt.split(".");
  const signingInput = `${header}.${payload}`;
  return verify(null, Buffer.from(signingInput),
    inopayPubKey, Buffer.from(sig, "base64url"));
}
# pip install requests cryptography
import os, requests, json, base64
from cryptography.hazmat.primitives.serialization import load_pem_public_key

API = "https://api.getinopay.com"
KEY = os.environ["INOPAY_API_KEY"]
headers = {"Authorization": f"Bearer {KEY}"}

# Lister les ordres routés vers votre SGI (à exécuter)
r = requests.get(f"{API}/v1/sgi/portfolio/orders?status=pending_routing", headers=headers)
for order in r.json()["orders"]:
    print(order["id"], order["direction"], order["quantity"])

# Confirmer l'exécution
r = requests.patch(f"{API}/v1/sgi/portfolio/orders/{order_id}/execute",
    headers=headers,
    json={"execution_ref": "EXEC-20260423-001",
          "gross_amount_fcfa": 1500000})
<?php
// Vérifier la signature HMAC d'un webhook reçu
$secret = getenv("INOPAY_HMAC_SECRET"); // depuis dashboard SGI
$body  = file_get_contents("php://input");
$sig   = $_SERVER["HTTP_X_INOPAY_SIGNATURE"] ?? "";

$expected = "sha256=" . hash_hmac("sha256", $body, $secret);

if (!hash_equals($expected, $sig)) {
    http_response_code(401);
    exit("invalid signature");
}

$event   = $_SERVER["HTTP_X_INOPAY_EVENT"]; // ex : kyc.validated
$payload = json_decode($body, true);

switch ($event) {
    case "consent.granted":  onConsentGranted($payload); break;
    case "kyc.validated":    onKycValidated($payload); break;
    case "order.routed":     onOrderRouted($payload); break;
}
http_response_code(200);
echo json_encode(["ok" => true]);
Webhooks

Événements poussés vers votre SGI

Inopay POST vers votre webhook_url. Signature HMAC-SHA256 dans X-Inopay-Signature. Retry backoff 30 s → 2 min → 10 min → 1 h → 6 h, 6 tentatives max.

consent.granted
Un investisseur vous a ajouté

Il vous autorise à voir son KYC et lui router des ordres. connection_id, user_id, consent_expires_at.

consent.revoked
Consentement révoqué

L'investisseur vous a retiré. Stoppez les sync et rapports. connection_id, user_id, reason.

kyc.validated
KYC Inopay validé

Attestation signée Ed25519 disponible. profile_id, level, valid_until.

attestation.revoked
Attestation révoquée

Le KYC n'est plus valide (fraude, expiration, demande user). profile_id, attestation_id, reason.

order.routed
Ordre investisseur

Un de vos clients a passé un ordre via Inopay — à exécuter sur BRVM/BVMAC/GSE. order_id, user_id, instrument_isin, quantity, direction, gross_amount_fcfa.

payment.confirmed
Paiement reçu (CinetPay/Paystack)

L'argent est arrivé sur votre compte marchand — l'ordre passe en pending_routing. order_id, payment_ref, amount_fcfa.

order.executed
Confirmation retour (vous → Inopay)

Déclenchée quand vous appelez PATCH /orders/:id/execute. Calcule la commission pilote ou standard. execution_ref, commission_fcfa.

test.ping
Test manuel depuis dashboard

Envoi à la demande pour vérifier votre receveur. Payload {test:true, message, requested_at}.

Principes techniques

Ce qui ne bouge jamais

OpenAPI 3.1 versionné

La spec /v1/ est gelée. Breaking changes → v2 avec 180 jours de préavis.

Webhooks HMAC-SHA256

Chaque événement signé avec votre secret. Header X-Inopay-Signature: sha256=… vérifiable en 3 lignes.

Ed25519 offline

Attestations KYC signées avec une clé Ed25519 publiée à /.well-known/inopay-kyc-pubkey.pem. Vérif sans appel réseau.

Idempotence

Header Idempotency-Key sur les mutations. Rejouer renvoie la première réponse.

Rate limiting

1 000 req/min par clé. Headers X-RateLimit-Remaining en temps réel.

Sandbox indistinguable

Mêmes endpoints, mêmes latences. Migration prod = changement de clé uniquement.

Ressources

Tout ce dont vous avez besoin

Prêt à intégrer Inopay ?

Clés sandbox self-service depuis votre dashboard SGI. La production s'active après signature de l'accord pilote.

Obtenir mes clés sandbox → Parler à l'équipe