What Are Recorders?
Recorders are pluggable contracts that update state after an action successfully executes on a PaymentOperator. Each operator has 5 recorder slots — one per action:| Slot | Records After |
|---|---|
AUTHORIZE_RECORDER | Authorization (e.g., timestamp) |
CHARGE_RECORDER | Charge event |
RELEASE_RECORDER | Release from escrow |
REFUND_IN_ESCROW_RECORDER | In-escrow refund |
REFUND_POST_ESCROW_RECORDER | Post-escrow refund |
IRecorder Interface
paymentInfo— The payment information structamount— The amount involved in the actioncaller— The address that executed the action (msg.sender on operator)
Default Behavior
Recorder slot =address(0) — no-op (does nothing). No state is recorded.
This means you only need to set recorders for slots where you want state tracking. Leave the rest as address(0).
BaseRecorder
All built-in recorders extendBaseRecorder, which verifies that the caller is an authorized operator. This prevents unauthorized contracts from writing state.
Choosing a Recording Strategy
Not every payment needs on-chain recorders. Choose based on your use case:Events Only (~0 Extra Gas)
The operator already emits events (AuthorizationCreated, ReleaseExecuted, etc.) for every action. If you only need payment history for analytics or display, skip recorders entirely and index events off-chain.
Best for: Micropayments, high-volume payments where gas overhead matters, simple UIs.
Events + Subgraph (Best Queries)
Index operator events with a subgraph for rich queries (payment history by payer, receiver, status, date range). No on-chain recorder gas cost. Best for: Analytics dashboards, payment history, multi-payment queries. Trade-off: Requires subgraph infrastructure (semi-centralized).On-Chain Recorders (~20k Gas per Write)
Use recorders when you need on-chain reads — other contracts or conditions that depend on recorded state. EscrowPeriod is the most common example: it records authorization time so the release condition can check if the escrow window has passed. Best for: Escrow enforcement, dispute evidence, decentralized frontends, on-chain composability. Trade-off: ~20k gas perSSTORE operation.
Decision Table
| Need | Strategy | Recorder Slots |
|---|---|---|
| Payment history for UI | Events only | address(0) |
| Rich queries, analytics | Events + Subgraph | address(0) |
| Time-locked releases | On-chain | EscrowPeriod on AUTHORIZE_RECORDER |
| On-chain payment index | On-chain | PaymentIndexRecorder |
| Multiple data points | On-chain | RecorderCombinator |
