MPPtslive · you pay per call

Pay per forecast over MPP

Buy a weather forecast with the Machine Payments Protocol — a challenge→credential handshake, priced pay-as-you-go (1 credit for today, up to 7 for a week).

http-simple-agent-ts/
MPPTypeScript@nevermined-io/paymentspay-as-you-goOpen-Meteo
1 What you'll learn

Pay per forecast with the Machine Payments Protocol.

  • MPP: a challenge→credential handshake over the same plans, delegations and credits as x402
  • Pay-as-you-go pricing — the agent's credits function charges 1 credit for today, up to 7 for a week
  • payments.mpp.fetch runs the whole round-trip and returns the Payment-Receipt
  • The same route also serves x402 buyers — mpp: true advertises both protocols
2 How it works

The buyer POSTs to /weather/payg with no credential and gets 402 with a WWW-Authenticate: Payment challenge — the price (credits) is sealed into the challenge at that moment. payments.mpp.fetch mints an MPP credential for your delegation, retries with Authorization: Payment, and the agent verifies, serves the forecast, and settles — returning a Payment-Receipt.

POST /weather/paygno credential
402WWW-Authenticate: Payment
credential + retryAuthorization: Payment
200Payment-Receipt
3 Under the hood
3.1 Client

payments.mpp.fetch runs the full challenge→credential handshake in one call.

# pay a PAYG forecast over MPP
// a delegation backs the buyer (erc4337), same as x402
const { delegationId } = await payments.delegation.createDelegation({
  provider: 'erc4337', spendingLimitCents: 10000, durationSecs: 604800, currency: 'usdc',
})

// one call: unpaid → 402 challenge → mint credential → retry → 200 + receipt
const { response, receipt, paid } = await payments.mpp.fetch(
  AGENT_URL + '/weather/payg',
  { method: 'POST', headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ city: 'Berlin', days: 5 }) },
  { delegationConfig: { delegationId }, planId: PLAN_ID_PAYG, maxCredits: 7 },
)
const forecast = await response.json()  // 5-day forecast
3.2 Agent

The credits function prices each request; mpp: true accepts the MPP handshake on the same route.

# pay-as-you-go route, dual-protocol
import { paymentMiddleware } from '@nevermined-io/payments/express'

app.use(paymentMiddleware(payments, {
  'POST /weather/payg': {
    planId: PLAN_ID_PAYG,
    credits: (req) => priceForRequest(req.body),  // 1 for today, up to 7 for a week
    mpp: true,
  },
}))

app.post('/weather/payg', async (req, res) => {
  const { city, days } = parseWeatherRequest(req.body)
  res.json(days && days > 1 ? await getForecast(city, days) : await getTodayWeather(city))
})
src/agent.tsthe /weather/payg route — dynamic credits, mpp: true
src/pricing.tspriceForRequest: 1 credit for today, up to 7 for a forecast
src/services/weather.service.tsgetForecast — keyless multi-day weather from Open-Meteo
scripts/smoke.tsbuyer: the MPP round-trip against the agent
4 See it run
Pay per forecast over MPP

Sandbox agent — real payment round-trips (402 → authorize → settle) with a per-session credit balance, no external service and no real money. Connect your Nevermined sandbox account, then send a city — the buyer runs the real MPP handshake (payments.mpp.fetch) against the deployed agent's pay-as-you-go route.