x402 and MPP on the same paywall: one server, two payment protocols
x402 reused HTTP 402 for a specific shape of payment: an
unsigned request, an on-chain settle, a retry with proof attached. It is not
the only proposal doing this. MPP - the Merchant
Payments Protocol, an IETF-track spec for a Payment HTTP auth scheme -
solves the same problem with a different wire format: a WWW-Authenticate: Payment challenge instead of a bare 402 body, and an Authorization: Payment
credential on retry instead of a custom header.
Two clients, two conventions, one seller who doesn't want to run two paywalls. So Agent402 speaks both, from the same routes, with the same settlement underneath.
What actually changes on the wire
Nothing about settlement. @x402/express keeps sole settlement
authority - it still verifies, still settles, still decides pass or fail.
What changes is the envelope around it:
- A 402 also carries
WWW-Authenticate: Payment, one HMAC-bound challenge per EVM rail we offer. The x402acceptsentry for that rail rides inside the challenge's own metadata, verbatim - so the challenge needs nothing stored server-side to issue or check later. Same statelessness x402 already has, extended to a second header. - An inbound
Authorization: Paymentcredential that verifies against that HMAC gets re-encoded asPAYMENT-SIGNATUREand falls through the normal x402 pipeline unchanged - the same replay guard, the same payer attribution, the same idempotency-key handling an x402 buyer gets. - A settled 200 mirrors its
PAYMENT-RESPONSEback asPayment-Receipt, MPP's expected receipt header.
The shim is a pure translation layer sitting in front of the paywall, not a
second payment path beside it. mppx (the reference codec) is only used for
encode/decode primitives here - its own request-guard and settle path are
never mounted, because two components with settlement authority is how you
get a double-settle bug.
Try it
If you already have an MPP-capable client, point it at any paid Agent402 route the normal way - no separate config, no MPP-specific endpoint:
curl -i -X POST https://agent402.tools/api/hash -d '{"text":"hi","algo":"sha256"}'
# HTTP/2 402
# www-authenticate: Payment realm="agent402.tools", evm=eip155:8453;charge="…"
Sign against that challenge the way your MPP client already knows how to,
retry with Authorization: Payment ..., and you get back 200 plus a
Payment-Receipt header - not a custom Agent402 format, the receipt shape
MPP itself defines.
Why bother running two protocols
Because the buyer shouldn't have to guess which one a seller picked. An agent
built against MPP tooling should be able to pay an x402-native seller without
a special case, and vice versa - and that only holds if sellers on both sides
actually do it, not just say they support it. This one is verified end to
end: a real mppx client buying over the native wire against this server,
one verify-and-settle, the EIP-712 signature checked against Base USDC's
actual on-chain domain, x402 traffic on the same routes untouched, and a
tampered or expired challenge rejected before it reaches a handler.
Rollout is a single switch server-side (present or absent, no partial state), and which EVM rails get an MPP challenge is configurable per deployment - so a seller can offer MPP on their primary chain without promising it everywhere they offer x402. The two protocols don't have to agree on everything to both work today.