Skip to main content

Abstraction unifiée des passerelles de paiement africaines (CinetPay, Kkiapay...) - Zéro dépendance externe.

Project description

payment-providers

Module Python d'abstraction des passerelles de paiement. Il fournit une interface unifiée pour intégrer plusieurs fournisseurs de paiement sans coupler le reste de l'application à un SDK tiers.

Dépendances externes : aucune — uniquement la bibliothèque standard Python.


Architecture

payment-providers/
├── base.py          # Contrat abstrait (ABC) + Protocol Transaction
├── factory.py       # Chargement dynamique des providers
├── cinetpay/
│   ├── client.py    # Implémentation CinetPay
│   └── settings.py  # Configuration via variables d'environnement
└── kkiapay/
    ├── client.py    # Implémentation Kkiapay
    └── settings.py  # Configuration via variables d'environnement

Patron de conception

Le module implémente le patron Strategy + Factory :

  • PaymentProvider (ABC) définit le contrat commun à tous les providers.
  • Transaction (Protocol) décrit l'objet attendu en entrée — n'importe quel objet Python exposant les bons attributs est accepté (duck typing).
  • factory.py charge dynamiquement le bon provider via importlib, avec mise en cache via lru_cache.

Contrat

Chaque provider implémente deux méthodes asynchrones :

async def initiate_payment(self, tx: Transaction) -> str:
    """Initialise un paiement. Retourne l'URL de redirection ou de rendu."""

async def verify_payment(self, transaction_id: str) -> dict:
    """Vérifie le statut d'une transaction. Retourne un dict normalisé."""

Format de retour de verify_payment

{
    "status": "SUCCESS" | "FAILED" | "PENDING",
    "raw_data": { ... }  # Réponse brute de l'API du provider
}

Protocol Transaction

class Transaction(Protocol):
    id: str
    amount: float
    currency: str
    description: str | None
    user_name: str | None
    user_email: str
    user_phone: str | None

Providers

CinetPay

Paiement via redirection : initiate_payment renvoie une URL de paiement hébergée sur CinetPay.

Variables d'environnement requises :

Variable Description
CINETPAY_API_KEY Clé API CinetPay
CINETPAY_SITE_ID Identifiant du site
CINETPAY_SECRET_KEY Clé secrète
CINETPAY_BASE_URL URL de base de l'API (ex: https://api-checkout.cinetpay.com/v2/)
SITE_URL URL publique du site (défaut : http://localhost:8080)

Les URLs de notification et de retour sont construites automatiquement :

  • notify_url{SITE_URL}/webhooks/cinetpay
  • return_url{SITE_URL}/payment/success

Kkiapay

Paiement via widget frontend : initiate_payment renvoie une URL de rendu interne (/payment/kkiapay/render/{tx.id}). La vérification se fait via l'API Kkiapay avec le transactionId retourné par le widget.

Variables d'environnement requises :

Variable Description
KKIAPAY_PUBLIC_KEY Clé publique
KKIAPAY_PRIVATE_KEY Clé privée
KKIAPAY_SECRET_KEY Clé secrète

Variables optionnelles :

Variable Défaut
KKIAPAY_URL https://api.kkiapay.me
KKIAPAY_SANDBOX_URL https://api-sandbox.kkiapay.me
KKIAPAY_TRANSACTION_STATUS_URL /api/v1/transactions/status
KKIAPAY_SANDBOX true

Utilisation

Sélectionner un provider dynamiquement

from app.providers.factory import PaymentProviderPath, select_provider

provider = select_provider(PaymentProviderPath.CINETPAY)
url = await provider.initiate_payment(tx)

Valider la valeur d'un provider

from app.providers.factory import validate_payment_provider

name = validate_payment_provider("cinetpay")  # "CINETPAY"

Ajouter un nouveau provider

  1. Créer un dossier myprovider/ avec __init__.py, client.py, settings.py.
  2. Implémenter MyProvider(PaymentProvider) avec initiate_payment et verify_payment.
  3. Ajouter les entrées dans factory.py :
class PaymentProviderPath(str, Enum):
    MYPROVIDER = "app.providers.myprovider.client.MyProvider"

class ProviderSettingsPath(str, Enum):
    MYPROVIDER = "app.providers.myprovider.settings.MyProviderSettings"

Notes

  • Les appels HTTP sont réalisés avec urllib.request (stdlib) encapsulé dans asyncio.to_thread pour rester compatible avec un contexte async (FastAPI, etc.).
  • La configuration est chargée une seule fois au démarrage grâce à lru_cache.
  • Le diagnostic réseau CinetPay (DNS + TCP) n'est activé qu'en mode DEBUG.

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

paygate_africa-0.1.0.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

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

paygate_africa-0.1.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file paygate_africa-0.1.0.tar.gz.

File metadata

  • Download URL: paygate_africa-0.1.0.tar.gz
  • Upload date:
  • Size: 6.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.12.13 Linux/6.17.0-1008-azure

File hashes

Hashes for paygate_africa-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e52e657b80a33acddbd51a01645813346275186c5a0e77aef71b483282b5313e
MD5 81a533bddf6f595439de083429ec27e9
BLAKE2b-256 6d889d652bbae5c9aed88166c3bc0de75d51f1a0f0acb5cff49b1651954031ce

See more details on using hashes here.

File details

Details for the file paygate_africa-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: paygate_africa-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.12.13 Linux/6.17.0-1008-azure

File hashes

Hashes for paygate_africa-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 49100891361c19d8aa3c206be657a053ca564eaba8344a561d05c9a63c753c8b
MD5 76d4c75202543d77799f216e23cdae89
BLAKE2b-256 6aa109bac7d5b704448c709870cca901e32931443776be7e5612b3c15332b4ff

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