Ir para o conteúdo
Sharkpay

Documentação da API

Integre pagamentos, saques e webhooks ao seu sistema com uma API HTTP/JSON aberta e documentada.

API 2026-10-14

Ferramentas para agentes

Para um agente consultar pagamentos ou executar operações, dê a ele ferramentas (function calling) que rodam no seu servidor. O agente escolhe a ferramenta e os argumentos; a sua camada aplica permissões, limites e aprovação, e é a única que enxerga as chaves.

Definições das ferramentas

O formato abaixo é JSON Schema puro, aceito (com pequenas adaptações de envelope) pelas APIs de function calling de Claude, OpenAI e outros frameworks de agentes. Note que há duas de leitura e uma de escrita com controle.

tools.json
[
  {
    "name": "sharkpay_get_invoice",
    "description": "Consulta uma cobrança pela referência (INV-XXXXXX). Somente leitura.",
    "input_schema": {
      "type": "object",
      "properties": { "reference": { "type": "string", "pattern": "^INV-[A-Za-z0-9]{6}$" } },
      "required": ["reference"],
      "additionalProperties": false
    }
  },
  {
    "name": "sharkpay_list_pending_invoices",
    "description": "Lista cobranças da conta (até 50). Somente leitura.",
    "input_schema": {
      "type": "object",
      "properties": {
        "limit": { "type": "integer", "minimum": 1, "maximum": 50 },
        "start_date": { "type": "string", "format": "date" },
        "end_date": { "type": "string", "format": "date" }
      },
      "additionalProperties": false
    }
  },
  {
    "name": "sharkpay_request_payout",
    "description": "SOLICITA um saque Pix. Não executa: cria um pedido de aprovação para um humano. Valor máximo por política.",
    "input_schema": {
      "type": "object",
      "properties": {
        "amount": { "type": "number", "exclusiveMinimum": 0 },
        "pixkey": { "type": "string", "maxLength": 140 },
        "keytype": { "type": "string", "enum": ["CPF", "CNPJ", "EMAIL", "PHONE", "EVP"] },
        "reason": { "type": "string", "maxLength": 200 }
      },
      "required": ["amount", "pixkey", "keytype", "reason"],
      "additionalProperties": false
    }
  }
]

Implementação com controles (Node.js)

tools.mjs
const BASE = process.env.SHARKPAY_BASE_URL;
let token = null, exp = 0;

async function autenticar() {
  if (token && Date.now() < exp - 60_000) return token;
  const basic = Buffer.from(`${process.env.SHARKPAY_PUBLIC_KEY}:${process.env.SHARKPAY_SECRET_KEY}`).toString('base64');
  const r = await fetch(`${BASE}/api/auth`, { method: 'POST', headers: { Authorization: `Basic ${basic}` }, signal: AbortSignal.timeout(15_000) });
  if (!r.ok) throw new Error('auth_failed');
  const j = (await r.json()).success;
  token = j.token; exp = Date.now() + j.expires_in * 1000;
  return token;
}

async function api(path, init = {}) {
  const r = await fetch(`${BASE}${path}`, {
    ...init,
    headers: { Authorization: `Bearer ${await autenticar()}`, 'Content-Type': 'application/json', ...(init.headers || {}) },
    signal: AbortSignal.timeout(30_000),
  });
  if (r.status === 401) { token = null; }
  return r;
}

// Política: o que o agente pode fazer (menor privilégio)
const POLITICA = { valorMaximoSaque: 500.00, chavesPermitidas: new Set(process.env.PIX_ALLOWLIST?.split(',') ?? []) };
const filaAprovacao = [];   // em produção: banco + tela/notificação para um humano

export const ferramentas = {
  async sharkpay_get_invoice({ reference }) {
    if (!/^INV-[A-Za-z0-9]{6}$/.test(reference)) return { erro: 'referencia_invalida' };
    const r = await api(`/api/invoice/ref/${reference}`);
    if (!r.ok) return { erro: `http_${r.status}` };
    const { invoice } = await r.json();
    // devolve ao modelo só o necessário (minimização de dados)
    return { reference: invoice.ref_id, status: invoice.status, total: invoice.total, due_date: invoice.due_date };
  },

  async sharkpay_list_pending_invoices({ limit = 10, start_date, end_date }) {
    const q = new URLSearchParams({ limit: String(Math.min(limit, 50)) });
    if (start_date && end_date) { q.set('start_date', start_date); q.set('end_date', end_date); }
    const r = await api(`/api/invoices?${q}`);
    if (!r.ok) return { erro: `http_${r.status}` };
    const { invoices } = await r.json();
    return invoices.filter(i => i.status === 'PENDING').map(i => ({ reference: i.ref_id, total: i.total, due_date: i.due_date }));
  },

  async sharkpay_request_payout({ amount, pixkey, keytype, reason }) {
    if (amount > POLITICA.valorMaximoSaque) return { erro: 'acima_do_limite' };
    if (!POLITICA.chavesPermitidas.has(pixkey)) return { erro: 'chave_fora_da_lista_permitida' };
    const pedido = { id: crypto.randomUUID(), amount, pixkey, keytype, reason, criadoEm: new Date().toISOString() };
    filaAprovacao.push(pedido);                      // NÃO chama a API ainda
    return { status: 'aguardando_aprovacao_humana', pedido: pedido.id };
  },
};

// Chamado SOMENTE pela tela/endpoint de aprovação, após um humano autenticado confirmar.
export async function executarSaqueAprovado(pedidoId, aprovador) {
  const p = filaAprovacao.find(x => x.id === pedidoId);
  if (!p) throw new Error('pedido_inexistente');
  const r = await api('/api/pixout/create', {
    method: 'POST',
    headers: { 'Idempotency-Key': `payout-${p.id}` },        // determinístico: reenviar não duplica
    body: JSON.stringify({ amount: p.amount, pixkey: p.pixkey, keytype: p.keytype, description: 'Saque aprovado' }),
  });
  console.log(JSON.stringify({ evento: 'saque_aprovado', pedido: p.id, aprovador, http: r.status })); // sem segredos
  return r.status;
}

O que este desenho garante

  • O modelo nunca vê chave, token ou cabeçalhos — só os resultados mínimos.
  • Leitura e escrita são ferramentas diferentes; ofereça ao agente só as que ele precisa.
  • Dinheiro só sai depois de aprovação humana, com limite, lista de chaves permitidas e Idempotency-Key determinística.
  • Argumentos são validados na sua camada; trate a saída do modelo como entrada não confiável (pode haver prompt injection em dados como nome do pagador ou descrição).
  • Erros voltam ao agente como códigos curtos, sem corpo bruto da API.

Frameworks de agentes

O mesmo objeto de ferramentas funciona em qualquer framework (SDKs de Claude e OpenAI, LangChain, LlamaIndex, Vercel AI SDK, etc.): registre as definições de tools.json e, ao receber uma chamada de ferramenta, execute ferramentas[nome](argumentos) e devolva o resultado. O SharkPay não exige nenhum framework específico, e este guia não depende de serviços pagos.