---
title: Multi-Provider Agent
description: Route payments across Stripe, Asaas, and Mercado Pago automatically. The agent calls codespar_pay — CodeSpar picks the best provider for each transaction.
---

<ActionBar githubPath="content/docs/cookbooks/multi-provider.mdx" markdownPath="/api/docs-md/cookbooks/multi-provider" />

<MetaStrip items={[
  { label: "TIME", value: "~10 min" },
  { label: "PROVIDER", value: (<><ServerChip name="Vercel AI" accent /><span style={{ color: "var(--color-fd-muted-foreground)", fontSize: 12 }}>gpt-4o</span></>) },
  { label: "SERVERS", value: (<><ServerChip name="stripe" /><ServerChip name="asaas" /><ServerChip name="mercadopago" /></>) },
]} />

Route payments across Stripe, Asaas, and Mercado Pago automatically. The agent calls `codespar_charge` (inbound) or `codespar_pay` (outbound) — CodeSpar picks the best provider for each transaction.

<Callout>
The meta-tools **are** the failover layer. The router scores connected providers per-call (cost, settlement speed, region) and dispatches to the top-ranked one. `codespar_charge` is for inbound (buyer pays merchant) — Pix QR / boleto / card. `codespar_pay` is for outbound (merchant pays out) — payouts, refunds, supplier transfers. This cookbook shows the inbound path; swap `codespar_charge` → `codespar_pay` for the outbound flavor.
</Callout>

<RoutingDiagram
  tool="codespar_charge"
  inputs={[
    { label: "method", value: "pix" },
    { label: "method", value: "credit_card" },
    { label: "method", value: "boleto" },
  ]}
  providers={[
    { name: "Asaas", tag: "pix", color: "#0F4C3A" },
    { name: "Stripe", tag: "card", color: "#635BFF" },
    { name: "Mercado Pago", tag: "boleto", color: "#00B1EA" },
  ]}
  note="agent calls codespar_charge({ method: 'pix' }) — CodeSpar routes to Asaas based on lowest Pix fees"
/>

## Prerequisites

```bash
npm install @codespar/sdk @codespar/vercel ai @ai-sdk/openai
```

<Callout>
You need active accounts on **Stripe**, **Asaas**, and **Mercado Pago**. CodeSpar prompts for authentication on first use.
</Callout>

## How routing works

When the agent calls `codespar_charge`, CodeSpar inspects the arguments and picks the optimal provider for the region and method:

| PAYMENT METHOD | PROVIDER | WHY |
| --- | --- | --- |
| `pix` | Asaas | Lowest Pix fees, instant settlement |
| `credit_card` | Stripe | Best international card support |
| `boleto` | Mercado Pago | Best boleto infrastructure |
| `debit_card` | Stripe | Card processing via Stripe |

Override automatic routing by passing `provider: "stripe"` explicitly:

```typescript
await session.execute("codespar_charge", {
  method: "pix",
  provider: "mercadopago", // force Mercado Pago instead of default Asaas
  amount: 35000,
});
```

## Full agent code

```typescript title="multi-provider.ts"
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/vercel";

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

async function multiProviderAgent(userMessage: string) {
  const session = await codespar.create("user_123", {
    servers: ["stripe", "asaas", "mercadopago"],
  });

  try {
    const tools = await getTools(session);

    const result = await generateText({
      model: openai("gpt-4o"),
      tools,
      maxSteps: 10,
      system: `Ask customer which payment method they prefer (Pix, card, boleto).
Use codespar_charge — CodeSpar routes to the right provider automatically.`,
      prompt: userMessage,
    });

    return result.text;
  } finally {
    await session.close();
  }
}
```

## When routing happens

Provider selection happens once, at call time. The payment router ranks connected providers for the method + region by total cost (fees + FX spread) and settlement speed, then picks the top-ranked one. There is **no automatic runtime failover** — if that provider returns an error, the error surfaces to your agent and you (or the LLM) decide whether to retry with an explicit `provider`:

```typescript
// First attempt — router picks the cheapest provider for Pix
let result = await session.execute("codespar_charge", {
  method: "pix",
  amount: 35000,
  currency: "BRL",
});

if (!result.success && result.error === "provider_unavailable") {
  // Explicit retry on a different provider
  result = await session.execute("codespar_charge", {
    method: "pix",
    amount: 35000,
    currency: "BRL",
    provider: "mercadopago",
  });
}
```

## Checking available providers

Use `codespar_discover` (or its typed wrapper `session.discover`) to search the catalog for tools that match an intent — biased toward providers your session has already connected:

```typescript
const discovery = await session.discover("emit a Pix charge in BRL");

// Returns: { matches: [{ tool_name, server_id, score }, ...] }
for (const m of discovery.matches) {
  console.log(m.tool_name, m.server_id, m.score);
}
```

## Next steps

<NextStepsGrid items={[
  { label: "COOKBOOK", title: "Pix Payment Agent", description: "A focused Pix-only agent, if you only need one provider.", href: "/docs/cookbooks/pix-payment-agent" },
  { label: "COOKBOOK", title: "E-Commerce Checkout", description: "Full checkout flow with invoicing and shipping.", href: "/docs/cookbooks/ecommerce-checkout" },
  { label: "PROVIDER", title: "Vercel AI SDK", description: "Framework reference for @codespar/vercel.", href: "/docs/providers/vercel" },
  { label: "CONCEPT", title: "Tools & Meta-Tools", description: "How routing and meta-tools actually work.", href: "/docs/concepts/tools" },
]} />
