Documentation

Intégrez LeekPay sur votre site

Démarrage

Obtenez vos clés API

  1. Créez un compte sur leekpay.me
  2. Allez dans Dashboard → Clés API
  3. Cliquez sur Nouvelle clé API
  4. Copiez votre pk_live_xxx (publique) et sk_live_xxx (secrète)

Ne partagez jamais votre clé secrète. Utilisez-la uniquement côté serveur.

Widget HTML

Intégrez un bouton de paiement sur votre site en quelques lignes de code HTML. Aucune configuration serveur nécessaire.

Étape 1 : Ajouter le script et le bouton

<!-- Charger le script LeekPay -->
<script src="https://leekpay.fr/js/leekpay.js"></script>

<!-- Bouton de paiement -->
<button 
  data-leekpay-amount="5000" 
  data-leekpay-currency="XOF"
  data-leekpay-key="pk_live_votre_cle_publique"
  data-leekpay-description="Commande #123">
  Payer 5 000 CFA
</button>

Étape 2 : Gérer le résultat (optionnel)

Ajoutez des callbacks pour réagir après le paiement :

<script>
LeekPay.configure({
  onSuccess: function(data) {
    console.log('Paiement réussi !');
    console.log('Montant:', data.amount, data.currency);
    window.location.href = '/merci';
  },
  onCancel: function() {
    console.log('Paiement annulé');
  }
});
</script>
AttributDescription
data-leekpay-keyVotre clé publique pk_live_xxx (requis)
data-leekpay-amountMontant à payer (requis)
data-leekpay-currencyDevise : XOF, EUR, USD (requis)
data-leekpay-descriptionDescription affichée au client
data-leekpay-emailEmail pré-rempli du client

JavaScript

Lancez le paiement depuis votre code JavaScript :

<!-- 1. Charger le script -->
<script src="https://leekpay.fr/js/leekpay.js"></script>

<!-- 2. Bouton de paiement -->
<button onclick="payer()">Payer maintenant</button>

<script>
function payer() {
  LeekPay.checkout({
    amount: 5000,
    currency: 'XOF',
    apiKey: 'pk_live_votre_cle_publique',
    description: 'Commande #123',
    
    onSuccess: function(data) {
      console.log('Paiement réussi:', data.amount, data.currency);
      window.location.href = '/merci';
    },
    onCancel: function() {
      console.log('Paiement annulé');
    }
  });
}
</script>

Données reçues dans onSuccess

data.statusdata.amountdata.currencydata.payment_id
OptionDescription
amountMontant à payer (requis)
currencyDevise : XOF, EUR, USD (requis)
apiKeyVotre clé publique pk_live_xxx (requis)
descriptionDescription affichée au client
customerEmailEmail pré-rempli du client
onSuccessFonction appelée après paiement réussi
onCancelFonction appelée si annulation

API REST

Utilisez l'API REST pour créer des paiements depuis votre serveur. Authentifiez-vous avec votre clé secrète (sk_live_xxx).

Créer un checkout

POST /api/v1/checkoutAuthentification : Bearer Token (clé secrète)

# Requête
curl -X POST https://leekpay.fr/api/v1/checkout \
  -H "Authorization: Bearer sk_live_votre_cle_secrete" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "XOF",
    "description": "Commande #123",
    "return_url": "https://votresite.com/merci",
    "customer_email": "client@example.com"
  }'
# Réponse (HTTP 201)
{
  "success": true,
  "data": {
    "id": "checkout_42",
    "payment_url": "https://leekpay.me/pay_AbCdEf1234567890",
    "amount": 5000,
    "currency": "XOF",
    "status": "pending",
    "expires_at": "2026-05-20T12:00:00+00:00",
    "return_url": "https://votresite.com/merci"
  }
}

Vérifier le statut

GET /api/v1/checkout/{id}

curl https://leekpay.fr/api/v1/checkout/checkout_42 \
  -H "Authorization: Bearer sk_live_votre_cle_secrete"
ParamètreTypeDescription
amountnumberMontant à payer dans l'unité de la devise — ex. 5000 = 5 000 XOF (requis)
currencystringXOF, EUR ou USD (requis)
descriptionstringDescription de la commande (max 500 caractères)
return_urlstringURL de redirection après paiement réussi
cancel_urlstringURL de redirection si le client annule
webhook_urlstringWebhook propre à cette session (prioritaire sur celui de la clé API)
customer_emailstringEmail du client (pré-rempli sur la page)
customer_namestringNom complet du client
customer_phonestringNuméro de téléphone du client
metadataobjectDonnées libres renvoyées dans le webhook (ex. n° commande)

Champs de la réponse

ChampTypeDescription
idstringIdentifiant unique du checkout (préfixé checkout_)
payment_urlstringURL de la page de paiement à afficher au client
amountnumberMontant du paiement
currencystringDevise du paiement
statusstringStatut du paiement (voir Statuts)
expires_atstring (ISO 8601)Date d'expiration du lien (24h après création)
return_urlstringURL de redirection fournie à la création (peut être null)

Webhooks

Recevez une notification sur votre serveur quand un paiement est effectué. Configurez l'URL de votre endpoint dans Dashboard → Clés API.

Format de la notification

LeekPay envoie une requête POST à votre URL avec les données du paiement :

