Payroon
ENFR Se connecter Commencer Application
Documentation développeur

Acceptez Payroon en quelques minutes

Une API simple : vous créez un paiement, le client paie sur la page Payroon, vous recevez un webhook signé. Exemples en 8 langages.

Ouvrir l’espace marchand Payroon Merchant

1Démarrage rapide

Créez votre espaceOuvrez l’espace marchand avec votre compte Payroon. Vos clés de test sont créées tout de suite.
Créez un paiementAppelez l’API depuis votre serveur avec votre clé secrète.
Envoyez le clientRedirigez-le vers checkout_url. Il paie avec son PIN.
Livrez la commandeVotre serveur reçoit payment.succeeded : confirmez la commande.

2Authentification

Envoyez votre clé secrète dans l’en-tête Authorization. Les clés de test commencent par sk_test_ et ne déplacent jamais d’argent. Les clés réelles commencent par sk_live_ et s’activent après approbation de votre activité. Ne mettez jamais une clé secrète dans une application mobile ou une page web : elle reste sur votre serveur.

Authorization: Bearer sk_test_a1b2c3...   (test key)
Authorization: Bearer sk_live_d4e5f6...   (live key)
Une clé secrète n’est affichée qu’une seule fois, à sa création. Si vous la perdez, remplacez-la depuis l’espace marchand (PIN requis) : l’ancienne cesse de fonctionner.

3Créer un paiement

Le montant est en unités entières de la devise de votre compte marchand (par exemple 5000 pour 5 000 XAF). Ajoutez un en-tête Idempotency-Key : si votre requête est répétée, vous obtenez le même paiement, jamais un doublon.

curl https://payroon.com/api/gateway.php?action=create_payment \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Idempotency-Key: order-1042-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{"amount": 5000, "reference": "order-1042", "description": "2 x T-shirt",
       "return_url": "https://yourshop.com/thanks", "cancel_url": "https://yourshop.com/cart"}'

Réponse

{ "success": true, "data": {
    "id": "pay_9f2c1a7e5b3d4c6a8e0f1b2d", "object": "payment", "mode": "test", "status": "pending",
    "amount": 5000, "currency": "XAF", "reference": "order-1042",
    "checkout_url": "https://payroon.com/pay?id=pay_9f2c1a7e5b3d4c6a8e0f1b2d",
    "expires_at": "2026-11-01T10:30:00+00:00", "paid_at": null } }

4Page de paiement et retour

Redirigez votre client vers checkout_url. Après le paiement il revient sur votre return_url avec ?payroon_payment=pay_… ajouté. Le client choisit sur cette page : Payroon (portefeuille), MTN MoMo ou Orange Money (sans compte Payroon). Les paiements MTN et Orange arrivent dans votre solde marchand. Des frais par moyen de paiement s’appliquent ; vous choisissez dans vos réglages (ou par paiement avec fee_payer) si c’est le client ou vous qui les payez. Vous pouvez retirer vers MTN ou Orange directement depuis votre solde marchand, gratuitement. Ne livrez jamais une commande sur la seule foi de cette redirection : attendez le webhook ou interrogez get_payment, car un client peut fermer la page avant de revenir.

5Webhooks

Enregistrez l’URL https de votre webhook dans l’espace marchand. Payroon y envoie un POST JSON à chaque événement. Répondez avec un code 2xx. Sinon, nous réessayons automatiquement : après 1 min, 5 min, 30 min, 2 h, 6 h puis 24 h. Vous pouvez aussi renvoyer un événement à la main depuis l’espace marchand.

Événements

payment.createdUn paiement vient d’être créé.
payment.succeededLe client a payé : livrez la commande.
payment.expiredLe lien a expiré sans paiement.
payment.cancelledLe paiement a été annulé.

Exemple d’événement

{ "id": "evt_4a1b...", "object": "event", "type": "payment.succeeded", "created": 1793000000, "mode": "live",
  "data": { "payment": { "id": "pay_9f2c...", "status": "paid", "amount": 5000, "currency": "XAF", "reference": "order-1042", "paid_at": "2026-11-01T10:12:09+00:00" } } }

