Skip to main content
Cookbooks

Pix Payment Agent

The simplest agent you can build with CodeSpar. Create a Pix charge, generate a QR code, and send it to the customer via WhatsApp — in ~50 lines of code.

1 min read
View MarkdownEdit on GitHub
TIME
~10 min
PROVIDER
OpenAIgpt-4o
SERVERS
asaasz-api

Create a Pix charge, generate the QR code, and send it to the customer via WhatsApp. The simplest agent you can build with CodeSpar — two steps, one conversation.

THE FLOW
Two steps, one conversation
1
Create Pix charge
codespar_charge
Routed to Asaas — QR code + copy-paste key
2
Send via WhatsApp
codespar_notify
Routed to Z-API — entrega instantânea no WhatsApp brasileiro
WHAT YOUR CUSTOMER GETS
R$ 150,00 · Pro Plan

codespar_charge vs codespar_paycharge is inbound (buyer pays merchant: Pix QR / boleto / card). pay is outbound (merchant pays out: payouts, refunds, supplier transfers). This cookbook is the inbound flavor. After the buyer settles, correlate via session.paymentStatus(toolCallId) (poll) or session.paymentStatusStream (SSE — see /docs/api/reference/sessions#streaming-status).

Conversation preview

What the agent does when you call pixAgent("+5511...", 15000, "Pro Plan").

agent · payment assistant
sb_pix_a3
Create a Pix payment of R$150 for Pro Plan - Monthly and send to +5511999887766.
Vou gerar o Pix de R$ 150,00 e enviar o QR code no WhatsApp.
Pronto. Pix criado (pay_abc123) e QR code enviado para o WhatsApp do cliente. Pagamento aguardando.
codespar_chargeasaas✓ done620ms
codespar_notifyz-api✓ done340ms
2 tool calls · 960ms total · 2 LLM iterationsRun this cookbook in Sandbox →

Prerequisites

Install the SDK and the OpenAI provider adapter:

npm install @codespar/sdk

Set your environment variables:

.env
CODESPAR_API_KEY=csk_test_...

You'll need active accounts on Asaas and Z-API. CodeSpar will prompt you to authenticate both on first run.

The charge, without a model in the path

A Pix charge is a deterministic call. Nothing here needs a language model, and production code should not put one between a customer and a payment. This is the whole thing, and it returns the copy-and-paste string directly:

pix-charge.ts
import { CodeSpar } from "@codespar/sdk";

const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

export async function cobrarPix(amountMajor: number, description: string, buyerName: string) {
  const session = await cs.create("user_123", { servers: ["asaas"] });
  try {
    const charge = await session.charge({
      amount: amountMajor,          // MAJOR units: R$ 150,00 is 150
      currency: "BRL",
      method: "pix",
      description,
      buyer: { name: buyerName },
    });
    return charge.pix_copy_paste;   // the string the payer pastes into their bank
  } finally {
    await session.close();
  }
}

charge.id is what you correlate settlement against later, with session.paymentStatus or by subscribing to commerce.charge.paid. Over plain HTTP the same call is POST /v1/charges.

The same thing inside a conversation

When the charge is one step of something a customer is talking their way through, session.send() runs the tool loop for you. The model picks the tools; the mandate still bounds what it may do.

pix-agent.ts
import { CodeSpar } from "@codespar/sdk";

const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

export async function pixAgent(phone: string, amountMinor: number, description: string) {
  const session = await cs.create("user_123", { servers: ["asaas", "z-api"] });
  try {
    const result = await session.send(
      `Create a Pix of R$${(amountMinor / 100).toFixed(2)} for "${description}", ` +
        `and send the QR code to ${phone} over WhatsApp.`,
    );
    return result.message;
  } finally {
    await session.close();
  }
}

That is the same shape as the Python version below, and it is complete: there is no loop for you to fill in, because the loop runs server-side.

Variations

Add boleto fallback

Pass payment_methods: ["pix", "boleto"] to codespar_charge and let the customer pick at checkout.

Chain an invoice

After payment confirmation, chain codespar_invoice to issue an NF-e automatically.

Swap to Claude

Replace @codespar/openai with @codespar/claude. The agent logic is identical.

Python version

For FastAPI services or async jobs, the same flow in Python — no framework-adapter needed, session.send() runs the agent loop on the backend:

pix_agent.py
from codespar import CodeSpar

cs = CodeSpar()  # reads CODESPAR_API_KEY

def pix_agent(phone: str, amount: int, description: str) -> str:
    with cs.create("user_123", servers=["asaas", "z-api"]) as session:
        result = session.send(
            f'Create a Pix of R${amount / 100:.2f} for "{description}", '
            f"send the QR code to {phone} via WhatsApp."
        )
    return result.message

Swap CodeSpar for AsyncCodeSpar and with for async with to run inside FastAPI. See Quickstart (Python).

Next steps

Pix Payment Agent | CodeSpar