# Enable agents to accept payments based on usage # Agent quickstart (Developer preview) Learn how to build a basic chatbot and bill for usage with the Stripe Agent Toolkit. > Explore this SDK to integrate Stripe into agentic workflows. Because agent behavior is non-deterministic, use the SDK in a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes) and run evaluations to assess your application’s performance. > > For security, we strongly recommend using [restricted API keys](https://docs.stripe.com/keys.md#create-restricted-api-secret-key) (`rk_*`) to limit your agent’s access to only the functionality it requires, especially in live mode. Tool availability is determined by the permissions you configure on the restricted key. ### Install the Stripe Agent Toolkit Install the package and import it into your code. #### npm Install the library: ```bash npm install --save @stripe/agent-toolkit ``` #### GitHub Or download the `@stripe/agent-toolkit` library source code directly [from GitHub](https://github.com/stripe/agent-toolkit). ### Create an endpoint to handle the request Add an endpoint on your server that handles the new chat input. ### Initialize the toolkit Using your Stripe API key, create a new instance of the `StripeAgentToolkit`. The toolkit allows you to insert billing middleware and also access Stripe functionality. ### Provide the middleware to the model Using middleware, you can report the prompt and completion token usage to Stripe through the Meter API. The `billing` configuration requires you to provide a [Customer](https://docs.stripe.com/api/customers/object.md) ID and input and output [Meter Events](https://docs.stripe.com/api/billing/meter-event/object.md). Learn how to [setup usage-based billing](https://docs.stripe.com/billing/subscriptions/usage-based/implementation-guide.md). ### Call the model Use Vercel’s AI SDK to call the model and stream back results to the client. Your request includes the existing message log and a system prompt to provide initial instructions to the model. ### Create a chat interface Use Next.js and Vercel’s AI SDK to build a basic chat interface to call into the backend you built. ### Set your environment variables Add your publishable and secret keys to a `.env` file. Next.js automatically loads them into your application as [environment variables](https://nextjs.org/docs/basic-features/environment-variables). ### Run the application Start your app with `npm run dev` and go to . ### Testing To test this functionality, send a message to the chat. ### View usage in the Dashboard View your Meters in the [Stripe Dashboard](https://dashboard.stripe.com/meters) to confirm that events are sent successfully. import { createStripeAgentToolkit } from '@stripe/agent-toolkit/ai-sdk'; // Initialize toolkit - use restricted key (rk_*) for better security. const toolkit = await createStripeAgentToolkit({ secretKey: process.env.STRIPE_SECRET_KEY!, configuration: {}, }); export async function POST(req: Request) { middleware: toolkit.middleware({ billing: { customer: process.env.STRIPE_CUSTOMER_ID!, meters: { input: process.env.STRIPE_METER_INPUT!, output: process.env.STRIPE_METER_OUTPUT!, }, }, }), }); // Call the model and stream back the results. const result = await streamText({ model: model, system: SYSTEM_PROMPT, messages: convertToCoreMessages(messages), }); import { createStripeAgentToolkit } from '@stripe/agent-toolkit/ai-sdk'; // Initialize toolkit - use restricted key (rk_*) for better security. const toolkit = await createStripeAgentToolkit({ secretKey: process.env.STRIPE_SECRET_KEY!, configuration: {}, }); export async function POST(req: Request) { middleware: toolkit.middleware({ billing: { customer: process.env.STRIPE_CUSTOMER_ID!, meters: { input: process.env.STRIPE_METER_INPUT!, output: process.env.STRIPE_METER_OUTPUT!, }, }, }), }); // Call the model and stream back the results. const result = await streamText({ model: model, system: SYSTEM_PROMPT, messages: convertToCoreMessages(messages), }); import { createStripeAgentToolkit } from '@stripe/agent-toolkit/ai-sdk'; // Initialize toolkit - use restricted key (rk_*) for better security. const toolkit = await createStripeAgentToolkit({ secretKey: process.env.STRIPE_SECRET_KEY!, configuration: {}, }); export async function POST(req: Request) { middleware: toolkit.middleware({ billing: { customer: process.env.STRIPE_CUSTOMER_ID!, meters: { input: process.env.STRIPE_METER_INPUT!, output: process.env.STRIPE_METER_OUTPUT!, }, }, }), }); // Call the model and stream back the results. const result = await streamText({ model: model, system: SYSTEM_PROMPT, messages: convertToCoreMessages(messages), }); import { createStripeAgentToolkit } from '@stripe/agent-toolkit/ai-sdk'; // Initialize toolkit - use restricted key (rk_*) for better security. const toolkit = await createStripeAgentToolkit({ secretKey: process.env.STRIPE_SECRET_KEY!, configuration: {}, }); export async function POST(req: Request) { middleware: toolkit.middleware({ billing: { customer: process.env.STRIPE_CUSTOMER_ID!, meters: { input: process.env.STRIPE_METER_INPUT!, output: process.env.STRIPE_METER_OUTPUT!, }, }, }), }); // Call the model and stream back the results. const result = await streamText({ model: model, system: SYSTEM_PROMPT, messages: convertToCoreMessages(messages), }); 'use client'; import { useChat } from 'ai/react'; export default function Chat() { const { input, isLoading, handleInputChange, handleSubmit, messages, } = useChat(); return (
{messages.map(m => (
{m.role === 'user' ? 'User: ' : 'Agent: '} {m.content}
))} {isLoading && (
Loading...
)}
); } \# https://dashboard.stripe.com/apikeys STRIPE_SECRET_KEY=<>