Skip to content

SDK Python

SDK officiel pour Python 3.8+. Disponible sur PyPI sous haybtech-sdk.

Intégration par IA (Prompt pour Marchands)

Si vous utilisez un assistant IA (comme Cursor, GitHub Copilot, ChatGPT, Claude, etc.), vous pouvez copier-coller le prompt suivant pour intégrer ce SDK de A à Z dans votre projet :

text
Agis en tant qu'expert en développement backend Python. Je souhaite intégrer la solution de paiement HayBTech (Afrique de l'Ouest) sur mon site marchand de A à Z avec le SDK Python officiel `haybtech-sdk`.

Voici ma stack technique actuelle :
- Framework : [ex: Django, Flask, FastAPI]
- Base de données & ORM : [ex: Django ORM, SQLAlchemy, Tortoise ORM]
- Modèle de commande : [décrivez brièvement votre structure de table Order, ex: { id, status (pending/paid/failed), amount, email }]

Tâches à accomplir dans le code généré :
1. **Initialisation & Config** : Configurer le client SDK `HayBTechClient` en chargeant la clé secrète via l'environnement (`HAYBTECH_SECRET_KEY`).
2. **Création du Paiement** : Créer une vue/route pour initier le paiement. Elle doit récupérer le montant de la commande, générer la transaction via le SDK en passant `merchant_ref`, `amount`, `currency='XOF'`, `success_url`, `failed_url`, `callback_url`, puis renvoyer l'URL de redirection vers le guichet de paiement.
3. **Webhook de Validation** : Créer une vue/route `/webhook/haybtech` acceptant le POST de HayBTech. Elle doit :
   - Récupérer le corps de la requête brut (raw request body) et le header `X-HayBTech-Signature`.
   - Utiliser `Webhook.construct_event(payload, signature, secret)` pour valider l'événement.
   - Gérer l'événement `payment.success` : marquer la commande comme payée de façon idempotente et valider le panier.
   - Gérer l'événement `payment.failed` : marquer la commande en échec.
   - Renvoyer une réponse HTTP 200.
4. **Sécurité & Gestion des Erreurs** : Intercepter `SignatureException` et `ApiException`, logger les erreurs de façon propre, et utiliser une comparaison de signature insensible aux attaques temporelles.

Génère un code propre, modulaire, commenté et prêt à être inséré dans mon projet.

Installation

bash
pip install haybtech-sdk

Configuration (Zéro-Config)

Si vous avez HAYBTECH_SECRET_KEY dans votre environnement (via .env), vous pouvez utiliser le SDK directement :

python
from haybtech import HayBTechClient

client = HayBTechClient()

(Optionnel) Passer la clé explicitement :

python
client = HayBTechClient('sk_live_votre_cle')

Créer un paiement

python
from haybtech import HayBTechClient
from haybtech.exceptions import ApiException, HayBTechException

client = HayBTechClient()

try:
    response = client.payments.create({
        'merchant_ref': 'ORDER-12345',
        'amount': 5000,
        'currency': 'XOF',
        'success_url': 'https://monsite.com/succes',
        'failed_url': 'https://monsite.com/echec',
        'callback_url': 'https://monsite.com/webhook'
    })

    print(f"Payment URL: {response['data']['payment_url']}")

except ApiException as e:
    print(f"Erreur API: {e.message} (code: {e.error_code})")

Webhooks

FastAPI

python
import os
from fastapi import FastAPI, Request, HTTPException
from haybtech import Webhook, SignatureException

app = FastAPI()

@app.post("/webhooks/haybtech")
async def webhook(request: Request):
    payload   = (await request.body()).decode('utf-8')
    signature = request.headers.get('X-HayBTech-Signature', '')

    try:
        event = Webhook.construct_event(
            payload, signature, os.environ['HAYBTECH_WEBHOOK_SECRET']
        )

        if event['event'] == 'payment.success':
            merchant_ref = event['data']['merchant_ref']
            # Marquer la commande comme payée

        return {"ok": True}
    except SignatureException:
        raise HTTPException(status_code=403, detail="Signature invalide")

Django

python
import os
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from haybtech import Webhook, SignatureException

@csrf_exempt
def haybtech_webhook(request):
    if request.method == 'POST':
        payload   = request.body.decode('utf-8')
        signature = request.headers.get('X-HayBTech-Signature', '')

        try:
            event = Webhook.construct_event(
                payload, signature, os.environ['HAYBTECH_WEBHOOK_SECRET']
            )

            if event['event'] == 'payment.success':
                # Logique métier ici
                pass

            return HttpResponse(status=200)
        except SignatureException:
            return HttpResponse(status=403)

Flask

python
import os
from flask import Flask, request, jsonify, abort
from haybtech import Webhook, SignatureException

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    payload   = request.get_data(as_text=True)
    signature = request.headers.get('X-HayBTech-Signature', '')

    try:
        event = Webhook.construct_event(
            payload, signature, os.environ['HAYBTECH_WEBHOOK_SECRET']
        )

        if event['event'] == 'payment.success':
            # Marquer la commande comme payée
            pass

        return jsonify(status='ok'), 200
    except SignatureException:
        abort(403)

Mode test

python
client = HayBTechClient('sk_test_...') # Aucun débit réel

Gestion des erreurs

python
from haybtech.exceptions import ApiException, HayBTechException

try:
    response = client.payments.create(params)
except ApiException as e:
    print(e.message)       # Message lisible
    print(e.http_status)   # 400, 422, 500...
    print(e.error_code)    # ex. "insufficient_funds"
    print(e.is_retryable)  # True si 5xx ou 429
except HayBTechException as e:
    # SDK non configuré, clé invalide, etc.
    print(e)

Tests pytest

python
import time, hmac, hashlib
from haybtech import Webhook, SignatureException
import pytest


def make_sig(body: str, secret: str, ts: int = None) -> str:
    ts = ts or int(time.time())
    sig = hmac.new(secret.encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
    return f"t={ts},v1={sig}"


def test_accepts_fresh_signature():
    body   = '{"event":"payment.success"}'
    secret = "whsec_test"
    event  = Webhook.construct_event(body, make_sig(body, secret), secret)
    assert event["event"] == "payment.success"


def test_rejects_old_signature():
    body   = '{"event":"payment.success"}'
    secret = "whsec_test"
    sig    = make_sig(body, secret, ts=int(time.time()) - 600)
    with pytest.raises(SignatureException):
        Webhook.construct_event(body, sig, secret)

Ressources API

RessourceDescription
client.paymentsCréer, récupérer, lister et vérifier des transactions
client.webhooksGérer vos endpoints de notification
client.refundsInitier des remboursements
client.payoutsEnvoyer des fonds vers un wallet mobile money

Documentation de l'API de paiement HayBTech.