API direct (encaissement direct fournisseur)
Envoyer le payeur droit chez son opérateur, sans passer par la page de paiement hébergée par Jèko
L'API direct est une variante du paiement en ligne. Au lieu de renvoyer le payeur vers la page de paiement hébergée par Jèko, elle contacte son opérateur immédiatement, avec le numéro que vous fournissez.
Vous construisez alors votre propre tunnel de paiement, et vous prenez à votre charge les cas limites de chaque opérateur.
Pour plus de détails : Create payment request (Partner API)
Quand la choisir
Le flux hébergé reste le choix par défaut : il absorbe pour vous les redirections, les contraintes d'interface et les variations de parcours propres à chaque opérateur.
L'API direct n'a de sens que si les trois conditions suivantes sont réunies :
- Vous connaissez déjà le numéro du payeur, vérifié, avant de créer la demande
- Vous connaissez déjà le moyen de paiement qu'il a choisi
- Vous voulez maîtriser l'écran de paiement de bout en bout et vous acceptez d'en assumer les cas limites
Si l'une des trois manque, restez sur le paiement en ligne.
Un opérateur peut modifier son parcours sans préavis. Sur le flux hébergé, Jèko absorbe ce changement pour vous. En API direct, c'est votre intégration qui le subit.
Les deux paramètres
L'API direct utilise le même endpoint et le même type que le paiement en ligne,
avec
paymentDetails.type: "redirect". Deux champs de paymentDetails.data s'y ajoutent.
forceProviderDirect:truepour activer ce mode. Omis oufalse, vous obtenez le flux hébergé standard.payerPhone: numéro mobile ivoirien du payeur, indicatif 225 obligatoire (+225ou225), suivi de01,05ou07puis huit chiffres.+2250765432108et2250765432108sont valides,0765432108est refusé. Obligatoire dès queforceProviderDirectvauttrue.
Tous les autres champs sont ceux du paiement en ligne :
storeId, amountCents, currency, reference, paymentMethod, successUrl et errorUrl.
Comment ça marche
La création se déroule en deux temps :
- Jèko crée la demande de paiement, comme pour un paiement en ligne classique.
- Jèko appelle immédiatement l'opérateur avec le numéro du payeur, en lui transmettant vos
successUrleterrorUrl.
C'est le second appel qui distingue l'API direct. Il a deux conséquences que vous devez traiter,
détaillées plus bas : le contenu de redirectUrl dépend de l'opérateur, et un échec de cet appel
consomme votre référence.
Exemple de requête
curl -X POST "https://api.jeko.africa/partner_api/payment_requests" \
-H "X-API-KEY: your_api_key_here" \
-H "X-API-KEY-ID: your_api_key_id_here" \
-H "Content-Type: application/json" \
-d '{
"storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
"amountCents": 10000,
"currency": "XOF",
"reference": "PAY-DIRECT-2024-001",
"paymentDetails": {
"type": "redirect",
"data": {
"paymentMethod": "orange",
"forceProviderDirect": true,
"payerPhone": "+2250765432108",
"successUrl": "https://myapp.com/payment/success?reference=PAY-DIRECT-2024-001",
"errorUrl": "https://myapp.com/payment/error?reference=PAY-DIRECT-2024-001"
}
}
}'Réponse réussie
{
"id": "d22c81f3-ee04-4ec5-8bd2-cd8af5dabcfc",
"storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
"reference": "PAY-DIRECT-2024-001",
"type": "redirect",
"paymentMethod": "orange",
"status": "pending",
"redirectUrl": "https://webpay.orange.ci/...",
"errorReason": null
}La réponse a la même forme qu'en paiement en ligne. Seul le contenu de redirectUrl change, et il
dépend de l'opérateur.
Le comportement dépend de l'opérateur
C'est le point le plus important de cette page. Les cinq moyens de paiement ne se comportent pas de la même façon en mode direct.
| Moyen de paiement | Ce que contient redirectUrl | Ce que vous en faites |
|---|---|---|
orange | L'URL webpay d'Orange Money | Redirigez le payeur dessus |
wave | L'URL de paiement de Wave | Redirigez le payeur dessus |
djamo | L'URL de paiement de Djamo | Redirigez le payeur dessus |
mtn | La page hébergée par Jèko | Voir ci-dessous |
moov | La page hébergée par Jèko | Voir ci-dessous |
MTN et Moov ne redirigent pas
Ces deux réseaux confirment le paiement par USSD : l'opérateur pousse une demande de code
directement sur le téléphone du payeur, il n'y a pas de page à ouvrir. En mode direct, redirectUrl
retombe donc sur le lien hébergé Jèko (), qui sert de
page d'attente.
Ne construisez pas votre intégration en supposant que redirectUrl mène toujours à l'opérateur.
Pour MTN et Moov, affichez plutôt un écran d'attente et laissez le webhook
vous annoncer le résultat.
Si l'appel à l'opérateur échoue
Quand le second appel échoue, l'API renvoie une erreur, mais la demande de paiement a déjà été
créée et votre reference lui reste attachée. Elle est conservée pour la traçabilité.
Conséquence directe : rejouer le même appel avec la même référence renvoie un
409 payment_request_exists_with_reference. Ce n'est pas une erreur de votre code, c'est la
demande de la tentative précédente.
Pour réessayer, générez une nouvelle référence. Une référence par tentative, pas une par commande.
async function createDirectPayment(orderId, attempt = 1) {
const reference = `ORDER-${orderId}-T${attempt}`;
const response = await fetch('https://api.jeko.africa/partner_api/payment_requests', {
method: 'POST',
headers: {
'X-API-KEY': process.env.JEKO_API_KEY,
'X-API-KEY-ID': process.env.JEKO_API_KEY_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
storeId: process.env.JEKO_STORE_ID,
amountCents: 10000,
currency: 'XOF',
reference,
paymentDetails: {
type: 'redirect',
data: {
paymentMethod: 'orange',
forceProviderDirect: true,
payerPhone: '+2250765432108',
successUrl: `https://myapp.com/payment/success?ref=${reference}`,
errorUrl: `https://myapp.com/payment/error?ref=${reference}`
}
}
})
});
if (!response.ok) {
// Ne rejouez jamais avec la même référence : elle est déjà consommée.
if (attempt < 3) return createDirectPayment(orderId, attempt + 1);
throw new Error('Initialisation du paiement direct impossible');
}
return response.json();
}Conservez la correspondance entre votre commande et chaque référence essayée. Le
webhook vous renvoie la référence dans transactionDetails.reference,
c'est elle qui vous permettra de réconcilier.
Erreurs de validation
| Situation | Réponse |
|---|---|
forceProviderDirect: true sans payerPhone | 422, payerPhone requis |
payerPhone sans indicatif 225, par exemple 0765432108 | 422, format invalide |
| Référence déjà utilisée par une tentative précédente | 409 payment_request_exists_with_reference |
Le catalogue complet est dans Gérer les échecs.
Suivre le paiement
Rien ne change par rapport au paiement en ligne. La demande naît en pending, et le
webhook reste la seule confirmation fiable. Les successUrl et
errorUrl sont transmises à l'opérateur, qui y ramène le payeur, mais une redirection n'est pas
une preuve de paiement.