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— echoedMPP.Challengestruct from the 402 responsepayload— 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 |
Summary
Functions
Decode a base64url JSON string into a credential with echoed challenge validation.
Encode a credential to a base64url JSON string (no padding) for the Authorization header.
Types
@type t() :: %MPP.Credential{ challenge: MPP.Challenge.t(), payload: map(), source: String.t() | nil }
Functions
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
Composes With
encode
# descripex:contract
%{
params: %{
encoded: %{
description: "Base64url-encoded JSON credential string",
kind: :value
}
},
errors: [:invalid_base64, :invalid_json, :missing_required_fields],
returns: %{
type: :tagged_tuple,
description: "`{:ok, credential}` on success, `{:error, reason}` on failure"
},
composes_with: [:encode]
}
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
# descripex:contract
%{
params: %{
credential: %{description: "Credential struct to encode", kind: :value}
},
returns: %{type: :string, description: "Base64url-encoded JSON string"},
composes_with: [:decode]
}