T
T
TrolooPAY
Se Connecter S'inscrire
Documentation Développeur

API Paiement Direct (Headless) — TROLOOPAY

Collectez des paiements sans redirection ni page de paiement : un seul appel POST initie le paiement directement sur le mobile du payeur (USSD push). Vérifiez le statut par polling ou recevez une notification IPN signée. Aucune intégration frontend requise.

Base URL
https://troloo.com
Initier un paiement
POST /api/payment/direct
Déclenche un USSD push sur le téléphone
Vérifier le statut
GET /api/payment/direct/status/{transuuid}
Polling ou après IPN

Prérequis & sécurité

  • HTTPS obligatoire : toutes les requêtes doivent être faites en HTTPS.
  • Rate limiting : 10 requêtes par minute sur l'endpoint d'initiation, 30/min sur le statut.
  • JSON uniquement : envoyez Content-Type: application/json.
  • Credentials côté serveur : client_secret ne doit jamais transiter dans le code frontend (JS, mobile natif).
  • ipn_url : doit être HTTPS et pointer vers un hôte public — les IP privées (10.x, 192.168.x, 127.x) sont bloquées (protection SSRF).
  • Signature IPN : vérifiez systématiquement le header X-TrolooPay-Signature avec votre client_secret.
  • reference_id unique : chaque transaction doit avoir un identifiant unique pour garantir l'idempotence.
Bonnes pratiques
Stockez client_secret dans une variable d'environnement. Générez un reference_id unique côté serveur (UUID, hash de commande…). Vérifiez la signature IPN avant toute action sur votre base de données. Ne faites jamais confiance au statut retourné par le payeur — attendez toujours le statut serveur.

Credentials : client_id & client_secret

Pour appeler l'API Direct, vous avez besoin d'un couple client_id / client_secret associé à votre compte marchand TROLOOPAY.

  1. Créez un compte marchand sur troloo.com/register et complétez votre profil (informations de l'entreprise, logo, devise).
  2. Accédez à la page Credentials depuis votre tableau de bord (Dashboard → Marchand → Applications API).
  3. Créez une application : un couple client_id / client_secret est généré automatiquement.
  4. Attendez l'approbation par l'administrateur TROLOOPAY (état Approved) avant de commencer à collecter.
  5. Stockez le client_secret en sécurité — une fois généré, il ne s'affiche plus en clair. Utilisez une variable d'environnement côté serveur.
Rôle des credentials
Champ Type Usage
client_id Identifiant public Identifie votre application marchande. Peut être visible.
client_secret Secret confidentiel Authentifie chaque requête. Ne jamais exposer côté client.

1) Initier un paiement direct

Un seul appel POST déclenche le paiement directement sur le téléphone du payeur (USSD push). Aucune redirection ni page de paiement.

Endpoint
POST https://troloo.com/api/payment/direct
Content-Type: application/json
Paramètres (JSON body)
Paramètre Requis Description
client_id Oui Identifiant de votre application marchande
client_secret Oui Secret confidentiel (jamais côté client)
amount Oui Montant à collecter (numérique, min 1). Entier recommandé pour le mobile money.
currency Oui Code devise : XOF, USD, EUR…
method Oui Méthode de paiement : MTNMOMO ou MOOVMONEY
payer_phone Oui Numéro du payeur au format E.164 (ex : 2290154000000)
reference_id Oui Votre identifiant unique de transaction (UUID, ID commande…). Garantit l'idempotence.
ipn_url Non URL HTTPS de callback (recommandé) — reçoit l'IPN signé dès confirmation
description Non Message affiché au payeur (ex : nom du produit)
Réponse attendue (200 OK)
JSON response
{
  "code": 200,
  "transaction_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "reference_id": "ORDER-12345",
  "status": "PENDING",
  "method": "MTNMOMO",
  "message": "Payment request sent. Waiting for payer confirmation."
}

Conservez transaction_uuid pour interroger le statut ultérieurement. Le paiement est en attente de confirmation USSD par le payeur.

