Jèko
Paiements

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 : true pour activer ce mode. Omis ou false, vous obtenez le flux hébergé standard.
  • payerPhone : numéro mobile ivoirien du payeur, indicatif 225 obligatoire (+225 ou 225), suivi de 01, 05 ou 07 puis huit chiffres. +2250765432108 et 2250765432108 sont valides, 0765432108 est refusé. Obligatoire dès que forceProviderDirect vaut true.

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 :

  1. Jèko crée la demande de paiement, comme pour un paiement en ligne classique.
  2. Jèko appelle immédiatement l'opérateur avec le numéro du payeur, en lui transmettant vos successUrl et errorUrl.

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 paiementCe que contient redirectUrlCe que vous en faites
orangeL'URL webpay d'Orange MoneyRedirigez le payeur dessus
waveL'URL de paiement de WaveRedirigez le payeur dessus
djamoL'URL de paiement de DjamoRedirigez le payeur dessus
mtnLa page hébergée par JèkoVoir ci-dessous
moovLa page hébergée par JèkoVoir 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

SituationRéponse
forceProviderDirect: true sans payerPhone422, payerPhone requis
payerPhone sans indicatif 225, par exemple 0765432108422, format invalide
Référence déjà utilisée par une tentative précédente409 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.

Et ensuite

On this page