API de Facturación
Tres endpoints permiten a los agentes e integraciones trabajar con el estado de facturación que gestiona su dashboard.
Todos los endpoints requieren una API key Bearer (consulte Autenticación).
GET /me/billing/state
Devuelve una instantánea de la suscripción de su tenant.
curl https://api.saiku.bi/me/billing/state \ -H "Authorization: Bearer $SAIKU_API_KEY"Respuesta:
{ "tenantId": "81e301f2-…", "tier": "team", "stripeCustomerId": "cus_…", "subscriptionStatus": "active", "currentPeriodEnd": "2026-06-23T00:00:00Z", "trialEndsAt": null, "billedFeaturesActive": true}Campos:
tier—starter,team,businessoenterprise.subscriptionStatus— el estado literal de Stripe. Los valores que verá en la práctica sontrialing,active,past_due,unpaid,canceledo vacío (gratis / pre-facturación).currentPeriodEnd— cuándo termina su período de facturación actual. La renovación ocurre en este momento si está activo.trialEndsAt— solo establecido mientrassubscriptionStatus = trialing.billedFeaturesActive—truemientras tiene acceso a las funcionalidades facturadas. Falso en caso contrario. Use esto para controlar el acceso en su propia UI.
POST /me/billing/checkout-session
Genera una URL de un solo uso al Checkout alojado de Stripe para iniciar una prueba o suscribirse a un plan.
curl -X POST https://api.saiku.bi/me/billing/checkout-session \ -H "Authorization: Bearer $SAIKU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tier": "team", "email": "alice@acme.com", "name": "Acme Corp", "successUrl": "https://app.acme.com/billing/success", "cancelUrl": "https://app.acme.com/billing/cancel" }'Respuesta:
{ "url": "https://checkout.stripe.com/c/pay/cs_test_a1…", "sessionId": "cs_test_a1…"}Envíe el navegador del usuario a url mediante una redirección 303.
La URL es de un solo uso y expira en pocos minutos — no la guarde en
caché.
successUrl y cancelUrl son URLs absolutas a las que Stripe envía
al usuario después de completar o abandonar el Checkout. Ambas deben
ser HTTPS.
POST /me/billing/portal-session
Genera una URL de un solo uso al Customer Portal de Stripe. El Portal es la página alojada de Stripe para gestionar la suscripción: actualizar tarjeta, cambiar de plan, descargar facturas, cancelar.
curl -X POST https://api.saiku.bi/me/billing/portal-session \ -H "Authorization: Bearer $SAIKU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "https://app.acme.com/billing" }'Respuesta:
{ "url": "https://billing.stripe.com/p/session/test_…" }Devuelve 409 no_customer si el tenant nunca ha completado el
Checkout — no hay cliente de Stripe que gestionar. Ejecute
POST /me/billing/checkout-session primero.
Un ejemplo trabajado — estado de suscripción incrustado
Si está construyendo una interfaz de administración que envuelve a Saiku Cloud y quiere mostrar a sus usuarios su plan actual en línea:
// pseudocodeconst state = await fetch('https://api.saiku.bi/me/billing/state', { headers: { Authorization: `Bearer ${saikuApiKey}` }}).then(r => r.json());
if (!state.billedFeaturesActive) { // user has no active subscription or trial — show "upgrade" CTA const session = await fetch( 'https://api.saiku.bi/me/billing/checkout-session', { method: 'POST', headers: { Authorization: `Bearer ${saikuApiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ tier: 'team', email: user.email, name: org.name, successUrl: `${window.location.origin}/billing/success`, cancelUrl: `${window.location.origin}/billing/cancel` }) } ).then(r => r.json()); window.location.href = session.url;} else { // user has access — show current plan + manage button renderPlan(state.tier, state.currentPeriodEnd); const portal = await fetch( 'https://api.saiku.bi/me/billing/portal-session', { method: 'POST', headers: { Authorization: `Bearer ${saikuApiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ returnUrl: `${window.location.origin}/billing` }) } ).then(r => r.json()); renderManageButton(portal.url);}