Flux complet (sans redirection)
1 Votre serveur envoie POST /api/payment/direct → reçoit transaction_uuid
2 TROLOOPAY envoie une demande USSD push directement sur le téléphone du payeur
3 Le payeur confirme (ou refuse) sur son téléphone via le menu USSD
4 TROLOOPAY poste l'IPN signé sur votre ipn_url ET met à jour le statut en base

2) Calcul des frais

Les frais dépendent du moyen de paiement (merchant_payment_fee, ex : 1.9% pour MTN Bénin) et du paramètre support_fee de votre compte marchand, qui détermine qui supporte les frais gateway. Pour le mobile money, les montants sont systématiquement arrondis au plafond (ceil).

support_fee Montant débité au payeur Frais portés par le marchand Crédité au wallet marchand
Yes amount (prix exact) ceil(amount × fee%) amount − ceil(fee)
No amount + ceil(amount × fee%) 0 (marchand reçoit le montant plein) amount
Shared amount + ceil(fee / 2) ceil(fee / 2) amount − ceil(fee/2)
Exemples concrets — MTN Bénin (fee = 1.9%)
amount support_fee gateway_fee payeur débité paid_amount (wallet)
100Yes1.9 → ceil=210098
105Yes1.995 → ceil=2105103
100No1.9 → ceil=2102100
100Shared1.9 → ½=0.95 → ceil=110199

La plateforme perçoit toujours la totalité du gateway_fee, quelle que soit la valeur de support_fee.

3) Vérifier le statut (polling)

Si votre ipn_url n'est pas disponible ou pour confirmer côté serveur, interrogez le statut par polling avec client_id et client_secret en query string.

Endpoint
GET https://troloo.com/api/payment/direct/status/{transaction_uuid}?client_id=…&client_secret=…
Réponses possibles
PENDING Le payeur n'a pas encore confirmé ou refusé. Relancez le polling dans quelques secondes.
SUCCESSFUL Paiement confirmé. Le champ paid_amount contient le montant net crédité au wallet marchand.
CANCELLED Paiement refusé, annulé ou expiré. paid_amount = 0.
Réponse statut — paiement confirmé
{
  "code": 200,
  "transaction_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "reference_id": "ORDER-12345",
  "status": "SUCCESSFUL",
  "method": "MTNMOMO",
  "currency": "XOF",
  "amount": 100,
  "paid_amount": 98,
  "created_at": "2026-05-28T18:23:24.000000Z"
}

IPN / Callback & signature

Si vous fournissez ipn_url, TROLOOPAY envoie un POST JSON signé sur cette URL dès que le paiement est confirmé ou échoué. C'est la méthode recommandée pour les intégrations serveur-à-serveur — plus fiable que le polling.

