compense es una herramienta de línea de comandos para las tareas que haces a mano mientras integras: validar una llave, ver el catálogo de eventos, registrar un endpoint, disparar un evento de prueba, revisar y reintentar entregas, mover un reloj de prueba, avanzar un simulador y reenviar webhooks a tu máquina. Cada orden es una envoltura delgada sobre el SDK e imprime la respuesta del gateway como JSON, así que puedes encadenarla con jq.

Instalación #

La CLI viene incluida en dos SDK, con las mismas órdenes y opciones. Úsala aunque tu integración esté en PHP, .NET o Go: esos SDK no traen CLI.

SDKCómo se instalaCómo se ejecuta
Python (3.9+)pip install compense-sdk-pythoncompense … (queda en el PATH del entorno)
JavaScript (Node 18+)npm install @compense/sdknpx compense …
Shell
compense --help              # Python y JavaScript
npx compense --version       # solo JavaScript: imprime la versión del SDK

Llave, entorno y URL #

Todas las órdenes que llaman al API aceptan tres opciones:

OpciónValorPor defecto
--key KEYTu llave cmp_...La variable de entorno COMPENSE_API_KEY
--environment ENVproduction, sandbox o devsandbox
--base-url URLCualquier otra URL del gateway (p. ej. la que te dieron en el onboarding); gana sobre --environment—
Shell
export COMPENSE_API_KEY="cmp_..."                 # PowerShell: $env:COMPENSE_API_KEY = "cmp_..."
compense health                                   # sandbox por defecto
compense health --environment dev
compense health --base-url https://sandbox.dev.compense.co/gw

Recuerda que el comportamiento lo decide la llave: con una llave de sandbox recibes respuestas del sandbox en cualquier entorno. Pon las opciones después de la orden (y de su acción, en clock y simulate): es la forma que aceptan las dos implementaciones.

Salida y códigos de salida #

  • La respuesta va a stdout como JSON indentado. Los modelos del SDK se imprimen con el cuerpo tal como lo devolvió el gateway.
  • Los mensajes (errores, el aviso de trigger) van a stderr.
CódigoSignificado
0Éxito.
1El gateway rechazó la petición (error: gateway rejected the request — …), o ejecutaste compense sin orden (imprime la ayuda). En JavaScript también un error de conexión o timeout, y una orden desconocida o incompleta.
2No hay llave (error: no API key. Pass --key or set $COMPENSE_API_KEY.), error de configuración (p. ej. trigger sin endpoints activos) u opciones inválidas. En Python también una orden desconocida o incompleta (error de argparse).

Órdenes #

OrdenQué haceOperación
healthValida la llave: tenant y scopesGET/v1/gateway/health/
events [--category C]Catálogo de eventos de webhooksGET/v1/gateway/webhooks/event-catalog/
endpointsTus endpoints (sin secreto)GET/v1/gateway/webhooks/endpoints/
endpoint-create --url U --event E [--event E …] [--label L]Registra un endpoint e imprime el secreto una vezPOST/v1/gateway/webhooks/endpoints/
trigger <evento> [--endpoint ID]Envía una entrega de prueba firmadaPOST/v1/gateway/webhooks/endpoints/{endpoint_id}/test/
deliveries [--status S] [--event-type T] [--endpoint ID]Historial de entregas (primera página)GET/v1/gateway/webhooks/deliveries/
replay <delivery_id>Reintenta una entrega failed o abandonedPOST/v1/gateway/webhooks/deliveries/{delivery_id}/replay/
clock create <frozen_time>Crea un reloj de pruebaPOST/v1/gateway/sandbox/test-clocks/
clock get <clock_id>Consulta un relojGET/v1/gateway/sandbox/test-clocks/{clock_id}/
clock advance <clock_id> <segundos>Adelanta un reloj (imprime el id nuevo)POST/v1/gateway/sandbox/test-clocks/{clock_id}/advance/
simulate transfer [--status S] [--amount A] [--transaction-id T]Un paso de una transferencia de billeteraPOST/v1/gateway/sandbox/wallet/simulate/
simulate credit <app_id> [--status S] [--amount A]Un paso de un desembolso de créditoPOST/v1/gateway/sandbox/credits/{app_id}/advance/
listen --forward-to URL [--port N]Reenvía webhooks recibidos a una URL local— (no llama al API)

