Référence API Complète

Documentation détaillée de tous les endpoints REST

REST API
HMAC-SHA512
Webhooks
JSON

Base URL

URL de base pour toutes les requêtes API

Production

https://api.huntertechpay.com/api/v1/payments

Sandbox (Test)

https://sandbox-api.huntertechpay.com/api/v1/payments

Authentification HMAC-SHA512

Toutes les requêtes doivent être signées avec votre Secret Key

Important: Si vous utilisez nos SDKs officiels (Python, Node.js, PHP), l'authentification HMAC-SHA512 est gérée automatiquement. Cette section est pour les implémentations manuelles.

Headers requis

X-API-Key - Votre clé API publique
X-Hunter-Signature - Signature HMAC-SHA512 du payload
X-Hunter-Timestamp - Timestamp UNIX de la requête
Content-Type - application/json

Génération de la signature

import hmac
import hashlib
import time
import json

# 1. Préparer les données
secret_key = "sk_live_your_secret_key"
payload = {
    "amount": 10000,
    "currency": "XAF",
    "country": "CM",
    "phone_number": "+237670000000",
    "service_code": "HT_PAIEMENTMARCHAND_MTN_CM",
    "partner_id": "ORDER-12345"
}

# 2. Générer timestamp
timestamp = str(int(time.time()))

# 3. Créer le message à signer
message = f"{timestamp}.{json.dumps(payload, separators=(',', ':'), sort_keys=True)}"

# 4. Calculer signature HMAC-SHA512
signature = hmac.new(
    secret_key.encode(),
    message.encode(),
    hashlib.sha512
).hexdigest()

# 5. Envoyer la requête
headers = {
    "X-API-Key": "htp_live_your_api_key",
    "X-Hunter-Signature": signature,
    "X-Hunter-Timestamp": timestamp,
    "Content-Type": "application/json"
}

Sécurité

  • • Ne jamais partager votre Secret Key
  • • Stocker la Secret Key dans les variables d'environnement
  • • Le timestamp ne doit pas dépasser 5 minutes (protection replay attack)
  • • Utiliser HTTPS pour toutes les requêtes

Dépôt (CASHIN)

POST /deposit

Recevoir un paiement depuis un compte Mobile Money vers votre wallet marchand

Use Case: Le client paie depuis son compte Mobile Money (MTN, Orange, etc.) et l'argent est crédité sur votre wallet marchand après déduction des frais.

Requête

POST /api/v1/payments/deposit
{
  "amount": 10000,           // Montant en centimes (100 = 1 XAF)
  "currency": "XAF",
  "country": "CM",
  "phone_number": "+237670000000",
  "service_code": "HT_PAIEMENTMARCHAND_MTN_CM",
  "partner_id": "ORDER-12345",
  "description": "Paiement commande #12345",
  "callback_url": "https://votresite.com/webhook",
  "metadata": {
    "order_id": "12345",
    "customer_email": "client@example.com"
  }
}

Paramètres

amount (required) - Montant en centimes
currency (required) - Code devise (XAF, XOF)
country (required) - Code pays ISO (CM, CI, SN...)
phone_number (required) - Numéro avec indicatif (+237...)
service_code (required) - Code du service (voir /providers)
partner_id (required) - Votre référence unique
callback_url (optional) - URL pour recevoir les notifications
metadata (optional) - Données additionnelles (JSON)

Réponse Success (201 Created)

{
  "success": true,
  "transaction_id": "txn_abc123xyz",
  "status": "pending",
  "amount": 10000,
  "currency": "XAF",
  "partner_id": "ORDER-12345",
  "created_at": "2026-03-24T10:30:00Z",
  "message": "Transaction créée. Le client va recevoir une demande USSD."
}

Flux de paiement

  1. API retourne transaction_id avec status="pending"
  2. Le client reçoit un USSD sur son téléphone
  3. Le client entre son code PIN pour confirmer
  4. Vérifiez le statut via /check-status ou attendez le webhook
  5. Une fois completé, votre wallet est crédité (montant - frais)

Retrait (CASHOUT)

POST /withdraw

Envoyer de l'argent depuis votre wallet marchand vers un compte Mobile Money

