transferWithAuthorization, the server validates it through mppx’s verify() hook, and settlement happens in a separate step you control.
Concept: For what MPP is and how it relates to x402, see Machine Payments Protocol (MPP). For the x402 equivalent, see Build a pay-per-call API.
The example uses Stable mainnet. Use small amounts when testing.
What you’ll build
An HTTP endpoint that returns402 Payment Required with an MPP WWW-Authenticate challenge, accepts a signed credential in the Authorization header, verifies it, settles transferWithAuthorization on USDT0, and returns the response with a Payment-Receipt header.
Prerequisites
- A funded USDT0 wallet on Stable. See Use the faucet or Move USDT0.
- Node 20+ with
mppx,viem, andzodinstalled. - A seller account (an EOA) on Stable. For the default settlement path, the seller pays gas in USDT0; the Gas Waiver section shows the zero-gas variant.
1. Define the shared schema
Method.from() declares the intent and the schemas for the request (Challenge) and the credential payload. Both client and server import this definition.
2. Server: verify the credential
Method.toServer wires verify() into mppx. The function receives the deserialized credential (challenge + payload) and must throw on invalid proofs or return a Receipt.
3. Settle: submit transferWithAuthorization
Settlement is intentionally separate from verify(). After verify() returns, you submit the authorization on-chain through whichever path fits your operational model. Three options, in order of recommendation.
Default: server submits directly
The seller’s EOA submitstransferWithAuthorization to USDT0 with the signed authorization. The seller pays gas in USDT0 (Stable’s native gas token), so there is no separate gas-token balance to manage.
Alternative: settle through the Gas Waiver
Use Stable’s Gas Waiver to submit the inner transaction atgasPrice = 0. The seller still signs the wrapping transaction, but pays no gas. Requires a Waiver Server API key.
gasPrice: 0, encoded transferWithAuthorization call) before posting.
Alternative: hand off to an x402 facilitator
If you already operate an x402 facilitator integration (Semantic Pay or Heurist), you can reuse it as a settlement target. POST apaymentPayload to /settle; the facilitator submits the on-chain call.
The exact paymentPayload shape is x402-middleware-internal and not specified at the wire level. The simplest path is to use the facilitator’s own SDK to build the payload, or stick with the direct-submission path above. The facilitator does not need to speak MPP; it sees only the transferWithAuthorization fields.
4. Client: sign a credential
Method.toClient wires createCredential() into mppx. The client reads the Challenge, signs the EIP-712 authorization with the agent’s viem account, and serializes the credential.
5. Wire the server together
Usemppx’s Express middleware to issue Challenges, parse incoming Authorization headers, run verify(), call your settle function, and emit the Payment-Receipt header.
6. Run the flow end to end
Start the server, confirm the Challenge, run a client, and confirm settlement.Confirm the Challenge
Send a paid request
Verify on Stablescan
Openhttps://stablescan.xyz/tx/0x8f3a1b2c... and confirm the transferWithAuthorization settled to your PAY_TO address.
What you just did
- Paid in USDT0, denominated in dollars, with no gas-token balance to manage on the buyer side.
- Used MPP’s
WWW-Authenticate/Authorization/Payment-Receiptwire format on the client-server hop. - Settled with
transferWithAuthorizationon Stable in the same HTTP request lifecycle (~700 ms block time).
Next recommended
MPP concept
Read how MPP relates to x402 and what the other intents look like.
MPP sessions
Stream micropayments with off-chain vouchers when per-request settlement is too expensive.
Facilitators
Use Semantic Pay or Heurist as the settlement target instead of submitting directly.

