AI Agent Payment Standard: MPP Protocol Analysis and Ecosystem Status

Stripe and Tempo promote the MPP machine payment protocol, using HTTP challenge-response for multi-currency settlement, with more fiat channels than x402, currently includes 137 services, transaction volume lags behind x402.

Author: Beosin

As the demand for AI Agents and automated clients to autonomously execute tasks explodes, how machines can complete payments without human intervention is becoming an urgent infrastructure problem. Traditional payment interfaces struggle to adapt to high-frequency, dynamic, cross-platform machine-to-machine transaction scenarios.

To address this, Stripe and Tempo have jointly launched the Machine Payments Protocol (MPP), an open protocol designed specifically for machine-to-machine payments. It aims to enable clients and servers to seamlessly negotiate prices, select payment methods, submit credentials, and settle transactions within automated workflows. This article analyzes MPP's protocol design and real-world progress from three dimensions: MPP protocol mechanics, comparison with x402, and current ecosystem status.

MPP Protocol Analysis

MPP borrows the challenge-response structure familiar to developers in HTTP, naturally embedding payment into the lifecycle of network requests. Transactions are completed through Stripe’s payment channels or blockchains like Tempo. The entire process follows a challenge-response pattern based on standard HTTP headers:

  1. The client sends a normal HTTP request (e.g., GET) to a paid endpoint.
  2. The server returns a payment challenge: the 402 Payment Required and WWW-Authenticate: Payment headers. These headers tell the client what currencies are accepted, the price, the recipient address, and available payment methods.
  3. The client selects a payment method and completes the payment (stablecoin transfer, card payment, etc.).
  4. The client resends the original request with the payment credential in the Authorization: Payment header.
  5. The server verifies the payment and returns a response with the Payment-Receipt header.

Image

https://mpp.dev/protocol

There are two important concepts in the entire process: payment challenge and payment credential. A payment challenge is the specific payment requirement issued by the server, with the following content structure:

WWW-Authenticate: Payment id="qB3wErTyU7iOpAsD9fGhJk",

    realm="mpp.dev",

    method="tempo",

    intent="charge",

    expires="2025-01-15T12:05:00Z",

    opaque="eyJyb3V0ZSI6Ii92MS9zZWFyY2gifQ",

    request="eyJhbW91bnQiOiIxMDAwIiwiY3VycmVuY3kiOiJ1c2QifQ"

The intent parameter is currently divided into three types: charge, subscription, and session. Taking the Tempo blockchain as an example:

Image

The request parameter is a base64url-encoded JSON string, which the client decodes to obtain detailed payment method information, such as:

{

  "amount": "1000",

  "currency": "usd",

  "recipient": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

}

The payment credential is used to prove that you have paid or authorized a payment. Its content is also a base64url-encoded JSON string:

Authorization: Payment eyJjaGFsbGVuZ2UiOnsiaWQiOiJxQjN3RXJUeVU3aU9wQXNEOWZHaEprIiwi...

After decoding, the content contains the original payment challenge, the specific payment method and payment proof, and the payer’s identity information (address, DID, account ID):

{

  "challenge": {

    "expires": "2025-01-15T12:05:00Z",

    "id": "qB3wErTyU7iOpAsD9fGhJk",

    "intent": "charge",

    "method": "tempo",

    "opaque": "eyJyb3V0ZSI6Ii92MS9zZWFyY2gifQ",

    "realm": "mpp.dev",

    "request": "eyJhbW91bnQiOiIxMDAwIi4uLn0",

  },

  "payload": {

    "signature": "0xabc123...",

    "type": "transaction"

  },

  "source": "did:pkh:eip155:4217:0x1234567890abcdef..."

}

Taking MPP’s TypeScript SDK as an example, the specific practice is as follows:

Server side

  1. Create a server endpoint to handle payment requests
import crypto from 'crypto';

import Stripe from 'stripe';

// 'stripe' here is the mppx payment method factory, not the Stripe Node SDK

import { Mppx, stripe as mppStripe, tempo } from 'mppx/server';

 // Tempo testnet token contract address for pathUSD (testnet USDC).

const PATH_USD = '0x20c0000000000000000000000000000000000000';

const mppSecretKey = crypto.randomBytes(32).toString('base64');

