Complete guide to all escrow lifecycle flows — creation, funding, release, dispute, and refund.
This guide walks through every escrow flow in OFFER-HUB: from creating and funding a contract to releasing, disputing, and refunding. Each flow includes step-by-step diagrams and code examples.
Note
OFFER-HUB uses Trustless Work smart contracts on Stellar for non-custodial escrow. All flows ultimately resolve on-chain.
Creating an Escrow
An escrow contract is created after an order is placed and the buyer's funds are reserved off-chain.
Steps
Create the order — Buyer's balance is reserved
Call the escrow creation endpoint — Deploys a Trustless Work contract on Stellar
Wait for confirmation — Contract becomes ESCROW_CREATED
After release, the seller's internal balance is credited. They can withdraw to their external wallet at any time via the Withdrawals flow.
Raising a Dispute
If the buyer believes the work was not delivered as agreed, they can open a dispute while the order is IN_PROGRESS.
Steps
Buyer opens dispute — Provides a reason
Status changes — Order moves to DISPUTING then DISPUTED
Funds remain locked — Neither party can access the escrow
Platform reviews — Manual or automated resolution begins
Mermaid
Rendering diagram…
REST
bash
curl -X POST http://localhost:4000/api/v1/orders/ord_xyz789/resolution/dispute \
-H "Authorization: Bearer ohk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"requestedBy": "usr_buyer123",
"reason": "Work delivered does not match agreed specifications"
}'
Response:
json
{
"data": {
"id": "ord_xyz789",
"status": "DISPUTED",
"dispute": {
"id": "dsp_abc123",
"reason": "Work delivered does not match agreed specifications",
"openedAt": "2026-03-01T10:00:00.000Z",
"openedBy": "usr_buyer123"
}
}
}
TypeScript SDK
ts
await sdk.resolution.dispute('ord_xyz789', {
requestedBy: 'usr_buyer123',
reason: 'Work delivered does not match agreed specifications',
});
Warning
Disputes can only be opened while the order is IN_PROGRESS. Once released or refunded, the order is final.
Dispute Resolution
After a dispute is opened, the platform reviews evidence and resolves with a release (seller wins) or refund (buyer wins).
Resolution Options
Resolution
Outcome
On-Chain Transaction
release
Funds go to seller
resolve_dispute → release
refund
Funds return to buyer
resolve_dispute → refund
split
Custom split between parties
resolve_dispute → split
REST — Resolve with Refund
bash
curl -X POST http://localhost:4000/api/v1/disputes/dsp_abc123/resolve \
-H "Authorization: Bearer ohk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"resolution": "refund",
"note": "Seller did not deliver agreed deliverables"
}'
REST — Resolve with Release
bash
curl -X POST http://localhost:4000/api/v1/disputes/dsp_abc123/resolve \
-H "Authorization: Bearer ohk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"resolution": "release",
"note": "Evidence confirms work was delivered as agreed"
}'
TypeScript SDK
ts
// Resolve in favor of buyer (refund)
await sdk.disputes.resolve('dsp_abc123', {
resolution: 'refund',
note: 'Seller did not deliver agreed deliverables',
});
// Resolve in favor of seller (release)
await sdk.disputes.resolve('dsp_abc123', {
resolution: 'release',
note: 'Evidence confirms work was delivered as agreed',
});
Note
Only the platform (using the master API key) can resolve disputes. This requires a co-signature from the Trustless Work smart contract arbiter.
Refund Flow
A refund can result from dispute resolution or, in some configurations, from a direct cancellation before work begins.
Refund via Dispute
Mermaid
Rendering diagram…
Two on-chain transactions are required:
Step
Transaction
Signer
1
dispute_escrow
Buyer opens dispute
2
resolve_dispute
Platform issues refund
Refund via Cancellation
If the order is cancelled before funding (e.g., the seller cannot fulfill), the off-chain reservation is released with no blockchain transaction: