NaabigaPay · Django
QuickstartsDocs

DocsQuickstarts › Django

Backend

Intégrer NaabigaPay en Django

Une vue crée le lien de paiement avec requests, une vue webhook vérifie la signature avec hmac, puis marque la commande payée.

Deux vues côté serveur : l'une crée un lien de paiement quand un client veut payer, l'autre vérifie la signature du webhook une fois le paiement réussi. La clé secrète (sk_live_…) reste dans vos réglages serveur et n'atteint jamais le navigateur.

1.Créer le lien

Votre front appelle cette vue ; elle appelle POST/v1/payment-links avec la clé secrète, puis renvoie l'url de paiement.

paiements/views.py
# pip install requests
import os
import json
import requests
from django.http import JsonResponse

NPAY = 'https://api.pay.naabiga.com/api/v1'
SECRET = os.environ['NPAY_SECRET']  # sk_live_... : reste côté serveur

def creer_lien(request):
    corps = json.loads(request.body)
    commande = corps['commande']

    r = requests.post(
        f'{NPAY}/payment-links',
        headers={
            'Authorization': f'Bearer {SECRET}',
            'Idempotency-Key': f'cmd-{commande}',  # évite un double lien si retry
        },
        json={
            'amount': corps['amount'],           # entier, en FCFA
            'reference': commande,               # votre numéro de commande
            'description': f'Commande {commande}',
            'return_url': 'https://monsite.com/merci',
            'cancel_url': 'https://monsite.com/panier',
            'single_use': True,
        },
        timeout=15,
    )
    r.raise_for_status()
    return JsonResponse({'url': r.json()['url']})  # le front ouvre cette URL

Pour un montant libre, remplacez amount par amount_min, amount_max et une description.

2.Vérifier le webhook

NaabigaPay envoie POST à l'URL enregistrée dans le portail marchand, avec les en-têtes X-NPay-Event et X-NPay-Signature (HMAC-SHA256 du corps brut). Utilisez request.body (les octets bruts), recalculez le HMAC, comparez avec hmac.compare_digest, et ne créditez qu'ensuite.

paiements/views.py (suite)
import hmac
import hashlib
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

WEBHOOK_SECRET = os.environ['NPAY_WEBHOOK_SECRET'].encode()

@csrf_exempt  # requête serveur à serveur, sans jeton CSRF
def webhook(request):
    signature = request.headers.get('X-NPay-Signature', '')
    # request.body = corps BRUT (bytes) ; la signature porte sur ces octets.
    attendu = hmac.new(WEBHOOK_SECRET, request.body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(signature, attendu):  # comparaison à temps constant
        return HttpResponse('signature invalide', status=400)

    charge = json.loads(request.body)
    if request.headers.get('X-NPay-Event') == 'payment.succeeded':
        # data.merchant_reference = VOTRE numéro de commande (la reference du lien).
        marquer_commande_payee(charge['data']['merchant_reference'])
    return HttpResponse('ok')

Astuce. Ne lisez pas le corps avec un parseur avant de vérifier : signez toujours sur request.body intact, sinon le HMAC ne correspond plus.

Router les deux vues

paiements/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('api/pay', views.creer_lien),
    path('webhooks/naabiga', views.webhook),
]

Référence rapide

MéthodeEndpointRôle
POST/v1/payment-linksCréer un lien de paiement
GET/v1/payments/{reference}Statut d'un paiement

Base : https://api.pay.naabiga.com/api/v1 · Auth : Authorization: Bearer sk_…. Voir la documentation complète et le format des webhooks.