Référence

Documentation API

Intégrez GnakryPay dans votre application (REST, clé API en Bearer). Cette page est publique : vous pouvez la partager à votre développeur sans qu'il ait de compte.

Langage des exemples :
Racine de l'API : https://api.gnakrypay.com/v1

1Authentification

Chaque requête porte votre clé API dans l'en-tête Authorization, sous la forme Bearer sk_live_…. Une clé sk_test_ encaisse par le simulateur et crédite votre portefeuille de test ; une clé sk_live_engage de l'argent réel.

Nous ne conservons de votre clé qu'une empreinte : elle n'est affichée qu'une seule fois, à sa création, et nous ne pouvons pas vous la redonner. Créer une nouvelle clé ne révoque pas les anciennes — vous pouvez donc les faire tourner sans coupure.

Où trouver mes clés ? Paramètres > Développeurs. L'encaissement par l'API exige un KYC validé ; la création d'une clé, non — vous pouvez préparer votre intégration pendant l'instruction de votre dossier.

2Consulter votre solde

GET /v1/balance

availableest le seul chiffre sur lequel vous pouvez vous engager : le solde moins ce qu'immobilisent les reversements en cours. balance inclut ces fonds réservés.

Tous les montants sont des entiers de GNF sérialisés en chaînes: le GNF n'a pas de subdivision, et un grand entier passé en nombre JavaScript perdrait de la précision.

Le solde renvoyé est celui du portefeuille de votre clé : une clé sk_test_ lit le portefeuille de test, une clé sk_live_l'argent réel. Les deux ne se mélangent jamais.

3Créer un encaissement

POST /v1/payments
L'en-tête Idempotency-Key est obligatoire. Sans elle, l'appel est refusé avec le code IDEMPOTENCY_KEY_REQUIRED. Utilisez une valeur unique par tentative de paiement, et rejouez la même si vous devez réessayer : la réponse d'origine vous est alors renvoyée au lieu de débiter deux fois votre client.
ChampTypeRequisDescription
amountEntier ou chaîneOuiMontant en GNF entiers, sans décimale. Les bornes dépendent de votre grille et du canal : hors bornes, l'appel est refusé (INVALID_AMOUNT) avec le minimum ou le maximum applicable.
currencyChaîneOuiDoit valoir exactement "GNF".
operatorÉnumérationOuiORANGE_GN, MTN_GN, PAYCARD_GN, KULU_GN, SOUTRA_GN, WAVE_GN, VISA, MASTERCARD, CRYPTO. Seuls les canaux ouverts sur votre compte aboutissent.
phoneChaîneOuiNuméro du payeur, de 8 à 20 caractères.
referenceChaîneOuiVotre référence, unique chez vous (100 caractères max). Un doublon est refusé (DUPLICATE_REFERENCE).
descriptionChaîneNonMotif de l'achat (500 caractères max).
emailChaîneNonCourriel du payeur, pour le reçu.
callback_urlURLNonConservée avec le paiement, pour votre propre réconciliation. Les notifications ne partent pas vers cette adresse : déclarez un récepteur de webhook (section 5).

La réponse revient avec payment_status à PENDING : le client doit encore valider sur son téléphone. Ne livrez rien à ce stade — attendez le webhook payment.success, ou interrogez le paiement. Sans confirmation, il expire au bout de 15 minutes.

4Consulter un paiement

GET /v1/payments/{payment_id}

Source de vérité sur l'état d'un paiement, à interroger si vous avez manqué un webhook. L'identifiant est celui renvoyé à la création, de la forme GNK-PAY-K7M2P9XQR.

Statuts possibles : PENDING, PROCESSING, SUCCESS, FAILED, EXPIRED, REFUNDED, PARTIALLY_REFUNDED.

5Webhooks et vérification de signature

Déclarez votre récepteur dans Paramètres > Développeurs. L'adresse doit être en HTTPS — un webhook transporte des données de paiement. Le secret de signature (whsec_…) y est affiché une seule fois, à la déclaration : il est chiffré au repos et ne peut plus être relu.

