Skip to main content

dexchangepay (Python)

SDK officiel Python pour l'API DEXPAY - Paiements Mobile Money pour l'Afrique de l'Ouest.

Compatible avec Django, Flask, FastAPI et tout projet Python 3.8+.

PyPI version License: MIT

Installation

pip install dexchangepay
# ou
poetry add dexchangepay

Démarrage rapide

from dexpay import DexPay

dexpay = DexPay(
    api_key="pk_test_xxx",     # Votre clé publique
    api_secret="sk_test_xxx",  # Votre clé secrète
)

# Créer une session de paiement
session = dexpay.checkout_sessions.create({
    "reference": "ORDER_123",
    "item_name": "Premium Plan",
    "amount": 10000,  # 10 000 XOF
    "currency": "XOF",
    "success_url": "https://example.com/success",
    "failure_url": "https://example.com/cancel",
    "webhook_url": "https://example.com/webhook",
})

# Rediriger le client vers la page de paiement
print(session["data"]["payment_url"])

Checkout Sessions

Créer une session

session = dexpay.checkout_sessions.create({
    "reference": "ORDER_123",
    "item_name": "Abonnement Premium",
    "amount": 10000,
    "currency": "XOF",
    "success_url": "https://example.com/success",
    "failure_url": "https://example.com/cancel",
    "webhook_url": "https://example.com/webhook",
    "metadata": {"user_id": "123", "plan": "premium"},
    "expires_at": "2025-12-31T23:59:59Z",  # Optionnel
    "client_support_fee": True,  # Optionnel - frais à la charge du client
})

Récupérer une session

# Par ID
session = dexpay.checkout_sessions.retrieve("session_id")

# Par référence
session = dexpay.checkout_sessions.retrieve_by_reference("ORDER_123")

Lister les sessions

sessions = dexpay.checkout_sessions.list({"page": 1, "limit": 10})

Créer une tentative de paiement

attempt = dexpay.checkout_sessions.create_payment_attempt(
    "ORDER_123",
    {
        "payment_method": "MOBILE_MONEY",
        "operator": "wave",  # wave, orange_money, mtn, moov
        "countryISO": "SN",  # SN, CI, ML, BF, etc.
        "customer": {
            "name": "Jean Dupont",
            "phone": "+221771234567",
            "email": "jean@example.com",
        },
    },
)

print(attempt["data"]["payment_url"])

Payouts (Retraits)

payout = dexpay.payouts.create({
    "amount": 10000,
    "currency": "XOF",
    "destination_phone": "+221771234567",
    "destination_details": {
        "operator": "wave",
        "countryISO": "SN",
        "recipient_name": "Jean Dupont",
    },
    "metadata": {"invoice_id": "INV_123"},
})

print(payout["reference"])  # PO_20251228_XXXXXX
print(payout["status"])     # PENDING, PROCESSING, COMPLETED, FAILED

# Récupérer, lister
dexpay.payouts.retrieve("payout_id")
dexpay.payouts.list({"page": 1, "limit": 10, "status": "COMPLETED"})

Remboursements

# Rembourser la dernière transaction réussie d'une session
refund = dexpay.checkout_sessions.refund("ORDER_123")
print(refund["status"])  # success

Balances

res = dexpay.balances.list()
print(res["data"][0]["balance"], res["data"][0]["currency"])

Providers

# Providers de collecte (paiement)
payment = dexpay.payment_providers.list({"provider_country": "SN"})

# Providers de retrait (payout)
payout = dexpay.payout_providers.list()

Products

# Produit ponctuel
product = dexpay.products.create({
    "name": "T-Shirt",
    "price": 5000,
    "currency": "XOF",
    "type": "ONE_TIME",
})

# Produit récurrent
plan = dexpay.products.create({
    "name": "Premium Plan",
    "price": 10000,
    "currency": "XOF",
    "type": "RECURRING",
    "billing_period": "MONTHLY",
})

dexpay.products.list({"page": 1, "limit": 10, "type": "RECURRING", "is_active": True})
dexpay.products.update("prod_123", {"price": 15000, "is_active": False})

Customers

customer = dexpay.customers.create({
    "name": "Jean Dupont",
    "email": "jean@example.com",
    "phone": "+221771234567",
    "country": "SN",
    "metadata": {"source": "website"},
})

# Rechercher
dexpay.customers.list({"email": "jean@example.com"})
dexpay.customers.list({"phone": "+221771234567"})

Subscriptions

