<!-- tempo-docs-context -->
> Source: [/docs/guide/machine-payments/one-time-payments](https://tempo.xyz/developers/docs/guide/machine-payments/one-time-payments.md)
> Section: [Machine Payments](https://tempo.xyz/developers/docs/agents.md). Pay for APIs, accept API payments, find services, and use Machine Payments Protocol (MPP).
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# 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](https://github.com/DMarby/picsum-photos) behind a paywall.

## One-time payment server setup

::::steps
### Install one-time payment dependencies

:::code-group
```bash [npm]
npm install mppx viem
```

```bash [pnpm]
pnpm add mppx viem
```

```bash [bun]
bun add mppx viem
```
:::

### Set up an `Mppx` charge instance

[Set `MPP_SECRET_KEY`](https://tempo.xyz/developers/docs/guide/machine-payments/server#set-the-server-secret) before starting the server.

Set up an `Mppx` instance with the `tempo` method.

* `recipient` is the address where you receive payments.
* `currency` is the token address for payments (in this case, `OUSD`).

```ts
import { Mppx, tempo } from 'mppx/server'

const mppx = Mppx.create({
  methods: [tempo({
    currency: '0x20c0000000000000000000006a37da5c996874be',
    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.

:::code-group
```ts [Next.js]
import { Mppx, tempo } from 'mppx/nextjs'

const mppx = Mppx.create({
  methods: [tempo({
    currency: '0x20c0000000000000000000006a37da5c996874be',
    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 })
  })
```

```ts [Hono]
import { Hono } from 'hono'
import { Mppx, tempo } from 'mppx/hono'

const app = new Hono()

const mppx = Mppx.create({
  methods: [tempo({
    currency: '0x20c0000000000000000000006a37da5c996874be',
    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 })
  },
)
```

```ts [Express]
import express from 'express'
import { Mppx, tempo } from 'mppx/express'

const app = express()

const mppx = Mppx.create({
  methods: [tempo({
    currency: '0x20c0000000000000000000006a37da5c996874be',
    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 })
  },
)
```

```ts [Fetch API]
import { Mppx, tempo } from 'mppx/server'

const mppx = Mppx.create({
  methods: [tempo({
    currency: '0x20c0000000000000000000006a37da5c996874be',
    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 }))
  },
})
```
:::

### Test the one-time payment endpoint

These examples charge mainnet OUSD. Configure the `mppx` CLI with a funded mainnet account before calling the endpoint; testnet faucet tokens cannot pay a mainnet challenge. To use test funds, [configure the server and client for Moderato](https://tempo.xyz/developers/docs/guide/machine-payments/server#test-your-mpp-server).

```bash
npx mppx http://localhost:3000/api/photo
```
::::

## Next steps for one-time payments

* [Accept pay-as-you-go payments](https://tempo.xyz/developers/docs/guide/machine-payments/pay-as-you-go) — Session-based billing with payment channels
* [Accept payments for an API](https://tempo.xyz/developers/docs/guide/machine-payments/server) — Framework middleware reference
* [Full charge reference](https://mpp.dev/payment-methods/tempo/charge) — Complete tempo.charge API documentation
