Skip to main content
A dispute is how a funded escrow is contested when delivery doesn’t go to plan. Because Payluk is a merchant platform, disputes always involve three roles:
  • Buyer — one of your customers (merchant_user) who funded the escrow.
  • Seller — the customer (merchant_user) who created the payment link.
  • You, the merchant — the super-admin account that arbitrates and releases the held funds. You are recorded on the dispute as the admin.
The held funds stay locked in escrow until you resolve the dispute. Neither the buyer nor the seller can move the money once a dispute is open — only your merchant super-admin key can.
Payluk does not resolve disputes between your customers. You — the merchant — handle and settle every dispute raised by your customers yourself, using the dispute APIs documented here. Payluk only holds the funds in escrow and executes the outcome you submit (release to the seller or refund the buyer); it never arbitrates a merchant_user dispute on your behalf. Building a fair review and resolution process for your customers is your responsibility.
A dispute can only be raised while the escrow is OPENED (funded and held). Before funding there is nothing to dispute; after the escrow is CLOSED (COMPLETED / REFUNDED) it is terminal and can’t be reopened.
Milestone escrows cannot be disputed. Disputes apply only to standard escrows. A milestone escrow releases its funds milestone-by-milestone as the buyer confirms each one, so there is no single held amount to contest — any attempt to open a dispute on one is rejected with Milestone escrows cannot be disputed.

Who opens a dispute, and who responds

Only the buyer can open a dispute. The seller cannot initiate one — they can only respond to a dispute the buyer has already raised. Once both sides have been heard, you (the merchant) review and resolve it. Both parties act through Submit dispute (POST /v1/escrow/submit-dispute/{paymentToken}), sending the acting customer’s ID in the customer-id header:

Buyer — opens the dispute

Raises the dispute any time after payment, while the escrow is OPENED — typically “I paid but the item never arrived / isn’t as described.”

Seller — responds only

Cannot open a dispute. Their only proactive recourse is to request to claim the funds once the delivery window passes. If the buyer opens a dispute, the seller then replies on this endpoint to put their side on record before you resolve it.
Each side may submit once. A repeat submission is rejected (Buyer already submitted Dispute / Seller already submitted Dispute). The request is multipart/form-data with a message and an optional evidence file.

How the status moves

The escrow’s status tracks the dispute as each party weighs in:
1

Buyer opens the dispute → DISPUTED

The escrow moves to status: DISPUTED and the seller is notified. The buyer’s submission is recorded under dispute.buyer.
2

Seller responds → INVESTIGATING

Once the seller has replied (recorded under dispute.seller), both sides are on record and the escrow automatically moves to status: INVESTIGATING. This is your cue to step in.
3

You resolve → COMPLETED or REFUNDED

You review both sides and resolve the dispute, disbursing the held funds to the seller (COMPLETED) or back to the buyer (REFUNDED).
The dispute object on the escrow holds each side’s contribution — buyer, seller, and (after resolution) admin — every entry carrying its message, optional proofUrl, the userId, and createdAt.
{
  "status": "INVESTIGATING",
  "dispute": {
    "buyer":  { "userId": "…c01", "message": "Item never arrived",       "proofUrl": "https://…", "createdAt": "1750584900" },
    "seller": { "userId": "…c02", "message": "Shipped, tracking attached", "proofUrl": "https://…", "createdAt": "1750585200" }
  }
}

Reviewing disputes as the merchant

You have both a per-customer and a merchant-wide view. Watch the customer-id header — it’s required on the per-customer routes and must be omitted on the merchant-wide ones.
ViewRoutecustomer-id
One customer’s disputesGET /v1/escrow/dispute/getRequired
A single dispute threadGET /v1/escrow/dispute/get/{escrowId}Required
Every customer’s disputesGET /v1/escrow/all-disputeOmit
All escrow activity (feeds)GET /v1/escrow/feedsOmit
The merchant-wide routes are scoped to your merchantId automatically, so you only ever see disputes belonging to your own customers.

Resolving and disbursing funds

Resolution is merchant super-admin only — the route sits behind the super-admin guard, so an individual customer cannot resolve their own dispute. Call Resolve dispute (POST /v1/escrow/dispute/resolve/{escrowId}) with no customer-id header, as multipart/form-data:
FieldRequiredNotes
resolutionyesYour decision note, stored under dispute.admin.
statusyesCOMPLETED (release to seller) or REFUNDED (return to buyer).
filenoOptional supporting document.
What happens under the hood depends on the outcome you choose (disputes apply to standard escrows only):
The full held amount (net of the seller fee) is released to the seller’s main balance and the escrow closes as COMPLETED, with commission charged once.
The held amount plus the buyer’s pro-rata fee share is refunded to the buyer’s main balance and the escrow closes as REFUNDED.
You can only resolve a dispute on an escrow that belongs to one of your customers (the escrow’s merchantId must match your account), and only while it is still open — an escrow already COMPLETED or REFUNDED will be rejected with Escrow already completed.

The seller’s recourse: claim funds

Since the seller can’t open a dispute, their way to push a stalled deal forward is to request to claim the funds. If the delivery window passes and the buyer never confirms, the seller calls Claim funds, moving the escrow to CLAIMED. This is the un-contested counterpart to a dispute; see the escrow lifecycle for how CLAIMED, DISPUTED, and INVESTIGATING fit alongside the happy path.
For the precise meaning of every status value and how it combines with the escrow state, see the status reference.