La CLI no tiene órdenes para editar, pausar, eliminar ni rotar endpoints, ni para el detalle de una entrega: usa el SDK o cURL (Suscribir un endpoint, Reintentos y entregas).

health #

Shell
compense health
JSON
{
  "status": "ok",
  "tenant": "horizonte",
  "scopes": ["affiliates:read", "credits:submit", "webhooks:read", "webhooks:manage"]
}

Webhooks #

Shell
# Catálogo (todo o una categoría: credits, subsidies, monetary_allowance, affiliates,
# wallets, loans, health, admin, pqrs, general)
compense events --category loans

# Registrar un endpoint: --event se repite por cada evento. Guarda el "secret" que imprime.
compense endpoint-create \
  --url https://erp.horizonte.example/compense/webhooks \
  --event payment.received \
  --event installment.overdue \
  --label "ERP Caja Horizonte"

compense endpoints

# Prueba firmada. Sin --endpoint elige un endpoint activo suscrito al evento
# (o, si no hay, el primero activo).
compense trigger payment.received
compense trigger test.ping --endpoint 3f1a2b3c-0000-4a1b-9c2d-000000000001

# Entregas fallidas de un evento y reintento de una de ellas
compense deliveries --status failed --event-type payment.received
compense replay 8b7c6d5e-0000-4a1b-9c2d-000000000301

deliveries muestra la primera página (25 entregas) y no tiene filtro de fechas ni de página; para recorrer todo el historial usa el SDK, como en Reprocesar todas las fallidas. Con jq puedes reintentar lo que ves:

Shell
compense deliveries --status failed | jq -r '.results[].id' | while read -r ID; do
  compense replay "$ID"
done

Relojes #

Shell
compense clock create 2026-10-01T00:00:00Z           # o segundos Unix: 1790812800
compense clock advance tcl-… 2592000                 # 30 días; imprime el reloj con id NUEVO
compense clock get tcl-…

# Encadenar avances con jq
ID=$(compense clock create 2026-07-15T00:00:00Z | jq -r .id)
ID=$(compense clock advance "$ID" 5443200 | jq -r .id)   # 63 días (máximo por llamada)
compense clock get "$ID" | jq -r .current_time

Los relojes solo responden a llaves de sandbox. Detalle en Relojes de prueba.

Simuladores #

Shell
# Transferencia: sin --status arranca en PENDING. 22.22 → FAILED, 33.33 → RETURNED.
compense simulate transfer --amount 33.33
compense simulate transfer --status PROCESSING --amount 33.33
compense simulate transfer --status SETTLED --amount 33.33 --transaction-id NOVA-P2P-2026-000123

# Desembolso de una solicitud de crédito del sandbox
compense simulate credit sbx-E-… --status PENDING
JSON
{
  "object": "wallet_transfer",
  "previous_status": "SETTLED",
  "status": "RETURNED",
  "terminal": true,
  "amount": 33.33,
  "reference": "NOVA-P2P-2026-000123",
  "reason_code": "TRANSFER_RETURNED",
  "environment": "sandbox"
}

Detalle en Simuladores de ciclo de vida.

listen #

listen levanta un servidor en 127.0.0.1 (puerto 8787 por defecto) que recibe entregas de webhooks y las reenvía tal cual (cuerpo crudo y cabeceras, salvo las de salto como Host o Content-Length) a la URL que le indiques. Imprime las cabeceras de firma de cada entrega y devuelve a Compense el mismo código que respondió tu receptor (o 502 si no lo alcanza), para que los reintentos reflejen lo que pasó de verdad. Se detiene con Ctrl-C.

Shell
compense listen --forward-to http://localhost:8000/compense/webhooks --port 8787

listen no usa la llave ni acepta --key, --environment o --base-url: solo reenvía. Como el sandbox no envía webhooks y un endpoint debe ser HTTPS público, necesitas un túnel y una llave de producción en el ambiente dev; el paso a paso está en Probar tus webhooks.

Diferencias entre la CLI de Python y la de JavaScript #

Las órdenes, las opciones y los códigos de salida son los mismos. Las diferencias son menores:

PythonJavaScript
Ejecutablecompensenpx compense (o compense si instalas el paquete de forma global)
--versionNo existeImprime la versión del SDK
Ayuda de cada ordencompense <orden> --helpUna sola ayuda general (--help o -h)
Posición de las opcionesDespués de la orden (y de la acción en clock / simulate)En cualquier posición
Error de conexión o timeoutLo muestra el intérprete (traza)error: … y código 1