APPD
← Protocols

MPP

Machine Payments Protocol

MPP is an internet payment protocol for machine-to-machine commerce. It uses the HTTP 402 status code to signal payment requirements, supporting both crypto (on-chain stablecoins) and fiat (cards, wallets via Stripe). Developed by Stripe and Tempo.

Key Features

Dual Payment Rails

Supports both on-chain crypto payments (USDC stablecoins) and traditional fiat payments (cards, wallets) through Stripe — all via the same protocol.

HTTP 402 Native

Built on the HTTP 402 Payment Required status code. Payment negotiation happens within standard HTTP request/response cycles.

Challenge-Based Sessions

Uses cryptographic challenge-response for payment verification. Each challenge is secured with a 32-byte random secret.

Machine-to-Machine First

Designed for autonomous agents and programmatic clients. No browser redirects or human interaction required.

How MPP Works

1

Client requests a paid resource from the server

2

Server returns HTTP 402 with a payment challenge (challengeId, amount, currency, accepted methods)

3

Client completes payment — either on-chain (crypto to deposit address) or off-chain (card/wallet via SPT)

4

Client retries the request with payment proof in the Authorization header

5

Server verifies the credential and returns 200 OK with the requested resource

Payment Methods

Two payment rails, one protocol

Crypto Payments

On-chain stablecoin payments via deposit addresses. The server provides a blockchain address, the client sends tokens directly. Settlement is confirmed on-chain.

  1. 1Server returns 402 with deposit address and supported tokens
  2. 2Client sends USDC to the deposit address on-chain
  3. 3Stripe auto-captures the PaymentIntent on fund arrival
  4. 4Client retries with Authorization header containing payment proof

SPT (Shared Payment Token) Payments

Fiat payments via cards, wallets, and other Stripe-supported methods. The client creates a token that the server uses to charge through Stripe's payment network.

  1. 1Client creates an SPT (Shared Payment Token)
  2. 2Server uses the token to create a Stripe PaymentIntent
  3. 3Payment processes through Stripe's rails (card, Link, etc.)
  4. 4Server verifies completion and grants access

Crypto PaymentsFlow

Client
Server
Stripe

Request paid resource (no payment)

Use crypto payment method

POST /v1/payment_intents

Return PaymentIntent with deposit address

HTTP 402 with payment requirements

Retry request with payment proof

Return requested resource

SPT (Shared Payment Token) PaymentsFlow

Client
Server
Stripe

Request paid resource (no payment)

HTTP 402 with payment requirements

Create Shared Payment Token (SPT)

Return SPT

Retry request with SPT credential

Create PaymentIntent with SPT

POST /v1/payment_intents

Return confirmed PaymentIntent

Return requested resource

HTTP Protocol Details

402 response and Authorization header specification

402 Response Body

When payment is required, the server returns a JSON problem details object following RFC 9457.

{
  "type": "https://paymentauth.org/problems/payment-required",
  "title": "Payment Required",
  "status": 402,
  "detail": "Payment is required to access this resource.",
  "challengeId": "ch_1abc2def3ghi..."
}

PaymentIntent (Crypto)

{
  "id": "pi_123",
  "amount": 5000,
  "currency": "usd",
  "status": "requires_action",
  "next_action": {
    "type": "crypto_display_details",
    "crypto_display_details": {
      "deposit_addresses": {
        "tempo": {
          "address": "0x...",
          "supported_tokens": [
            {
              "token_currency": "usdc",
              "token_contract_address": "0x..."
            }
          ]
        }
      }
    }
  }
}

Authorization Header

After payment, the client includes proof in the Authorization header. The scheme is extracted and validated by the server.

Code Example

Crypto Payments (Node.js)

// Server: MPP crypto payment endpoint
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2026-03-04.preview',
});

// 1. Client requests resource → server returns 402
app.get('/api/data', async (req, res) => {
  const credential = Credential.fromRequest(req);

  if (!credential) {
    const challenge = await createChallenge({
      amount: 500, // $5.00
      currency: 'usd',
    });
    return res.status(402).json({
      type: 'https://paymentauth.org/problems/payment-required',
      title: 'Payment Required',
      status: 402,
      challengeId: challenge.id,
    });
  }

  // 4. Verify payment credential
  const scheme = Credential.extractPaymentScheme(credential);
  const verified = await verifyPayment(scheme);

  if (verified) {
    return res.json({ data: 'protected resource' });
  }
});

SPT (Shared Payment Token) Payments (Client)

// Client: SPT (Shared Payment Token) flow
const response = await fetch('https://api.example.com/data');

if (response.status === 402) {
  const challenge = await response.json();

  // Create SPT and complete payment via Stripe
  const payment = await stripe.charge({
    networkId: 'internal',
    paymentMethodTypes: ['card', 'link'],
    secretKey: process.env.STRIPE_SECRET_KEY,
  });

  // Retry with Authorization header
  const result = await fetch('https://api.example.com/data', {
    headers: {
      'Authorization': `Bearer ${payment.token}`,
    },
  });

  const data = await result.json();
}

Security

Challenge Secret — 32-byte cryptographic random value (Base64-encoded) secures each payment challenge

Credential Verification — Server extracts and validates payment scheme, PaymentIntent ID, and address consistency

Replay Protection — Each challenge is single-use with unique identifiers

Ecosystem

Key organizations behind MPP

Stripe

Global payments infrastructure, MPP protocol co-creator, fiat payment rails

Tempo

On-chain payment infrastructure, crypto payment rails, stablecoin settlement

Testing & Tools

Stripe Sandbox for test transactions with simulated crypto deposits

mppx CLI tool (npm package) for command-line payment testing

Tempo testnet with PATH_USD test tokens for crypto flow development

Next Steps