> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metalntwx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Settlement and Finality

> Payment completion conditions, receipt and finality fields, and reconciliation rules

An onchain payment is complete when its expected result has executed
successfully and the block recording that result is final. The application
retrieves the transaction receipt, checks the payment result, and verifies that
Simplex consensus has finalized the containing block before crediting a ledger
or fulfilling an order.

This page verifies onchain outcomes. A Clearing preconfirmation can precede
onchain epoch settlement and may have no transaction hash. Use the separate
[Clearing payment stages](https://docs.metalntwx.com/agents/clearing.md) for those
receipts. A finalized transaction can also place funds in
[quarantine](https://docs.metalntwx.com/reference/compliance/receive-policy.md), so verify the intended recipient
credit before marking a payment delivered.

## RPC methods

Use the same Metal network for all reads and verify its chain ID against the
network configured by your application.

| Method | Parameters | Settlement use |
| - | - | - |
| `eth_chainId` | `[]` | Identify the network |
| `eth_getTransactionReceipt` | `[transactionHash]` | Read execution status, block identity, and emitted logs |
| `consensus_status` | `[]` | Read the finalized block height |
| `eth_getBlockByNumber` | `[receipt.blockNumber, false]` | Read the canonical block at the receipt's height |
| `eth_call` | `[callObject, blockNumber]` | Read contract state at a verified finalized block when the payment requires a state check |

See the [JSON-RPC reference](https://docs.metalntwx.com/reference/json-rpc/overview.md) for request and
response formats.

### Fields and encodings

These are the raw JSON-RPC encodings. SDKs may decode them into integers or
named status values.

| Field | Encoding | Meaning |
| - | - | - |
| `eth_chainId.result` | `0x`-prefixed hex quantity | Network chain ID |
| `receipt.status` | `"0x1"` or `"0x0"` | Successful or failed execution |
| `receipt.transactionHash` | `0x`-prefixed 32-byte hash | Transaction whose result the receipt reports |
| `receipt.blockNumber` | `0x`-prefixed hex quantity | Height of the block containing the transaction |
| `receipt.blockHash` | `0x`-prefixed 32-byte hash | Identity of that block |
| `receipt.logs` | Array of log objects | Emitting contract, event topics, encoded data, and log index |
| `consensus_status.finalized.number` | JSON integer (`uint64`) | Latest finalized block height known to this node |
| `consensus_status.finalized.hash` | 32-byte hex string without `0x` | Hash of that finalized head |
| `eth_getBlockByNumber.result.hash` | `0x`-prefixed 32-byte hash | Canonical block hash at the requested height |

Decode `receipt.blockNumber` from hex before comparing it numerically with
`consensus_status.finalized.number`. Compare hashes as bytes or consistently
formatted hex strings. The finalized head may have advanced beyond the receipt's
block. Fetch the block at `receipt.blockNumber` and compare its hash with
`receipt.blockHash` to verify that the transaction belongs to the finalized
chain.

## Finality check

Require all of the following for the transaction recording the payment result:

1. The receipt exists and its transaction hash matches the expected transaction.
2. `receipt.status` is `"0x1"`.
3. The receipt's logs or contract state establish the expected payment result.
4. `receipt.blockNumber <= consensus_status.finalized.number`, after decoding
   both heights.
5. `eth_getBlockByNumber(receipt.blockNumber, false)` returns a block whose
   hash equals `receipt.blockHash`.

If the block read returns `null` or an RPC request fails, keep verification
pending because the transaction may already have succeeded. Query its original
hash to resolve the outcome before creating a new payment transaction.

### Block selectors

| Selector | Meaning for settlement |
| - | - |
| `"finalized"` | Read state from the block finalized by Simplex consensus |
| `"safe"` | Alias for `"finalized"` on Metal |
| `"latest"` | Execution head, which equals the finalized head in steady state. Use the explicit finality check when verifying a payment |
| `"pending"` | Speculative state that cannot establish settlement |

When checking contract state for a payment, read it at the verified receipt's
block number. This ensures that the state you inspect corresponds to the block
recording the payment result.

## Payment result checks

Each contract defines the events and state changes that establish its payment
result. Use the evidence listed below to verify the intended transfer or hold
outcome.

| Payment or transaction | Required result |
| - | - |
| Direct or authorized MIP20 payment | A `Transfer(from, to, value)` log from the expected token contract, with the expected sender, recipient, and amount |
| Routed MIP20 payment | The expected routing decision and token transfer to the intended destination. An inbound transfer alone may only establish arrival at an intermediate address |
| MIP410 initiation | `HoldCreated` for the intended hold. This reserves notes and leaves the payment awaiting resolution |
| MIP410 acceptance | `HoldAccepted(holdId)` for the intended hold, with the expected payment effect. The recipient's wallet must have the corresponding note data to recognize the received value |
| MIP410 rejection | `HoldRejected(holdId)` releases the sender's input locks. It completes rejection, with no payment to the recipient |
| MIP410 reclaim | `HoldReclaimed(holdId)` releases the sender's input locks after expiry. The deadline passing alone does not release them |

When verifying that evidence:

* Require successful execution and finality for the transaction recording
  the result
* Match logs to the expected contract and transaction
* Compare token amounts as integers in the token's base units
* For payments with additional lifecycle steps, verify the final contract
  outcome required by the payment agreement

Match the event's token, sender, recipient and amount to the saved payment
instruction. For a routed payment, verify the transfer to the final recipient
after any intermediate transfers.

Use the [Event Catalog](https://docs.metalntwx.com/reference/network-fundamentals/events.md) to interpret the event's
fields. For a shielded payment, also consult the
[MIP410 hold states and getters](https://docs.metalntwx.com/reference/assets-and-payments/mip410.md#pool-and-hold-state)
and use the private payment data to check that the accepted payment effect
matches the intended recipient note and any sender change.

## Verification outcomes

Use the observations below to decide whether to keep verification pending,
record a failure, or complete the payment in your application.

| Observation | Application decision |
| - | - |
| Submission refused by admission | Inspect the admission error before another submission |
| Receipt is `null` | Keep the transaction unresolved and query its original hash again |
| Receipt has `status = "0x0"` | Record failed execution and inspect the revert |
| Expected result exists but finality has not been established | Keep the payment pending |
| Block hash differs from the receipt | Keep the payment unverified and re-read the receipt and canonical block |
| Finalized successful transaction has an unexpected result | Investigate the mismatch before crediting or fulfilling |
| Expected payment result is final | Record completion and apply the business effect once |
| MIP410 rejection or reclaim is final | Record the terminal outcome and restored input availability |

For admission and execution failures, see [Error Codes](https://docs.metalntwx.com/reference/error-codes.md).

## Reconciliation and duplicate processing

Save the application's payment identifier and expected result with the signed
transaction and its hash before broadcasting. If the submission response is
lost, the saved hash lets you query the original transaction's outcome and match
it to the payment record.

Once an event is verified, retain its chain ID, emitting contract, transaction
hash, log index, block number, and block hash as the evidence for that payment.
The chain ID, transaction hash, and log index together identify the event with a
durable key:

```text theme={null}
chainId:transactionHash:logIndex
```

Enforce uniqueness on the event key to prevent the same event from being
processed twice. Record the verified event and apply its ledger change in the
same database transaction so they succeed or fail together. If multiple
transaction attempts could fulfill the same payment, also enforce uniqueness on
the application payment identifier to prevent separate events from crediting it
twice.

For MIP410, store the pool contract address and hold ID with the resolution
transaction hash. These identifiers connect initiation and resolution to the
same application payment record.

See [Verify and reconcile payments](https://docs.metalntwx.com/build/payments/verify-and-reconcile-payments.md) to
implement these checks in a server application.

## Independent finality verification

The RPC checks rely on the endpoint reporting chain state accurately. To verify
finality independently:

1. Fetch the certificate and header using
   `metal_getFinalityCertificate(blockHash)`.
2. Verify the certificate against trusted network parameters and the validator
   set for its epoch.
3. Check that the header hashes to the certified block hash.

A verified certificate authenticates the header, which contains the roots needed
to verify the payment evidence independently. Check the receipt's inclusion
proof against the header's receipts root and any contract state proof against
its state root. The
[Finality Certificates reference](https://docs.metalntwx.com/reference/interop/finality-certificates.md)
defines the certificate formats, signature checks, quorum requirements, and
current verifier limits used in this process.

A `null` response means the node cannot provide the certificate. This can happen
before the certificate has been persisted or after it has been pruned, even for
a finalized block.

> [card] [Verify and reconcile payments](https://docs.metalntwx.com/build/payments/verify-and-reconcile-payments.md)
>
> Implement receipt, event, finality, and duplicate-processing checks.

> [card] [Finality certificates](https://docs.metalntwx.com/reference/interop/finality-certificates.md)
>
> Verify finalized headers independently of the RPC endpoint.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.