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.
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 acustomer-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.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).id and paymentToken; state: AWAITING_PAYMENT, status: PENDING,
settlementType: STANDARD. While in AWAITING_PAYMENT you can still
edit or
delete it.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
Fund the escrow (Checkout SDK)
The buyer pays through the Checkout SDK. All money comes in
as an escrow payment; there are no direct deposits and no card payments.Checkout generates a temporary virtual account for the escrow and the
buyer pays it by bank transfer. 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. You get
payment.escrow.success and escrow.ongoing webhooks.On staging, pay the temporary account from the Payluk Test Bank.
5
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
Buyer never confirms → seller claims
Buyer never confirms → seller claims
One day after the delivery window, the seller calls
GET /v1/escrow/claim-funds/{paymentToken}
(customer-id: <sellerId>). Allowed only when OPENED and the window plus
one day has passed. Closes as CLAIMED.Something's wrong → dispute
Something's wrong → dispute
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).
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.settlementType: MILESTONE with a milestones[] array; each milestone
has its own id and status: PENDING.2
Fund it in full (as the buyer)
Same as standard: the buyer pays through the Checkout SDK
with the milestone escrow’s
paymentToken. 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)
Endpoint checklist
- Standard payment
- Milestone payment
POST /v1/customer/create: seller, then buyer (once)POST /v1/escrow/createwithcustomer-id: sellerGET /v1/escrow/verify/{paymentToken}: buyer previews (optional)- Buyer pays through the Checkout SDK:
pay({ paymentToken }) POST /v1/escrow/confirm-payment/{escrowId}withcustomer-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.