402 Payment Required until the agent pays, then returns the resource.
For the shortest path, read the Payments quickstart first. For Python, Go, and Rust, see Protect an endpoint in Python, Go, or Rust.
Before you start
Accept MPP and x402
Integrate both protocols in the same service, so that agents of either protocol can pay. Share the pricing and fulfillment logic between them. A request must never pass through two independent charging paths. Payments with MPP and x402 compares the protocols. The InFlow balance is the default way for agents to pay. It is thebalance rail in MPP and the balance scheme in x402. Agents can also pay onchain or with a linked card.
Install the packages
For MPP,
mppx is a peer dependency. Each framework has a runnable example in SDK packages.
Protect an endpoint with x402
This server from thex402-seller-express example protects two endpoints and leaves one endpoint free.
server.ts
What each part does
Pass
inflowSchemeRegistrations as the third argument. Without it, the middleware stops at boot with RouteConfigurationError.
Write a price
inflowAccepts reads three price formats. Each format accepts up to 8 decimal places.
For
balance and exact offers, USD matches any stablecoin in your seller configuration. For an instrument offer, USD is fiat USD.
Stablecoin payments have no minimum amount. An instrument price must be in USD, at least USD 0.50, and in whole cents.
Limit the schemes
Passschemes to limit the payment options on an endpoint, as POST /api/upload does above.
Use more than one facilitator
The middleware accepts a list of facilitators. The first facilitator that claims a scheme and network pair gets the payments for that pair.Caching
The foundation middleware sets the cache headers. An unpaid challenge getsno-store. A settled response gets private.
Protect an endpoint with MPP
MPP usesmppx. Add the InFlow method to Mppx.create. Then charge() returns a 402 challenge for an unpaid request.
mppx/express, mppx/hono, mppx/nextjs, or mppx/elysia. The Payments quickstart shows the Express adapter.
Pass paymentHttpTransport() as the transport. Without it, a server error also sends a payment challenge.
Set the secret key
Mppx.create needs a secretKey. It also reads the MPP_SECRET_KEY variable. Generate the secret.
Choose the currency
The charge currency sets the rail. The SDK reads the rail for each currency fromGET /v1/mpp/config, one time at startup.
Stablecoin payments have no minimum amount. Card payments in USD have a minimum of USD 0.50 and must be in whole cents. This applies to the
instrument rail, card, and stripe.
Accept more than one currency
charge() advertises one currency. For several currencies, use inflowChargesNodeListener or inflowCharges. The endpoint sends one challenge for each price.
checkout(req, res) on a Node http server or on an Express endpoint. For a Web Fetch handler, use inflowCharges(mppx, prices).
The framework adapters expose charge only and remove compose. Thus a multi-currency endpoint needs the core Mppx instance from @inflowpayai/mpp-seller.
The buyer pays one challenge. Each amount is independent. It is not an exchange rate.
Control which offers appear
Two hooks select the challenges for a request.canOffer works on one method. selectOffers works on the server and runs after every canOffer.
canOffer rejects every offer, the handler fails with No payment offers are available for this request. selectOffers must return at least one offer.
Offer a subscription
A subscription protects a resource with recurring payment terms. The buyer approves the terms, and InFlow charges the first period. InFlow then manages later charges, past-due states, and cancellation. Subscriptions use the InFlowbalance rail. The buyer and the seller do not need a blockchain wallet.
inflowSubscriptions(mppx, plans).
The SDK also accepts minute for tests, with a minimum periodCount of 5. Do not offer minute plans to customers.
Charge in TIP-20 tokens on Tempo
@inflowpayai/mpp-seller also exports a tempo method for Tempo TIP-20 charges. Pass it to Mppx.create as tempo({ apiKey, currency, recipient }). Fee-payer sponsorship is off by default. Set methodDetails.feePayer: true to issue a sponsored challenge.
The package also exports card for USD payments with Visa network tokens, and stripe for USD payments with Stripe Shared Payment Tokens. The mpp-card-seller-express example uses card.
Check trusted-agent signatures
@inflowpayai/tap-seller checks trusted-agent request signatures on your own server. See SDK packages.
Next step
Test a payment
Pay your own endpoint in the sandbox.