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_TOKENdans.env(ne pas l'exposer dans les templates/JS).
- Créer le projet
mkdir -p demo_django && cd demo_djangopython -m venv .venv && source .venv/bin/activatepip install django requests python-dotenvdjango-admin startproject sitecore .python manage.py startapp payments
- Ajouter l'environnement
- Fichier :
.env
YKNPG_API_TOKEN=remplacez-par-votre-jeton
YKNPG_BASE_URL=https://yknpg.ngoul.com/api/v1
- Activer l'app et dotenv
- Fichier :
sitecore/settings.py- Ajouter "payments" dans
INSTALLED_APPS. - Charger dotenv en haut :
- Ajouter "payments" dans
from pathlib import Path
import dotenv, os
dotenv.load_dotenv()
- 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)
- 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
- 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)
- 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")),
]
- 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>
- Lancer le serveur
python manage.py migratepython 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.