Use Case: Envoyer de l'argent à un bénéficiaire (remboursement, paiement fournisseur, salaires, etc.). L'argent est débité de votre wallet et envoyé vers le Mobile Money.

Requête

POST /api/v1/payments/withdraw
{
  "amount": 5000,
  "currency": "XAF",
  "country": "CM",
  "phone_number": "+237690000000",
  "service_code": "HT_PAIEMENTMARCHAND_ORANGE_CM",
  "partner_id": "REFUND-789",
  "description": "Remboursement client",
  "callback_url": "https://votresite.com/webhook"
}

Réponse Success (201 Created)

{
  "success": true,
  "transaction_id": "txn_xyz789abc",
  "status": "pending",
  "amount": 5000,
  "currency": "XAF",
  "partner_id": "REFUND-789",
  "created_at": "2026-03-24T11:00:00Z",
  "message": "Retrait initié avec succès"
}

Vérifier le Statut

POST /check-status

Vérifier le statut d'une transaction par transaction_id ou partner_id

Requête

POST /api/v1/payments/check-status
{
  "reference": "ORDER-12345",
  "reference_type": "partner_id"    // ou "transaction_id"
}

Réponse Success (200 OK)

{
  "success": true,
  "transaction": {
    "transaction_id": "txn_abc123xyz",
    "partner_id": "ORDER-12345",
    "status": "completed",           // pending, completed, failed
    "amount": 10000,
    "currency": "XAF",
    "operation_type": "cashin",
    "phone_number": "+237670000000",
    "provider": "MTN",
    "created_at": "2026-03-24T10:30:00Z",
    "completed_at": "2026-03-24T10:31:45Z",
    "metadata": {
      "order_id": "12345",
      "customer_email": "client@example.com"
    }
  }
}

Statuts possibles

pending - Transaction en cours
completed - Transaction réussie
failed - Transaction échouée

Liste des Providers

GET /providers

Obtenir la liste des providers Mobile Money disponibles par pays

Requête

GET /api/v1/payments/providers?country=CM
Headers: X-API-Key, X-Hunter-Signature, X-Hunter-Timestamp

Réponse Success (200 OK)

{
  "success": true,
  "country": "CM",
  "providers": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "MTN Cameroun",
      "code": "mtn",
      "cashin_service_code": "HT_PAIEMENTMARCHAND_MTN_CM",
      "cashout_service_code": "HT_PAIEMENTMARCHAND_MTN_CM",
      "supports_cashin": true,
      "supports_cashout": true,
      "logo_url": "https://cdn.huntertechpay.com/logos/mtn.png",
      "limits": {
        "min_amount": 10000,      // 100 XAF
        "max_amount": 500000000   // 5,000,000 XAF
      }
    },
    {
      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "name": "Orange Money Cameroun",
      "code": "orange",
      "cashin_service_code": "HT_PAIEMENTMARCHAND_ORANGE_CM",
      "cashout_service_code": "HT_PAIEMENTMARCHAND_ORANGE_CM",
      "supports_cashin": true,
      "supports_cashout": true,
      "logo_url": "https://cdn.huntertechpay.com/logos/orange.png",
      "limits": {
        "min_amount": 10000,
        "max_amount": 200000000
      }
    }
  ],
  "total": 2
}

Important

Utilisez le champ cashin_service_code ou cashout_service_code dans vos requêtes de paiement selon l'opération.

Historique des Transactions

GET /transactions

Liste paginée de toutes vos transactions avec filtres

Requête

GET /api/v1/payments/transactions?limit=20&offset=0&status=completed
Query Parameters: limit, offset, status, operation_type, start_date, end_date

Paramètres de filtrage

limit (optional, default: 20) - Nombre de résultats
offset (optional, default: 0) - Pagination
status (optional) - pending, completed, failed
operation_type (optional) - cashin, cashout
start_date (optional) - Date début ISO 8601
end_date (optional) - Date fin ISO 8601

Réponse Success (200 OK)

{
  "success": true,
  "transactions": [
    {
      "transaction_id": "txn_abc123",
      "partner_id": "ORDER-12345",
      "status": "completed",
      "operation_type": "cashin",
      "amount": 10000,
      "currency": "XAF",
      "phone_number": "+237670000000",
      "provider": "MTN",
      "created_at": "2026-03-24T10:30:00Z",
      "completed_at": "2026-03-24T10:31:45Z"
    }
  ],
  "total": 150,
  "limit": 20,
  "offset": 0
}

