Skip to main content
ConceptsMeta-tools

codespar_charge

Inbound charges — buyer pays merchant. 19 provider rails — Pix/boleto/card/wallet across BR, MX, PE, CO, CL, AR + USD. Async settlement, uniform payload.

3 min read

codespar_charge

Meta-tool

codespar_charge is the inbound counterpart to codespar_pay. Use it for ecommerce checkout, marketplace order capture, and any flow where money comes IN. Covered by session.charge(args) typed wrapper.

Charge is async. The call returns immediately with the payment artifact (Pix copy-paste, Stripe Checkout URL, etc.) plus a tool_call_id. Wait for settlement via paymentStatus(toolCallId) or paymentStatusStream(toolCallId). The common downstream pattern is: charge → wait for settlement → invoice + ship + notify.

Rails

RailCurrencyCountryProviders
PixBRLBRAsaas (default), Mercado Pago, EBANX, iugu, Stone
CardBRLBRGetnet, PagSeguro, Rede
Card · hosted checkoutUSDUSStripe ACP
CardUSDINTLCircle
CardMXNMXClip, Kushki
CardPENPEIzipay, Niubiz, Kushki
CardCOPCOBold, ePayco, Kushki
PSECOPCOBold
CardCLPCLKushki
CardARSARPayway
CardUSDECKushki
WalletBRLBRPicPay
WalletCOPCONequi

19 provider rails. Asaas Pix returns pix_copy_paste synchronously; iugu (create_invoice) and Stone (create_pix_charge) are the two newest BR Pix charge rails; Stripe ACP and the LATAM card rails return a hosted checkout URL the agent surfaces to the buyer. The router fails over within a rail (e.g. Pix BRL: Asaas → Mercado Pago).

Typed wrapper (TS / Python)

const charge = await session.charge({
  amount: 9990,
  currency: "BRL",
  method: "pix",
  description: "Order #1234",
  buyer: {
    name: "Maria Silva",
    document: "12345678900",
    phone: "+5511999998888",
  },
  metadata: { order_id: "1234" },
});

console.log(charge.id, charge.pix_copy_paste, charge.tool_call_id);
charge = session.charge({
    "amount": 9990,
    "currency": "BRL",
    "method": "pix",
    "description": "Order #1234",
    "buyer": {
        "name": "Maria Silva",
        "document": "12345678900",
        "phone": "+5511999998888",
    },
    "metadata": {"order_id": "1234"},
})

print(charge["id"], charge["pix_copy_paste"], charge["tool_call_id"])

Direct execute

const charge = await session.execute("codespar_charge", {
  amount: 9990,
  currency: "BRL",
  method: "pix",
  description: "Order #1234",
  buyer: { name: "Maria Silva", document: "12345678900", phone: "+5511999998888" },
});

Args shape

FieldTypeRequiredDescription
amountnumberYesAmount in smallest currency unit
currencystringYesBRL for Pix; USD for card
methodstringYespix or card
descriptionstringYesShown to the buyer on the invoice / checkout page
buyerobjectYes{ name, document, phone, email? }
metadataobjectNoArbitrary key-value pairs persisted on the tool_calls row

Result shape

Uniform across providers — the backend normalizes the per-PSP response into a single envelope:

type ChargeResult = {
  id: string;                      // provider's payment id
  tool_call_id: string;            // CodeSpar correlation id
  pix_copy_paste?: string;         // Pix BRL only
  qr_code_url?: string;            // Pix BRL only
  checkout_url?: string;           // Stripe Checkout / Stripe ACP rails
  status: "pending";               // always pending; terminal state via paymentStatus
  expires_at?: string;             // ISO 8601
};

Operator setup

Each rail expects credentials in /dashboard/auth-configs:

  • Asaas / Mercado Pago / iugu / Stone — API key (api_key auth_type). Sandbox vs production toggle in the modal.
  • Stripe — Restricted key with payment_intents:write scope. The same key handles both regular charges and ACP create_checkout_session.

Async settlement

codespar_charge returns the artifact immediately so the buyer can pay; the merchant must wait for the webhook to know it settled. Pattern:

const charge = await session.charge({ method: "pix", amount: 9990, currency: "BRL", ... });
// 1. Show pix_copy_paste / checkout_url to the buyer

// 2. Poll until terminal:
let status = await session.paymentStatus(charge.tool_call_id);
while (status.status === "pending") {
  await new Promise((r) => setTimeout(r, 2000));
  status = await session.paymentStatus(charge.tool_call_id);
}

// 3. Now status.status === "succeeded" — issue invoice, ship, notify.

See async settlement for the full correlation chain (the Mercado Pago external_reference GET-back caveat in particular). Use paymentStatusStream when you need sub-second latency to terminal — e.g. live UX or boleto.

See also

codespar_charge | CodeSpar