Aller au contenu

API de facturation

Trois endpoints permettent aux agents et intégrations de travailler avec l’état de facturation géré par votre dashboard.

Tous les endpoints nécessitent une clé API Bearer (voir Authentification).

GET /me/billing/state

Renvoie un instantané de l’abonnement de votre tenant.

Fenêtre de terminal
curl https://api.saiku.bi/me/billing/state \
-H "Authorization: Bearer $SAIKU_API_KEY"

Réponse :

{
"tenantId": "81e301f2-…",
"tier": "team",
"stripeCustomerId": "cus_…",
"subscriptionStatus": "active",
"currentPeriodEnd": "2026-06-23T00:00:00Z",
"trialEndsAt": null,
"billedFeaturesActive": true
}

Champs :

  • tierstarter, team, business ou enterprise.
  • subscriptionStatus — statut Stripe tel quel. Les valeurs que vous verrez en pratique sont trialing, active, past_due, unpaid, canceled, ou vide (gratuit / pré-facturation).
  • currentPeriodEnd — date de fin de votre période de facturation actuelle. Le renouvellement intervient à cette date si l’abonnement est actif.
  • trialEndsAt — défini uniquement tant que subscriptionStatus = trialing.
  • billedFeaturesActivetrue tant que vous avez accès aux fonctionnalités facturées. False sinon. Utilisez ce champ pour contrôler votre propre interface.

POST /me/billing/checkout-session

Crée une URL à usage unique vers Stripe Checkout (hébergé) pour démarrer un essai ou souscrire à un plan.

Fenêtre de terminal
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"
}'

Réponse :

{
"url": "https://checkout.stripe.com/c/pay/cs_test_a1…",
"sessionId": "cs_test_a1…"
}

Envoyez le navigateur de l’utilisateur vers url via une redirection 303. L’URL est à usage unique et expire au bout de quelques minutes — ne la mettez pas en cache.

successUrl et cancelUrl sont des URL absolues vers lesquelles Stripe renvoie l’utilisateur après la finalisation ou l’abandon du Checkout. Les deux doivent être en HTTPS.

POST /me/billing/portal-session

Crée une URL à usage unique vers le portail client Stripe. Le portail est la page hébergée par Stripe pour gérer l’abonnement : mettre à jour la carte, changer de plan, télécharger les factures, annuler.

Fenêtre de terminal
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" }'

Réponse :

{ "url": "https://billing.stripe.com/p/session/test_…" }

Renvoie 409 no_customer si le tenant n’a jamais finalisé de Checkout — il n’y a pas de client Stripe à gérer. Exécutez d’abord POST /me/billing/checkout-session.

Un exemple concret — état d’abonnement embarqué

Si vous construisez une interface d’administration qui enveloppe Saiku Cloud et souhaitez afficher à vos utilisateurs leur plan actuel directement :

// pseudocode
const 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);
}