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

Payment credential — the client's response to a 402 challenge.

A credential is sent in the `Authorization: Payment <base64url JSON>` header
after the client has fulfilled payment. It echoes the original challenge
parameters alongside method-specific payment proof, enabling the server to
verify both the challenge binding (via `MPP.Challenge.verify/2`) and the
payment itself (via the method module).

## Wire Format

The base64url-decoded JSON contains:

    %{
      "challenge" => %{...},   # Echoed challenge parameters
      "payload"   => %{...},   # Method-specific payment proof
      "source"    => "did:..."  # (optional) Payer identifier
    }

The `challenge.request` field remains as its raw base64url string — never
re-serialized — to preserve the exact bytes used in HMAC computation.

## Fields

  * `challenge` — echoed `MPP.Challenge` struct from the 402 response
  * `payload` — method-specific payment proof (opaque map at this layer)
  * `source` — (optional) payer identifier, recommended as DID format

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `encode` | 1 | Encode a credential to a base64url JSON string (no padding) for the Authorization header. | `credential: value` |
| `decode` | 1 | Decode a base64url JSON string into a credential with echoed challenge validation. | `encoded: value` |

# `t`

```elixir
@type t() :: %MPP.Credential{
  challenge: MPP.Challenge.t(),
  payload: map(),
  source: String.t() | nil
}
```

# `decode`

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

Decode a base64url JSON string into a credential with echoed challenge validation.

## Parameters

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

## Returns

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

## Errors

  * `:invalid_base64`
  * `:invalid_json`
  * `:missing_required_fields`
  * `:invalid_optional_field`
  * `:empty_id`
  * `:invalid_method`
  * `:invalid_request`
  * `:invalid_digest`

## Composes With

  * `encode`

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

# `encode`

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

Encode a credential to a base64url JSON string (no padding) for the Authorization header.

## Parameters

  * `credential` - Credential struct to encode (value)

## Returns

Base64url-encoded JSON string (`string`)

## Composes With

  * `decode`

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

---

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