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.
- ✅ 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%
-
Compte API Arzeka Money
- Username
- Password
- Hash Secret
- Merchant ID
-
Certificats SSL (si fournis par l'opérateur)
-
Python 3.8 ou supérieur
requests>=2.31.0
setuptools
urllib3Le client nécessite Python 3.8 ou supérieur.
# 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 .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": "T20220923.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']}")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="T20220923.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("T20220923.203221.24732")
# Le client est automatiquement fermé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()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()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')}")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}")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}") # TrueLe 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()# .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')
)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ésLe 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 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 navigateurLa 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
- Guide de démarrage rapide - Commencer en 5 minutes
- Guide d'authentification - Tout sur l'authentification
- Validation des tokens - Gestion des tokens
- Réauthentification automatique - Fonctionnalité avancée
- Exemples pratiques - Code exécutable
authentication_example.py- Exemples d'authentificationtoken_validation_example.py- Validation de tokensshared_client_example.py- Instance partagéeauto_reauth_example.py- Réauthentification automatique
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 PoetryArzekaPayment- Client principal pour interactions APIBasePayment- Classe de base avec gestion session et requêtes
ArzekaPaymentError- Exception de baseArzekaConnectionError- Erreurs de connexion réseauArzekaValidationError- Erreurs de validation de donnéesArzekaAPIError- Erreurs retournées par l'APIArzekaAuthenticationError- Erreurs d'authentification
# 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 !# Les connexions HTTP sont réutilisées pour meilleures performances
from fasoarzeka import ArzekaPayment
client = ArzekaPayment()
# La session est automatiquement gérée# Gestion automatique des ressources
from fasoarzeka import ArzekaPayment
with ArzekaPayment() as client:
client.authenticate("user", "pass")
response = client.initiate_payment(...)
# Fermeture automatique de la sessionfrom 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()import os
from fasoarzeka import authenticate
username = os.getenv('ARZEKA_USERNAME')
password = os.getenv('ARZEKA_PASSWORD')
authenticate(username, password)from fasoarzeka import ArzekaPayment
with ArzekaPayment() as client:
client.authenticate("user", "pass")
# ... opérations ...
# Nettoyage automatiquetry:
response = client.initiate_payment(...)
except ArzekaValidationError:
# Données invalides
except ArzekaAuthenticationError:
# Problème d'authentification
except ArzekaConnectionError:
# Problème réseauif client.is_token_valid(margin_seconds=300): # 5 minutes
# Token valide pour au moins 5 minutes
long_operation()import logging
logging.basicConfig(level=logging.DEBUG)
# Logs détaillés des requêtesclass ArzekaPayment(base_url: str = BASE_URL, timeout: int = 30)authenticate(username, password)- Authentification et obtention du tokeninitiate_payment(...)- Initialiser un paiementcheck_payment(mapped_order_id, transaction_id)- Vérifier statut paiementis_token_valid(margin_seconds=60)- Vérifier validité du tokenget_token_expiry_info()- Obtenir infos détaillées sur expirationclose()- Fermer la session
get_reference()- Générer ID de référence uniqueformat_msisdn(phone)- Formater numéro de téléphonevalidate_phone_number(phone)- Valider numéro burkinabè
authenticate(username, password, base_url, timeout)- Authentificationinitiate_payment(payment_data, base_url, timeout)- Initialiser paiementcheck_payment(mapped_order_id, transaction_id, base_url, timeout)- Vérifier paiementget_shared_client()- Obtenir instance partagéeclose_shared_client()- Fermer instance partagée
- ✅ 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)
Les contributions sont les bienvenues ! Voici comment contribuer :
- Fork le projet
- Créez une branche pour votre fonctionnalité (
git checkout -b feature/AmazingFeature) - Committez vos changements (
git commit -m 'Add some AmazingFeature') - Pushez vers la branche (
git push origin feature/AmazingFeature) - Ouvrez une Pull Request
- Suivre le style de code existant
- Ajouter des tests pour nouvelles fonctionnalités
- Mettre à jour la documentation
- S'assurer que tous les tests passent
Voir CHANGELOG.md pour l'historique détaillé des modifications.
Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus de détails.
Mohamed Zeba - m.zeba@mzeba.dev
- L'équipe Arzeka pour l'API
- La communauté Python du Burkina Faso
- Tous les contributeurs
- Issues : GitHub Issues
- Email : m.zeba@mzeba.dev
- Documentation : GitHub Wiki
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.
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/...")