Skip to main content
This is the map of the whole journey. It shows every endpoint you call, in the order you call it, and who the customer-id header points to at each step. Read it once and the individual API reference pages will fall into place.
Two actors run through every flow:
  • Seller: the merchant customer selling the item (the escrow is created on their behalf).
  • Buyer: the merchant customer funding the escrow.
You, the merchant, hold the secret key and act on behalf of both by setting the customer-id header to whichever one the current step concerns. The secret key (Authorization: Bearer sk_…) is on every request.

The journey at a glance

1

Set up (once)

Get your secret key, and optionally seed categories.
2

Onboard your customers

Create the buyer and seller as merchant customers.
3

Create the deal

Create a standard escrow or a milestone escrow. You get a paymentToken and an id.
4

Fund it

The buyer pays into escrow. Funds are held, not released.
5

Deliver & release

The buyer confirms (or each milestone is confirmed), releasing funds net of fees.
6

Handle exceptions

Claims, disputes and refunds (only if the happy path doesn’t complete).

Phase 0: Set up (once per merchant)

These don’t move money, so do them once and cache the IDs.

Phase 1: Onboard your customers

Almost every later call needs a customer-id, so you create the people first.
The seller needs canSell, the buyer needs canBuy. A buyer with canBuy disabled is rejected at payment time.
Keep the returned customer IDs; they become the customer-id header for the rest of the flow.

Phase 2: The standard escrow flow

A single item, paid once, released once. This is the common case.
1

Create the escrow (as the seller)

POST /v1/escrow/create with customer-id: <sellerId>. This is multipart/form-data (so you can attach up to 5 images).
Returns id and paymentToken; state: AWAITING_PAYMENT, status: PENDING, settlementType: STANDARD. While in AWAITING_PAYMENT you can still edit or delete it.
Selling more than one unit off this single link? Set totalQuantity above 1 and read Multi-quantity escrows; the behaviour is different and is explained there.
2

Add your delivery fee (optional)

Charging for delivery? PUT /v1/escrow/additional-fee/{paymentToken} with { "additionalFee": 2500 } and no customer-id header. It is added to what the buyer pays and credited to your merchant wallet when the escrow completes. Adjustable until the buyer pays; see Fees & settlement.
3

Buyer resolves the link (optional)

Share the paymentToken. The buyer’s side can read the full escrow with GET /v1/escrow/verify/{paymentToken} to display amount, purpose and images before paying.
4

Make sure the buyer's wallet is funded

Paying with gateway: wallet requires balance. Top it up first:
  • Production: POST /v1/payment/create-intent (transactionType: deposit). With depositDetails.cardId the saved card is charged; without one the response carries a hosted collection to pay (checkoutConfig, or a testAccount on staging). Either way, settle it with POST /v1/payment/verify and the intent’s reference.
  • Staging shortcut: POST /v1/payment/topup with customer-id: <buyerId> (1,000 to 100,000, once per customer per day).
Skip this step if you fund the escrow directly with a PAYSTACK/FLUTTERWAVE gateway.
5

Fund the escrow (as the buyer)

POST /v1/payment/escrow with customer-id: <buyerId>.
The buyer is charged the escrow amount + their share of the fee + any additionalFee. The escrow moves to state: OPENED / status: ONGOING and the delivery window starts.
gateway: card charges a saved card instead: pass its cardId from List customer cards. Card payments are available to Nigerian customers only. To collect from a card, bank transfer or cNGN the buyer has not saved, use the hosted Checkout SDK rather than this route.
6

Release the funds

The happy path: the buyer confirms delivery: POST /v1/escrow/confirm-payment/{escrowId} with customer-id: <buyerId>. The escrow closes as COMPLETED and the seller is paid net of fee.

If the happy path doesn’t happen

After the delivery window elapses, the seller calls GET /v1/escrow/claim-funds/{paymentToken} (customer-id: <sellerId>). Allowed only when OPENED and the window has passed. Closes as CLAIMED.
Either party opens POST /v1/escrow/submit-dispute/{paymentToken}. You, the merchant, then resolve it with POST /v1/escrow/dispute/resolve/{escrowId}: release to the seller (COMPLETED), refund the buyer (REFUNDED), or split the held funds between them (SPLIT).
The resolve and feeds routes are merchant-wide; do not send a customer-id header.

Phase 3: The milestone escrow flow

Fund the whole project upfront; release it in stages as each milestone is confirmed. Same money rails, different create + release steps.
1

Create the milestone escrow (as the seller)

POST /v1/escrow/milestone/create with customer-id: <sellerId>. Unlike standard create, this is JSON (no file upload).
At least 2 milestones.
Milestone amounts must sum to the escrow amount.
whoPays must be buyer on milestone escrows.
Returns settlementType: MILESTONE with a milestones[] array; each milestone has its own id and status: PENDING.
2

Fund it in full (as the buyer)

Same endpoint as standard: POST /v1/payment/escrow with customer-id: <buyerId>. The buyer pays the entire amount once. Escrow → OPENED.
3

Confirm each milestone (as the buyer)

Read the current milestones any time with GET /v1/escrow/milestone/{paymentToken}. As each deliverable lands, the buyer confirms it: POST /v1/escrow/milestone/confirm/{escrowId}/{milestoneId} with customer-id: <buyerId>. That milestone’s net share (its amount minus its pro-rata fee) is released and its status becomes RELEASED.
4

Auto-complete

When the final milestone is released, the escrow moves to CLOSED / COMPLETED automatically. No separate confirm-payment call.

Phase 4: Monitor & reconcile (any time)

Don’t poll for status changes; register a callback URL and let Payluk push every escrow update, and every transaction your customers settle, to you. See Webhooks.

Endpoint checklist

  1. POST /v1/customer/create: seller, then buyer (once)
  2. POST /v1/escrow/create with customer-id: seller
  3. GET /v1/escrow/verify/{paymentToken}: buyer previews (optional)
  4. Fund wallet: POST /v1/payment/create-intentPOST /v1/payment/verify (or topup on staging)
  5. POST /v1/payment/escrow with customer-id: buyer
  6. POST /v1/escrow/confirm-payment/{escrowId} with customer-id: buyer
  • Exceptions: GET /v1/escrow/claim-funds/{paymentToken} · POST /v1/escrow/submit-dispute/{paymentToken} · POST /v1/escrow/dispute/resolve/{escrowId}
Selling multiple units off one link? That introduces escrow duplication: read Multi-quantity escrows next.