const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY!, {

  apiVersion: '2026-03-04.preview',

});

 export async function handler(request: Request) {

  const recipientAddress = await createPayToAddress(request);

   const mppx = Mppx.create({

    methods: [

      tempo.charge({

        currency: PATH_USD,

        recipient: recipientAddress,

        testnet: true,

      }),

      mppStripe.charge({

        client: stripeClient,

        networkId: process.env.STRIPE_PROFILE_ID!,

        paymentMethodTypes: ['card', 'link'],

      }),

    ],

    secretKey: mppSecretKey,

  });

   const response = await Mppx.compose(

    mppx.tempo.charge({ amount: '0.01', recipient: recipientAddress }),

    mppx.stripe.charge({ amount: '0.50', currency: 'usd' }),

  )(request);

   if (response.status === 402) return response.challenge;

   return response.withReceipt(Response.json({ data: '...' }));

}

2. Create a payment intent (PaymentIntent) to receive stablecoin/cryptocurrency payments. After the client initiates a request, createPayToAddress will return a cryptocurrency deposit address, which the client will receive and use for payment.

import Stripe from 'stripe';

import { Credential } from 'mppx';

import NodeCache from 'node-cache';

const paymentCache = new NodeCache({ stdTTL: 300, checkperiod: 60 });

 async function createPayToAddress(request: Request): Promise<`0x${string}`> {

  const authHeader = request.headers.get('authorization');

  if (authHeader && Credential.extractPaymentScheme(authHeader)) {

    const credential = Credential.fromRequest(request);

    const toAddress = credential.challenge.request.recipient as `0x${string}`;

     if (!toAddress) {

      throw new Error(

        'PaymentIntent did not return expected crypto deposit details'

      );

    }

    if (!paymentCache.has(toAddress)) {

      throw new Error('Invalid payTo address: not found in server cache');

    }

    return toAddress;

  }

   const decimals = 6;

  const amountInCents = Number(10000) / 10 ** (decimals - 2);

   const paymentIntent = await stripe.paymentIntents.create({

    amount: amountInCents,

    currency: 'usd',

    payment_method_types: ['crypto'],

    payment_method_data: {

      type: 'crypto',

    },

    payment_method_options: {

      crypto: {

        mode: 'deposit',

        deposit_options: {

          networks: ['tempo'],

        },

      } as Stripe.PaymentIntentCreateParams.PaymentMethodOptions.Crypto,

    },

    confirm: true,

  });

   if (

    !paymentIntent.next_action ||

    !('crypto_display_details' in paymentIntent.next_action)

  ) {

    throw new Error(

      'PaymentIntent did not return expected crypto deposit details'

    );

  }

   const depositDetails = paymentIntent.next_action

    .crypto_display_details as unknown as {

    deposit_addresses?: Record<string, { address?: string }>;

  };

  const payToAddress = depositDetails.deposit_addresses?.tempo?.address;

   if (!payToAddress) {

    throw new Error(

      'PaymentIntent did not return expected crypto deposit details'

    );

  }

   console.log(

    `Created PaymentIntent ${paymentIntent.id} for $${(

      amountInCents / 100

    ).toFixed(2)} -> ${payToAddress}`

  );

   paymentCache.set(payToAddress, true);

  return payToAddress as `0x${string}`;

}

Client Side

Create a Tempo / other payment account

import { Mppx, tempo } from 'mppx/client'

const provider = Provider.create({ mpp: false }) // Avoid double 402 handling; mppx is configured below.

await provider.request({ method: 'wallet_connect' })

Based on that, create the payment handler

import { Provider } from 'accounts'

 Mppx.create({ 

  methods: [tempo({ 

    account: provider.getAccount({ signable: true }), 

    getClient: provider.getClient, 

  })], 

}) 

Use fetch to request a resource

const response = await fetch('https://mpp.dev/api/ping/paid')

Differences between MPP and x402

In May 2025, Coinbase launched the x402 protocol, using 402 Payment Required to implement a stablecoin payment protocol. Its flow is very similar to MPP: the client requests a resource → the server returns HTTP 402 with payment headers → the client signs a stablecoin transfer and retries with the payment signature → the Facilitator verifies settlement on-chain → the server returns HTTP 200.

