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
- Client: Requests the resource—
GET /resource - Server: Returns a payment challenge—
402Payment Required withWWW-Authenticate: Paymentheader - Client: Fulfills the payment—Sign a transaction, pay an invoice, or complete a card payment
- Client: Retries with a payment credential—
GET /resourcewithAuthorization: Paymentheader - Server: Verifies the payment and delivers the resource—
200OK withPayment-Receiptheader
Core concepts
The 402 status code that signals payment is required
Server-issued payment requirements in WWW-Authenticate
Client-submitted payment proofs in Authorization
Server acknowledgment of successful payment
HTTP and MCP transport bindings
Status codes
MPP uses HTTP status codes consistently to signal payment-related conditions:
| Condition | Status | Response |
|---|---|---|
| Resource requires payment, no credential provided | 402 | Fresh challenge in WWW-Authenticate |
| Malformed credential (invalid base64url, bad JSON) | 402 | Fresh challenge + malformed-credential problem |
| Unknown, expired, or already-used challenge id | 402 | Fresh challenge + invalid-challenge problem |
| Payment proof invalid or verification failed | 402 | Fresh challenge + verification-failed problem |
| Payment verified, access granted | 200 | Resource + optional Payment-Receipt |
| Payment verified, but policy denies access | 403 | No 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:
| Method | Description | Status |
|---|---|---|
| Tempo | Native stablecoin payments on Tempo Network | Production |
| Stripe | Traditional card payment methods through Stripe | Production |
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:
- Method identifier—Unique lowercase ASCII string (for example,
tempoorstripe) - Request schema—JSON structure for the
requestparameter in challenges - Payload schema—JSON structure for credential
payloadfields - Verification procedure—How servers validate payment proofs
- 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 immediatelysession—Streaming payment over a payment channel
Intent Specifications define:
- Required and optional
requestfields payloadrequirements- 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}):
| Code | Description |
|---|---|
payment-required | Resource requires payment |
payment-insufficient | Amount too low |
payment-expired | Challenge or authorization expired |
verification-failed | Proof invalid |
method-unsupported | Method not accepted |
malformed-credential | Invalid credential format |
invalid-challenge | Challenge 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:
- Requested amount is reasonable for the resource
- Recipient/address is expected
- Currency/asset is as expected
- 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
realmparameter - The
descriptionparameter can contain localized text; useAccept-Languageto determine appropriate language
Full specification
These docs provide a practical overview. For the full specification:
Core protocol spec (draft-httpauth-payment-00)
Model Context Protocol binding
Method and intent definitions (charge, session)
Browse the full specification directory
The full specification includes detailed ABNF grammar, security analysis, IANA considerations, and complete examples for various payment scenarios.