Vue d’ensemble
Vous devez vérifier le statut des paiements car le traitement bancaire est asynchrone. Utilisez deux méthodes simples :- Tâche cron : Vérifiez les commandes en attente toutes les 20 minutes
- Vérification manuelle : Lorsque le client consulte sa commande
Méthode 1 : Tâche cron (toutes les 20 minutes)
const cron = require("node-cron");
// Exécuter toutes les 20 minutes
cron.schedule("*/20 * * * *", async () => {
console.log("Vérification des paiements en attente...");
try {
// Récupérer les commandes en attente des dernières 24 heures
const pendingOrders = await db.orders.find({
status: "PENDING",
paymentRef: { $exists: true },
createdAt: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) },
});
for (const order of pendingOrders) {
await checkAndUpdateOrder(order.id, order.paymentRef);
await sleep(100); // Petit délai entre les requêtes
}
console.log(`Vérifié ${pendingOrders.length} commandes`);
} catch (error) {
console.error("Erreur tâche cron :", error);
}
});
async function checkAndUpdateOrder(orderId, paymentRef) {
try {
const response = await fetch(
`https://api.oneclickdz.com/v3/ocpay/checkPayment/${paymentRef}`,
{
headers: { "X-Access-Token": process.env.ONECLICK_API_KEY },
}
);
const data = await response.json();
const status = data.data.status;
if (status === "CONFIRMED") {
await db.orders.update(orderId, { status: "PAID" });
console.log(`✅ Commande ${orderId} marquée comme PAYÉE`);
} else if (status === "FAILED") {
await db.orders.update(orderId, { status: "FAILED" });
console.log(`❌ Commande ${orderId} marquée comme ÉCHOUÉE`);
}
} catch (error) {
console.error(`Erreur vérification commande ${orderId} :`, error);
}
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
from apscheduler.schedulers.background import BackgroundScheduler
import requests
import os
from datetime import datetime, timedelta
import time
scheduler = BackgroundScheduler()
# Exécuter toutes les 20 minutes
@scheduler.scheduled_job('interval', minutes=20)
def check_pending_payments():
print('Vérification des paiements en attente...')
try:
# Récupérer les commandes en attente des dernières 24 heures
yesterday = datetime.now() - timedelta(days=1)
pending_orders = db.orders.find({
'status': 'PENDING',
'paymentRef': {'$exists': True},
'createdAt': {'$gte': yesterday}
})
count = 0
for order in pending_orders:
check_and_update_order(order['id'], order['paymentRef'])
time.sleep(0.1) # Petit délai entre les requêtes
count += 1
print(f'Vérifié {count} commandes')
except Exception as e:
print(f'Erreur tâche cron : {e}')
def check_and_update_order(order_id, payment_ref):
try:
response = requests.get(
f'https://api.oneclickdz.com/v3/ocpay/checkPayment/{payment_ref}',
headers={'X-Access-Token': os.getenv('ONECLICK_API_KEY')}
)
data = response.json()
status = data['data']['status']
if status == 'CONFIRMED':
db.orders.update(order_id, {'status': 'PAID'})
print(f'✅ Commande {order_id} marquée comme PAYÉE')
elif status == 'FAILED':
db.orders.update(order_id, {'status': 'FAILED'})
print(f'❌ Commande {order_id} marquée comme ÉCHOUÉE')
except Exception as e:
print(f'Erreur vérification commande {order_id} : {e}')
# Démarrer le planificateur
scheduler.start()
<?php
// cron-check-payments.php
// Ajouter au crontab : */20 * * * * php /path/to/cron-check-payments.php
require_once 'config.php';
echo "Vérification des paiements en attente...\n";
try {
// Récupérer les commandes en attente des dernières 24 heures
$yesterday = date('Y-m-d H:i:s', strtotime('-24 hours'));
$stmt = $db->prepare("
SELECT id, payment_ref
FROM orders
WHERE status = 'PENDING'
AND payment_ref IS NOT NULL
AND created_at >= ?
");
$stmt->execute([$yesterday]);
$pendingOrders = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($pendingOrders as $order) {
checkAndUpdateOrder($order['id'], $order['payment_ref']);
usleep(100000); // Délai de 100ms
}
echo "Vérifié " . count($pendingOrders) . " commandes\n";
} catch (Exception $e) {
echo "Erreur tâche cron : " . $e->getMessage() . "\n";
}
function checkAndUpdateOrder($orderId, $paymentRef) {
global $db;
try {
$ch = curl_init("https://api.oneclickdz.com/v3/ocpay/checkPayment/{$paymentRef}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-Access-Token: ' . getenv('ONECLICK_API_KEY')
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
$status = $data['data']['status'];
if ($status === 'CONFIRMED') {
$stmt = $db->prepare("UPDATE orders SET status = 'PAID' WHERE id = ?");
$stmt->execute([$orderId]);
echo "✅ Commande {$orderId} marquée comme PAYÉE\n";
} elseif ($status === 'FAILED') {
$stmt = $db->prepare("UPDATE orders SET status = 'FAILED' WHERE id = ?");
$stmt->execute([$orderId]);
echo "❌ Commande {$orderId} marquée comme ÉCHOUÉE\n";
}
} catch (Exception $e) {
echo "Erreur vérification commande {$orderId} : " . $e->getMessage() . "\n";
}
}
?>
Configurer la tâche cron
Ajoutez à votre crontab (Linux/Unix) :# Modifier le crontab
crontab -e
# Ajouter une ligne pour exécuter toutes les 20 minutes
*/20 * * * * /usr/bin/node /path/to/cron-job.js >> /var/log/payment-check.log 2>&1
# Ou pour Python
*/20 * * * * /usr/bin/python3 /path/to/cron-job.py >> /var/log/payment-check.log 2>&1
# Ou pour PHP
*/20 * * * * /usr/bin/php /path/to/cron-check-payments.php >> /var/log/payment-check.log 2>&1
Méthode 2 : Vérification manuelle (quand le client consulte sa commande)
Déjà implémenté à l’Étape 2 ! Quand le client arrive sur la page de commande, elle vérifie automatiquement une fois. Optionnel : Ajoutez un bouton pour vérifier à la demande (vérifie au maximum toutes les minutes) :<!DOCTYPE html>
<html>
<head>
<title>Statut de la commande</title>
</head>
<body>
<h1>Statut de la commande</h1>
<p>Statut : <span id="status">PENDING</span></p>
<button id="checkBtn" onclick="startChecking()">
Check Payment Status
</button>
<p id="message"></p>
<script>
let checking = false;
let checkInterval = null;
const orderId = window.location.pathname.split("/").pop();
async function checkPayment() {
const response = await fetch(`/orders/${orderId}/check`, {
method: "POST",
});
const data = await response.json();
document.getElementById("status").textContent = data.status;
if (data.status === "CONFIRMED") {
document.getElementById("message").textContent =
"✅ Paiement confirmé !";
stopChecking();
setTimeout(() => location.reload(), 2000);
} else if (data.status === "FAILED") {
document.getElementById("message").textContent = "❌ Paiement échoué";
stopChecking();
} else {
document.getElementById("message").textContent =
"⏳ Toujours en attente...";
}
}
function startChecking() {
if (checking) return;
checking = true;
document.getElementById("checkBtn").disabled = true;
// Check immediately
checkPayment();
// Puis vérifier toutes les minutes
checkInterval = setInterval(checkPayment, 60000);
// Arrêter après 10 minutes
setTimeout(stopChecking, 10 * 60000);
}
function stopChecking() {
checking = false;
document.getElementById("checkBtn").disabled = false;
if (checkInterval) {
clearInterval(checkInterval);
checkInterval = null;
}
}
// Vérification automatique au chargement (si en attente)
if (document.getElementById("status").textContent === "PENDING") {
checkPayment();
}
</script>
</body>
</html>
Résumé
Deux méthodes simples :
- ✅ Tâche cron toutes les 20 minutes pour toutes les commandes en attente
- ✅ Vérification manuelle quand le client consulte sa commande (maximum toutes les minutes)
- ✅ Vérification automatique une fois au chargement de la page de commande
Prochaines étapes
Continuer vers les bonnes pratiques
Apprenez les bonnes pratiques de sécurité et de gestion des erreurs

