---
title: codespar_pay
description: Outbound spend. Money leaves the wallet or account your agent governs. 26 provider rails across BR (incl. 9 banks direct via mTLS), MX, PE, CL, CO, and international card/wire.
---

import { Callout } from "fumadocs-ui/components/callout";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";

# codespar_pay

<Callout title="Meta-tool" type="info">
**Buy-side.** Your agent is the spender: money leaves the wallet/account your agent governs, under a signed mandate.

`codespar_pay` is the spend primitive. Use it whenever money leaves the wallet or account the agent governs and lands with a payee (a Pix key, a bank account, a card recipient): paying suppliers, marketplace payouts, refunds, and consumer spend under mandate. The agent specifies the recipient and the amount; CodeSpar picks the rail.
</Callout>

Collecting FROM a buyer instead? That is [`codespar_charge`](/docs/concepts/meta-tools/charge) (sell-side).

Every call must pass `action`: `pay` executes a payment or transfer under governance (policy, mandate, routing); `status` reads a charge or boleto issued through the platform's charge rail by its `payment_id` (it does not read a Pix cash-out or a boleto settlement; those report inline and confirm via webhook). Settlement is rail-dependent: some rails return a terminal result inline, others accept the payment and settle asynchronously. A Pix cash-out returns `settled` plus a `status_message`; `PROCESSING` means accepted and settling within seconds, with the wallet already debited. A boleto settlement with `settled: false` means not yet confirmed (neither paid nor failed); the confirmation arrives through the payment webhook. Read the result you get back; do not treat accepted-and-settling as failure.

## Rails

| Rail | Currency | Country | Providers |
|---|---|---|---|
| Pix | BRL | BR | **Asaas** (default), Mercado Pago, a licensed Brazilian BaaS provider — plus **9 banks direct via mTLS**: Banco do Brasil, Itaú, Bradesco, Santander, Caixa, Sicoob, Sicredi, C6, Original |
| Card | BRL | BR | Cielo (+ 3DS), Pagar.me |
| Boleto (settle an existing boleto by its linha digitável) | BRL | BR | Licensed Brazilian BaaS partner |
| Card | MXN | MX | Conekta |
| Card | PEN | PE | Culqi |
| Card | CLP | CL | Transbank |
| Card | COP | CO | Wompi |
| Bank transfer | COP | CO | Cobre |
| Wire | CLP | CL | Khipu |
| Card · hosted checkout | USD / EUR | US / INTL | Stripe ACP, Adyen, Airwallex, dLocal, Rapyd |