The x402 protocol is a breakthrough for stablecoin payments — the protocol is very concise and developers can integrate it quickly. However, x402 does not have a fiat payment channel, so enterprise-grade Agents cannot use company credit cards to pay for various API fees via the x402 protocol. Stripe fills this fiat channel gap through the MPP protocol, with payment methods that already include Tempo, EVM, Solana, Stellar, Lightning, Stripe, and bank cards. It has also designed different payment specifications for different scenarios: Charge, Session, Discovery, and JSON-RPC/MCP transport. In summary, x402 is the internet’s on-chain stablecoin payment standard, while MPP is a more general-purpose HTTP payment standard:

图片

Current State of the MPP Ecosystem

According to the official registry (MPP Service Registry), MPP has recorded a total of 137 services (one service can belong to multiple categories) and 1,439 endpoints. Among them, 128 services support only Tempo payments, 2 services support only Stripe payments, and 7 services support both Tempo and Stripe payments.

*Note: The MPP protocol documentation supports more payment methods than just these two; it also supports lightning, evm, card, solana, and other payment methods. However, this official service registry currently only includes two types of payment services: Tempo and Stripe.

From the endpoint perspective, the registry lists 1,261 endpoints that are marked with a price or dynamic price. Of these, 1,068 are fixed-price, 193 are dynamic-price, and another 178 have no explicit price or can be considered free/unpriced. The median fixed price is $0.02/request, the average is about $0.139/request, and the highest fixed price is StablePhone's buy-phone-number endpoint at $20/request.

In terms of intent usage: 129 services use charge, 8 services use session. Session-based services include Anthropic, Dune, Google Gemini, Modal, OpenRouter, Alchemy, Conduit, and Tempo RPC—services characterized by high frequency, repeated calls, and dynamically changing usage—while ordinary data services are more suited to one charge per request.

In terms of category, the distribution of registered services leans toward data and tool APIs consumable by agents:

Imagedata source: https://raw.githubusercontent.com/tempoxyz/mpp/main/schemas/services.ts

The third-party data platform MPPscan has indexed over 3,700 MPP servers. According to its statistics, the total number of MPP transactions exceeds 1.1 million, with a total transaction volume of approximately $140,000, and an average transaction value of about $0.127.

Since the x402 protocol was launched about 8 months earlier than MPP, we only selected data from the past 30 days for both the MPP and x402 protocols (excluding data from MPP's non-blockchain payment channels) for comparison, as shown in the figure below:

Image

At the current stage, the overall adoption scale of the x402 protocol is significantly higher than that of MPP. Over the past 30 days, the total number of x402 transactions was 10.6 times that of MPP, and the total transaction amount was 20.2 times that of MPP. In terms of protocol positioning, x402 emphasizes lightweight, open, and fast integration, making it easier to scale transaction volume first. MPP, on the other hand, places more emphasis on multiple payment methods and payment system completeness. Given that it is still early in ecosystem development and scenario validation, there is a scale gap between MPP and the x402 protocol.

Conclusion

MPP deeply embeds payment logic into the lifecycle of an HTTP request, lowering the barrier for machine payments through the challenge-response pattern familiar to developers. Compared to Coinbase's x402 protocol, MPP is more diversified in payment methods (covering stablecoins, bank cards, Lightning Network, etc.), supports one-time deductions, session-level usage-based settlement, and subscriptions in settlement models, and leverages Stripe's fiat rails and Tempo's on-chain compliance controls to provide a more complete payment framework for enterprise applications of various sizes.

In the future, whether MPP can become the universal payment protocol for the AI Agent economy depends on whether more service providers register and actually enable multiple payment methods. In terms of on-chain payment channel transaction data, the x402 protocol currently leads by a wide margin. While MPP offers more comprehensive payment channels through platforms like Tempo and Stripe, its payment scale and developer adoption still need to be validated over time.

Share to:

Author: Beosin

Opinions belong to the column author and do not represent PANews.

This content is not investment advice.

Image source: Beosin. If there is any infringement, please contact the author for removal.

Follow PANews official accounts, navigate bull and bear markets together
PANews APP
Securitize intends to list on the NYSE under the ticker SECZ on July 2, expected to raise approximately $400 million
PANews Newsflash