À chaque changement d'état, nous envoyons une requête POST en JSON vers les récepteurs abonnés à l'événement, avec trois en-têtes :

En-têteContenu
X-GnakryPay-SignatureHMAC-SHA256 du corps brut, préfixé : sha256=<hexadécimal>. Le préfixe fait partie de la valeur à comparer.
X-GnakryPay-EventNom de l'événement, par exemple payment.success.
X-GnakryPay-Delivery-AttemptNuméro de tentative, à partir de 1.

La signature se calcule avec votre secret sur le corps brutde la requête, tel qu'il est arrivé. Analyser le JSON puis le re-sérialiser produit une autre chaîne, donc une autre signature : c'est la cause habituelle d'une vérification qui échoue alors que le secret est bon.

Répondez 2xxen moins de 10 secondes. Au-delà, ou sur une autre réponse, la livraison est réessayée jusqu'à 6 fois avec un délai croissant : le même événement peut donc vous parvenir plusieurs fois, et votre traitement doit être idempotent sur payment_id. Après 20 échecs consécutifs, le récepteur est désactivé et vous devez le réactiver depuis votre espace.

Le journal des livraisons — code de réponse, durée, numéro de tentative, prochaine échéance de réessai — est consultable dans Paramètres > Développeurs. Il répond à « pourquoi n'ai-je pas reçu ce webhook ? » avec des faits.

Événements disponibles
payment.successpayment.failedpayment.expiredrefund.successrefund.failedpayout.paidpayout.failed
Corps d'un événement de paiement
{
  "payment_id": "GNK-PAY-K7M2P9XQR",
  "reference": "CMD-2026-00042",
  "amount": "25000",
  "fee": "475",
  "net_amount": "24525",
  "currency": "GNF",
  "channel": "ORANGE_MONEY",
  "aggregator": "NOTCHPAY",
  "phone": "621000000",
  "payment_status": "SUCCESS",
  "timestamp": "2026-10-29T18:00:00.000Z"
}

L'état se lit dans payment_status. Un événement de remboursement porte en plus refund_id.

6Erreurs

Toute erreur revient sous la même enveloppe : un code stable à tester dans votre code, un messageen français destiné à l'affichage, et un requestId à nous communiquer en cas de litige.

{
  "status": 400,
  "code": "IDEMPOTENCY_KEY_REQUIRED",
  "message": "L'en-tête Idempotency-Key est obligatoire sur la création de paiement.",
  "requestId": "01JB2P9XQR7K8M"
}
1. Authentification & solde
curl https://api.gnakrypay.com/v1/balance \
  -H "Authorization: Bearer sk_live_votre_cle_secrete"
2. Créer un encaissement
curl -X POST https://api.gnakrypay.com/v1/payments \
  -H "Authorization: Bearer sk_live_votre_cle_secrete" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount": 25000,
    "currency": "GNF",
    "operator": "ORANGE_GN",
    "phone": "621000000",
    "reference": "CMD-2026-00042",
    "description": "Achat panier 9876"
  }'
3. Consulter un paiement
curl https://api.gnakrypay.com/v1/payments/GNK-PAY-K7M2P9XQR \
  -H "Authorization: Bearer sk_live_votre_cle_secrete"
4. Vérifier une signature de webhook
# Vérification d'une signature déjà reçue, depuis un shell.
# CORPS = corps brut de la requête, exactement tel qu'il est arrivé.
SECRET="whsec_votre_secret_de_webhook"
RECUE="sha256=..."   # en-tête X-GnakryPay-Signature

ATTENDUE="sha256=$(printf '%s' "$CORPS" \
  | openssl dgst -sha256 -hmac "$SECRET" -hex \
  | awk '{ print $NF }')"

if [ "$RECUE" = "$ATTENDUE" ]; then
  echo "Signature valide"
else
  echo "Signature invalide : rejetez la requête"
fi