Solde du Wallet

GET /balance

Consulter le solde disponible de votre wallet marchand

Requête

GET /api/v1/payments/balance
Headers: X-API-Key, X-Hunter-Signature, X-Hunter-Timestamp

Réponse Success (200 OK)

{
  "success": true,
  "balance": {
    "available": 2500000,        // 25,000 XAF disponible
    "pending": 150000,           // 1,500 XAF en attente
    "currency": "XAF",
    "last_updated": "2026-03-24T12:00:00Z"
  }
}

Note

  • available : Solde disponible pour les retraits (cashout)
  • pending : Montant des transactions en cours de traitement

Webhooks (Notifications)

Recevez des notifications en temps réel sur le statut de vos transactions

Les webhooks vous permettent d'être notifié automatiquement lorsqu'une transaction change de statut (pending → completed/failed), sans avoir à faire du polling sur /check-status.

Configuration

Configurez votre URL webhook dans le dashboard HunterTech Pay ou lors de la création de votre API Key. Exemple:

https://votresite.com/webhook/huntertechpay

Payload envoyé

{
  "event": "transaction.completed",    // ou transaction.failed
  "transaction": {
    "transaction_id": "txn_abc123",
    "partner_id": "ORDER-12345",
    "status": "completed",
    "operation_type": "cashin",
    "amount": 10000,
    "currency": "XAF",
    "phone_number": "+237670000000",
    "provider": "MTN",
    "created_at": "2026-03-24T10:30:00Z",
    "completed_at": "2026-03-24T10:31:45Z",
    "metadata": {
      "order_id": "12345"
    }
  },
  "timestamp": "2026-03-24T10:31:46Z"
}

Vérification de la signature

Chaque webhook contient une signature HMAC-SHA512 dans les headers pour garantir son authenticité:

X-Hunter-Signature: a4f2d8e9c1b3...
X-Hunter-Timestamp: 1711234567
import hmac
import hashlib
from flask import request, jsonify

@app.route('/webhook/huntertechpay', methods=['POST'])
def handle_webhook():
    # 1. Récupérer signature et timestamp
    signature = request.headers.get('X-Hunter-Signature')
    timestamp = request.headers.get('X-Hunter-Timestamp')

    # 2. Récupérer le body
    payload = request.get_data(as_text=True)

    # 3. Recalculer la signature
    message = f"{timestamp}.{payload}"
    expected_signature = hmac.new(
        SECRET_KEY.encode(),
        message.encode(),
        hashlib.sha512
    ).hexdigest()

    # 4. Vérifier la signature
    if signature != expected_signature:
        return jsonify({"error": "Invalid signature"}), 401

    # 5. Traiter le webhook
    data = request.json
    if data['event'] == 'transaction.completed':
        # Mettre à jour votre base de données
        update_order_status(data['transaction']['partner_id'], 'paid')

    return jsonify({"success": True}), 200

Important

  • • Votre endpoint doit retourner un HTTP 200 OK rapidement (< 5 secondes)
  • • Si pas de réponse, nous réessayons : Immédiat, +5min, +30min, +2h
  • • Vérifiez TOUJOURS la signature avant de traiter le webhook
  • • Implémentez l'idempotence (ne pas traiter 2 fois le même webhook)

Codes d'Erreur

Liste complète des codes d'erreur et leur signification

400 Bad Request
Paramètres manquants ou invalides
401 Unauthorized
Signature HMAC invalide ou API Key incorrecte
403 Forbidden
API Key révoquée ou permissions insuffisantes
404 Not Found
Transaction ou ressource introuvable
429 Too Many Requests
Rate limit dépassé (100 req/min)
500 Internal Server Error
Erreur serveur - Réessayer plus tard

Rate Limiting

Limites de taux pour protéger l'API

Limite par défaut:
100 requêtes / minute
Headers de réponse:X-RateLimit-*

Chaque réponse API inclut ces headers :

  • X-RateLimit-Limit - Limite totale
  • X-RateLimit-Remaining - Requêtes restantes
  • X-RateLimit-Reset - Timestamp de réinitialisation