MPP.Transports.JsonRpc (mpp v0.14.0)

Copy Markdown View Source

Bare JSON-RPC 2.0 payment transport (non-MCP).

Payment challenges ride on the same JSON-RPC channel as the method call: a -32042 error carries error.data.challenges, the client retries with org.paymentauth/credential on the root-level _meta field (so params may be an array), and a successful result returns org.paymentauth/receipt on the response's root _meta.

This is the generic JSON-RPC placement from the MPP transport spec (paymentauth.org draft-payment-transport-mcp-00 § Metadata Placement). MCP's nested params._meta / result._meta lives in MPP.Mcp. Servers accept credentials in either location.

Server adapter

config = MPP.Transports.JsonRpc.init(
  secret_key: secret,
  realm: "rpc.example.com",
  method: MyMethod,
  amount: "1000",
  currency: "usd"
)

MPP.Transports.JsonRpc.call(request, config, fn request ->
  dispatch(request)
end)

Mount on Plug with MPP.Transports.JsonRpc.Plug.

API Functions

FunctionArityDescriptionParam Kinds
receipt_meta_key0Metadata key for receipts in _meta.-
credential_meta_key0Metadata key for credentials in _meta.-
verification_failed_code0JSON-RPC error code for verification failed (-32043).-
payment_required_code0JSON-RPC error code for payment required (-32042).-
extract_challenges1Parse payment challenges from a JSON-RPC error map or full response envelope.response: value
payment_required?1Return true if a JSON-RPC error or envelope signals payment required (-32042).response: value
attach_receipt3Attach a payment receipt at the JSON-RPC response's root _meta.response: value, receipt: value, challenge_id: value
attach_credential2Attach a payment credential at the JSON-RPC request's root _meta.request: value, credential: value
extract_credential1Extract a payment credential from root _meta, falling back to params._meta.request: value
call3Run a JSON-RPC request through payment verification and attach a root-level _meta receipt on success.request: value, config: value, handler: value
init1Build server-side JSON-RPC transport configuration from the same endpoint options as MPP.Plug.opts: value

Summary

Functions

Attach a payment credential at the JSON-RPC request's root _meta.

Attach a payment receipt at the JSON-RPC response's root _meta.

Run a JSON-RPC request through payment verification and attach a root-level _meta receipt on success.

Metadata key for credentials in _meta.

Parse payment challenges from a JSON-RPC error map or full response envelope.

Extract a payment credential from root _meta, falling back to params._meta.

Build server-side JSON-RPC transport configuration from the same endpoint options as MPP.Plug.

Return true if a JSON-RPC error or envelope signals payment required (-32042).

JSON-RPC error code for payment required (-32042).

Metadata key for receipts in _meta.

JSON-RPC error code for verification failed (-32043).

Functions

attach_credential(request, credential)

@spec attach_credential(map(), MPP.Credential.t()) :: map()

Attach a payment credential at the JSON-RPC request's root _meta.

Parameters

  • request - JSON-RPC request map (value)
  • credential - An MPP.Credential.t() struct (value)

Returns

Request with root _meta containing the credential (map)

# descripex:contract
%{
  params: %{
    request: %{description: "JSON-RPC request map", kind: :value},
    credential: %{description: "An `MPP.Credential.t()` struct", kind: :value}
  },
  returns: %{
    type: :map,
    description: "Request with root `_meta` containing the credential"
  }
}

attach_receipt(response, receipt, challenge_id)

@spec attach_receipt(map(), MPP.Receipt.t(), String.t()) :: map()

Attach a payment receipt at the JSON-RPC response's root _meta.

Parameters

  • response - JSON-RPC response envelope (value)
  • receipt - An MPP.Receipt.t() struct (value)
  • challenge_id - The challenge ID this receipt fulfills (value)

Returns

Response envelope with root _meta containing the receipt (map)

# descripex:contract
%{
  params: %{
    response: %{description: "JSON-RPC response envelope", kind: :value},
    receipt: %{description: "An `MPP.Receipt.t()` struct", kind: :value},
    challenge_id: %{
      description: "The challenge ID this receipt fulfills",
      kind: :value
    }
  },
  returns: %{
    type: :map,
    description: "Response envelope with root `_meta` containing the receipt"
  }
}

call(request, config, handler)

@spec call(map(), MPP.Plug.Config.t(), (map() -> term())) :: map()

Run a JSON-RPC request through payment verification and attach a root-level _meta receipt on success.

