Skip to main content

API non officielle de paiement mobile pour le service FASO ARZEKA au Burkina Faso

Project description

FASO ARZEKA Mobile Money Payment API (Burkina Faso)

Python 3.8+ License: MIT

API client Python non officiel pour les paiements mobiles FASO ARZEKA au Burkina Faso v3.0.1. Client robuste, production-ready avec gestion automatique des erreurs, retry automatique, et réauthentification automatique.

✨ Fonctionnalités principales

  • Authentification sécurisée avec gestion automatique des tokens
  • Réauthentification automatique quand le token expire
  • Gestion complète des erreurs avec exceptions personnalisées
  • Retry automatique avec backoff exponentiel
  • Logging intégré pour traçabilité complète
  • Session persistante pour meilleures performances
  • Type hints complets pour meilleure auto-complétion
  • Context manager pour gestion automatique des ressources
  • Validation des tokens avec informations d'expiration
  • Tests unitaires complets avec couverture >90%

📋 Prérequis

  1. Compte API Arzeka Money

    • Username
    • Password
    • Hash Secret
    • Merchant ID
  2. Certificats SSL (si fournis par l'opérateur)

  3. Python 3.8 ou supérieur

📦 Dépendances

requests>=2.31.0
setuptools
urllib3

Le client nécessite Python 3.8 ou supérieur.

🚀 Installation

# Avec pip
pip install git+https://github.com/mzeba/fasoarzeka.git

# Avec poetry
poetry add git+https://github.com/mzeba/fasoarzeka.git

# Installation en mode développement
git clone https://github.com/mzeba/fasoarzeka.git
cd fasoarzeka
pip install -e .

🎯 Guide de démarrage rapide

Option 1 : Utilisation avec fonctions de convenance (Recommandé)

from fasoarzeka import authenticate, initiate_payment, check_payment

# 1. Authentifiez-vous une fois
auth = authenticate("your_username", "your_password")
print(f"Token expires in: {auth['expires_in']} seconds")

# 2. Initiez un paiement
payment_data = {
    "amount": 1000,  # Montant en FCFA (minimum 100)
    "merchant_id": "MERCHANT_123",
    "additional_info": {
        "first_name": "Jean",
        "last_name": "Dupont",
        "mobile": "22670123456"  # Numéro avec indicatif
    },
    "mapped_order_id": "eT20220923.203221.24732",
    "hash_secret": "your_hash_secret",
    "link_for_update_status": "https://example.com/webhook",
    "link_back_to_calling_website": "https://example.com/return"
}

response = initiate_payment(payment_data)
print(f"URL to redirect user for payment: {response['url']}")

# 3. Vérifiez le statut du paiement
payment_response = check_payment(payment_data['mapped_order_id'])
print(f"Payment status: {payment_response['status']}")

Option 2 : Utilisation avec instance de classe

from fasoarzeka import ArzekaPayment

# Utilisez le context manager pour gestion automatique
with ArzekaPayment() as client:
    # 1. Authentification
    auth = client.authenticate("your_username", "your_password")

    # 2. Vérifiez la validité du token
    if client.is_token_valid():
        print("Token is valid")

    # 3. Initiez un paiement
    response = client.initiate_payment(
        amount=1000,
        merchant_id="MERCHANT_123",
        additional_info={
            "first_name": "Jean",
            "last_name": "Dupont",
            "mobile": "70123456"
        },
        mapped_order_id="eT20220923.203221.24732",
        hash_secret="your_hash_secret",
        link_for_update_status="https://example.com/webhook",
        link_back_to_calling_website="https://example.com/return"
    )

    # 4. Vérifiez le statut
    status = client.check_payment("eT20220923.203221.24732")

# Le client est automatiquement fermé

📚 Exemples détaillés

Authentification et gestion des tokens

from fasoarzeka import ArzekaPayment

client = ArzekaPayment()

# Authentification
auth = client.authenticate("username", "password")
print(f"Access Token: {auth['access_token']}")
print(f"Token Type: {auth['token_type']}")
print(f"Expires In: {auth['expires_in']} seconds")

# Vérifier la validité du token
if client.is_token_valid():
    print("Token is still valid")
else:
    print("Token has expired")

# Obtenir des informations détaillées sur le token
info = client.get_token_expiry_info()
print(f"Expires in {info['expires_in_minutes']:.1f} minutes")
print(f"Is expired: {info['is_expired']}")

client.close()

Réauthentification automatique

from fasoarzeka import ArzekaPayment

client = ArzekaPayment()
client.authenticate("username", "password")

# Faites plusieurs requêtes sur une longue période
# La réauthentification est AUTOMATIQUE si le token expire

for i in range(10):
    # Pas besoin de vérifier la validité du token !
    # Le client se réauthentifie automatiquement si nécessaire
    response = client.initiate_payment(
        amount=1000,
        merchant_id="MERCHANT_123",
        additional_info={...},
        hash_secret="secret",
        link_for_update_status="https://...",
        link_back_to_calling_website="https://..."
    )
    print(f"Payment {i+1}: {response['mappedOrderId']}")

client.close()

Initialisation de paiement avec reçu

from fasoarzeka import initiate_payment, authenticate

# Authentifiez-vous d'abord
authenticate("username", "password")

# Paiement avec génération de reçu
payment_data = {
    "amount": 5000,
    "merchant_id": "MERCHANT_123",
    "additional_info": {
        "first_name": "Marie",
        "last_name": "Kaboré",
        "mobile": "70987654",
        "generateReceipt": True,  # Activer la génération de reçu
        "paymentDescription": "Facture N°12345",
        "accountingOffice": "Bureau Principal",
        "accountantName": "Jean Traoré",
        "address": "Ouagadougou, Burkina Faso"
    },
    "hash_secret": "your_secret",
    "link_for_update_status": "https://example.com/webhook",
    "link_back_to_calling_website": "https://example.com/return",
    "mapped_order_id": "ORDER-2025-001"  # ID personnalisé
}

response = initiate_payment(payment_data)
print(f"Payment URL: {response.get('payment_url')}")
print(f"Order ID: {response.get('mappedOrderId')}")

Vérification de paiement

from fasoarzeka import check_payment, authenticate

authenticate("username", "password")

# Vérification simple
status = check_payment("ORDER-2025-001")
print(f"Status: {status}")

# Vérification avec transaction ID
status = check_payment(
    mapped_order_id="ORDER-2025-001",
    transaction_id="TXN-12345"
)
print(f"Transaction Status: {status}")

Utilisation des fonctions utilitaires

from fasoarzeka import get_reference, format_msisdn, validate_phone_number

# Générer un ID de référence unique
ref = get_reference()
print(f"Reference: {ref}")  # Ex: REF-20251023-123456

# Formater un numéro de téléphone
msisdn = format_msisdn("70 12 34 56")
print(f"Formatted: {msisdn}")  # 22670123456

# Valider un numéro burkinabè
is_valid = validate_phone_number("70123456")
print(f"Valid: {is_valid}")  # True

🔒 Gestion des erreurs

Le client fournit des exceptions spécifiques pour différents types d'erreurs :

from fasoarzeka import ArzekaPayment
from fasoarzeka.exceptions import (
    ArzekaPaymentError,
    ArzekaConnectionError,
    ArzekaValidationError,
    ArzekaAPIError,
    ArzekaAuthenticationError
)

client = ArzekaPayment()

try:
    # Tentative d'authentification
    client.authenticate("username", "password")

    # Tentative de paiement
    response = client.initiate_payment(
        amount=1000,
        merchant_id="MERCHANT_123",
        additional_info={...},
        hash_secret="secret",
        link_for_update_status="https://...",
        link_back_to_calling_website="https://..."
    )

except ArzekaAuthenticationError as e:
    print(f"Authentication failed: {e}")

except ArzekaValidationError as e:
    print(f"Invalid data: {e}")

except ArzekaConnectionError as e:
    print(f"Connection error: {e}")

except ArzekaAPIError as e:
    print(f"API error: {e}")
    print(f"Status code: {e.status_code}")
    print(f"Response: {e.response_data}")

except ArzekaPaymentError as e:
    print(f"General error: {e}")

finally:
    client.close()

⚙️ Configuration

Variables d'environnement (recommandé)

# .env
ARZEKA_USERNAME=your_username
ARZEKA_PASSWORD=your_password
ARZEKA_MERCHANT_ID=MERCHANT_123
ARZEKA_HASH_SECRET=your_hash_secret
ARZEKA_BASE_URL=https://pwg-test.fasoarzeka.com/AvepayPaymentGatewayUI/avepay-payment/
import os
from fasoarzeka import ArzekaPayment

client = ArzekaPayment(
    base_url=os.getenv('ARZEKA_BASE_URL'),
    timeout=30
)

client.authenticate(
    os.getenv('ARZEKA_USERNAME'),
    os.getenv('ARZEKA_PASSWORD')
)

Configuration du logging

import logging
from fasoarzeka import ArzekaPayment

# Configurer le niveau de log
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

client = ArzekaPayment()
# Les logs détaillés seront affichés

🧪 Tests

Le projet inclut des tests unitaires complets :

# Exécuter tous les tests
python -m pytest test/

# Exécuter avec couverture
python -m pytest test/ --cov=arzeka --cov-report=html

# Exécuter un test spécifique
python -m pytest test/test.py::TestArzekaPayment::test_authenticate

# Mode verbose
python -m pytest test/ -v

📖 Documentation complète

Documentation style ReadTheDocs

📚 Documentation HTML complète disponible dans docs_sphinx/

Pour générer et consulter la documentation :

cd docs_sphinx
pip install -r requirements.txt
./build.sh
# Puis ouvrez _build/html/index.html dans votre navigateur

La documentation comprend :

  • Guide d'installation détaillé
  • Guide de démarrage rapide
  • Guide d'authentification complet
  • Référence API complète avec autodoc
  • Exemples de code annotés
  • Guide de gestion d'erreurs
  • Fonctionnalités avancées
  • Guide de contribution

Guides Markdown

Exemples de code

  • Exemples pratiques - Code exécutable
    • authentication_example.py - Exemples d'authentification
    • token_validation_example.py - Validation de tokens
    • shared_client_example.py - Instance partagée
    • auto_reauth_example.py - Réauthentification automatique

🏗️ Architecture

arzeka-payment/
├── src/
│   └── fasoarzeka/           # Package principal       ├── __init__.py       # Exports publics       ├── arzeka.py         # Module principal       ├── exceptions.py     # Exceptions personnalisées       └── utils.py          # Fonctions utilitaires
├── test/
│   ├── __init__.py           # Tests package   └── test.py               # Tests unitaires (authentification & vérification)
├── docs/
│   ├── QUICKSTART.md         # Guide de démarrage rapide   ├── AUTHENTICATION.md     # Guide d'authentification   ├── AUTO_REAUTH.md        # Réauthentification automatique   ├── TOKEN_VALIDATION.md   # Validation des tokens   └── MODIFICATIONS_SUMMARY.md  # Résumé des modifications
├── examples/
│   ├── authentication_example.py      # Exemples d'authentification   ├── auto_reauth_example.py         # Réauthentification automatique   ├── shared_client_example.py       # Instance partagée   ├── token_validation_example.py    # Validation de tokens   ├── example.py                     # Exemple simple   ├── test_auto_reauth.py            # Test réauthentification   └── test_signature_improvements.py # Test signatures améliorées
├── CHANGELOG.md              # Historique des modifications
├── INSTALLATION_GUIDE.md     # Guide d'installation détaillé
├── LICENSE                   # Licence MIT
├── README.md                 # Ce fichier
├── requirements.txt          # Dépendances du projet
├── setup.py                  # Configuration setuptools
├── setup.cfg                 # Configuration additionnelle
└── pyproject.toml            # Configuration Poetry

🔧 Classes et Exceptions

Classes principales

  • ArzekaPayment - Client principal pour interactions API
  • BasePayment - Classe de base avec gestion session et requêtes

Exceptions personnalisées

  • ArzekaPaymentError - Exception de base
  • ArzekaConnectionError - Erreurs de connexion réseau
  • ArzekaValidationError - Erreurs de validation de données
  • ArzekaAPIError - Erreurs retournées par l'API
  • ArzekaAuthenticationError - Erreurs d'authentification

🚀 Fonctionnalités avancées

1. Retry automatique avec backoff exponentiel

# Le client réessaie automatiquement en cas d'erreur réseau
# - Maximum 3 tentatives
# - Backoff exponentiel (1s, 2s, 4s)
# - Status codes: 429, 500, 502, 503, 504
from fasoarzeka import ArzekaPayment
client = ArzekaPayment()
# Les retries sont automatiques !

2. Session persistante avec connection pooling

# Les connexions HTTP sont réutilisées pour meilleures performances
from fasoarzeka import ArzekaPayment
client = ArzekaPayment()
# La session est automatiquement gérée

3. Context manager

# Gestion automatique des ressources
from fasoarzeka import ArzekaPayment
with ArzekaPayment() as client:
    client.authenticate("user", "pass")
    response = client.initiate_payment(...)
# Fermeture automatique de la session

4. Instance partagée pour fonctions de convenance

from fasoarzeka import authenticate, initiate_payment, get_shared_client, close_shared_client

# Les fonctions partagent une même instance
authenticate("user", "pass")
initiate_payment(payment_data)

# Accéder à l'instance partagée
client = get_shared_client()
print(client.is_token_valid())

# Nettoyer l'instance partagée
close_shared_client()

💡 Bonnes pratiques

1. Utiliser les variables d'environnement

import os
from fasoarzeka import authenticate

username = os.getenv('ARZEKA_USERNAME')
password = os.getenv('ARZEKA_PASSWORD')
authenticate(username, password)

2. Utiliser le context manager

from fasoarzeka import ArzekaPayment
with ArzekaPayment() as client:
    client.authenticate("user", "pass")
    # ... opérations ...
# Nettoyage automatique

3. Gérer les exceptions spécifiques

try:
    response = client.initiate_payment(...)
except ArzekaValidationError:
    # Données invalides
except ArzekaAuthenticationError:
    # Problème d'authentification
except ArzekaConnectionError:
    # Problème réseau

4. Vérifier les tokens avant longues opérations

if client.is_token_valid(margin_seconds=300):  # 5 minutes
    # Token valide pour au moins 5 minutes
    long_operation()

5. Utiliser le logging pour debug

import logging
logging.basicConfig(level=logging.DEBUG)
# Logs détaillés des requêtes

🔍 API Reference

ArzekaPayment

class ArzekaPayment(base_url: str = BASE_URL, timeout: int = 30)

Méthodes

  • authenticate(username, password) - Authentification et obtention du token
  • initiate_payment(...) - Initialiser un paiement
  • check_payment(mapped_order_id, transaction_id) - Vérifier statut paiement
  • is_token_valid(margin_seconds=60) - Vérifier validité du token
  • get_token_expiry_info() - Obtenir infos détaillées sur expiration
  • close() - Fermer la session

Fonctions utilitaires

  • get_reference() - Générer ID de référence unique
  • format_msisdn(phone) - Formater numéro de téléphone
  • validate_phone_number(phone) - Valider numéro burkinabè

Fonctions de convenance

  • authenticate(username, password, base_url, timeout) - Authentification
  • initiate_payment(payment_data, base_url, timeout) - Initialiser paiement
  • check_payment(mapped_order_id, transaction_id, base_url, timeout) - Vérifier paiement
  • get_shared_client() - Obtenir instance partagée
  • close_shared_client() - Fermer instance partagée

📊 Statut du projet

  • ✅ Authentification sécurisée
  • ✅ Initialisation de paiements
  • ✅ Vérification de statut
  • ✅ Gestion complète des erreurs
  • ✅ Retry automatique
  • ✅ Réauthentification automatique
  • ✅ Tests unitaires (>90% couverture)
  • ✅ Documentation complète
  • ✅ Type hints complets
  • ✅ Logging intégré
  • ⏳ Publication sur PyPI (à venir)

🤝 Contribution

Les contributions sont les bienvenues ! Voici comment contribuer :

  1. Fork le projet
  2. Créez une branche pour votre fonctionnalité (git checkout -b feature/AmazingFeature)
  3. Committez vos changements (git commit -m 'Add some AmazingFeature')
  4. Pushez vers la branche (git push origin feature/AmazingFeature)
  5. Ouvrez une Pull Request

Guidelines de contribution

  • Suivre le style de code existant
  • Ajouter des tests pour nouvelles fonctionnalités
  • Mettre à jour la documentation
  • S'assurer que tous les tests passent

📝 Changelog

Voir CHANGELOG.md pour l'historique détaillé des modifications.

�📄 Licence

Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus de détails.

👥 Auteur

Mohamed Zeba - m.zeba@mzeba.dev

🙏 Remerciements

  • L'équipe Arzeka pour l'API
  • La communauté Python du Burkina Faso
  • Tous les contributeurs

📞 Support

⚠️ Avertissement

Ceci est un client non officiel pour l'API Arzeka. Utilisez-le à vos propres risques. Assurez-vous de respecter les conditions d'utilisation de l'API Arzeka.

🌟 Soutenez le projet

Si ce projet vous aide, n'oubliez pas de lui donner une ⭐ sur GitHub !


Note importante : Ce client utilise l'environnement de test par défaut. Pour la production, assurez-vous de configurer l'URL de production :

from fasoarzeka import ArzekaPayment

client = ArzekaPayment(base_url="https://pwg.fasoarzeka.com/...")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fasoarzeka-0.1.2.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fasoarzeka-0.1.2-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file fasoarzeka-0.1.2.tar.gz.

File metadata

  • Download URL: fasoarzeka-0.1.2.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for fasoarzeka-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0235ad9de0241984ef4a6311edebf51eb007e33e63d0ec82f196bbc35f3f4bf3
MD5 e0b1ec83c841f06a8d03431902914bda
BLAKE2b-256 0650a7df6e80388dbc94c036fbe5e5b0e2fc87830bd969a89215bfca922dcc44

See more details on using hashes here.

File details

Details for the file fasoarzeka-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: fasoarzeka-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for fasoarzeka-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 245ae54683417b4e067270fd7919112f41bc154f52b82769e5af9735430dd0d8
MD5 a4c2d6d1c602176d1fc088a1528ae195
BLAKE2b-256 71c56f2e359fa58ad49c3a130c13db35023080be59da176714bf0da18d4f746e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page