Decodes and validates x402 v2 PAYMENT-SIGNATURE header values.
The header value is Base64-encoded JSON carrying the v2 PaymentPayload
envelope (x402Version: 2). accepted must be a complete
X402.PaymentRequirements object and payload must contain the
scheme-specific signed data. When requirements are passed to validate/2,
every core field is matched and advertised extra values must be preserved.
Payloads that declare x402Version: 1 — or omit the version entirely, which
x402 v1 clients do — are rejected with
{:error, {:unsupported_x402_version, version}}. This SDK does not speak the
v1 wire format (v1 payments arrive in the X-PAYMENT header, which
X402.Plug.PaymentGate never reads); rejecting explicitly is safer than the
false interop of validating a shape no facilitator settles.
Scheme-specific structural validation (for example the upto ceiling
check) dispatches through X402.Scheme.Registry; pass additional
X402.Scheme modules with the :schemes option of validate/3 or
decode_and_validate/3. Kinds with no registered scheme module pass
through with :ok — the facilitator remains the authority.
Summary
Header Encoding
Decodes a Base64 PAYMENT-SIGNATURE value to a map.
Returns the canonical x402 header name.
Payment Verification
Decodes and validates a PAYMENT-SIGNATURE header in one step.
Decodes and validates a PAYMENT-SIGNATURE header against requirements.
Decodes and validates a PAYMENT-SIGNATURE header with custom schemes.
Validates a decoded v2 PAYMENT-SIGNATURE payload.
Validates a decoded PAYMENT-SIGNATURE payload against payment requirements.
Validates a decoded PAYMENT-SIGNATURE payload with custom schemes.
Header Encoding
@spec decode(String.t()) :: {:ok, map()} | {:error, decode_error()}
Decodes a Base64 PAYMENT-SIGNATURE value to a map.
Examples
iex> payload = %{"x402Version" => 2, "accepted" => %{"scheme" => "exact"}, "payload" => %{}}
iex> value = payload |> Jason.encode!() |> Base.encode64()
iex> X402.PaymentSignature.decode(value)
{:ok, payload}
iex> X402.PaymentSignature.decode("not-base64")
{:error, :invalid_base64}
@spec header_name() :: String.t()
Returns the canonical x402 header name.
Examples
iex> X402.PaymentSignature.header_name()
"PAYMENT-SIGNATURE"
Payment Verification
@spec decode_and_validate(String.t()) :: {:ok, map()} | {:error, decode_and_validate_error()}
Decodes and validates a PAYMENT-SIGNATURE header in one step.
Examples
iex> payload = %{"x402Version" => 2, "accepted" => %{"scheme" => "exact", "network" => "eip155:8453", "amount" => "1", "asset" => "asset", "payTo" => "receiver", "maxTimeoutSeconds" => 60, "extra" => %{}}, "payload" => %{}}
iex> value = payload |> Jason.encode!() |> Base.encode64()
iex> X402.PaymentSignature.decode_and_validate(value)
{:ok, payload}
@spec decode_and_validate(String.t(), map()) :: {:ok, map()} | {:error, decode_and_validate_error()}
Decodes and validates a PAYMENT-SIGNATURE header against requirements.
@spec decode_and_validate(String.t(), map(), keyword()) :: {:ok, map()} | {:error, decode_and_validate_error() | term()}
Decodes and validates a PAYMENT-SIGNATURE header with custom schemes.
Behaves like decode_and_validate/2; opts are passed to validate/3.
@spec validate(map()) :: {:ok, map()} | {:error, validate_error()}
Validates a decoded v2 PAYMENT-SIGNATURE payload.
Payloads with x402Version: 2 are validated against the v2
PaymentPayload structure. Payloads declaring version 1 — or omitting the
version, as v1 clients do — return
{:error, {:unsupported_x402_version, version}}; any other version returns
{:error, :invalid_x402_version}.
Examples
iex> payload = %{
...> "x402Version" => 2,
...> "accepted" => %{
...> "scheme" => "exact",
...> "network" => "eip155:8453",
...> "amount" => "10000",
...> "asset" => "0xasset",
...> "payTo" => "0xreceiver",
...> "maxTimeoutSeconds" => 60,
...> "extra" => %{}
...> },
...> "payload" => %{"signature" => "0xsignature"}
...> }
iex> X402.PaymentSignature.validate(payload)
{:ok, payload}
iex> X402.PaymentSignature.validate(%{"x402Version" => 2})
{:error, :invalid_payload}
@spec validate(map(), map()) :: {:ok, map()} | {:error, validate_error()}
Validates a decoded PAYMENT-SIGNATURE payload against payment requirements.
For v2, this matches the complete accepted object. For the "upto" scheme,
it also ensures the signed maximum does not exceed the advertised amount.
Validates a decoded PAYMENT-SIGNATURE payload with custom schemes.
Behaves like validate/2, additionally consulting the given
X402.Scheme modules (before the built-ins) for scheme-specific payload
validation — see X402.Scheme.Registry for the resolution rules.
Options
:schemes- AdditionalX402.Schememodules consulted (before the built-ins) for scheme-specific payload validation — seeX402.Scheme.Registry. The default value is[].
Types
@type decode_and_validate_error() :: decode_error() | validate_error()
@type decode_error() :: :invalid_base64 | :invalid_json | :payload_too_large
@type upto_validation_error() :: X402.Scheme.UptoEVM.validation_error()
@type validate_error() :: :invalid_payload | :invalid_payment_requirements | :invalid_x402_version | :no_matching_requirements | {:unsupported_x402_version, 1 | nil} | {:missing_fields, [String.t()]} | {:invalid_fields, [String.t()]} | {:invalid_upto_payment, upto_validation_error()}