Documentation API

Intégrez ItoPay comme moyen de paiement sur votre site. Les fonds transitent par papi.mg, votre wallet est crédité, puis un webhook signé vous est envoyé.

1. Introduction

ItoPay est un agrégateur de paiement pour Madagascar. Vous créez un paiement via l’API, le client paie sur papi.mg (MVola, Orange Money, Airtel Money, carte), puis :

  1. Les fonds arrivent sur le compte PAPI d’ItoPay
  2. Le wallet du marchand est crédité
  3. Votre serveur reçoit un webhook signé avec la confirmation

Base URL : http://141.95.19.108:2493

Référence unique : chaque paiement a une référence du type ITP-20260925-A1B2C3D4 — la même côté ItoPay et PAPI pour le rapprochement.

2. Authentification

Toutes les routes /api/v1/* exigent le header :

Authorization: Bearer itopay_live_xxxxxxxx
Content-Type: application/json

Récupérez vos clés dans le dashboard → Clés API après connexion.

3. Créer un paiement

POST /api/v1/payments

Corps JSON

ChampTypeObligatoireDescription
amountnumberOuiMontant en MGA (min. 100)
merchant_referencestringNonVotre référence commande / facture
descriptionstringNonLibellé affiché
customer_namestringNonNom du client
customer_emailstringNonE-mail du client
customer_phonestringNonTéléphone (ex. +26134…)
success_urlstringNonRedirection après succès
failure_urlstringNonRedirection après échec
providerstringNonMVOLA, ORANGE, AIRTEL… (optionnel)
metadataobjectNonDonnées libres (JSON)

Exemple cURL

curl -X POST http://141.95.19.108:2493/api/v1/payments \
  -H "Authorization: Bearer itopay_test_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "merchant_reference": "CMD-42",
    "description": "Commande #42",
    "customer_name": "Jean Rakoto",
    "customer_email": "jean@exemple.mg",
    "customer_phone": "+261340000000",
    "success_url": "https://monsite.mg/paiement/ok",
    "failure_url": "https://monsite.mg/paiement/ko"
  }'

Réponse 201

{
  "success": true,
  "message": "Paiement créé",
  "data": {
    "invoice_uuid": "a1b2c3d4-...",
    "reference": "ITP-20260925-A1B2C3D4",
    "merchant_reference": "CMD-42",
    "amount": 15000,
    "currency": "MGA",
    "status": "processing",
    "payment_url": "https://pay.papi.mg/payment/...",
    "expires_at": "2026-09-25T13:00:00+03:00"
  }
}

Redirigez le client vers payment_url pour qu’il paie sur papi.mg.

4. Statut d'une facture

GET /api/v1/payments/{invoice_uuid}

curl http://141.95.19.108:2493/api/v1/payments/a1b2c3d4-... \
  -H "Authorization: Bearer itopay_live_VOTRE_CLE"

Statuts possibles : pending, processing, paid, failed, expired, cancelled, refunded.

5. Webhooks (notifications)

Configurez votre URL de webhook dans Dashboard → Paramètres. Lorsqu’un paiement est confirmé, ItoPay envoie un POST JSON :

POST https://monsite.mg/webhook/itopay
Content-Type: application/json
X-ItoPay-Signature: <hmac-sha256>
X-ItoPay-Event: invoice.paid
User-Agent: ItoPay-Webhook/2.0

{
  "event": "invoice.paid",
  "invoice_uuid": "a1b2c3d4-...",
  "reference": "ITP-20260925-A1B2C3D4",
  "merchant_reference": "CMD-42",
  "amount": 15000,
  "currency": "MGA",
  "status": "paid",
  "paid_at": "2026-09-25T12:05:00+03:00",
  "customer": {
    "name": "Jean Rakoto",
    "email": "jean@exemple.mg",
    "phone": "+261340000000"
  },
  "papi_provider": "MVOLA"
}

Répondez avec un statut HTTP 2xx. En cas d’échec, ItoPay réessaie automatiquement (jusqu’à 5 tentatives avec délai progressif).

6. Vérifier la signature

Utilisez le secret webhook (dashboard → Clés API) pour vérifier que la requête vient bien d’ItoPay.

PHP

$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_ITOPAY_SIGNATURE'] ?? '';
$secret    = 'votre_webhook_secret';

$expected = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Signature invalide');
}

$data = json_decode($payload, true);
// Traiter $data['reference'], $data['amount'], etc.
http_response_code(200);
echo 'OK';

Node.js

const crypto = require('crypto');

function verify(req, secret) {
  const signature = req.headers['x-itopay-signature'];
  const expected = crypto
    .createHmac('sha256', secret)
    .update(req.rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature || '')
  );
}

7. Flux complet

1. Votre site        →  POST /api/v1/payments  (Bearer key)
2. ItoPay            →  crée invoice + référence ITP-...
3. ItoPay            →  appelle papi.mg (même référence)
4. ItoPay            →  renvoie payment_url
5. Client            →  paie sur papi.mg
6. PAPI              →  POST /webhooks/papi  (ItoPay)
7. ItoPay            →  crédite le wallet marchand
8. ItoPay            →  POST votre webhook_url  (X-ItoPay-Signature)
9. Votre site        →  marque la commande comme payée

8. Codes d'erreur

HTTPSignification
200 / 201Succès
401Clé API manquante ou invalide
404Ressource introuvable
422Données invalides (montant, champs…)
502Erreur côté PAPI ou service externe
500Erreur interne ItoPay
{
  "success": false,
  "message": "Le champ amount est obligatoire"
}

9. Mode test (sandbox)

Passez en production en utilisant itopay_live_… et en configurant votre clé PAPI réelle dans le .env serveur d’ItoPay.

Besoin d’aide ? Connectez-vous au dashboard pour vos clés, ou contactez le support ItoPay.