Kobana

Endpoints REST, webhooks firmados, idempotencia nativa.

2 ambientes aislados (producción y sandbox). HMAC-SHA256 en todos los webhooks. Idempotencia vía X-Idempotency-Key. Autenticación por access token de la Conta Kobana.

Funcionalidad
Pantalla de API del dashboard
300+
endpoints REST
2
ambientes aislados
HMAC-SHA256
webhooks firmados
X-Idempotency-Key
nativo

Ambientes para flujo seguro de integración

Production
Ambiente real. Cobros reales. Logs auditados.
  • https://api.billing.kobana.com.br
  • Cobros reales
  • Logs auditados
Sandbox
Aislado de producción. Misma API, sin transacciones reales.
  • https://api.billing.sandbox.kobana.com.br
  • Sin transacciones reales
  • Token propio del ambiente

Qué está disponible para integrar

REST API Completa
300+ endpoints cubriendo todos los recursos: suscripciones, facturas, pagos, clientes, planes, NFe, propuestas, eventos.
  • JSON request/response estandarizados
  • HTTP status codes semánticos
  • Paginación cursor + offset
  • Versionamiento por URL (/v1)
Webhooks Firmados
WebhookEndpoint por organización. Eventos seleccionados vía array events. Cada delivery en WebhookDelivery con retry y backoff.
  • HMAC-SHA256 vía X-Kobana-Signature header
  • Secret cifrado en reposo (AES-256-GCM)
  • 40+ tipos de evento
  • Retry exponencial en hasta 7 intentos
Idempotencia Nativa
Header X-Idempotency-Key aceptado en POST, PUT y PATCH. La misma clave devuelve la respuesta original durante 24 horas.
  • UUID v4 recomendado
  • Alcance por organización
  • Header X-Idempotent-Replay en la reejecución
  • Retención de 24 horas
Tokens de la Conta Kobana
La API se autentica con un access token JWT emitido por la Conta Kobana (account.kobana.com.br). Las claves creadas en el dashboard ya no autentican la API.
  • Expiración obligatoria
  • Token distinto por ambiente
  • Revocación inmediata
Rate Limiting
Límites separados para lectura (GET) y escritura. Headers ratelimit-* en las respuestas.
  • Lectura y escritura con límites propios
  • Límites mayores bajo consulta
  • 429 con Retry-After
Eventos Internos
Modelo Event registra todo cambio de estado. Útil para auditoría, replay y debug. Worker EventDispatch dispara webhooks.
  • Tipo + resource + data JSON
  • Filtros por tipo y período
  • Reenvío manual desde el dashboard
Sandbox Aislado
Ambiente separado de producción, con la misma API y sin transacciones reales.
  • https://api.billing.sandbox.kobana.com.br
  • Webhooks entregados en el endpoint que registres (ngrok recomendado)
  • Misma API que producción
OpenAPI Spec
Especificación OpenAPI 3.1 para generación de clientes y documentación interactiva.
  • Publicada en /v1/openapi.json
  • Colección Postman
  • CLI kobana generado a partir de la spec
Callbacks de Gateways
Endpoints públicos /api/callbacks/{provider} reciben webhooks de Pagar.me, Kobana Gateway Bancario, NFe.io. Procesados vía worker con handlers dedicados.
  • Idempotencia por payload
  • Validación de firma
  • Logs en modelo Callback

Verificar firma HMAC del webhook

javascript
const crypto = require('crypto');

// Body crudo: la firma cubre los bytes exactos recibidos
app.post('/webhooks/kobana', express.raw({ type: 'application/json' }), (req, res) => {
  const id = req.headers['webhook-id'];
  const timestamp = req.headers['webhook-timestamp'];
  const signature = req.headers['webhook-signature'] ?? '';

  // Secret whsec_<base64>: la clave HMAC es el base64 decodificado
  const key = Buffer.from(process.env.KOBANA_WEBHOOK_SECRET.slice(6), 'base64');
  const expected = crypto
    .createHmac('sha256', key)
    .update(`${id}.${timestamp}.${req.body}`)
    .digest();

  const valid = signature.split(' ').some((token) => {
    const received = Buffer.from(token.replace(/^v1,/, ''), 'base64');
    return received.length === expected.length && crypto.timingSafeEqual(received, expected);
  });
  if (!valid || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  switch (event.type) {
    case 'invoice.paid':
      // marca pedido como pagado
      break;
    case 'subscription.canceled':
      // remueve acceso
      break;
  }
  res.sendStatus(200);
});

Perguntas frequentes

Integración que aguanta en producción