Developer Portal Gestion des erreurs

Gestion des erreurs

L'API retourne des erreurs structurées avec des codes HTTP sémantiques et des codes d'erreur machine-readable.

Format de toutes les erreurs

json Structure d'erreur
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The amount field must be at least 100.",
    "details": {
      "amount": ["The amount field must be at least 100."]
    }
  }
}

Codes HTTP

HTTPSignification
200Succès — la transaction a été initiée
400Requête invalide — vérifiez vos paramètres
401Non authentifié — clé API manquante ou invalide
403Accès refusé — scope insuffisant ou IP non autorisée
409Conflit — référence dupliquée ou requête concurrente
422Validation échouée — données invalides
429Trop de requêtes — rate limit atteint
502Erreur provider — le provider de paiement a retourné une erreur
503Aucun provider disponible — essayez un autre opérateur ou pays

Codes d'erreur applicatifs

CodeHTTPDescription
UNAUTHORIZED401Clé API invalide ou absente
FORBIDDEN_SCOPE403Scope insuffisant pour cette action
IP_NOT_ALLOWED403IP source non autorisée par la whitelist
KEY_EXPIRED403La clé API a expiré
VALIDATION_ERROR422Un ou plusieurs champs sont invalides
DUPLICATE_REFERENCE409La référence marchande existe déjà
IDEMPOTENCY_CONFLICT422Même Idempotency-Key, payload différent
CONCURRENT_REQUEST409Requête avec cette clé déjà en cours
PROVIDER_ERROR502Erreur retournée par le provider Mobile Money
NO_PROVIDER_AVAILABLE503Aucun provider ne supporte cette combinaison méthode/pays
PAYMENT_ERROR400Erreur générique de paiement

Stratégie de retry

Certaines erreurs sont transitoires et peuvent être retentées. Voici les recommandations :

Code HTTPPeut être retenté ?Recommandation
429✅ OuiRespecter le header Retry-After
502✅ OuiAttendre 30s, max 3 tentatives
503⚠️ PartielEssayer un autre opérateur (method)
409❌ NonNe pas retenter avec la même référence
422❌ NonCorriger les paramètres avant de réessayer
401 / 403❌ NonVérifier la clé API
php Exemple retry avec backoff
$maxAttempts = 3;
$attempt = 0;
$retryable = [502, 503, 429];

do {
    $response = Http::withHeaders([...])
        ->post('/api/v1/merchant/payin', $payload);

    if ($response->successful()) {
        break;
    }

    if (!in_array($response->status(), $retryable)) {
        throw new \Exception($response->json('error.message'));
    }

    $attempt++;
    sleep(min(30, pow(2, $attempt))); // exponential backoff

} while ($attempt < $maxAttempts);