# Settlement record

Where the money is after authorization: stage, amounts, fees, the rail’s references, and the one field nobody else records, the finality class.

Status: Live · Updated: 2026-09-13
For: finance, agent, seller
Source: https://enruta.ai/docs/settlement

A settlement record is a record and a reconciliation input, not settlement itself: the money still moves on the buyer’s rail and the merchant’s PSP. Its most important field is `finality_class`, because a card payment, an ACH debit and an on-chain transfer are three different legal states and no other object names them.

## Fields

| Field | Contents |
|---|---|
| `id`, `record_id`, `request_id`, `mandate_id` | `stl_01M2513A9C2K7Q4W8T1N6B3RXH` |
| `rail` | `stripe_issuing` · `sandbox` today; `ramp`, `mercury`, `bill_com`, `ach`, `wire`, `x402`, `mpp` reserved for the planned adapters |
| `stage` | `authorized` · `captured` · `cleared` · `settled` · `paid_out` · `reversed` |
| `amounts` | `{ authorized, incremented, captured, reversed, settled, fees, net }`, decimal strings |
| `finality_class`, `finality_at` | `reversible` (cards: a 120-to-540-day dispute window) · `conditionally_reversible` (ACH: return codes, 60 days) · `irreversible` (x402 `exact` and `upto`, on-chain transfers); the expected or actual moment of finality |
| `rail_refs` | `{ authorization_id, transaction_id, reversal_transaction_ids, clearing_id, settlement_batch_id, trace_id, tx_hash, block, chain_id }`; `transaction_id` is the capture, refunds post as their own transactions |
| `expected_settlement_at`, `settled_at` | From the adapter’s defaults (Stripe Issuing 2 days, sandbox 0) and the rail’s event |
| `payout_ref` | The merchant-side payout batch, when a merchant adapter reports one |
| `currency_pair`, `fx` | Cross-border, two currencies |
| `fulfillment` | `{ confirmed_at, order_id, evidence[], source }` once the merchant confirmed |
| `events[]` | `enruta:settlement:authorized` · `:captured` · `:settled` · `:paid-out` · `:reconciled` |
| `settlement_record_id` | The sealed linked record |

## How it moves

1. **Authorized.** Created when the rail authorizes: `amounts.authorized`, `rail_refs.authorization_id`, `expected_settlement_at`, `finality_class` from the adapter.
2. **Captured and settled.** On Stripe Issuing an `issuing_transaction.created` of type `capture` moves the record to `captured` and, since Issuing posts once, to `settled` with `settled_at` and `finality_at = settled_at + 120 days`. The sandbox rail captures when the merchant confirms fulfillment, or two minutes after authorization.
3. **Paid out.** When a merchant adapter reports the payout batch (planned with the PSP adapters).
4. **Reversed.** A completed [reversal](https://enruta.ai/docs/reversal) with `fund_change: true` updates `amounts.reversed` and the stage.

The linked record (`kind: settlement_record`, `chain: settlement_of`, the last rail object in `artifacts.rail_event`, `strength.subject: third_party_signed`) is sealed when the stage reaches `settled`, `paid_out` or `reversed`. `SETTLEMENT_OVERDUE` and `FINALITY_MISMATCH` are computed by [reconciliation](https://enruta.ai/docs/reconciliation), not stored here.

## Fulfillment

The merchant confirms fulfillment three ways: the order webhook `order_shipped` (or a `shipped` event in `fulfillment.events[]`), `POST /v0/sellers/fulfillments` with `{ domain, order_id, fulfilled_at, evidence[] }`, or the store’s own “Ship” action. Confirmation writes `fulfillment` on the request and the settlement, sets the payment record’s `outcome.status` to `fulfilled` when the record is still open, and on sandbox keys triggers the capture.

```json
GET /v0/settlements/rec_01M25129GZMJXTNQ47TMZRDGHN

{
  "id": "stl_01M2513A9C2K7Q4W8T1N6B3RXH",
  "record_id": "rec_01M25129GZMJXTNQ47TMZRDGHN", "mandate_id": "mnd_01M2512M8FQ7ZK4T1V9W3N6BXC",
  "rail": "stripe_issuing", "stage": "settled",
  "amounts": { "authorized": "24.98", "incremented": "0.00", "captured": "24.98", "reversed": "9.99", "settled": "24.98", "fees": "0.00", "net": "14.99" },
  "finality_class": "reversible", "finality_at": "2027-01-08T17:42:30Z",
  "rail_refs": { "authorization_id": "iauth_1S7Kq2…", "clearing_id": "ipi_1S7Kq9…" },
  "expected_settlement_at": "2026-09-12T17:42:30Z", "settled_at": "2026-09-10T17:42:30Z",
  "fulfillment": { "confirmed_at": "2026-09-11T09:15:00Z", "order_id": "ord_01M2512SM3V3A9R4EBJM8RRRV5", "source": "webhook", "evidence": [{ "type": "tracking", "ref": "1Z…" }] },
  "events": ["enruta:settlement:authorized", "enruta:settlement:captured", "enruta:settlement:settled"],
  "settlement_record_id": "rec_01M2GC2H8W4T7Q1K9N3B6D2H5XR"
}
```

## Three rails, three finalities

Under one policy, three payments could settle on three rails: $24.98 on Stripe Issuing, `reversible`, final 120 days after settlement; $0.05 over x402 `exact`, `irreversible`, final when the block confirms, so a reversal can only be a `credit`; $8,300 over ACH, `conditionally_reversible`, final 60 days after settlement. The weekly report shows the three classes side by side so a controller sees at a glance what can still be recovered. Today the first is live; the other two wait for their adapters (x402 2027, ACH with Bill.com from January 2027, read-only first).

## Interfaces

| Surface | Call |
|---|---|
| REST | `GET /v0/settlements/{record_id}` (agent for own records, developer, auditor); `POST /v0/sellers/fulfillments` (seller) |
| MCP | `get_settlement({ record_id })` |
| SDK | `settlements.get(recordId)`; `sellers.fulfillments.confirm(body)` |
| CLI | `enruta settlements get <rec>` |
| Webhooks | `settlement.updated` |
| Console | The rail settlement row on `/payments/{id}`: stage, finality class, finality date |
