Jèko

Escrow (séquestre opérationnel)

Bloquer un encaissement Partner jusqu'à libération par la clé plateforme du Service Provider

Produit Service Provider

L'escrow n'est pas un encaissement instantané. Seule la clé plateforme (clé API marchand émise par le Service Provider) peut créer un pot, le lier à un collect, et plus tard le libérer ou le rembourser. Le marchand ne peut pas se débloquer lui-même.

crée uniquement un pot en attente. L'encaissement reste sur les endpoints existants (payment_requests / payment_links) via escrowId. Ce n'est pas un séquestre réglementé : Jèko retient les fonds sur un portefeuille escrow du magasin, invisible dans le solde et dans . Seule la part de l'opérateur de paiement est prélevée au paiement. Les frais Jèko (et votre commission de Service Provider) ne sont prélevés qu'à la libération ou au remboursement.

Clés

CléEncaissement instantané/escrows et escrowId
Clé plateforme (émise par le SP pour ce marchand)OuiOui
Clé Owner / Dashboard du marchandOui403
Clé entreprise du SP (/service_providers/*)Non (pas d'argent)403

La clé plateforme est scoped au marchand. Elle ne peut pas toucher les escrows d'un autre marchand (404). Vous l'obtenez via Clés et magasin dédié.

Il n'y a pas d'activation par marchand. Dès que la clé plateforme existe, et escrowId sont disponibles pour ce marchand.

De la création à la libération

POST /partner_api/escrows                 { storeId, holdUntil? }  → pending
POST /partner_api/payment_requests        corps habituel + escrowId
  ou POST /partner_api/payment_links      corps habituel + escrowId
  → le client paie (redirect / in-app / soundbox / lien)
  → escrow held ; GET /transactions reste vide pour ce job
GET  /partner_api/escrows/{id}            lifecycle (pending → held)

Sans escrowId, le collect crédite tout de suite le solde opérable — comportement inchangé.

1. Créer le pot

Create escrow (Partner API)
curl -X POST "https://api.jeko.africa/partner_api/escrows" \
  -H "X-API-KEY: platform_key" \
  -H "X-API-KEY-ID: platform_key_id" \
  -H "Content-Type: application/json" \
  -d '{
    "storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa"
  }'

Corps : uniquement storeId et, optionnellement, holdUntil (ISO 8601 UTC). Pas de paymentDetails, successUrl, deviceId, forceProviderDirect, ni titre de lien.

  • holdUntil omis → auto-libération à 7 jours (fonds crédités au solde opérable du marchand).
  • Doit être dans le futur, au plus 30 jours.
  • À l'échéance, Jèko libère le hold (pas un remboursement au payeur).
  • Un pot = un seul collect. Relier deux fois le même escrowId → 409.

Réponse (pending) :

{
  "id": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
  "storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
  "status": "pending",
  "holdUntil": "2026-09-14T20:00:00.000Z",
  "amount": null,
  "paymentRequestId": null,
  "paymentLinkId": null,
  "createdAt": "2026-09-07T20:00:00.000Z"
}

2. Lier le collect existant

Ajoutez escrowId au corps habituel de Paiement en ligne ou de Liens de paiement.

curl -X POST "https://api.jeko.africa/partner_api/payment_requests" \
  -H "X-API-KEY: platform_key" \
  -H "X-API-KEY-ID: platform_key_id" \
  -H "Content-Type: application/json" \
  -d '{
    "storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
    "amountCents": 1000000,
    "currency": "XOF",
    "reference": "ORDER-1042",
    "escrowId": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
    "paymentDetails": {
      "type": "redirect",
      "data": {
        "paymentMethod": "wave",
        "successUrl": "https://example.com/success",
        "errorUrl": "https://example.com/error"
      }
    }
  }'

Règles au bind :

  • Même storeId que le pot, pot encore pending, clé plateforme.
  • Rails v1 : Wave, Orange, Djamo. Autre moyen → 400.
  • allowMultiplePayments: true + escrowId → 400.
  • Clé Owner / Dashboard ou clé entreprise du SP → 403.
  • Pot introuvable ou autre marchand → 404.

Le client paie comme aujourd'hui (redirect, soundbox, lien). Poller ou reste valide.

3. Après le paiement (held)

  • : status: "held", amount renseigné, paymentRequestId (et paymentLinkId si lien).
  • : escrowId présent, pas de transaction — le hold n'est pas dépensable.
  • : vide pour ce job. Le solde magasin () ne change pas.
  • Webhook ESCROW_HELD, pas TRANSACTION_COMPLETED. Ne créditez pas le marchand comme si le paiement était dépensable. TRANSACTION_COMPLETED arrive plus tard, à la libération (voir plus bas).

Exemple ESCROW_HELD (walletAvailableBalance = solde opérable) :

{
  "event": "ESCROW_HELD",
  "escrowId": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
  "storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
  "status": "held",
  "amount": { "amount": 985000, "currency": "XOF" },
  "paymentRequestId": "d22c81f3-ee04-4ec5-8bd2-cd8af5dabcfc",
  "paymentLinkId": null,
  "businessName": "Boutique Example",
  "storeName": "Cocody",
  "walletAvailableBalance": { "amount": 0, "currency": "XOF" }
}

Un abonnement events: ["TRANSACTION_COMPLETED"] ne reçoit pas ESCROW_HELD. events: null (défaut) le reçoit. Lisez d'abord l'en-tête Jeko-Event. Le champ event du corps le répète, ce n'est pas le discriminant. Qui reçoit l'appel est dans Événements. L'abonnement se crée avec la clé Service Provider : Webhooks marchand.

/escrows vs /transactions

SurfaceRôle
Lifecycle du hold (pending → held → released / refunded)
Portefeuille opérable seulement. Instantané, transferts, retraits. Rien pendant le hold. Après libération (manuelle ou timeout) : une ligne type=escrow avec le net crédité, les frais réellement facturés et le moyen de paiement du payeur.
Disponible opérable seulement

Erreurs fréquentes

CodeQuand
400holdUntil invalide ; rail non supporté ; lien multi-paiements + escrowId
403Clé Owner / Dashboard ou clé entreprise du SP
404Magasin ou escrow introuvable, ou autre marchand
409L'escrow est déjà lié à un collect

Libération, remboursement, timeout

Tant que le pot est held :

  • prélève les frais Jèko (et votre commission de Service Provider), puis crédite le net sur le solde opérable du marchand. Résultat : status: "released" et une ligne type=escrow sur , avec le net, les frais et le moyen de paiement du payeur. Deux webhooks partent : ESCROW_RELEASED et TRANSACTION_COMPLETED, dont le corps est cette ligne type=escrow.
  • renvoie au payeur le montant net de frais : le montant du paiement moins les frais quand le marchand paie les frais, ou le montant hors frais quand le payeur les a payés. Les frais Jèko sont prélevés sur le pot, pas sur le solde opérable. Le solde opérable ne paie que les éventuels frais de remboursement. Résultat : status: "refunded" et webhook ESCROW_REFUNDED, mais pas de TRANSACTION_COMPLETED et rien de dépensable sur .
  • À holdUntil, Jèko libère automatiquement comme un release : status: "released", ESCROW_RELEASED et TRANSACTION_COMPLETED, solde opérable crédité. Ce n'est pas un remboursement.

Exemple : un paiement Wave de 500 XOF avec 8 XOF de frais payés par le marchand. À la libération, la ligne type=escrow affiche un montant de 492 et des frais de 8. En cas de remboursement, le payeur reçoit 492.

Un pot déjà held avant la mise en place de ce fonctionnement garde l'ancien comportement : à la libération, il crédite le net avec des frais à 0 et n'envoie que ESCROW_RELEASED.

On this page