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 });
}

É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);

Une livraison échouée est retentée pendant 72 heures au plus. Un endpoint qui met plus de 10 secondes à répondre est considéré comme en échec : 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
Journaux APIDonnées envoyées, réponse reçue et durée
Journal de routagePrestataire sélectionné et repli effectué
Webhooks › ÉvénementsEnregistrement de l'événement et endpoints atteints
Webhooks › LivraisonsTentatives de livraison, codes de réponse et relance

Reliez vos logs aux nôtres

Chaque réponse contient X-Request-Id. 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.xxxxxxxxxxxxxxxx…" \
  -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, et son graphique montre le plafond de l'équipe approcher. Il ne compte que le compteur de l'équipe : un 429 du compteur par endpoint (30 appels par minute sur /payments au plan d'entrée), du plafond propre à une clé ou d'une limite nommée comme les écritures de versement peut arriver alors que l'en-tête est encore haut. Comptez vos 429 par leur type (team, api_key, endpoint, payout_writes…) à côté de l'en-tête. Limites de requêtes présente les 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à.

Le même état se lit par programme, sans clé, pour que votre propre supervision l'affiche à côté de vos chiffres :

L'état de la plateforme, en JSON
curl https://dashboard.wajub.com/api/status

La réponse contient status, qui vaut operational, degraded ou major_outage, la liste des incidents ouverts dans active_incidents (id, title, severity, status, is_critical, created_at, started_at), et updated_at. major_outage signifie qu'au moins un incident ouvert est critique.

La santé de l'API elle-même

GET https://api.wajub.com/health répond sans clé : status vaut ok, degraded ou down, version est la version d'API actuelle, et un down répond 503. Il ne s'accompagne d'aucun engagement de disponibilité.

Que pensez-vous de ce contenu ?