MPP vs x402 on Stellar comes down to one question: do you want a facilitator in the loop or not. Both protocols turn HTTP 402 into a payment step and both settle in Stellar USDC through the Soroban asset contract, but x402 routes the payment through a facilitator that verifies and settles, while MPP has the server itself verify and broadcast the transfer. MPP also adds a session (channel) intent for many small payments; x402 on Stellar today is per-request only.
Most “x402 vs MPP” write-ups compare Base and Tempo and stop there. This one covers Stellar specifically, because we run a router that accepts both dialects on the same URL and had to learn the differences the hard way.
What each protocol is
MPP (Machine Payments Protocol) is specified at mpp.dev, announced by Stripe and Tempo, and implemented in the mppxTypeScript framework. Stellar is one of its listed payment methods (“Smart contract payments on Stellar”), alongside Tempo, EVM, Solana and others. The Stellar method lives in the Stellar Development Foundation’s stellar-mpp-sdk (npm @stellar/mpp, MIT) and is documented at developers.stellar.org.
x402 is Coinbase Developer Platform’s protocol, launched in May 2025 according to the SDF announcement. On Stellar it uses the exact scheme: the client signs Soroban authorization entries for a SEP-41 token transfer, and a facilitator exposes /verify, /settle and /supported. The Stellar guide is at developers.stellar.org/docs/build/agentic-payments/x402.
MPP vs x402 on Stellar: side by side
| MPP (Stellar method) | x402 (Stellar, exact scheme) | |
|---|---|---|
| Origin / spec owner | mpp.dev; announced by Stripe and Tempo; Stellar method by SDF | Coinbase Developer Platform; Stellar scheme with OpenZeppelin |
| Settlement on Stellar | Soroban SAC transfer. Pull mode: client signs the envelope (or only the auth entries when fees are sponsored), server simulates and broadcasts. Push mode: client broadcasts, sends a signedHash | Client signs Soroban auth entries; facilitator runs verify (simulation) then settle (broadcast) |
| Facilitator required? | No. The resource server verifies and broadcasts itself | Yes. Coinbase (Stellar testnet only, per SDF docs) or OpenZeppelin’s Relayer facilitator (testnet and mainnet) |
| Intents | charge (one transfer per request) and session / channel (deposit once, sign cumulative commitments off-chain, one close transaction) | exact only: one signed transfer per request |
| Who pays gas | Client by default; with feePayer the server rebuilds the transaction with its own source account, so the agent never holds XLM | The facilitator. SDF describes the OpenZeppelin facilitator as covering network fees; Coinbase sponsors fees on testnet |
| SDK / packages | @stellar/mpp + mppx + @stellar/stellar-sdk; subpaths charge/client, charge/server, channel/client, channel/server | x402-stellar (SDF docs); @x402/core + @x402/stellar for spec-compliant clients |
| Replay protection | Server-side store (Store.memory() and friends, required since v0.7) keyed on the challenge id | Per-authorization nonce plus validAfter / validBefore window, checked at verify time |
| Wallets | Any Stellar keypair via the SDK; no browser-wallet list published | Freighter (extension), Albedo, Hana, HOT, Klever, OneKey. Freighter Mobile not yet |
| Headers | WWW-Authenticate: Payment ... challenge; Authorization: Payment ... credential | PAYMENT-REQUIRED challenge; PAYMENT-SIGNATURE credential; PAYMENT-RESPONSE receipt |
| Best for | Servers that want no third party in the money path; high frequency calls (channel); gasless agents | Teams already on x402 elsewhere; browser wallets; standard clients that must work against many servers |
Charge vs session: the turnstile and the bar tab
The biggest structural difference is not the header names. It is that MPP has two intents and x402 on Stellar has one. The SDF developer meeting of 7 May 2026 put it well:
“The mental model: charge mode is a turnstile; channel mode is a bar tab.” — Machine Payments Protocol: A Deep Dive
A turnstile charges once per pass. Every MPP charge request and every x402 exact request is a turnstile: one signed transfer, one on-chain transaction, one receipt. The MPP session guide describes the bar tab: the funder deposits into a one-way payment channel contract once, the client signs cumulative commitments locally, the server verifies each one by read-only simulation, and “no on-chain transaction is needed per payment”. The server closes the channel with a single transaction. For an agent making hundreds of sub-cent calls to one API, that is the mode that matters, and x402 does not offer it on Stellar.
Gas: who holds XLM
Stellar requires XLM for fees, and a freshly created agent wallet usually has USDC and nothing else. Both protocols solve this, but in different places. In x402 the facilitator submits the transaction, so the facilitator pays. In MPP the charge guide explains that when the server configures feePayer, it “signals fee sponsorship to the client via the challenge” and the client “then signs only the Soroban auth entries (not the full transaction envelope)”. The practical difference: with MPP the party that sells the API also sponsors the fee, so there is no third account to fund or trust.
One mainnet gotcha with the MPP SDK
If you go to mainnet with @stellar/mpp, do not copy the exported USDC_SAC_MAINNET constant. As of 2026-09-01 both mainnet SAC constants in the package are StrKey-invalid (54 and 55 characters instead of 56); see stellar-mpp-sdk issue #68. The package does not use them internally, so only code that follows the README into its own config is affected. Pass the contract id yourself. The pubnet USDC SAC is CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75, which is also the value the SDF x402 page lists.
And if you need both
You may not get to choose. Some of the APIs an agent wants only speak MPP, some only x402, and the client library you already ship speaks one of them. MPP Router sidesteps the choice at the HTTP layer: a request to a paid route with no credential gets a dual-format 402 carrying both header families in one response.
HTTP/2 402
www-authenticate: Payment id="...", realm="apiserver.mpprouter.dev",
method="stellar", intent="charge", request="<base64url JSON>", expires="..."
payment-required: <base64url JSON>The two encodings carry the same amount (7-decimal Stellar base units), the same USDC SAC and the same recipient. An mppx client with @stellar/mpp/charge/client reads WWW-Authenticate and replies with Authorization: Payment. A vanilla @x402/core client with @x402/stellar/exact/client reads Payment-Required and replies with Payment-Signature. Neither needs router-specific code. We verified the x402 path end to end on Stellar mainnet on 2026-04-12, and as of 2026-08-18 the catalog has 20 distinct services verified with real paid calls across 446 payable routes.
To be precise about what the router is: a payment proxy. It accepts your Stellar USDC payment for one request, pays the merchant on Tempo (or Base for x402 merchants), and returns the merchant’s response. It is not a facilitator for other people’s servers (there is no public /x402/verify or /x402/settle), it does not resell tokens, and it holds nothing beyond the per-request payment.
Which should you pick?
- You are a server on Stellar and want no intermediary: MPP. Verify and broadcast yourself, sponsor fees if you want gasless agents.
- You expect many small calls from the same agent: MPP session. One deposit, one close, everything else off-chain.
- You already run x402 on Base or Solana: x402 with the OpenZeppelin facilitator on mainnet, and reuse your existing client.
- You are an agent that just wants to pay: either client works against a dual-format 402, so pick the one your stack already has.
Try it
The shortest way to see MPP vs x402 on Stellar is to fire one request each way at the same URL and diff the headers. Start at how it works, browse the service catalog, or hand your agent apiserver.mpprouter.dev/llms.txt and let it read the contract directly.