Shopping and checkout agents in Next.js typically combine the App Router, the Vercel AI SDK, and server-side secrets. Paybond belongs on the server — bind middleware per request, never expose capability tokens to the browser.
Server-only Paybond
Run Paybond.open() and instrument() in Route Handlers or Server Actions. Pass guarded tools to generateText / streamText on the server. Client components receive streamed text — not raw capability tokens.
Try it
terminal
paybond login
paybond agent demo vercel-ai smoke \
--operation commerce.checkout \
--requested-spend-cents 1000 \
--evidence-preset cost_and_completion \
--format tableScaffold the shopping preset:
terminal
paybond init --solution shopping --max-spend-usd 100 --framework vercel-ai --non-interactive
paybond policy init --preset shopping --out paybond.policy.yamlLazy context pattern (recommended)
Load policy once at module scope; resolve the active bind per request:
// lib/paybond.ts
import { Paybond } from "@paybond/kit";
import { AsyncLocalStorage } from "node:async_hooks";
const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });
const requestStore = new AsyncLocalStorage<{ runtime: Awaited<ReturnType<typeof instrumented.bind>> }>();
const instrumented = await paybond.instrument({
policy: "./paybond.policy.yaml",
framework: "vercel-ai",
tools: {
checkout: checkoutToolDef,
searchProducts: searchProductsToolDef,
},
context: () => requestStore.getStore()!.runtime,
});
export { paybond, instrumented, requestStore };
Route handler
// app/api/agent/route.ts
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { instrumented, requestStore } from "@/lib/paybond";
export async function POST(req: Request) {
const { prompt, intentId, capabilityToken } = await req.json();
const runtime = await instrumented.bind({ intentId, capabilityToken });
const { agentTools: tools, toolApproval } = runtime;
return requestStore.run({ runtime }, async () => {
const result = streamText({
model: openai("gpt-4.1"),
tools,
toolApproval,
prompt,
});
return result.toDataStreamResponse();
});
}
Sandbox rehearsal: use paybond.agent({ policy: "shopping", framework: "vercel-ai", tools }) to skip manual bind during local dev.
Shopping preset defaults
| Tool | Side effecting | Cap |
|---|---|---|
commerce.checkout | Yes | $100 per call / $100 intent budget |
search.products | No | — |
See Let agents buy groceries for the full multi-tool shopping walkthrough.
Production checklist
- Create and fund intents server-side — Fund intents by rail.
- Pass
intentId+capabilityTokenfrom your session layer — not from unauthenticated client identifiers alone. - Validate policy in CI:
paybond policy validate-tools --file paybond.policy.yaml --local-only.
Related guides
- Vercel AI SDK spend controls — toolApproval primitives
- Let agents buy groceries — shopping preset
- Express and Fastify agent routes — non-Next.js HTTP servers
Developer reference: /docs/kit/vercel-ai.