Desenvolvedores

SDK TypeScript

Instale cobrebase, crie cliente e assinatura com idempotência, paginação com listAll, webhooks com constructEvent e helpers de sandbox.

Instalar

Pacote npm: cobrebase. Node.js 20 ou superior. A chave fica no servidor. Não importe este pacote no browser.

npm install cobrebase

Iniciar o cliente

Passe cb_test_... no sandbox ou cb_live_... na cobrança real. Sem baseUrl, o SDK chama https://api.cobrebase.com.br.

import { CobreBase } from "cobrebase";

const cb = new CobreBase(process.env.COBREBASE_API_KEY!);

// Desenvolvimento local (Compose)
const cbLocal = new CobreBase({
  apiKey: process.env.COBREBASE_API_KEY!,
  baseUrl: "http://localhost:18000",
});

Dinheiro é inteiro em centavos (R$ 10,00 = 1000). Moeda BRL. PAN e CVV não passam por esta API.

Cliente e assinatura

Todo POST manda Idempotency-Key. Passe idempotencyKey estável para repetir a mesma operação. Rede, 429 e 5xx repetem com a mesma chave.

const customer = await cb.customers.create(
  { name: "Acme Tecnologia", email: "[email protected]" },
  { idempotencyKey: "customer-acme-42" },
);

const subscription = await cb.subscriptions.create(
  {
    customer_id: customer.id,
    items: [{ price_id: "price_...", quantity: 1 }],
  },
  { idempotencyKey: "sub-acme-42" },
);

Use um price_... já existente (painel ou cb.prices.create).

Listagem e paginação

list devolve uma página (data, links, meta). page começa em 1 e limit vai até 100. listAll percorre as páginas:

for await (const customer of cb.customers.listAll({ limit: 100 })) {
  // customer.id
}

Webhook no body cru

Confira a assinatura com constructEvent antes de fazer parse do JSON. O secret whsec_ aparece uma vez na criação do endpoint (ou no cobrebase listen).

import { constructEvent, WebhookSignatureError } from "cobrebase";

const payload = await request.text();
const header = request.headers.get("CobreBase-Signature");

try {
  const event = constructEvent(
    payload,
    header,
    process.env.COBREBASE_WEBHOOK_SECRET!,
  );

  if (event.type === "invoice.paid") {
    const invoice = event.data.object;
  }
} catch (err) {
  if (err instanceof WebhookSignatureError) {
    // responda HTTP 400
  }
}

Detalhes do envelope e dos tipos: documentação de webhooks.

Sandbox: testHelpers e testClocks

Só com cb_test_. Com chave live a API responde 403.

await cb.testHelpers.confirmPayment("pay_...");
await cb.testHelpers.failPayment("pay_...", { code: "card_declined" });
await cb.testHelpers.expirePayment("pay_...");
await cb.testHelpers.payLate("pay_...", { days_late: 3 });
await cb.testHelpers.fixture("invoice.paid", { method: "pix" });

const clock = await cb.testClocks.create({ frozen_time: 1_700_000_000 });
const advanced = await cb.testClocks.advance(clock.id, {
  frozen_time: 1_700_086_400,
});
if (advanced.status === "advancing") {
  await cb.testClocks.waitUntilReady(clock.id);
}

frozen_time é unix em segundos. Tokens de cartão de teste: tok_visa, tok_visa_declined, tok_insufficient_funds, tok_expired_card, tok_processing (campo provider_token).

Erros

Erros sobem como CobreBaseError com status, type, code, message e param.

import { CobreBaseError } from "cobrebase";

try {
  await cb.customers.create({ name: "Acme" }, { idempotencyKey: "customer-acme" });
} catch (err) {
  if (err instanceof CobreBaseError) {
    // err.status, err.type, err.code, err.message, err.param
  }
}

Contrato HTTP completo: https://api.cobrebase.com.br/docs.