Payload IPN (POST JSON)
{
  "method":            "MTNMOMO",
  "status":            "SUCCESSFUL",
  "transuuid":         "550e8400-e29b-41d4-a716-446655440000",
  "reference_id":      "ORDER-12345",
  "gateway_reference": "uuid-interne-gateway",
  "currency":          "XOF",
  "amount":            100,
  "paid_amount":       98
}
Champ Description
methodMéthode utilisée : MTNMOMO, MOOVMONEY
statusSUCCESSFUL ou FAILED
transuuidUUID de la transaction (retourné à l'initiation)
reference_idVotre identifiant de transaction transmis à l'initiation
amountMontant de la transaction (tel qu'envoyé lors de l'initiation)
paid_amountMontant net crédité au wallet marchand (après frais). 0 en cas d'échec.
Signature IPN (HMAC-SHA256)

Chaque IPN est signé avec votre client_secret. La signature est transmise dans le header X-TrolooPay-Signature: sha256=<hash>.

PHP — vérifier la signature IPN
<?php
$clientSecret = getenv('TROLOOPAY_CLIENT_SECRET');
$rawBody      = file_get_contents('php://input');
$signature    = $_SERVER['HTTP_X_TROLOOPAY_SIGNATURE'] ?? '';

// Extraire le hash (format "sha256=<hash>")
$receivedHash = str_starts_with($signature, 'sha256=') ? substr($signature, 7) : $signature;
$expectedHash = hash_hmac('sha256', json_encode(json_decode($rawBody, true)), $clientSecret);

if (!hash_equals($expectedHash, $receivedHash)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Signature valide — traiter le paiement
$payload = json_decode($rawBody, true);

if ($payload['status'] === 'SUCCESSFUL') {
    $uuid      = $payload['transuuid'];
    $refId     = $payload['reference_id'];
    $paidAmount = $payload['paid_amount'];
    // Mettre à jour votre base de données...
}

http_response_code(200);
echo json_encode(['received' => true]);

Votre ipn_url doit répondre avec un code 2xx pour accuser réception. Ne jamais délivrer une commande sans avoir vérifié la signature.

Idempotence (reference_id)

Le champ reference_id garantit qu'une même transaction n'est jamais initiée deux fois. Si vous soumettez la même valeur avec le même client_id, l'API retourne un 409 Conflict avec l'UUID et le statut de la transaction existante — aucun nouveau débit n'est effectué.

409 Conflict — doublon détecté
{
  "code": 409,
  "message": "Conflict: reference_id already used for this application.",
  "transaction_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "SUCCESS"
}
Bonne pratique : générez le reference_id à partir de l'ID unique de votre commande (ex : ORDER-{id}-{timestamp} ou un UUID v4). Ne réutilisez jamais la même valeur pour deux transactions différentes.

Méthodes de paiement supportées

L'API Direct supporte les paiements mobile money avec déclenchement USSD push. Le pays est détecté automatiquement à partir du préfixe E.164 du numéro.

Valeur method Réseau Pays détectés (préfixe) Fee gateway
MTNMOMO MTN Mobile Money 229 (Bénin), 233 (Ghana), 256 (Uganda), 225 (CI), 237 (Cameroun), 250 (Rwanda)… 1.9%
MOOVMONEY Moov Money 229 (Bénin) 1.9%
Le numéro payer_phone doit être au format E.164 complet (avec indicatif pays, sans +). Exemple : 2290154000000 pour un numéro MTN Bénin.

Erreurs & codes

HTTP Code Message type Cause fréquente
400 400 Validation error Champ requis manquant, amount < 1, devise inactive, méthode inconnue
400 400 SSRF protection ipn_url non HTTPS ou IP privée (10.x, 192.168.x, 127.x)
401 401 Invalid credentials client_id ou client_secret incorrect
403 403 Account not approved Compte marchand en attente, suspendu ou inactif
409 409 Conflict: reference_id reference_id déjà utilisé pour cette application (idempotence)
422 422 Gateway rejected Numéro non supporté par MTN/Moov, montant hors limites gateway
429 429 Too Many Requests Rate limiting : 10 req/min sur /charge, 30 req/min sur /status
502 502 Gateway unavailable La gateway mobile money est temporairement indisponible
500 500 Internal error Erreur serveur interne — contacter le support TROLOOPAY

Exemples d'intégration

Exemples prêts à copier/coller. Choisissez votre langage.

cURL — initier + vérifier le statut
# 1) Initier le paiement
curl -s -X POST https://troloo.com/api/payment/direct \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "client_id":     "VOTRE_CLIENT_ID",
    "client_secret": "VOTRE_CLIENT_SECRET",
    "amount":        5000,
    "currency":      "XOF",
    "method":        "MTNMOMO",
    "payer_phone":   "2290154000000",
    "reference_id":  "ORDER-12345",
    "ipn_url":       "https://votre-site.com/webhook/payment",
    "description":   "Commande #12345"
  }'

# Réponse :
# { "code": 200, "transaction_uuid": "550e8400-...", "status": "PENDING", ... }

# 2) Vérifier le statut (polling)
curl -s "https://troloo.com/api/payment/direct/status/550e8400-e29b-41d4-a716-446655440000\
?client_id=VOTRE_CLIENT_ID&client_secret=VOTRE_CLIENT_SECRET"