Ledger
Your operational record of authorizations, charges, and claims — in your own database.
The ledger is the merchant's operational record. The payment network or provider is the final authority on whether money moved; reconciliation keeps the two in agreement.
| Record | Purpose |
|---|---|
| Authorizations | What each payer authorized, with limit, reserved, and consumed amounts |
| Charges | Each economic effect, with payment and fulfillment states |
| Transitions | Every state change, for audit |
| Claims | Single-use keys such as nonces |
Guarantees a ledger must provide
createChargereserves capacity atomically and refuses a second charge on a single-use authorization that was not released.transitionChargeis compare-and-set on both axes and updates reserved and consumed amounts in the same step.- An authorization holds one currency: a charge in another is refused with
CURRENCY_MISMATCH. - Amounts are integers between
0and2^63 − 1micros. Nothing is stored as a float.
Ledgers
| Ledger | Use | Status |
|---|---|---|
memoryLedger() | Tests and local development; one process | Implemented |
@tollstile/postgres | Bring your own client: pg, postgres.js, Neon, PGlite | Implemented; conformance suite on PGlite |
@tollstile/sqlite | node:sqlite, better-sqlite3, bun:sqlite, Cloudflare D1 | Implemented; conformance suite on node:sqlite |
All three run one conformance suite. Rail evidence needed to settle after a crash, such as a signed payload, may sit in an authorization's data until the charge is final; core then calls replaceAuthorizationData with the rail's redacted data.
There is no Tollstile account, no required dashboard, and no telemetry.
Idempotency records
The charge ID encodes the payer, idempotency key, and attempt number when a key is present. Repeated creation of that ID returns the existing charge. All instances serving the same payer must share the ledger; a per-process memory ledger cannot deduplicate across instances or restarts.
| Charge field | SQL column | Meaning |
|---|---|---|
requestHash | request_hash (nullable text) | Request commitment for keyed charges; null without a key. Core compares it before admitting a keyed retry. |
resultRef | result_ref (nullable text) | Reference supplied through payment.fulfill({ resultRef }), returned as result in already_paid; no handler response is stored. |
Ledgers persist both fields; transitions can update resultRef. Keep charge records for the period in which you need retry protection. See Idempotency.