Intégrer MonCash avec Django
Intégrez les paiements MonCash dans votre application Django : vue de paiement, vue webhook exempt CSRF et vérification de signature.
Commencez en Sandbox
Avant d'implémenter le code ci-dessous avec votre clé live (sk_proj_…), nous recommandons de tester d'abord en mode Sandbox avec sk_test_proj_…. Le code est identique — vous ne changez que la valeur de la variable d'environnement. Lisez le Guide Sandbox avant de continuer.
Prérequis
- Python 3.9+
- Django 4.2+ (ou 5.x)
- Un projet MonCashConnect avec clé secrète — créer un projet
Installation
pip install moncashconnectOu ajoutez moncashconnect dans votre requirements.txt. Zéro dépendance — utilise uniquement la bibliothèque standard Python.
Configuration
Ajoutez dans settings.py (ou utilisez un fichier .env avec python-decouple) :
import os
MCC_SECRET_KEY = os.environ.get("MCC_SECRET_KEY", "")
MCC_WEBHOOK_SECRET = os.environ.get("MCC_WEBHOOK_SECRET", "")Fichier .env (non versionné) :
MCC_SECRET_KEY=sk_proj_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MCC_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxVues de paiement
Dans payments/views.py :
from django.shortcuts import redirect
from django.http import HttpResponse, HttpResponseBadRequest
from django.conf import settings
from moncashconnect import MonCashClient, MonCashError
# Instancié une fois au niveau du module — pas de state partagé, c'est safe
client = MonCashClient(settings.MCC_SECRET_KEY)
def initiate_payment(request, order_id: str, amount: int):
"""Lance le flux de paiement MonCash pour une commande."""
try:
payment = client.create_payment(
amount=amount,
reference_id=order_id,
return_url=request.build_absolute_uri("/payment/return/"),
)
except MonCashError as exc:
return HttpResponseBadRequest(str(exc))
return redirect(payment["paymentUrl"])
def payment_return(request):
"""Page de retour après le paiement MonCash."""
ref = request.GET.get("ref")
if not ref:
return HttpResponseBadRequest("Référence manquante.")
try:
tx = client.get_payment_status(ref)
except MonCashError as exc:
return HttpResponse(str(exc), status=exc.status_code)
# Ne faites pas confiance aux paramètres URL pour confirmer le paiement —
# attendez le webhook payment.completed pour créditer définitivement.
return render(request, "payments/return.html", {"tx": tx})Vue webhook
La vue webhook doit être décorée avec @csrf_exempt. La protection est assurée par la vérification HMAC-SHA256, non par le token CSRF.
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.http import HttpResponse
from moncashconnect import construct_event, MonCashError
from django.conf import settings
from .models import Order
@csrf_exempt
@require_POST
def moncash_webhook(request):
raw_body = request.body # bytes, AVANT tout parsing
signature = request.META.get("HTTP_X_MCC_SIGNATURE", "")
timestamp = request.META.get("HTTP_X_MCC_TIMESTAMP", "")
try:
event = construct_event(
raw_body,
signature,
timestamp,
settings.MCC_WEBHOOK_SECRET,
)
except MonCashError as exc:
return HttpResponse(str(exc), status=exc.status_code)
if event["event"] == "payment.completed":
Order.objects.filter(
reference=event["reference"]
).update(status="paid")
elif event["event"] == "payment.failed":
Order.objects.filter(
reference=event["reference"]
).update(status="failed")
return HttpResponse("OK")request.body en premier — accéder à request.POST ou request.data (DRF) avant consomme le stream et invalide la signature.URLs
Dans payments/urls.py :
from django.urls import path
from . import views
urlpatterns = [
path("payment/return/", views.payment_return, name="payment-return"),
path("webhooks/moncash/", views.moncash_webhook, name="moncash-webhook"),
]Incluez dans project/urls.py :
from django.urls import path, include
urlpatterns = [
# ...
path("", include("payments.urls")),
]https://votresite.com/webhooks/moncash/ comme URL webhook dans votre projet MonCashConnect. N'oubliez pas le slash final Django.Liste de contrôle avant mise en production
MCC_SECRET_KEY et MCC_WEBHOOK_SECRET sont dans les variables d'environnement du serveur (pas dans settings.py en clair)
DEBUG = False en production
La vue webhook est décorée @csrf_exempt et @require_POST
request.body est lu AVANT tout accès à request.POST ou json.loads()
La vue webhook est idempotente (peut recevoir le même événement plusieurs fois)
La page de retour vérifie le statut via get_payment_status() — pas les paramètres GET
L'URL webhook https://votresite.com/webhooks/moncash/ est configurée dans le tableau de bord MonCashConnect
Autres guides d'intégration