Skip to content
LogoLogo

Protocol overview

Standardizing HTTP 402 for machine-to-machine payments

The Machine Payments Protocol (MPP) is a protocol for machine-to-machine payments. It standardizes HTTP 402 "Payment Required" with an extensible framework that works with any payment network.

These docs provide a developer-friendly overview. For the full specification, see the full IETF Specification.

Flow

  1. Client: Requests the resourceGET /resource
  2. Server: Returns a payment challenge402 Payment Required with WWW-Authenticate: Payment header
  3. Client: Fulfills the payment—Sign a transaction, pay an invoice, or complete a card payment
  4. Client: Retries with a payment credential GET /resource with Authorization: Payment header
  5. Server: Verifies the payment and delivers the resource200 OK with Payment-Receipt header

Core concepts

Status codes

MPP uses HTTP status codes consistently to signal payment-related conditions:

ConditionStatusResponse
Resource requires payment, no credential provided402Fresh challenge in WWW-Authenticate
Malformed credential (invalid base64url, bad JSON)402Fresh challenge + malformed-credential problem
Unknown, expired, or already-used challenge id402Fresh challenge + invalid-challenge problem
Payment proof invalid or verification failed402Fresh challenge + verification-failed problem
Payment verified, access granted200Resource + optional Payment-Receipt
Payment verified, but policy denies access403No challenge (payment was valid)

See HTTP 402 for details on when to return each status code.

Payment method agnostic

MPP works with any payment network or currency. The core protocol defines the framework, while payment methods define how specific networks integrate:

MethodDescriptionStatus
TempoNative stablecoin payments on Tempo NetworkProduction
StripeTraditional card payment methods through StripeProduction

Each payment method specifies its own request and payload schemas while sharing the common Challenge/Credential flow.

Payment method requirements

Payment method specifications must define:

  1. Method identifier—Unique lowercase ASCII string (for example, tempo or stripe)
  2. Request schema—JSON structure for the request parameter in challenges
  3. Payload schema—JSON structure for credential payload fields
  4. Verification procedure—How servers validate payment proofs
  5. Settlement procedure—How payment is finalized

Payment intents

Payment intents describe the type of payment being requested. Common intents include:

  • charge—One-time payment that settles immediately
  • session—Streaming payment over a payment channel

Intent Specifications define:

  • Required and optional request fields
  • payload requirements
  • Verification and settlement semantics

Servers can offer multiple intents in separate challenges, allowing clients to choose:

WWW-Authenticate: Payment id="abc", method="tempo", intent="charge", ...
WWW-Authenticate: Payment id="def", method="tempo", intent="session", ...

Request body binding

For requests with bodies (POST, PUT, PATCH), servers can bind the challenge to the request body using a digest parameter:

WWW-Authenticate: Payment id="...",
    method="tempo",
    intent="charge",
    digest="sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:",
    request="..."

When a digest is present, clients must submit the credential with a request body whose digest matches. This prevents clients from modifying the request body after receiving the challenge.

The digest is computed per RFC 9530 Content-Digest header format.

Error handling

Failed payment attempts return 402 with a fresh challenge and a Problem Details RFC 9457 body:

{
  "type": "https://paymentauth.org/problems/verification-failed",
  "title": "Payment Verification Failed",
  "status": 402,
  "detail": "Invalid payment proof."
}

Common error codes (full type URI: https://paymentauth.org/problems/{code}):

CodeDescription
payment-requiredResource requires payment
payment-insufficientAmount too low
payment-expiredChallenge or authorization expired
verification-failedProof invalid
method-unsupportedMethod not accepted
malformed-credentialInvalid credential format
invalid-challengeChallenge ID unknown, expired, or already used

Use the Retry-After header to indicate when clients can retry failed payments.

Security considerations

Transport security

TLS 1.2 or later is REQUIRED for all Payment authentication flows. Use TLS 1.3 where possible. Payment Credentials contain sensitive authorization data that could result in financial loss if intercepted.

Replay protection

Payment methods must provide single-use proof semantics. A payment proof can be used exactly once; subsequent attempts to use the same proof must be rejected.

Idempotency

Servers must not perform side effects (database writes, external API calls) for requests that have not been paid. The unpaid request that triggers a 402 challenge must not modify server state beyond recording the challenge itself.

For non-idempotent methods (POST, PUT, DELETE), accept an Idempotency-Key header to enable safe client retries.

Amount verification

Clients must verify before authorizing payment:

  1. Requested amount is reasonable for the resource
  2. Recipient/address is expected
  3. Currency/asset is as expected
  4. Validity window is appropriate

Credential handling

Payment credentials are bearer tokens that authorize financial transactions. Servers and intermediaries must not log Payment credentials or include them in error messages, debugging output, or analytics.

Caching

Payment challenges contain unique identifiers and time-sensitive payment data that must not be cached. Servers must send Cache-Control: no-store with 402 responses. Responses containing Payment-Receipt headers must include Cache-Control: private.

Extensibility

The protocol is designed for extensibility, with simple constraints where required for security or a consistent developer experience:

Custom parameters

Implementations may define additional parameters in challenges:

  • Parameters must use lowercase names
  • Unknown parameters must be ignored by clients
  • This allows payment methods to add method-specific fields

Size considerations

  • Keep challenges under 8 KB
  • Clients must handle challenges of at least 4 KB
  • Servers must handle credentials of at least 4 KB

Internationalization

  • All string values use UTF-8 encoding
  • Payment method identifiers are restricted to ASCII lowercase
  • Use ASCII-only values for the realm parameter
  • The description parameter can contain localized text; use Accept-Language to determine appropriate language

Full specification

These docs provide a practical overview. For the full specification:

The full specification includes detailed ABNF grammar, security analysis, IANA considerations, and complete examples for various payment scenarios.