MPP.Headers (mpp v0.6.1)

Copy Markdown View Source

Parse and format the three MPP protocol headers.

Headers

  • WWW-Authenticate: Payment — challenge header using RFC 9110 auth-param syntax
  • Authorization: Payment — credential header (scheme + base64url JSON blob)
  • Payment-Receipt — receipt header (bare base64url JSON blob)

Usage

# Server: format a 402 challenge response header
header_value = MPP.Headers.format_challenge(challenge)
# → ~s(Payment id="x7Tg...", realm="api.example.com", method="stripe", ...)

# Client: parse a 402 challenge from response
{:ok, challenge} = MPP.Headers.parse_challenge(header_value)

# Client: format credential for request
header_value = MPP.Headers.format_credential(credential)
# → "Payment eyJjaGFsbGVuZ2..."

# Server: parse credential from request
{:ok, credential} = MPP.Headers.parse_credential(header_value)

# Server: format receipt for response
header_value = MPP.Headers.format_receipt(receipt)

# Client: parse receipt from response
{:ok, receipt} = MPP.Headers.parse_receipt(header_value)

API Functions

FunctionArityDescriptionParam Kinds
parse_receipt1Parse a Payment-Receipt header value into a receipt struct.header: value
format_receipt1Format a receipt as a Payment-Receipt header value (bare base64url JSON, no scheme prefix).receipt: value
parse_credential1Parse an Authorization: Payment header value into a credential struct.header: value
format_credential1Format a credential as an Authorization: Payment header value.credential: value
parse_challenges1Parse a WWW-Authenticate header containing one or more Payment challenges. Splits on scheme boundaries, skips non-Payment schemes. Partial failures are tolerated: if some challenges parse and others fail, only the successful ones are returned (matching mppx deserializeList semantics).header: value
parse_challenge1Parse a WWW-Authenticate: Payment header value into a challenge struct.header: value
format_challenge1Format a challenge as a WWW-Authenticate: Payment header value with RFC 9110 auth-param syntax.challenge: value

Summary

Functions

Format a challenge as a WWW-Authenticate: Payment header value with RFC 9110 auth-param syntax.

Format a credential as an Authorization: Payment header value.

Format a receipt as a Payment-Receipt header value (bare base64url JSON, no scheme prefix).

Parse a WWW-Authenticate: Payment header value into a challenge struct.

Parse a WWW-Authenticate header containing one or more Payment challenges. Splits on scheme boundaries, skips non-Payment schemes. Partial failures are tolerated: if some challenges parse and others fail, only the successful ones are returned (matching mppx deserializeList semantics).

Parse an Authorization: Payment header value into a credential struct.

Parse a Payment-Receipt header value into a receipt struct.

Functions

format_challenge(challenge)

@spec format_challenge(MPP.Challenge.t()) :: String.t()

Format a challenge as a WWW-Authenticate: Payment header value with RFC 9110 auth-param syntax.

Parameters

  • challenge - Challenge struct to format (value)

Returns

Header value string with quoted auth-params (string)

Composes With

  • parse_challenge
# descripex:contract
%{
  params: %{
    challenge: %{description: "Challenge struct to format", kind: :value}
  },
  returns: %{
    type: :string,
    description: "Header value string with quoted auth-params"
  },
  composes_with: [:parse_challenge]
}

format_credential(credential)

@spec format_credential(MPP.Credential.t()) :: String.t()

Format a credential as an Authorization: Payment header value.

Parameters

  • credential - Credential struct to format (value)

Returns

Header value with Payment scheme prefix and base64url JSON blob (string)

Composes With

  • parse_credential
# descripex:contract
%{
  params: %{
    credential: %{description: "Credential struct to format", kind: :value}
  },
  returns: %{
    type: :string,
    description: "Header value with Payment scheme prefix and base64url JSON blob"
  },
  composes_with: [:parse_credential]
}

format_receipt(receipt)

@spec format_receipt(MPP.Receipt.t()) :: String.t()

Format a receipt as a Payment-Receipt header value (bare base64url JSON, no scheme prefix).

Parameters

  • receipt - Receipt struct to format (value)

