Aller au contenu

Surveillance

Les signaux qui méritent une alerte et la source de chacun.

Vos propres données révèlent la plupart des incidents de paiement avant leur signalement. Quatre signaux couvrent presque tous les cas et chacun possède une source précise.

SignalSourceSignification d'une variation
Taux de réussite par canalGET /paymentsDégradation d'un opérateur ou bug dans votre système
Paiements bloqués dans pendingGET /payments?status=pendingPayeurs qui ne confirment pas ou prestataire sans réponse
Solde disponibleGET /balancePayouts bientôt voués à l'échec
Échecs de livraison des webhooksKonsoleCommandes qui ne sont pas livrées sans erreur visible

Taux de réussite par canal

Calculez le taux de votre côté au lieu de le demander à Wajub. Récupérez la période, comptez les éléments par statut et envoyez la valeur à votre système d'alerte.

Taux d'échec de la dernière journée
const today = new Date().toISOString().slice(0, 10);
const page = await wajub.payments.list({ date_from: today, per_page: 100 });

const counts = { succeeded: 0, failed: 0, pending: 0, other: 0 };
for await (const payment of page) {
  counts[payment.status in counts ? payment.status : 'other'] += 1;
}

const settled = counts.succeeded + counts.failed;
const failureRate = settled > 0 ? (counts.failed / settled) * 100 : 0;

metrics.gauge('wajub.payments.failure_rate', failureRate, { env: 'production' });

Calculez le taux uniquement à partir des paiements terminés. Inclure pending dans le dénominateur améliore artificiellement le taux d'échec lorsque des paiements sont bloqués, ce qui masque justement le problème recherché.

Paiements bloqués

Un paiement qui reste pending longtemps après sa création correspond soit à un payeur qui a abandonné, soit à un prestataire qui n'a jamais répondu. Les deux situations sont identiques vues de l'extérieur, d'où l'utilité d'une alerte.

Paiements en attente depuis plus de trente minutes
const cutoff = Date.now() - 30 * 60_000;
const stale = [];

for await (const payment of await wajub.payments.list({ status: 'pending', per_page: 100 })) {
  if (Date.parse(payment.created_at) < cutoff) stale.push(payment.id);
}

if (stale.length > 0) alert('wajub.payments.stuck', { count: stale.length, ids: stale.slice(0, 20) });

Les paiements expirent automatiquement après expires.in minutes, soit 24 heures par défaut. Cette alerte doit donc surveiller l'écart entre la création et l'expiration plutôt que de considérer chaque paiement pending comme un problème.

Solde

GET /balance renvoie huit valeurs. Les deux importantes pour les alertes sont available et pending.

ChampSignification
totalTous les fonds enregistrés
availableFonds immédiatement disponibles au retrait
pendingFonds crédités encore soumis à leur période de retenue
reserved, hold, disputed, in.transit, creditFonds retenus pour une raison précise

Les payouts utilisent available. Configurez donc l'alerte sur cette valeur. Les fonds dans pending ne peuvent pas encore être envoyés. Plafonds et quotas présente les durées de retenue par réseau.

Vérification d'un solde faible
const balance = await wajub.balance.retrieve();

metrics.gauge('wajub.balance.available', balance.available, { currency: balance.currency });

if (balance.available < FLOOR_FOR_TOMORROWS_PAYOUTS) {
  alert('wajub.balance.low', { available: balance.available, pending: balance.pending });
}

La réponse est mise en cache pendant trois minutes. Un polling plus fréquent renvoie les mêmes valeurs.

État des webhooks

Les échecs de livraison sont le seul signal impossible à calculer depuis votre base de données. Un webhook qui n'arrive jamais ne laisse aucune trace chez vous. Konsole conserve l'historique des livraisons, les codes de réponse et les nouvelles tentatives.

Vous pouvez aussi rechercher les événements, ce qui permet de récupérer sans ouvrir de ticket.

Rechercher un événement et le renvoyer
const events = await wajub.events.list({ type: 'payment.succeeded', per_page: 100 });
const event = events.data.find((e) => e.data?.id === paymentId);

if (event) await wajub.events.resend(event.id);

Chaque livraison fait l'objet de cinq tentatives après 30 secondes, 1 minute, 5 minutes, 10 minutes et 1 heure. Un endpoint qui met plus de 10 secondes à répondre est considéré comme échoué et fait l'objet d'une nouvelle tentative. Un handler lent produit donc des doublons plutôt que des pertes.

Konsole

Konsole permet d'examiner un paiement en échec de bout en bout, ce qu'aucune mesure ne peut fournir.

VueInformations fournies
API LogsDonnées envoyées, réponse reçue et durée
Routing LogPrestataire sélectionné et repli effectué
Event StreamMême décision affichée en direct
Webhook TesterTentatives de livraison, codes de réponse et répétition

Reliez vos logs aux nôtres

Chaque réponse contient X-Request-Id, X-Trace-Id et un traceparent W3C. Envoyez votre propre X-Request-Id, dans la limite de 64 caractères. Le même identifiant apparaîtra alors dans vos logs et dans les nôtres.

Transmettre votre propre identifiant de requête
curl https://api.wajub.com/payments \
  -H "Authorization: sk_test.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…" \
  -H "X-Request-Id: checkout-7f3a91" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 25000, "currency": "XAF", "customer": { "email": "amina@example.com" } }' \
  -D -

Enregistrez cette valeur de votre côté chaque fois qu'un appel échoue. Le support vous la demandera en premier, car elle transforme un signalement vague en une ligne précise.

Marge avant la limite de requêtes

X-RateLimit-Remaining figure dans chaque réponse. Son affichage dans un graphique permet d'anticiper une réponse 429 une semaine à l'avance. Limites de requêtes présente les quatre compteurs et l'attente progressive à mettre en place.

État de la plateforme

Les incidents, les dégradations et les périodes de maintenance sont publiés sur status.wajub.com, avec des abonnements par e-mail et webhook. Consultez ce site avant d'ouvrir un ticket. Une panne chez un opérateur y figure généralement déjà.

Que pensez-vous de ce contenu ?