# `MPP.Receipt`
[🔗](https://github.com/ZenHive/mpp/blob/v0.10.0/lib/mpp/receipt.ex#L1)

Payment receipt — proof-of-payment returned in the `Payment-Receipt` header.

A receipt confirms that payment was verified successfully. It is serialized
as base64url-encoded JSON (no padding) for transport in HTTP headers.

Receipts only represent success. Payment failures are communicated via
HTTP 402 responses with RFC 9457 Problem Details (see `MPP.Errors`).

## Fields

  * `status` — always `"success"`
  * `method` — payment method name (e.g., `"stripe"`, `"tempo"`)
  * `timestamp` — RFC 3339 datetime string
  * `reference` — method-specific payment reference (PaymentIntent ID, tx hash, etc.)
  * `external_id` — optional, echoed from the credential payload

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `decode` | 1 | Decode a base64url JSON string into a receipt. | `encoded: value` |
| `encode` | 1 | Encode a receipt to a base64url JSON string (no padding) for the `Payment-Receipt` header. | `receipt: value` |
| `new` | 1 | Create a new receipt with defaults for `status` and `timestamp`. | `opts: value` |

# `t`

```elixir
@type t() :: %MPP.Receipt{
  external_id: String.t() | nil,
  method: String.t(),
  reference: String.t(),
  status: String.t(),
  timestamp: String.t()
}
```

# `decode`

```elixir
@spec decode(String.t()) :: {:ok, t()} | {:error, atom()}
```

Decode a base64url JSON string into a receipt.

## Parameters

  * `encoded` - Base64url-encoded JSON receipt string (value)

## Returns

`{:ok, receipt}` on success, `{:error, reason}` on failure (`tagged_tuple`)

## Errors

  * `:invalid_base64`
  * `:invalid_json`
  * `:missing_required_fields`

## Composes With

  * `encode`

```elixir
# descripex:contract
%{
  params: %{
    encoded: %{
      description: "Base64url-encoded JSON receipt string",
      kind: :value
    }
  },
  errors: [:invalid_base64, :invalid_json, :missing_required_fields],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, receipt}` on success, `{:error, reason}` on failure"
  },
  composes_with: [:encode]
}
```

# `encode`

```elixir
@spec encode(t()) :: String.t()
```

Encode a receipt to a base64url JSON string (no padding) for the `Payment-Receipt` header.

## Parameters

  * `receipt` - Receipt struct to encode (value)

## Returns

Base64url-encoded JSON string (`string`)

## Composes With

  * `decode`

```elixir
# descripex:contract
%{
  params: %{receipt: %{description: "Receipt struct to encode", kind: :value}},
  returns: %{type: :string, description: "Base64url-encoded JSON string"},
  composes_with: [:decode]
}
```

# `new`

```elixir
@spec new(keyword()) :: t()
```

Create a new receipt with defaults for `status` and `timestamp`.

## Parameters

  * `opts` - Keyword list with `:method` (required), `:reference` (required), `:external_id` (optional), `:timestamp` (optional, defaults to now) (value)

## Returns

Receipt struct with status `"success"` and RFC 3339 timestamp (`struct`)

```elixir
# descripex:contract
%{
  params: %{
    opts: %{
      description: "Keyword list with `:method` (required), `:reference` (required), `:external_id` (optional), `:timestamp` (optional, defaults to now)",
      kind: :value
    }
  },
  returns: %{
    type: :struct,
    description: "Receipt struct with status `\"success\"` and RFC 3339 timestamp"
  }
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