Parameters

  • request - JSON-RPC request map; credential may be on root _meta or params._meta (value)
  • config - Transport config from init/1 (value)
  • handler - Function receiving the request after verification and returning a JSON-RPC response or result (value)

Returns

JSON-RPC response with payment-required/verification error, or successful root _meta receipt (map)

# descripex:contract
%{
  params: %{
    request: %{
      description: "JSON-RPC request map; credential may be on root `_meta` or params._meta",
      kind: :value
    },
    config: %{description: "Transport config from init/1", kind: :value},
    handler: %{
      description: "Function receiving the request after verification and returning a JSON-RPC response or result",
      kind: :value
    }
  },
  returns: %{
    type: :map,
    description: "JSON-RPC response with payment-required/verification error, or successful root `_meta` receipt"
  }
}

credential_meta_key()

@spec credential_meta_key() :: String.t()

Metadata key for credentials in _meta.

Returns

Key "org.paymentauth/credential" (string)

# descripex:contract
%{
  returns: %{type: :string, description: "Key `\"org.paymentauth/credential\"`"}
}

extract_challenges(response)

@spec extract_challenges(map()) ::
  {:ok, [MPP.Challenge.t()]} | {:error, :no_challenges | :invalid_challenge}

Parse payment challenges from a JSON-RPC error map or full response envelope.

Parameters

  • response - JSON-RPC error map with data.challenges, or a full response envelope (value)

Returns

{:ok, [challenge]} or {:error, :no_challenges | :invalid_challenge} (tagged_tuple)

Errors

  • :no_challenges
  • :invalid_challenge
# descripex:contract
%{
  params: %{
    response: %{
      description: "JSON-RPC error map with `data.challenges`, or a full response envelope",
      kind: :value
    }
  },
  errors: [:no_challenges, :invalid_challenge],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, [challenge]}` or `{:error, :no_challenges | :invalid_challenge}`"
  }
}

extract_credential(request)

@spec extract_credential(map()) ::
  {:ok, MPP.Credential.t()}
  | {:error, :no_credential | :invalid_credential | :invalid_challenge}

Extract a payment credential from root _meta, falling back to params._meta.

Parameters

  • request - JSON-RPC request map (value)

Returns

{:ok, credential} or {:error, :no_credential | :invalid_credential | :invalid_challenge} (tagged_tuple)

Errors

  • :no_credential
  • :invalid_credential
  • :invalid_challenge
# descripex:contract
%{
  params: %{request: %{description: "JSON-RPC request map", kind: :value}},
  errors: [:no_credential, :invalid_credential, :invalid_challenge],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, credential}` or `{:error, :no_credential | :invalid_credential | :invalid_challenge}`"
  }
}

init(opts)

@spec init(keyword()) :: MPP.Plug.Config.t()

Build server-side JSON-RPC transport configuration from the same endpoint options as MPP.Plug.

Parameters

  • opts - Keyword options including :secret_key, :realm, and one or more payment methods (value)

Returns

MPP.Plug.Config reused by the JSON-RPC server adapter (struct)

# descripex:contract
%{
  params: %{
    opts: %{
      description: "Keyword options including :secret_key, :realm, and one or more payment methods",
      kind: :value
    }
  },
  returns: %{
    type: :struct,
    description: "`MPP.Plug.Config` reused by the JSON-RPC server adapter"
  }
}

payment_required?(response)

@spec payment_required?(map()) :: boolean()

Return true if a JSON-RPC error or envelope signals payment required (-32042).

Parameters

  • response - JSON-RPC error map or full response envelope (value)

Returns

true if the error code is -32042 (boolean)

# descripex:contract
%{
  params: %{
    response: %{
      description: "JSON-RPC error map or full response envelope",
      kind: :value
    }
  },
  returns: %{
    type: :boolean,
    description: "`true` if the error code is `-32042`"
  }
}

payment_required_code()

@spec payment_required_code() :: integer()

JSON-RPC error code for payment required (-32042).

Returns

Error code -32042 (integer)

# descripex:contract
%{returns: %{type: :integer, description: "Error code `-32042`"}}

receipt_meta_key()

@spec receipt_meta_key() :: String.t()

Metadata key for receipts in _meta.

Returns

Key "org.paymentauth/receipt" (string)

# descripex:contract
%{returns: %{type: :string, description: "Key `\"org.paymentauth/receipt\"`"}}

verification_failed_code()

@spec verification_failed_code() :: integer()

JSON-RPC error code for verification failed (-32043).

Returns

Error code -32043 (integer)

# descripex:contract
%{returns: %{type: :integer, description: "Error code `-32043`"}}