Gérer les échecs de paiement
Comprendre les raisons d'échec des paiements et comment les gérer
Vue d'ensemble
Un paiement échoue le plus souvent parce que le lien a expiré ou a déjà servi, parce qu'un identifiant est inconnu (storeId, deviceId, demande de paiement), ou parce que l'opérateur refuse l'opération. Cette page liste chaque erreur renvoyée par l'API et ce qu'il faut en faire.
Statuts de paiement
Seules les demandes de paiement ont un statut. Les liens de paiement, eux, exposent canReceivePayments.
Les demandes de paiement peuvent avoir les statuts suivants :
pending: Le paiement est en attente de confirmationsuccess: Le paiement a été effectué avec succèserror: Le paiement a échoué
Pour les liens de paiement, utilisez le champ canReceivePayments (booléen) pour vérifier si le lien peut accepter de nouveaux paiements.
Erreurs communes
Lien expiré
Erreur : link_expired ou payment_link_expired
Message : "Payment link has expired"
Cause : Le lien de paiement a expiré et ne peut plus accepter de paiements.
Solution :
- Vérifiez toujours
canReceivePaymentsavant de diriger un client vers un lien - Créez un nouveau lien de paiement si le lien a expiré
- Informez le client que le lien a expiré et proposez de créer un nouveau lien
Exemple de gestion :
async function checkAndRedirectToPayment(paymentLinkId) {
// Vérifier la disponibilité du lien
const response = await fetch(
`https://api.jeko.africa/partner_api/payment_links/${paymentLinkId}`,
{
headers: {
'X-API-KEY': apiKey,
'X-API-KEY-ID': apiKeyId
}
}
);
const paymentLink = await response.json();
if (!paymentLink.canReceivePayments) {
// Le lien a expiré ou a été utilisé
if (paymentLink.allowMultiplePayments === false) {
// Lien à usage unique - créer un nouveau lien
const newLink = await createNewPaymentLink(paymentLink.storeId, paymentLink.amount);
return newLink.link;
} else {
// Lien expiré - informer l'utilisateur
throw new Error('Le lien de paiement a expiré. Veuillez créer un nouveau lien.');
}
}
return paymentLink.link;
}Lien déjà utilisé
Erreur : link_used ou payment_link_already_used
Message : "Payment link has already been used"
Cause : Le lien de paiement est à usage unique (allowMultiplePayments: false) et a déjà été utilisé pour un paiement réussi.
Solution :
- Vérifiez
canReceivePaymentsavant de diriger un client vers un lien - Pour les liens à usage unique, créez un nouveau lien pour chaque paiement
- Informez le client que le lien a déjà été utilisé
Exemple de gestion :
async function handlePaymentLink(paymentLinkId) {
const paymentLink = await getPaymentLink(paymentLinkId);
if (!paymentLink.canReceivePayments) {
if (paymentLink.allowMultiplePayments === false) {
// Lien à usage unique déjà utilisé
// Créer un nouveau lien
const newLink = await createPaymentLink({
storeId: paymentLink.storeId,
title: paymentLink.title,
amountCents: paymentLink.amount.amount,
currency: paymentLink.amount.currency,
allowMultiplePayments: false
});
return {
error: 'LINK_USED',
message: 'Ce lien a déjà été utilisé. Un nouveau lien a été créé.',
newLink: newLink.link
};
}
}
return { link: paymentLink.link };
}Demande de paiement non trouvée (404 Not Found)
Erreur : payment_request_not_found
Message : "Payment request not found"
Cause : La demande de paiement n'existe pas ou n'appartient pas à votre entreprise.
Solution :
- Vérifiez que l'ID de la demande de paiement est correct
- Vérifiez que la demande appartient à votre entreprise
- Vérifiez que la demande n'a pas été supprimée
Magasin non trouvé (404 Not Found)
Erreur : store_not_found
Message : "Store not found"
Cause : Le storeId fourni n'existe pas ou n'appartient pas à votre entreprise.
Solution :
- Vérifiez que le
storeIdest correct - Utilisez l'endpoint pour lister vos magasins
- Assurez-vous que le magasin existe et est actif
Dispositif non trouvé (422 Validation Error)
Erreur : validation_error
Message : "The paymentDetails.data.deviceId field is required when paymentDetails.type is soundbox"
Cause : Pour les paiements Jèko Box, le deviceId est requis mais manquant ou invalide.
Solution :
- Vérifiez que le
deviceIdest fourni pour les paiements Jèko Box - Vérifiez que le
deviceIdexiste via l'endpoint - Assurez-vous que le terminal est actif et associé au bon magasin
Erreur de validation (422 Unprocessable Entity)
Erreur : validation_error
Message : "Validation error"
Cause : Les données fournies ne respectent pas les règles de validation.
Problèmes courants :
- Montant inférieur au minimum (100 centimes pour payment_requests, 10000 centimes pour payment_links) ou qui n'est pas un multiple de 100
- Code devise invalide (doit être ISO 4217, 3 caractères)
- Référence manquante ou invalide (5 à 100 caractères)
- Titre manquant ou invalide pour payment_links (10-255 caractères)
- URLs de callback invalides (doivent être des URLs bien formées ; HTTPS recommandé)
- Méthode de paiement invalide
Solution :
- Vérifiez que tous les champs requis sont présents
- Vérifiez que les valeurs respectent les contraintes (montant minimum, longueur, format)
- Vérifiez que les URLs sont valides et utilisent HTTPS
Paiement échoué
Erreur : payment_failed ou transaction_failed
Message : "Payment failed"
Cause : Le paiement a échoué côté opérateur (Mobile Money ou banque).
Solution :
- Vérifiez que le client a suffisamment de fonds
- Vérifiez que le compte du client est actif
- Proposez au client de réessayer
- Contactez le support si le problème persiste
Clé API invalide (401 Unauthorized)
Erreur : unauthorized
Message : "Unauthorized"
Cause : Les clés API sont invalides, manquantes ou expirées.
Solution :
- Vérifiez que les en-têtes
X-API-KEYetX-API-KEY-IDsont présents - Vérifiez que les clés API sont correctes
- Régénérez vos clés API depuis le Dashboard Business si nécessaire
Accès interdit (403 Forbidden)
Erreur : forbidden ou forbidden_action
Message : "Forbidden" ou "Action interdite"
Cause : La clé API n'a pas la permission d'accéder à cette ressource ou d'effectuer cette action.
Solution :
- Vérifiez les permissions de votre clé API
- Contactez le support pour vérifier les permissions de votre compte
Conflit de référence (409 Conflict)
Erreur : payment_request_exists_with_reference
Message : "Une demande de paiement avec cette référence existe déjà"
Cause : Une demande de paiement avec la même référence existe déjà.
Solution :
- Utilisez des références uniques pour chaque demande de paiement
- Incluez un identifiant unique (timestamp, UUID, orderId) dans la référence
Gestion des erreurs dans votre application
Vérification préventive
Avant de créer un paiement, effectuez ces vérifications :
- Vérifier l'existence du magasin :
curl -X GET "https://api.jeko.africa/partner_api/stores/{storeId}" \
-H "X-API-KEY: your_api_key_here" \
-H "X-API-KEY-ID: your_api_key_id_here"- Pour les paiements Jèko Box, vérifier le terminal :
curl -X GET "https://api.jeko.africa/partner_api/devices" \
-H "X-API-KEY: your_api_key_here" \
-H "X-API-KEY-ID: your_api_key_id_here"- Pour les liens de paiement, vérifier la disponibilité :
curl -X GET "https://api.jeko.africa/partner_api/payment_links/{paymentLinkId}" \
-H "X-API-KEY: your_api_key_here" \
-H "X-API-KEY-ID: your_api_key_id_here"Gestion des erreurs dans le code
async function createPaymentRequest(paymentData) {
try {
// Vérifications préventives
await validateStore(paymentData.storeId);
if (paymentData.type === 'soundbox') {
await validateDevice(paymentData.deviceId);
}
// Créer la demande de paiement
const response = await fetch('https://api.jeko.africa/partner_api/payment_requests', {
method: 'POST',
headers: {
'X-API-KEY': apiKey,
'X-API-KEY-ID': apiKeyId,
'Content-Type': 'application/json'
},
body: JSON.stringify(paymentData)
});
if (!response.ok) {
const error = await response.json();
// Gérer les erreurs spécifiques
switch (error.id) {
case 'payment_request_exists_with_reference':
throw new Error('Une demande avec cette référence existe déjà. Utilisez une référence unique.');
case 'store_not_found':
throw new Error('Magasin introuvable. Vérifiez le storeId.');
case 'validation_error':
throw new Error(`Erreur de validation: ${error.extras?.errors?.map(e => e.message).join(', ')}`);
case 'unauthorized':
throw new Error('Clés API invalides. Vérifiez vos identifiants.');
default:
throw new Error(`Erreur: ${error.message}`);
}
}
return await response.json();
} catch (error) {
console.error('Erreur lors de la création du paiement:', error);
throw error;
}
}
async function handlePaymentLink(paymentLinkId) {
try {
// Vérifier la disponibilité du lien
const response = await fetch(
`https://api.jeko.africa/partner_api/payment_links/${paymentLinkId}`,
{
headers: {
'X-API-KEY': apiKey,
'X-API-KEY-ID': apiKeyId
}
}
);
if (!response.ok) {
const error = await response.json();
if (error.id === 'payment_link_not_found') {
throw new Error('Lien de paiement introuvable.');
}
throw new Error(`Erreur: ${error.message}`);
}
const paymentLink = await response.json();
if (!paymentLink.canReceivePayments) {
if (paymentLink.allowMultiplePayments === false) {
throw new Error('LINK_USED', 'Ce lien a déjà été utilisé.');
} else {
throw new Error('LINK_EXPIRED', 'Ce lien a expiré.');
}
}
return paymentLink.link;
} catch (error) {
console.error('Erreur lors de la vérification du lien:', error);
throw error;
}
}Utilisation des webhooks pour le suivi
Configurez des webhooks pour être notifié automatiquement des changements de statut des paiements. Cela vous permet de :
- Suivre les paiements en temps réel
- Gérer les échecs automatiquement
- Mettre à jour votre système lorsque le statut change
Consultez la documentation Webhooks pour plus d'informations.
Bonnes pratiques
- Vérifications préventives : Toujours vérifier les prérequis avant de créer un paiement
- Gestion d'erreurs : Traitez chaque code d'erreur listé ci-dessus
- Logging : Enregistrez toutes les erreurs pour le débogage et l'analyse
- Messages utilisateur : Informez l'utilisateur des erreurs de manière claire et actionnable
- Retry logic : Pour les erreurs temporaires, implémentez une logique de réessai avec backoff exponentiel
- Monitoring : Surveillez les taux d'échec pour identifier les problèmes récurrents
- Vérification des liens : Toujours vérifier
canReceivePaymentsavant de diriger un client vers un lien
Support
Si vous rencontrez des erreurs persistantes ou des problèmes non documentés, contactez le support Jèko à hello@jeko.africa.