subscription = dexpay.subscriptions.create({
    "customer_id": "cus_123",
    "product_id": "prod_456",
    "metadata": {"referral_code": "ABC123"},
})

dexpay.subscriptions.update("sub_123", {"status": "PAUSED"})
dexpay.subscriptions.cancel("sub_123")

Gestion des erreurs

from dexpay import DexPay, DexPayError

try:
    session = dexpay.checkout_sessions.create({...})
except DexPayError as error:
    print("Code:", error.code)
    print("Message:", error.message)
    print("Status:", error.status_code)

Intégration frameworks

Django

# settings.py
DEXPAY_API_KEY = os.environ["DEXPAY_API_KEY"]
DEXPAY_API_SECRET = os.environ["DEXPAY_API_SECRET"]

# views.py
import json
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from dexpay import DexPay

dexpay = DexPay(api_key=settings.DEXPAY_API_KEY, api_secret=settings.DEXPAY_API_SECRET)

@csrf_exempt
def webhook(request):
    event = json.loads(request.body)
    if event["type"] == "checkout.completed":
        ...  # Marquer la commande comme payée
    return JsonResponse({"received": True})

Flask

from flask import Flask, request, jsonify
from dexpay import DexPay

app = Flask(__name__)
dexpay = DexPay(api_key="pk_live_xxx", api_secret="sk_live_xxx")

@app.post("/webhook")
def webhook():
    event = request.get_json()
    if event["type"] == "checkout.completed":
        ...
    return jsonify(received=True)

FastAPI

from fastapi import FastAPI, Request
from dexpay import DexPay

app = FastAPI()
dexpay = DexPay(api_key="pk_live_xxx", api_secret="sk_live_xxx")

@app.post("/webhook")
async def webhook(request: Request):
    event = await request.json()
    if event["type"] == "checkout.completed":
        ...
    return {"received": True}

Webhooks

Évènements envoyés par DEXPAY (POST JSON sur votre webhook_url) :

Évènement Description
checkout.completed Paiement réussi
checkout.failed Paiement échoué
payout.completed Payout réussi
payout.failed Payout échoué
subscription.created Abonnement créé
subscription.cancelled Abonnement annulé

Configuration avancée

# Production (défaut)
dexpay = DexPay(api_key="pk_live_xxx", api_secret="sk_live_xxx")

# Sandbox (test)
dexpay = DexPay(api_key="pk_test_xxx", api_secret="sk_test_xxx", sandbox=True)

# Personnalisée
dexpay = DexPay(
    api_key="pk_live_xxx",
    api_secret="sk_live_xxx",
    base_url="https://api.dexpay.africa/api/v1",  # Override URL
    timeout=60,  # 60 secondes
)

URLs de l'API

Environnement URL
Production https://api.dexpay.africa/api/v1
Sandbox https://api-sandbox.dexpay.africa/api/v1

Devises supportées

Code Devise
XOF Franc CFA BCEAO (Sénégal, Côte d'Ivoire, Mali, Burkina Faso, etc.)
XAF Franc CFA BEAC (Cameroun, Gabon, Congo, etc.)
GNF Franc Guinéen

Opérateurs supportés

Opérateur Code Pays
Wave wave SN, CI, ML, BF
Orange Money orange_money SN, CI, ML, BF, GN
MTN mtn CI, BF
Moov moov CI, BF

Développement

pip install -e ".[dev]"
pytest          # Lancer les tests
mypy dexpay     # Vérification de types

Support

License

MIT © DEXCHANGE GROUP

Metadata

Release files for dexchangepay 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dexchangepay 1.1.0
File Size Uploaded Provenance
dexchangepay-1.1.0.tar.gz 13.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dexchangepay 1.1.0
File Interpreter ABI Platform
dexchangepay-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.0 kB

Release files / dexchangepay-1.1.0.tar.gz

Download URL dexchangepay-1.1.0.tar.gz
Size 13.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4bcd0d244962370c4324ecb29f635072600cd4ca01b0074d9936a249ea0d17be
BLAKE2b-256 checksum
How to use checksums
3a34337dae18b5ec6789b83e4a3ed6d41a86bfcf3873295cc3a1178054b7b6c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / dexchangepay-1.1.0-py3-none-any.whl

Download URL dexchangepay-1.1.0-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6c5875936f0820c58d362d18bbba65f605414b2da01ca44fe356aea8f9ade38c
BLAKE2b-256 checksum
How to use checksums
507f66dacdbee6f8e6c9121e45010490cf950c0b4bae9f29ce08b70934695d22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for dexchangepay 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page