| [ Web Proxy ] |
| Viewing: https://docs.stripe.com/payments/machine/mpp | [Back] [Original] |
MPP, the Machine Payments Protocol, is an open protocol that lets agents pay for your APIs and services programmatically without a checkout UI, co-authored by Stripe and Tempo.
When an agent requests your API or service, your server returns an HTTP 402 response with payment details. The agent authorizes the payment, retries the request, and gets access to the paid resource along with a receipt.
profile_ ID. You use this value as the networkId to create your endpoint.You can build an API that uses MPP with a single prompt to your coding agent:
Read https://docs.stripe.com/payments/machine/mpp.md?lang=node, and monetize my API using MPP to charge 0.50 USD per API call. Run `npx mppx@latest validate http://localhost:4242` to iteratively validate the implementation as you develop.
To build the integration yourself, follow the steps in this guide to install the dependencies, create an endpoint that returns an HTTP 402 challenge and verifies payments, add payment methods such as cards or stablecoins, and test the full flow.
Use this approach if you want more control over your server implementation or want to understand each part of the integration.
You can also review the apps complete source code on GitHub.
Install the required dependencies:
npm install mppx stripe
Create an endpoint that checks for a 0.50 USD payment on each request and returns an HTTP 402 challenge if no payment is present. If it verifies a payment, it returns a receipt.
import crypto from 'crypto'; import StripeClient from 'stripe'; import { Mppx, stripe } from 'mppx/server'; // Secret used to secure payment challenges // https://mpp.dev/protocol/challenges#challenge-binding const mppSecretKey = crypto.createHmac("sha256", process.env.STRIPE_SECRET_KEY!).update("mpp-challenge-signing").digest("base64"); const stripeClient = new StripeClient(process.env.STRIPE_SECRET_KEY!); const stripeMachinePayments = stripe.create({ client: stripeClient, networkId: process.env.STRIPE_PROFILE_ID!, livemode: !process.env.STRIPE_SECRET_KEY!.includes('_test_') }); const mppx = Mppx.create({ methods: [stripeMachinePayments.spt.charge()], secretKey: mppSecretKey, }); export async function handler(request: Request) { const response = await mppx.compose([ 'stripe/charge', { amount: '0.50', currency: 'usd', decimals: 2 }, ])(request); if (response.status === 402) return response.challenge; return response.withReceipt(Response.json({ data: '...' })); }
Use MPP to accept payments from agents with a variety of payment methods, including cards through Shared Payment Tokens (SPTs) and stablecoin payments.
See availability requirements for SPTs and stablecoin payments to learn more.
By default, the endpoint you create supports SPTs. Make sure that you also add support for stablecoin payments to support agents with crypto wallets and charge for payments as low as 0.01 USDC.
To accept stablecoin payments, follow the steps below to:
Agents with stablecoins send payments to this onchain address on supported blockchains, such as Tempo. Stripe automatically offramps these payments and settles them into your Stripe balance.
curl https://api.stripe.com/v1/crypto/deposit_addresses \ -u "$STRIPE_SECRET_KEY:" \ -H "Stripe-Version: 2026-05-27.preview" \ -d network=tempo
Create a deposit address and store the returned address as TEMPO_DEPOSIT_ADDRESS in your servers environment variables.
You can create deposit addresses as often as you want, but we recommend that you keep these calls off your core request path.
Add the deposit address to your stripeMachinePayments configuration, then rebuild mppx with defaultMethods(), which includes SPTs and stablecoin payments. Update compose to accept payments with either method.
const stripeMachinePayments = stripe.create({ client: stripeClient, networkId: process.env.STRIPE_PROFILE_ID!, livemode: !process.env.STRIPE_SECRET_KEY!.includes('_test_'), depositAddresses: { tempo: process.env.TEMPO_DEPOSIT_ADDRESS! }, }); const mppx = Mppx.create({ methods: stripeMachinePayments.defaultMethods(), secretKey: mppSecretKey, }); export async function handler(request: Request) { const response = await mppx.compose( ['tempo/charge', { amount: '0.50' }], ['stripe/charge', { amount: '0.50', currency: 'usd', decimals: 2 }], )(request); if (response.status === 402) return response.challenge; return response.withReceipt(Response.json({ data: '...' })); }
Run mppx validate to automatically verify your implementation end-to-end. The command tests discovery, challenge formats, error handling, and the full payment flow.
npx mppx@latest validate http://localhost:4242
We recommend running validate against both a sandbox and live mode version of your server. In a sandbox, the CLI automatically completes roundtrip test transactions against your server. In live mode, the CLI can also complete roundtrip transactions with real funds.
You can also test each step individually. First, verify your server returns a 402 with the payment requirements:
Use the Tempo CLI to send a payment from the command line. If your server uses a live mode deposit address, this command moves real funds.
curl -fsSL https://tempo.xyz/install | bash tempo wallet login tempo wallet fund tempo request -X POST --json '{}' http://localhost:4242/paid
After a successful payment, the server returns the content. In the Dashboard, go to Payments to see the transaction.
To test in a sandbox:
profile_test_ ID.curl https://api.stripe.com/v1/crypto/deposit_addresses \ -u "$STRIPE_SECRET_KEY:" \ -H "Stripe-Version: 2026-05-27.preview" \ -d network=tempo
Store the returned address as your TEMPO_DEPOSIT_ADDRESS environment variable. The configuration above detects your sandbox API key and sets livemode to false. mppxs stripe.create automatically configures Tempo testnet.
| Web Proxy Viewer | New URL | Original Page |