Minimum requirements for conformant MPP SDK implementations.
Normative References:
- draft-ietf-httpauth-payment — Core protocol
- draft-payment-intent-charge — Charge intent semantics
- draft-tempo-charge — Tempo charge implementation
- Protocol-first — Core types (
Challenge,Credential,Receipt) map directly to HTTP headers - Pluggable methods — Payment methods (Tempo, Stripe, etc.) are independently packaged and gated wherever possible.
- Minimal dependencies — Core has no or minimal dependencies.
- Designed for extension — Users should be able to extend interface to support new
IntentandMethods without needing to make PRs against the core SDKs. - Well tested -- All SDKs should have high test coverage and include fuzz testing whenever possible.
SDKs must implement all core types and control flow defined in draft-ietf-httpauth-payment §5.
SDKs must implement at least the following payment method:
| Method | Spec |
|---|---|
tempo |
draft-tempo-charge |
Additional methods (e.g., stripe) may be implemented but are not required for conformance.
SDKs must implement each of the following intents:
| Intent | Spec |
|---|---|
charge |
draft-payment-intent-charge |
Additional intents (e.g., authorize) may be implemented but are not required for conformance.
SDKs MUST provide an HTTP transport layer that intercepts responses and handles the 402 payment flow transparently. The transport wraps the underlying HTTP client and manages credential creation without requiring application code changes.
This interface should be able to be defined in an explicit way (e.g. wrapped client) as well as implicitly (e.g. a fetch polyfill).
When a 402 response is received, the transport MUST implement the following retry logic:
SDKs MUST provide an HTTP transport/client that automatically handles 402 responses:
- Make initial request
- On 402 response, parse
WWW-Authenticateheader - Match challenge
methodto a configured payment method - Call
method.create_credential(challenge)to produce a credential - Retry request with
Authorization: Payment <credential>header - Return final response (with receipt if present)
SDKs MUST provide a way to generate challenges:
Intent.challenge(request: object) -> Challenge
The challenge:
- MUST generate a unique
idbound to the challenge parameters - MUST include
method,intent, andrequest - SHOULD include
expiresfor time-limited challenges
SDKs MUST provide a way to verify credentials.
Depending on method or intent, this may require making live API requests or submitting transactions to blockchains.
SDKs should keep these requirements in mind and ensure their primitives are configurable and their control flows reliable.
Intent.verify(credential: Credential, request: object) -> Receipt
Verification MUST:
- Validate the
challenge.idmatches the expected binding - Validate
challengeparameters match the original request - Validate
expireshas not passed - Verify the
payloadaccording to the payment method specification - Return a
Receipton success, or raise an error on failure
SDKs SHOULD provide integrations for common HTTP client/server libraries.
| SDK | Libraries |
|---|---|
mppx (TypeScript) |
fetch polyfill, fetch wrapper |
pympp (Python) |
httpx.AsyncClient, PaymentTransport |
mpp-rs (Rust) |
reqwest middleware (example) |
| SDK | Frameworks |
|---|---|
mppx (TypeScript) |
Fetch Request/Response, Node.js http module |
pympp (Python) |
@requires_payment decorator (Starlette/FastAPI, Django) |
mpp-rs (Rust) |
axum, actix-web examples |