Quickstart

Acceptez votre premier paiement Mobile Money en quelques minutes. Toutes les requêtes se font sur :

Base URL
https://api.goropay.com/v1

Montants en unité mineure entière (le franc CFA n’a pas de décimale : 15000 = 15 000 F). Réponses en JSON, snake_case.

Authentification

Chaque requête porte votre clé secrète dans l’en-tête Authorization. Les clés sk_test_ ciblent le bac à sable (simulateurs, argent fictif) ; les clés sk_live_ le mode réel.

En-tête d’authentification
Authorization: Bearer sk_test_...

Créez votre compte et récupérez votre clé de test depuis le dashboard. Une clé de test ne peut jamais toucher d’argent réel.

Créer un paiement

Un POST /v1/payments avec une clé d’idempotence. Choisissez votre langage — l’API REST se consomme partout (les SDK officiels arrivent). Le simulateur répond selon le dernier chiffre du numéro (voir numéros de test).

curl https://api.goropay.com/v1/payments \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: cmd_84921" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "XOF",
    "payment_method": {
      "type": "mobile_money",
      "operator": "mtn",
      "phone": "+2290197000001"
    }
  }'
Réponse 201
{
  "id": "pay_1a2b3c...",
  "object": "payment",
  "status": "succeeded",
  "amount": 15000,
  "currency": "XOF",
  "psp": "momo_sim",
  "created_at": "2026-07-19T10:00:00Z"
}

Si le paiement demande une action (push USSD), le statut est requires_action avec un champ next_action. Consultez toujours l’état réel via GET /v1/payments/:id.

Statuts d’un paiement

La machine à états est stricte — aucune transition hors du graphe autorisé.

pendingCréé, pas encore traité
requires_actionLe payeur doit valider (push USSD)
processingEn cours chez l’opérateur
succeededEncaissé — écriture au ledger
failedRefusé
refundedRemboursé (total ou partiel)

Numéros de test (sandbox)

En mode test, le dernier chiffre du numéro force un scénario déterministe :

…0succeeded — paiement réussi
…1failed — refusé
…2requires_action — push USSD à valider
…9processing — résolu ensuite par callback

Idempotence

Toute création de paiement porte un en-tête Idempotency-Key. Rejouer la même clé avec le même corps renvoie la réponse d’origine — jamais un second débit. Même clé + corps différent → 409. C’est ce qui rend les retries réseau sûrs.

Rejeu sûr
# 2e appel identique → même paiement, pas de double débit
Idempotency-Key: cmd_84921

Webhooks

GoroPay notifie votre serveur des événements (payment.succeeded, payment.failed, refund.succeeded…). Chaque livraison est signée en HMAC-SHA256 dans l’en-tête Goropay-Signature, avec retries pendant 72 h.

Vérifier la signature (Node.js)
import { createHmac } from "crypto";

function verify(payload, header, secret) {
  const [t, v1] = header.split(",").map(p => p.split("=")[1]);
  const expected = createHmac("sha256", secret)
    .update(t + "." + payload).digest("hex");
  return expected === v1; // + vérifier que t est récent
}

Traitez les webhooks de façon idempotente via Goropay-Event-Id : la livraison est at-least-once.

Remboursements

Total ou partiel, lié à un paiement. La commission GoroPay n’est pas restituée.

Remboursement partiel
curl https://api.goropay.com/v1/refunds \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: ref_1 " \
  -d '{"payment":"pay_1a2b3c...","amount":5000}'

SDK & support

Les SDK serveur (Node.js, PHP, Python) arrivent — ils gèreront l’idempotence et la vérification de signature pour vous. En attendant, l’API REST se consomme depuis n’importe quel langage.

Une question ? support@goropay.com.