# Requête envoyée par LeekPay à votre serveur

POST https://votresite.com/webhook
Content-Type: application/json
X-LeekPay-Event: payment.completed
X-LeekPay-Delivery: 12345
X-LeekPay-Signature: 5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a...

{
  "event": "payment.completed",
  "data": {
    "transaction_id": "TXN_ABC123XYZ",
    "checkout_id": "TXN_ABC123XYZ",
    "amount": 5000,
    "currency": "XOF",
    "status": "paid",
    "payment_method": "mobile_money",
    "customer": {
      "email": "client@example.com",
      "name": "Jean Dupont",
      "phone": "+22990123456"
    },
    "metadata": null,
    "paid_at": "2026-01-15T10:30:00+00:00"
  }
}

Vérifier la signature (sécurité)

La signature X-LeekPay-Signature est envoyée dans les headers HTTP. Utilisez votre clé publique pour la vérifier.

<?php
// Exemple PHP : vérification de la signature webhook

// 1. Récupérer la signature envoyée par LeekPay
$signature = $_SERVER['HTTP_X_LEEKPAY_SIGNATURE'];

// 2. Récupérer le corps de la requête (payload JSON)
$payload = file_get_contents('php://input');

// 3. Calculer la signature attendue avec votre clé publique
$expected = hash_hmac('sha256', $payload, 'pk_live_votre_cle_publique');

// 4. Comparer les signatures de manière sécurisée
if (hash_equals($expected, $signature)) {
    // Signature valide : traiter le paiement
    $data = json_decode($payload, true);
    $transactionId = $data['data']['transaction_id'];
    $amount = $data['data']['amount'];
    $status = $data['data']['status']; // "paid", "failed", ...

    // Mettre à jour votre base de données...
    
    http_response_code(200);
    echo 'OK';
} else {
    // Signature invalide : rejeter la requête
    http_response_code(401);
    echo 'Invalid signature';
}
ChampTypeDescription
eventstringType d'événement (ex. payment.completed)
data.transaction_idstringRéférence unique de la transaction
data.checkout_idstringRéférence du checkout associé
data.amountnumberMontant payé
data.currencystringDevise (XOF, EUR, USD)
data.statusstringStatut du paiement (voir Statuts)
data.payment_methodstringMéthode utilisée (mobile_money, card, ...)
data.customer.emailstringEmail du client
data.customer.namestringNom complet du client
data.customer.phonestringNuméro de téléphone du client
data.metadataobject | nullMétadonnées fournies à la création du checkout
data.paid_atstring (ISO 8601)Date du paiement

Confirmer un paiement

Ne créditez jamais une commande sur la seule base du navigateur (le client peut fermer la page). Confirmez côté serveur de l'une de ces deux manières :

1. Webhook (recommandé si configuré)

LeekPay envoie payment.completed (et payment.failed / payment.cancelled) sur votre webhook_url, signé. Voir la section Webhooks. Le webhook_url peut être défini par clé API ou par session (champ webhook_url dans POST /v1/checkout).

2. Polling du statut (obligatoire si vous n'avez PAS de webhook)

Si aucun webhook n'est configuré, interrogez le statut depuis votre serveur jusqu'à paid :

GET https://leekpay.fr/api/v1/checkout/checkout_42
Authorization: Bearer sk_live_votre_cle_secrete

→ { "data": { "status": "paid" | "pending", "paid_at": "..." } }

L'événement navigateur (onSuccess du widget / postMessage leekpay_success) sert uniquement à mettre à jour votre interface : ce n'est jamais la source de vérité.

App mobile & iframe

⚠️ Ne pas intégrer le checkout en <iframe>

La page de paiement finale est hébergée par le prestataire (ex. mobile money), qui interdit l'affichage en iframe (protection anti-clickjacking). Selon le prestataire actif, une iframe peut donc échouer en cours de paiement. Utilisez un popup ou une redirection.

Site web

Le widget leekpay.js ouvre automatiquement le paiement dans un popup et vous renvoie le résultat via onSuccess/onCancel. Vous pouvez aussi rediriger toute la page vers le payment_url.

Application mobile (Android / iOS)

Ouvrez le payment_url (renvoyé par POST /v1/checkout) dans une vue navigateur plein écran — pas dans une iframe HTML :

  • Android : Chrome Custom Tabs (ou une WebView).
  • iOS : SFSafariViewController (ou WKWebView).

La page de paiement étant alors en plein écran, elle fonctionne avec tous les prestataires. Interceptez le retour sur votre return_url (ou l'URL /payment/success) pour fermer la vue, et confirmez le paiement par webhook ou polling (voir ci-dessus).

Devises

DeviseMinimum
XOF (Franc CFA)100 CFA
EUR (Euro)1 €
USD (Dollar)1 $

Statuts de paiement

Les transactions passent par différents statuts au cours de leur cycle de vie.

StatutDescription
pendingPaiement en attente, le client n'a pas encore payé
processingPaiement en cours de traitement par le prestataire
paidPaiement réussi et validé
failedPaiement échoué (fonds insuffisants, erreur technique)
cancelledPaiement annulé par le client
expiredLien de paiement expiré (délai dépassé)

Besoin d'aide ? Contactez support@leekpay.fr

© 2025 LeekPay