Paquete@compense/sdk (ESM y CommonJS, con declaraciones TypeScript)
Versión1.1.0 · API v1
RequisitosNode.js 18+ (usa fetch nativo); también Deno, Bun, Cloudflare Workers y Vercel/Next.js edge
DependenciasNinguna en tiempo de ejecución
RepositorioAppiasoft/compense-saas-sdk-js · guías en docs/ · ejemplos en examples/

Instalar #

Shell
npm install @compense/sdk
TypeScript
import { CompenseClient } from "@compense/sdk";        // ESM / TypeScript
// const { CompenseClient } = require("@compense/sdk"); // CommonJS

Cliente #

TypeScript
const client = new CompenseClient({
  apiKey: process.env.COMPENSE_API_KEY!, // obligatorio; viaja como X-API-Key
  environment: "sandbox",                // "production" (defecto) | "sandbox" | "dev"
  baseUrl: undefined,                    // otra URL; gana sobre environment
  timeout: 30_000,                       // ms por intento
  retry: { maxAttempts: 3, backoffBaseMs: 500, backoffMaxMs: 30_000, jitter: true, retryWrites: false },
  fetch: undefined,                      // fetch propio (proxy, instrumentación, pruebas)
  logger: console,                       // avisos de deprecación
});

Hay un solo cliente y todo devuelve Promise. La llave es un secreto de servidor: aunque el cliente funciona en navegadores, nunca pongas una llave en código de frontend.

Convenciones #

  • Métodos en camelCase y un objeto de opciones para los parámetros: client.wallet.bills.pay({ document, billerCode, reference, amount, idempotencyKey }).
  • Los campos libres (extra, y fields en el módulo administrativo) se envían tal cual, con los nombres del contrato en snake_case.
  • Duraciones en milisegundos (timeout, backoffBaseMs), salvo err.retryAfter, en segundos como la cabecera.
  • Los parámetros de ruta se codifican (percent-encoding).

Errores #

TypeScript
import {
  CompenseError, CompenseConfigError, CompenseAPIError, AuthError, NotFoundError,
  IdempotencyConflictError, ValidationError, RateLimitError, UpstreamError, ServerError,
  CompenseConnectionError, CompenseTimeoutError,
} from "@compense/sdk";

A diferencia de Python, los fallos de transporte son tipados: CompenseConnectionError (y su subclase CompenseTimeoutError). No se reintentan solos: reenvía con la misma idempotencyKey.

Paginación asíncrona #

Page y OffsetPage recorren todas las páginas siguientes con for await, repitiendo la misma llamada con los mismos filtros:

TypeScript
for await (const delivery of await client.webhooks.deliveries.list({ status: "failed" })) {
  await client.webhooks.deliveries.replay(String(delivery.id));
}

const first = await client.wallet.transactions.list("1032456789", { limit: 100 });
for await (const page of first.iterPages()) console.log(page.offset, page.length);
const next = await first.getNextPage(); // o null

Webhooks #

ImportRuntimeAPI
@compense/sdk/webhooksNode.js (también Bun, Deno y Workers con compatibilidad Node)verifyWebhook(...) síncrono
@compense/sdk/webhooks/webWeb Crypto: navegadores, Cloudflare Workers, Vercel/Next.js edge, Denoawait verifyWebhook(...)
TypeScript
import { verifyWebhook, WebhookVerificationError } from "@compense/sdk/webhooks";

const event = verifyWebhook(rawBody, req.headers, [NEW_SECRET, OLD_SECRET], { tolerance: 300 });
event.eventId; event.event; event.resource; event.isTest;

Recibe el cuerpo crudo (express.raw(), nunca express.json()). Receptores completos en Verificar la firma.

CLI #

El paquete trae el comando compense (Node): npx compense health, events, endpoints, endpoint-create, trigger, deliveries, replay, clock, simulate, listen y --version. Ver CLI.

Pruebas #

Pasa un fetch propio:

TypeScript
import { CompenseClient } from "@compense/sdk";

const fakeFetch: typeof fetch = async (input) => {
  const url = new URL(String(input instanceof Request ? input.url : input));
  if (url.pathname === "/v1/gateway/wallet/balance/") {
    return new Response(JSON.stringify({ total: "150000.00", available_cash: "150000.00", currency: "COP" }),
      { status: 200, headers: { "content-type": "application/json" } });
  }
  return new Response(JSON.stringify({ title: "Not Found", status: 404, trace_id: "t" }), { status: 404 });
};

const client = new CompenseClient({ apiKey: "cmp_test", environment: "sandbox", fetch: fakeFetch });
console.assert((await client.wallet.balance("1032456789")).available.amount === "150000.00");

Diferencias con el SDK de Python #

Mismas operaciones, cuerpos, idempotencia y reintentos (la suite compara cada llamada con lo que envía Python), con estas diferencias deliberadas: un solo cliente asíncrono; duraciones en ms; objetos de opciones en vez de argumentos con nombre; sin los alias deprecados de la 1.0; errores de transporte tipados; paginación asíncrona; dos entradas de verificación de webhooks.