# PIP-0011 · Settlement receipts in the common vocabulary

The capability used, the amounts sent and received, typed rail references, and receipts issued by either side of a payment.

## Why

A receipt states what happened. In 0.3 it names the rail as free text, carries one amount and one currency, and points at the rail through two untyped fields, `source_tx_hash` and `source_reference`. Only the payee's member issues receipts, although several failure reasons are observed on the payer's side. This PIP restates the receipt in the vocabulary of [PIP-0006](/pips/0006).

## The object

```json
{
  "type": "path.receipt",
  "reference": "q8w2e5r7t9y1u3i6o0p4as",
  "issuer": "member-a",
  "issued_by": "payee",
  "payer": { "member": "member-b" },
  "payee": { "member": "member-a", "address": "path:4a91c2f7e8d3" },
  "request": "7fk2m9pq3vx8",
  "instruction": "k3v9n2x8p4q7r1s6t0w5yz",
  "via": {
    "rail": "blockchain",
    "chain": { "slug": "base", "caip2": "eip155:8453" },
    "asset_type": "token",
    "asset_code": "USDC",
    "standard": "erc20",
    "contract": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"
  },
  "sent": { "value": "7.62", "asset_type": "token", "asset_code": "USDC" },
  "received": { "value": "5000", "asset_type": "fiat", "asset_code": "USD" },
  "fx": { "rate": "656.17", "source": "operator_quote" },
  "fees": [
    {
      "kind": "network",
      "amount": { "value": "0.01", "asset_type": "token", "asset_code": "USDC" },
      "paid_by": "payer"
    }
  ],
  "rail_references": [{ "type": "tx_hash", "value": "0x9f…", "index": 3 }],
  "attestations": [],
  "status": "settled",
  "reason_code": null,
  "supersedes": null,
  "route": null,
  "grammar": 2
}
```

## Rules

| Field | Rule |
|---|---|
| `issuer` | The member that signs. |
| `issued_by` | `payee` or `payer`: the side `issuer` speaks for. |
| `payer`, `payee` | Parties. Each side states only itself: `payer.member` appears on a payee-issued receipt when an attestation signed by the payer's member supports it. |
| `request`, `instruction` | References, or `null`. A payment to an address with no request carries `payee.address`. |
| `via` | The single capability used. |
| `sent` | Required when the asset sent differs from the asset received. |
| `received` | Required from `settled` on, on a payee-issued receipt. |
| `fx` | Required when `sent` and `received` differ in asset. |
| `fees` | Fees actually applied, as Fee objects. |
| `rail_references[]` | At least one from `settled` on. Each `type` is one of the rail's `rail_reference_types` ([PIP-0007](/pips/0007)). Replaces `source_tx_hash` and `source_reference`. |
| `attestations[]` | Signed PATH envelopes from other parties, such as the payer's member confirming its side. Nothing else. |
| `status`, `reason_code`, `supersedes` | Unchanged. |
| `route` | Unchanged: `null`. The shape is in [PIP-0005](/pips/0005). |
| `reference` | From the common reference generator, like every linkable object. |

## Which side states what

| Side | May issue | Reason codes it may state |
|---|---|---|
| `payer` | `pending`, `failed` | `insufficient_funds`, `rail_unavailable`, `rail_rejected`, `limit_exceeded`, `compliance_blocked`, `expired` |
| `payee` | `pending`, `settled`, `failed`, `reversed` | `destination_unknown`, `destination_closed`, `limit_exceeded`, `compliance_blocked` |

The registry of reasons stays closed. A reason outside the issuing side's list is a 400. One payment may have a receipt from each side; they are matched by `instruction` and `rail_references`.

The state machine is unchanged: `pending → settled | failed`, `settled → reversed`.

## Compatibility

Breaking for readers of `amount`, `currency`, `rail`, `source_tx_hash`, `source_reference`, `payer_member` and `payee_member`. Receipts signed in the 0.3 shape are replayed as signed. A transition of a 0.3 receipt is issued in the 0.3 shape, so that its `supersedes` chain stays in one grammar.