Accept one-time payments
Build a payment-gated API that charges $0.01 per request using mppx. The server returns a random photo from Picsum behind a paywall.
One-time payment server setup
Set up an Mppx charge instance
Set up an Mppx instance with the tempo method.
recipientis the address where you receive payments.currencyis the token address for payments (in this case,pathUSD).
import { Mppx, tempo } from 'mppx/server'
const mppx = Mppx.create({
methods: [tempo({
currency: '0x20c0000000000000000000000000000000000000',
recipient: '0xa726a1CD723409074DF9108A2187cfA19899aCF8',
})],
})Add a one-time payment route
Add payment verification using mppx.charge as route middleware. The handler only runs after payment is verified.
import { Mppx, tempo } from 'mppx/nextjs'
const mppx = Mppx.create({
methods: [tempo({
currency: '0x20c0000000000000000000000000000000000000',
recipient: '0xa726a1CD723409074DF9108A2187cfA19899aCF8',
})],
})
export const GET =
mppx.charge({ amount: '0.01', description: 'Random stock photo' })
(async () => {
const res = await fetch('https://picsum.photos/1024/1024')
return Response.json({ url: res.url })
})import { Hono } from 'hono'
import { Mppx, tempo } from 'mppx/hono'
const app = new Hono()
const mppx = Mppx.create({
methods: [tempo({
currency: '0x20c0000000000000000000000000000000000000',
recipient: '0xa726a1CD723409074DF9108A2187cfA19899aCF8',
})],
})
app.get(
'/api/photo',
mppx.charge({ amount: '0.01', description: 'Random stock photo' }),
async (c) => {
const res = await fetch('https://picsum.photos/1024/1024')
return c.json({ url: res.url })
},
)import express from 'express'
import { Mppx, tempo } from 'mppx/express'
const app = express()
const mppx = Mppx.create({
methods: [tempo({
currency: '0x20c0000000000000000000000000000000000000',
recipient: '0xa726a1CD723409074DF9108A2187cfA19899aCF8',
})],
})
app.get(
'/api/photo',
mppx.charge({ amount: '0.01', description: 'Random stock photo' }),
async (req, res) => {
const response = await fetch('https://picsum.photos/1024/1024')
res.json({ url: response.url })
},
)import { Mppx, tempo } from 'mppx/server'
const mppx = Mppx.create({
methods: [tempo({
currency: '0x20c0000000000000000000000000000000000000',
recipient: '0xa726a1CD723409074DF9108A2187cfA19899aCF8',
})],
})
Bun.serve({
async fetch(request) {
const result = await mppx.charge({
amount: '0.01',
description: 'Random stock photo',
})(request)
if (result.status === 402) return result.challenge
const res = await fetch('https://picsum.photos/1024/1024')
return result.withReceipt(Response.json({ url: res.url }))
},
})Next steps for one-time payments
Accept pay-as-you-go payments
Session-based billing with payment channels
Server quickstart
Framework middleware reference
Full charge reference
Complete tempo.charge API documentation
Was this helpful?