Guide

Guide Django pour appeler le flux de transaction YKNPG depuis une vue serveur.

Guide Django pour appeler le flux de transaction YKNPG depuis une vue serveur.

Pré-requis

  • Python 3.10+, Django 4+, requests, python-dotenv.
  • Conservez YKNPG_API_TOKEN dans .env (ne pas l'exposer dans les templates/JS).
  1. Créer le projet
  • mkdir -p demo_django && cd demo_django
  • python -m venv .venv && source .venv/bin/activate
  • pip install django requests python-dotenv
  • django-admin startproject sitecore .
  • python manage.py startapp payments
  1. Ajouter l'environnement
  • Fichier : .env
YKNPG_API_TOKEN=remplacez-par-votre-jeton
YKNPG_BASE_URL=https://yknpg.ngoul.com/api/v1
  1. Activer l'app et dotenv
  • Fichier : sitecore/settings.py
    • Ajouter "payments" dans INSTALLED_APPS.
    • Charger dotenv en haut :
from pathlib import Path
import dotenv, os
dotenv.load_dotenv()
  1. Créer un formulaire d'entrée
  • Fichier : payments/forms.py
from django import forms

class TransactionForm(forms.Form):
    phone = forms.CharField(label="Phone number", max_length=32)
    amount = forms.IntegerField(min_value=1)
  1. Créer un helper de service
  • Fichier : payments/services.py
import os
import time
import requests

API_TOKEN = os.environ["YKNPG_API_TOKEN"]
BASE_URL = os.environ.get("YKNPG_BASE_URL", "https://yknpg.ngoul.com/api/v1")
HEADERS = {"Authorization": f"Bearer {API_TOKEN}"}


def create_transaction(amount: int, phone: str) -> dict:
    payload = {
        "amount": amount,
        "provider": "ORANGE_MONEY",
        "user_infos": {"number": phone},
        "callback_url": "http://example.com",
        "callback_method": "POST",
        "your_message": "pay this",
        "your_order_ref": "demo-1",
        "provider_fees_on_customer": True,
    }
    resp = requests.post(f"{BASE_URL}/transactions/", headers=HEADERS, json=payload, timeout=10)
    resp.raise_for_status()
    return resp.json()


def pay_transaction(uuid: str) -> dict:
    resp = requests.post(f"{BASE_URL}/transactions/{uuid}/pay/", headers=HEADERS, timeout=10)
    resp.raise_for_status()
    return resp.json()


def poll_status(uuid: str) -> str:
    status = "new"
    while status in {"new", "paying"}:
        time.sleep(5)
        resp = requests.get(f"{BASE_URL}/transactions/{uuid}/", headers=HEADERS, timeout=10)
        resp.raise_for_status()
        status = resp.json()["status"]
    return status
  1. Créer la vue
  • Fichier : payments/views.py
from django.shortcuts import render
from .forms import TransactionForm
from .services import create_transaction, pay_transaction, poll_status


def start_payment(request):
    context = {"form": TransactionForm()}
    if request.method == "POST":
        form = TransactionForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            trx = create_transaction(data["amount"], data["phone"])
            pay = pay_transaction(trx["uuid"])
            final_status = poll_status(trx["uuid"])
            context.update(
                {
                    "instructions": trx.get("instructions"),
                    "post_pay_instructions": pay.get("instructions"),
                    "final_status": final_status,
                    "form": form,
                }
            )
        else:
            context["form"] = form
    return render(request, "payments/start.html", context)
  1. Ajouter l'URL
  • Fichier : payments/urls.py
from django.urls import path
from .views import start_payment

urlpatterns = [path("pay/", start_payment, name="start-payment")]
  • Fichier : sitecore/urls.py (inclure payments)
from django.urls import include, path
urlpatterns = [
    path("", include("payments.urls")),
]
  1. Ajouter le template
  • Fichier : payments/templates/payments/start.html
<!DOCTYPE html>
<html>
  <body>
    <h1>Start payment</h1>
    <form method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Pay</button>
    </form>
    {% if instructions %}
      <p>Gateway instructions: {{ instructions }}</p>
      <p>Post-pay instructions: {{ post_pay_instructions }}</p>
      <p>Final status: {{ final_status }}</p>
    {% endif %}
  </body>
</html>
  1. Lancer le serveur
  • python manage.py migrate
  • python manage.py runserver 0.0.0.0:8000
  • Visiter /pay/ et tester.

Remarques

  • Le token reste cĂ´tĂ© serveur ; le frontend ne le voit jamais.
  • Le flux reflète la commande de management : crĂ©ation → affichage des instructions → paiement → polling.