26 provider rails across six countries. The router fails over **within a rail** when the primary provider degrades — e.g. Pix BRL walks Asaas → Mercado Pago → a direct bank. See `/dashboard/router` for live failover telemetry. The 9 Brazilian banks connect over mTLS (client certificate) for direct-from-account Pix; see [cert auth](/docs/concepts/authentication#provider-auth-schemes).

## Direct execute

There is no typed wrapper for `codespar_pay` yet — call via `session.execute()`.

<Tabs items={["TypeScript", "Python"]}>

```ts tab="TypeScript"
const result = await session.execute("codespar_pay", {
  action: "pay",
  amount: 25000,
  currency: "BRL",
  method: "pix",
  recipient: "vendor@example.com", // a Pix key: email, phone, CPF/CNPJ or EVP
  description: "Invoice 1042, vendor payout",
});
console.log(result.tool_call_id, result.data); // executor output lives under data
```

```python tab="Python"
result = session.execute("codespar_pay", {
    "action": "pay",
    "amount": 25000,
    "currency": "BRL",
    "method": "pix",
    "recipient": "vendor@example.com",  # a Pix key: email, phone, CPF/CNPJ or EVP
    "description": "Invoice 1042, vendor payout",
})
print(result["tool_call_id"], result["data"])  # executor output lives under data
```

</Tabs>

## Args shape

This mirrors the published schema in `@codespar/types` (`SHARED_META_TOOL_DEFINITIONS.codespar_pay`).

| Field | Type | Required | Description |
|---|---|---|---|
| `action` | `string` | Yes | `pay` (execute a payment or transfer) or `status` (read an existing payment, charge or boleto by id). Pass it on every call. |
| `amount` | `number` | For `pay` | Amount in minor units (centavos for BRL). When paying a QR / copia-e-cola it must match the code's amount. |
| `currency` | `string` | For `pay` | Currency code: `BRL`, `USD`, `EUR` |
| `description` | `string` | For `pay` | Payment description |
| `method` | `string` | No | `pix`, `card`, `usdc`, `boleto`, `sepa`, `wire`. `boleto` settles an existing boleto (pass `linha_digitavel`); it does not issue new boleto charges. |
| `country` | `string` | No | ISO 3166-1 alpha-2 for the eligibility rail |
| `recipient` | `string` | One of | Recipient identifier: a Pix key (email, phone, CPF/CNPJ, EVP). Do not put a copia-e-cola here. |
| `copia_e_cola` | `string` | One of | A Pix copia-e-cola / BR Code to pay. Preferred for a store order over retyping the code. |
| `checkout_session_id` | `string` | No | A `codespar_shop` checkout to settle: the backend resolves the store's Pix code server-side and records the order as paid. Pass it with `consumer_id` and without `copia_e_cola` (a code passed by the caller is used verbatim and skips the checkout lookup). |
| `linha_digitavel` | `string` | With `method: "boleto"` | The 47/48-digit linha digitável (or barcode) of an existing boleto |
| `consumer_id` | `string` | No | Whose governed wallet pays. Defaults to the session user. |
| `mandateId` | `string` | No | Pre-authorized mandate id |
| `payment_id` | `string` | For `status` | The payment / charge / boleto id to read |

A caller-supplied `idempotency_key` is not part of the published schema. The backend keeps its own correlation key on the tool-call record; it is not returned in the call result.

## Result shape

`session.execute` returns the standard tool envelope; the executor output is under `data`.

```ts
type ToolResult = {
  success: boolean;
  data: {
    // action: "pay"
    id: string;                // provider payment id
    status: string;            // status as reported by the rail (e.g. CONFIRMED, PROCESSING)
    settled?: boolean;         // async rails: true once the provider confirmed
    status_message?: string;   // human-readable state to relay to the user
    amount?: number;
    currency?: string;
    method?: string;
    // rail-specific extras, e.g. end_to_end_id (Pix), linha_digitavel / beneficiary / due_date (boleto)
    // action: "status" returns { id, status, billing_type, value, due_date }
  };
  error: string | null;
  tool_call_id?: string;
  server: string;              // provider that executed the call
};
```

How to read `settled` and `status`:

- Pix cash-out: `PROCESSING` with `settled: false` means the rail accepted the payment and is settling (seconds); the wallet is already debited. A terminal failure is returned as an error, not as a status.
- Boleto: `settled: false` means not yet confirmed. Do not treat it as paid or as failed; the confirmation arrives through the payment webhook (or the account statement).
- `action: "status"` reads a charge or boleto issued through the platform's charge rail by `payment_id` and returns the provider status verbatim (e.g. `OVERDUE`). It does not read Pix cash-outs or boleto settlements made with `action: "pay"`.

## Operator setup

Each rail needs operator-stamped credentials in `/dashboard/auth-configs`:

- **Asaas** — API key (`api_key` auth_type). Sandbox key for test, production key for live.
- **Mercado Pago** — Access token (`api_key` auth_type). Tied to a single seller account.
- **Wompi / Conekta / Khipu / Transbank** — Per-provider API key + sandbox toggle.

The dashboard wizard renders the right inputs based on each server's `auth_type` declared in the catalog.

## Async settlement

After `codespar_pay` returns, settlement happens via the provider webhook. The flow:

```
session.execute("codespar_pay", { action: "pay", ... }) → { tool_call_id, data: { status, settled?, status_message? } }
  ↓
provider settles asynchronously (seconds for Pix, hours-to-days for SPEI/wallet)
  ↓
provider POSTs webhook → backend correlates external_reference ↔ idempotency_key
  ↓
session.paymentStatus(tool_call_id) → { status: "succeeded", final_amount_minor, settled_at }
```

See [async settlement](/docs/api/sessions#async-settlement) for the full correlation chain and per-provider idempotency-key shapes (Asaas `externalReference`, Mercado Pago `X-Idempotency-Key` header, etc.). Streaming variant: [SSE streaming](/docs/api/sessions#streaming-status).

## See also

- [codespar_charge](/docs/concepts/meta-tools/charge) — inbound counterpart
- [Async settlement](/docs/api/sessions#async-settlement) — correlation chain + webhook flow
- [SDK reference](/docs/api/sdk#paymentstatustoolcallid-promisepaymentstatusresult) — `paymentStatus` / `paymentStatusStream`
- [Tools & meta-tools](/docs/concepts/tools) — full meta-tool list
- [Pix Payment Agent cookbook](/docs/cookbooks/pix-payment-agent) — simplest end-to-end example
- [Marketplace Payout cookbook](/docs/cookbooks/marketplace-payout) — split fee + seller payout