Returns

Base64url-encoded JSON string (string)

Composes With

  • parse_receipt
# descripex:contract
%{
  params: %{receipt: %{description: "Receipt struct to format", kind: :value}},
  returns: %{type: :string, description: "Base64url-encoded JSON string"},
  composes_with: [:parse_receipt]
}

parse_challenge(header)

@spec parse_challenge(String.t()) :: {:ok, MPP.Challenge.t()} | {:error, atom()}

Parse a WWW-Authenticate: Payment header value into a challenge struct.

Parameters

  • header - Raw WWW-Authenticate header value string (value)

Returns

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

Errors

  • :invalid_scheme
  • :missing_required_params
  • :duplicate_param
  • :invalid_auth_params
  • :request_too_large

Composes With

  • format_challenge
# descripex:contract
%{
  params: %{
    header: %{
      description: "Raw WWW-Authenticate header value string",
      kind: :value
    }
  },
  errors: [:invalid_scheme, :missing_required_params, :duplicate_param,
   :invalid_auth_params, :request_too_large],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, challenge}` on success, `{:error, reason}` on failure"
  },
  composes_with: [:format_challenge]
}

parse_challenges(header)

@spec parse_challenges(String.t()) :: {:ok, [MPP.Challenge.t()]} | {:error, atom()}

Parse a WWW-Authenticate header containing one or more Payment challenges. Splits on scheme boundaries, skips non-Payment schemes. Partial failures are tolerated: if some challenges parse and others fail, only the successful ones are returned (matching mppx deserializeList semantics).

Parameters

  • header - Raw WWW-Authenticate header value, possibly containing multiple challenges (value)

Returns

{:ok, [challenge]} on success, {:error, reason} if no Payment challenges found or all fail to parse (tagged_tuple)

Errors

  • :no_payment_challenges
  • :invalid_scheme
  • :missing_required_params
  • :duplicate_param
  • :invalid_auth_params
  • :request_too_large

Composes With

  • parse_challenge
  • format_challenge
# descripex:contract
%{
  params: %{
    header: %{
      description: "Raw WWW-Authenticate header value, possibly containing multiple challenges",
      kind: :value
    }
  },
  errors: [:no_payment_challenges, :invalid_scheme, :missing_required_params,
   :duplicate_param, :invalid_auth_params, :request_too_large],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, [challenge]}` on success, `{:error, reason}` if no Payment challenges found or all fail to parse"
  },
  composes_with: [:parse_challenge, :format_challenge]
}

parse_credential(header)

@spec parse_credential(String.t()) :: {:ok, MPP.Credential.t()} | {:error, atom()}

Parse an Authorization: Payment header value into a credential struct.

Parameters

  • header - Raw Authorization header value string (value)

Returns

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

Errors

  • :invalid_scheme
  • :invalid_base64
  • :invalid_json
  • :missing_required_fields
  • :token_too_large

Composes With

  • format_credential
# descripex:contract
%{
  params: %{
    header: %{
      description: "Raw Authorization header value string",
      kind: :value
    }
  },
  errors: [:invalid_scheme, :invalid_base64, :invalid_json,
   :missing_required_fields, :token_too_large],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, credential}` on success, `{:error, reason}` on failure"
  },
  composes_with: [:format_credential]
}

parse_receipt(header)

@spec parse_receipt(String.t()) :: {:ok, MPP.Receipt.t()} | {:error, atom()}

Parse a Payment-Receipt header value into a receipt struct.

Parameters

  • header - Raw Payment-Receipt header value (bare base64url JSON) (value)

Returns

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

Errors

  • :invalid_base64
  • :invalid_json
  • :missing_required_fields
  • :token_too_large

Composes With

  • format_receipt
# descripex:contract
%{
  params: %{
    header: %{
      description: "Raw Payment-Receipt header value (bare base64url JSON)",
      kind: :value
    }
  },
  errors: [:invalid_base64, :invalid_json, :missing_required_fields,
   :token_too_large],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, receipt}` on success, `{:error, reason}` on failure"
  },
  composes_with: [:format_receipt]
}