Settlement network boundaries
What 0Pools exposes about settlement and what stays inside private 0Bit liquidity operations.
0Pools connects fiat rails, stablecoin delivery, trade state, and partner reconciliation. It does not expose the private settlement machinery directly. Developers should model settlement through partner-visible statuses, webhooks, balances, and ledger records.
Boundary diagram
What partners can rely on
| Public signal | Meaning |
|---|---|
| Quote terms | The side, amount, rate, fees, network, delivery target, and expiry accepted by the user. |
| Trade status | The current lifecycle state of the execution. |
| Terminal webhook | Async notification for settled, failed, or released where configured. |
| Balance ledger | Partner-visible credits, debits, refunds, and references. |
| Request id | Support trace for a specific API request. |
What partners should not rely on
Do not rely on or expose:
- Bank names or provider names.
- Exchange accounts or venue routing.
- Treasury balances.
- Rebalancing thresholds.
- Worker names or cron timing.
- Private settlement adapter behavior.
These can change without changing the partner API contract.
Settlement states
| State | Partner action |
|---|---|
reserved | Show pending. Keep user ledger provisional. |
settled | Final success for the partner flow. |
failed | Failure after attempted processing. Start support/refund workflow. |
released | Clean unwind. Let user retry. |
returned | Downstream return after settlement. Reverse or review your ledger entry. |
Before and after
| Without a boundary | With 0Pools boundary |
|---|---|
| Product teams leak provider-specific terms into UI. | UI speaks in stable trade states. |
| Support needs private runbooks to explain a user state. | Support starts from quote/trade/request ids. |
| Provider changes require partner code changes. | Provider changes stay behind the 0Pools contract. |
| Ledger updates happen from inconsistent sources. | Ledger updates from status/webhook/balance joins. |
Settlement lifecycle
This state model is intentionally simpler than internal settlement operations. It gives partner developers the states they need to drive product UX and ledger updates.
Partner ledger mapping
| Settlement state | User-facing state | Ledger stance |
|---|---|---|
quoted | Review quote. | No final movement. |
expired | Refresh required. | No final movement. |
reserved | Pending. | Provisional hold or pending row only. |
settled | Complete. | Finalize according to product flow. |
failed | Failed. | Reverse pending state or open support case. |
released | Cancelled/released. | Remove hold and allow retry. |
returned | Under review or reversed. | Reverse/review completed entry. |
Example support investigation
{
"partner_order_id": "order_123",
"quote_id": "pool_quote_123",
"trade_id": "pool_trade_456",
"status": "reserved",
"created_at": "2026-06-28T12:00:00Z",
"last_status_at": "2026-06-28T12:01:00Z",
"request_id": "req_abc",
"private_settlement_detail": "not_exposed"
}This is enough for first-line support to explain that the trade is pending and escalate with precise ids. It is not enough to infer why a private settlement worker is still processing, and that is by design.
Boundary checklist
- User-facing pages should show product states, not provider states.
- Partner dashboards should show quote/trade/request ids, not route names.
- Finance reports should reconcile against approved ledger/report rows, not raw private balances.
- Webhook handlers should verify event signatures and dedupe event ids.
- Support packets should never include secret keys, raw customer identity files, bank payloads, or private route assumptions.
Settlement evidence model
Settlement boundaries are easier to respect when each actor has a specific evidence set.
| Actor | Sees | Should not need |
|---|---|---|
| End user | Pending, settled, failed, returned, amount, asset, timestamp. | Provider route, reserve account, settlement worker details. |
| Partner support | User order id, quote id, trade id, request id, status history. | Raw bank files or venue payloads. |
| Partner finance | Ledger entries, debit/credit amounts, terminal status, close date. | Operational route selection. |
| 0Bit support | Partner ids plus request/event ids. | Partner customer secrets unless required by an approved escalation path. |
Settlement timeline record
{
"partner_order_id": "order_7841",
"quote_id": "pq_live_01J4",
"transact_id": "pt_live_9A2",
"status_timeline": [
{ "status": "reserved", "at": "2026-06-28T20:13:11Z" },
{ "status": "settled", "at": "2026-06-28T20:15:03Z" }
],
"ledger_entries": [
{ "type": "debit", "asset": "EUR", "amount": "100.00" },
{ "type": "credit", "asset": "USDT", "amount": "107.42" }
]
}Boundary tests
| Test | Expected result |
|---|---|
| Webhook says settled before UI refresh. | Ledger updates from webhook; UI later displays server state. |
| User asks where funds are. | Support answers from status and ids, not provider route. |
| Finance sees debit without terminal status. | Exception remains open until status/ledger join is complete. |
Implementation depth
This page is about separating partner-visible settlement state from private settlement operations. For developers, the durable boundary is simple: your product should depend on statuses, timestamps, settlement references, and reconciliation ids; it should not depend on bank rail instructions, provider payloads, wallet custody, and settlement worker internals. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.
Product scenario
A settled trade needs to update a partner ledger and a customer screen. The partner stores the terminal state and reconciliation references but does not depend on which private rail completed the settlement.
Before and after in practice
| Before 0Pools | With 0Pools |
|---|---|
| Products expose rail-specific language, so a provider change breaks UX copy and support playbooks. | Products speak in stable 0Pools states and keep provider-specific mechanics out of customer flows. |
| Product teams infer liquidity behavior from provider-specific screens or manual notes. | Product teams branch on 0Pools objects: pool, quote, trade, balance, webhook, and ledger. |
| Support asks engineering to reconstruct state from logs. | Support starts from request id, quote id, trade id, event id, and ledger id. |
System flow
Records to keep
| Record | Why it matters | Example |
|---|---|---|
trade_status | The canonical settlement state. | settled |
settled_at | When the terminal success was observed. | 2026-06-28T12:00:00Z |
settlement_reference | Partner-safe settlement reference where provided. | set_123 |
return_state | Shows downstream return when applicable. | returned |
A useful implementation stores these records before adding optional analytics. Analytics can be rebuilt from durable state; missing ids usually cannot be reconstructed after a customer-impacting failure.
Example product record
{
"product_area": "settlement-network-boundaries",
"partner_reference": "partner_order_123",
"pool_id": "EUR-USDT",
"quote_id": "pq_test_123",
"transact_id": "pt_test_456",
"status": "reserved",
"request_id": "req_01HZY0POOLS",
"reconciliation_state": "open"
}This record is intentionally partner-facing. It references 0Pools objects and your own product ids, but it does not include private liquidity routes, treasury balances, raw provider payloads, or customer secrets.
Failure modes and recovery
| Failure mode | Product response |
|---|---|
| Provider-specific UX | Use 0Pools statuses instead of rail names. |
| Ledger update too early | Wait for terminal state. |
| Return ignored | Model returned as a post-settlement exception. |
| No settlement timestamp | Do not close reconciliation until the timestamp is present. |
Use-case patterns
| Pattern | How 0Pools helps |
|---|---|
| Finance ledger | Close daily movement reports. |
| Customer support | Explain pending vs settled. |
| Product copy | Avoid rail-specific promises. |
Developer checklist
- Read runtime discovery and capabilities before rendering enabled actions.
- Create firm quotes only when the user is ready to accept the terms.
- Execute from your server with an idempotency key.
- Treat webhooks and status reads as the source of truth for settlement state.
- Reconcile by durable ids first, then by amount and timestamp.
- Do not branch product behavior on provider names, route names, reserve balances, or treasury assumptions.