Skip to main content
Cookbooks

E-Commerce Checkout

Build an AI-powered checkout flow that handles product discovery, payment, invoicing, and shipping — in a single conversation.

View MarkdownEdit on GitHub
TIME
~15 min
PROVIDER
Claudeopus-4-6
SERVERS
stripenuvem-fiscalcorreios

Build an end-to-end commerce agent that handles the full checkout flow: discover products, create a checkout link, process payment, issue an invoice (NF-e), and create a shipping label — all driven by a single conversation with your user.

The Complete Loop

COMPLETE LOOPWhat this agent does
5 steps · one conversation
1
Discover
codespar_discover
Find payment methods & shipping options
2
Checkout
codespar_checkout
Create payment link (Pix + card)
3
Invoice
codespar_invoice
Issue NF-e through Nuvem Fiscal
4
Ship
codespar_ship
Quote Correios & create label
5
Notify
codespar_notify
Send WhatsApp with tracking + NF-e

Conversation preview

This is how a real session looks when the agent runs.

agent · TechBR checkout assistant
session sb_9f7c2a
Quero comprar o Starter Kit. Meu CEP é 01310-100.
O Starter Kit custa R$ 149,00. Vou gerar o checkout com Pix + cartão, emitir a NF-e e calcular o frete. Confirma?
Confirmo.
Tudo pronto. Link de pagamento enviado, NF-4421 emitida, envio SEDEX R$ 18,50 (chega em 2 dias). Vou mandar tudo no seu WhatsApp.
codespar_checkoutstripe✓ done1.1s
codespar_invoicenuvem-fiscal✓ done1.8s
codespar_shipcorreios✓ done2.1s
6 tool calls · 5.4s total · 2 LLM iterationsRun this cookbook in Sandbox →

Prerequisites

Install the SDK and the Claude provider adapter:

npm install @codespar/sdk @codespar/claude @anthropic-ai/sdk

Set your environment variables:

.env
CODESPAR_API_KEY=csk_live_...
ANTHROPIC_API_KEY=sk-ant-...

You'll also need accounts on Stripe, Nuvem Fiscal and Correios — CodeSpar will prompt you to authenticate each one on first use.

Steps in action

Each step maps to one meta-tool. The agent calls them sequentially, feeding outputs from one into the next.

The agent knows the product catalog from the system prompt. In production, it would call codespar_discover to find available payment methods and shipping carriers for the customer's region (e.g., Pix + boleto for Brazil; card + OXXO for Mexico).

await session.execute("codespar_discover", {
  region: "BR",
  categories: ["payments", "shipping"]
});

Full agent code

Drop-in file. This is the same code the Sandbox runs when you pick this cookbook.

checkout-agent.ts
import Anthropic from "@anthropic-ai/sdk";
import { CodeSpar } from "@codespar/sdk";
import { getTools, handleToolUse, toToolResultBlock } from "@codespar/claude";

const claude = new Anthropic();
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

async function checkoutAgent(userMessage: string) {
  const session = await codespar.sessions.create({
    servers: ["stripe", "nuvem-fiscal", "correios"],
  });

  try {
    const tools = await getTools(session);

    const messages: Anthropic.MessageParam[] = [
      { role: "user", content: userMessage },
    ];

    let response = await claude.messages.create({
      model: "claude-opus-4-6",
      max_tokens: 4096,
      system: `You are a commerce assistant for TechBR. Products:
- Pro Plan: R$49.90/month
- Enterprise Plan: R$199.90/month
- Starter Kit: R$149.00 (one-time)

Flow: confirm → checkout → invoice → ship → notify. Respond in Portuguese.`,
      tools,
      messages,
    });

    let iterations = 0;
    while (response.stop_reason === "tool_use" && iterations < 10) {
      const toolBlocks = response.content.filter(
        (b): b is Anthropic.ToolUseBlock => b.type === "tool_use",
      );

      const resultBlocks = [];
      for (const block of toolBlocks) {
        const result = await handleToolUse(session, block);
        resultBlocks.push(toToolResultBlock(block.id, result));
      }

      messages.push({ role: "assistant", content: response.content });
      messages.push({ role: "user", content: resultBlocks });

      response = await claude.messages.create({
        model: "claude-opus-4-6",
        max_tokens: 4096,
        tools,
        messages,
      });
      iterations++;
    }

    const textBlock = response.content.find(
      (b): b is Anthropic.TextBlock => b.type === "text",
    );
    return textBlock?.text ?? "";
  } finally {
    await session.close();
  }
}

Deterministic mode: session.loop()

When you don't need the LLM to make decisions mid-flow — for example, a programmatic post-purchase workflow — use session.loop() to declare steps imperatively. It's faster, cheaper, and easier to debug.

checkout-loop.ts
const result = await session.loop({
  steps: [
    { tool: "codespar_checkout", params: { provider: "stripe", amount: 14900, currency: "BRL" } },
    { tool: "codespar_invoice", params: (prev) => ({
      payment_id: prev[0].data.checkout_id,
      type: "nfe",
    }) },
    { tool: "codespar_ship", params: (prev) => ({
      from_cep: "04538-132",
      to_cep: "01310-100",
      weight_kg: 0.5,
    }) },
  ],
  abortOnError: true,
});

console.log(`Completed ${result.completedSteps}/${result.totalSteps} steps`);

When to use agent loop vs deterministic. Agent loop handles conversations with user input and branching logic. Deterministic loop is for server-side jobs where the sequence is known — post-webhook fulfillment, scheduled reconciliation, retry pipelines.

Variations

Add boleto fallback

Pass payment_methods: ["pix", "boleto", "card"] to codespar_checkout to let the customer pick.

Swap LLM provider

Replace @codespar/claude with @codespar/openai or @codespar/vercel. The agent logic is identical — only the adapter changes.

Multi-tenant setup

Pass a user_id to sessions.create() to isolate credentials and sessions per end-customer. See Multi-Tenant Agent.

Next steps