6Vérifier la signature

Chaque requête contient l’en-tête Payroon-Signature : t=<horodatage>,v1=<signature>. Calculez HMAC-SHA256 de « t.corps » avec votre secret de webhook (whsec_…), comparez en temps constant et refusez les horodatages de plus de 5 minutes. Utilisez le corps brut, pas un JSON ré-encodé.

$body = file_get_contents('php://input');
preg_match('/t=(\d+),v1=([a-f0-9]+)/', $_SERVER['HTTP_PAYROON_SIGNATURE'] ?? '', $m);
$ok = $m && abs(time() - (int)$m[1]) < 300
   && hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, getenv('PAYROON_WEBHOOK_SECRET')), $m[2]);
if (!$ok) { http_response_code(400); exit; }
$event = json_decode($body, true);
if ($event['type'] === 'payment.succeeded') { /* fulfil order $event['data']['payment']['reference'] once */ }
http_response_code(200);
Votre handler doit être idempotent : un même événement (même id) peut arriver plus d’une fois.

7Référence de l’API

Toutes les routes sont sous /api/gateway.php?action=… et utilisent la même clé.

POST/api/gateway.php?action=create_payment

Crée un paiement et renvoie le lien de paiement.

ParamètreTypeRequisDescription
amountnumberouiMontant en unités entières de votre devise.
currencystringnonDoit être la devise de votre compte (facultatif).
referencestringnonVotre numéro de commande (100 caractères max).
descriptionstringnonTexte affiché au client.
customer_emailstringnonAdresse email du client (facultatif).
return_urlstringnonAdresse https vers laquelle revenir après paiement.
cancel_urlstringnonAdresse https si le client annule.
metadataobjectnonJusqu’à 20 clés, 1000 caractères : vous les retrouvez dans les webhooks.
expires_inintegernonDurée de vie du lien en minutes (5 à la limite fixée par Payroon).
fee_payerstringnon« customer » : le client paie le prix + les frais ; « merchant » : les frais sont prélevés sur votre vente. Par défaut : le réglage de votre compte.
GET/api/gateway.php?action=get_payment&id=pay_…

Retourne un paiement.

ParamètreTypeRequisDescription
idstringouiIdentifiant du paiement (pay_…).
GET/api/gateway.php?action=list_payments

Liste vos paiements (mode de votre clé).

ParamètreTypeRequisDescription
limitintegernonNombre de résultats, 1 à 100.
statusstringnonpending, paid, expired ou cancelled.
referencestringnonVotre numéro de commande (100 caractères max).
POST/api/gateway.php?action=cancel_payment

Annule un paiement encore en attente.

ParamètreTypeRequisDescription
idstringouiIdentifiant du paiement (pay_…).
GET/api/gateway.php?action=ping

Vérifie votre clé et renvoie votre profil.

8Erreurs

Les erreurs ont toujours la même forme et un code HTTP adapté.

{ "success": false, "error": { "code": "invalid_amount", "message": "amount must be a number, in whole currency units." } }
401Clé manquante, incorrecte ou remplacée.
403Compte marchand non approuvé (clé réelle) ou suspendu.
404Paiement introuvable pour cette clé.
409Action impossible dans l’état actuel du paiement.
422Données invalides : lisez le champ message.
429Trop de requêtes : ralentissez.

9Mode test et mode réel

Avec une clé de test, la page de paiement propose « Simuler un paiement réussi » et « Simuler un paiement annulé ». Aucun argent ne bouge et vos webhooks portent mode=test. Basculez entre Test et Réel à tout moment dans l’espace marchand. Les paiements réels arrivent dans votre solde marchand : vous les passez ensuite gratuitement vers votre solde principal.

Besoin d’un autre langage ? L’API est du JSON sur HTTPS : n’importe quelle bibliothèque HTTP fonctionne.