Skip to main content

Multi-Provider Agent

Route payments across Stripe, Asaas, and Mercado Pago automatically. The agent calls codespar_pay — CodeSpar picks the best provider for each transaction.

1 min read · updated
View MarkdownEdit on GitHub
TIME
~10 min
PROVIDER
Vercel AIgpt-4o
SERVERS
stripeasaasmercadopago

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.

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_chargecodespar_pay for the outbound flavor.

↻ ROUTING
One meta-tool, multiple providers
method:pix
method:credit_card
method:boleto
codespar_charge
meta-tool
Asaaspix
Stripecard
Mercado Pagoboleto
agent calls codespar_charge({ method: 'pix' }) — CodeSpar routes to Asaas based on lowest Pix fees

Prerequisites

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

You need active accounts on Stripe, Asaas, and Mercado Pago. CodeSpar prompts for authentication on first use.

How routing works

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

PAYMENT METHODPROVIDERWHY
pixAsaasLowest Pix fees, instant settlement
credit_cardStripeBest international card support
boletoMercado PagoBest boleto infrastructure
debit_cardStripeCard processing via Stripe

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

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

Full agent code

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:

// 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:

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

Edit on GitHub

Last updated on