Jèko
Service Providers

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 le net sur un portefeuille escrow du magasin, invisible dans le solde et dans .

Clés

CléEncaissement instantané/escrows et escrowId
Clé plateforme (émise par le SP pour ce marchand)OuiOui (si le flag est activé)
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é.

Flux

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, flag escrow activé, clé plateforme.
  • Rails v1 : Wave, Orange, Djamo. Autre moyen → 400.
  • allowMultiplePayments: true + escrowId → 400.
  • Clé Owner / flag off / clé SP entreprise → 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.

Exemple ESCROW_HELD (enveloppe, 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. Parsez event avant de traiter le corps comme une transaction. 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.
Disponible opérable seulement

Erreurs fréquentes

CodeQuand
400holdUntil invalide ; rail non supporté ; lien multi-paiements + escrowId
403Clé Owner / Dashboard, clé entreprise SP, ou flag escrow inactif
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 :

  • crédite le solde opérable du marchand (status: "released", webhook ESCROW_RELEASED, une ligne type=escrow sur ).
  • renvoie les fonds au payeur (status: "refunded", webhook ESCROW_REFUNDED). Rien de dépensable sur .
  • À holdUntil, Jèko libère automatiquement comme un release : status: "released", ESCROW_RELEASED, solde opérable crédité. Ce n'est pas un remboursement.

On this page