Skip to content

Plans & Abonnements

Klapy propose trois plans : Gratuit (essai limité), Starter (entrée de gamme) et Premium (complet). La stratégie de monétisation repose sur des plafonds de volume sur le plan Gratuit et un découpage de fonctionnalités entre Starter et Premium.

Vue d'ensemble

PlanTarif (lancement)Tarif normalCible
Gratuit0 €0 €Découverte, 30 jours, sans carte bancaire
Starter9 € HT/mois15 € HT/moisVidéaste freelance qui veut centraliser sa prospection
Premium19 € HT/mois29 € HT/moisVidéaste qui facture régulièrement, a besoin d'acomptes et de support prioritaire

Pas d'engagement, résiliable à tout moment.

Fonctionnalités par plan

Gratuit (essai)

  • Accès complet 30 jours
  • Plafond strict : 5 clients
  • Toutes les fonctionnalités Starter sont accessibles pendant la période d'essai

Starter

  • Clients & contacts illimités
  • Pipeline commercial complet
  • Suivi prospects avancé
  • Dashboard CA temps réel
  • Gestion des tâches
  • Synchronisation Google Calendar
  • Ressources & accompagnement
  • Portfolio
  • Devis & factures (basique)

Premium

  • Tout Starter, plus :
  • Devis professionnels vidéaste
  • Factures & acomptes intégrés
  • Support prioritaire

Les libellés exacts et les plafonds sont la source de vérité publiée sur klapy.fr. Cette page reflète l'état actuel du site marketing.

Principe de gating

Le découpage suit deux axes :

  1. Plafonds de volume : actuellement appliqués uniquement sur le plan Gratuit (5 clients). Au-delà du palier, l'utilisateur doit passer à Starter ou Premium.
  2. Fonctionnalités payantes : certaines fonctionnalités sont réservées aux plans payants (ex. import CSV en masse), ou réparties entre Starter et Premium (ex. acomptes intégrés sont Premium uniquement).

Pour les comptes Gratuit qui tentent d'utiliser une fonctionnalité réservée, le bouton reste visible avec un badge Pro et ouvre une fenêtre d'incitation à passer au plan supérieur. Cela favorise la découverte du produit pendant la période d'essai sans frustrer l'utilisateur.

Quotas et compteurs (système technique)

Compteurs dénormalisés

Chaque utilisateur a un document users/{uid} avec des champs compteurs maintenus en temps réel :

  • contacts_count
  • quotes_active_count
  • invoices_month_count
  • storage_bytes_used
  • emails_month_count

Les compteurs sont mis à jour par des triggers Firestore à chaque création / suppression de document. L'utilisateur voit son usage actualisé instantanément dans l'interface (binding réactif via VueFire useDocument), sans rechargement.

Application serveur

Avant chaque écriture concernée, la Cloud Function appelle assertQuota(uid, resource, increment). Si l'opération dépasserait le plafond, la fonction lève une erreur resource-exhausted avec le code quota_exceeded:<resource> et un payload { plan, used, cap, requested } que le client utilise pour afficher une fenêtre d'upsell ciblée.

Source de vérité côté serveur : functions/src/lib/quotas.ts. Côté client (UX uniquement) : src/constants/plans.ts.

Sécurité

Les champs compteurs sont en écriture serveur uniquement (règles Firestore). Aucun client ne peut les modifier, ce qui empêche un utilisateur Gratuit de remettre son compteur à zéro pour contourner la limite.

Réconciliation

En cas de dérive (échec d'un trigger, migration), la Cloud Function admin adminBackfillUsage recalcule les compteurs à partir de la source de vérité (les documents eux-mêmes) et normalise les téléphones legacy au format E.164. Idempotente : peut être lancée manuellement ou planifiée hebdomadairement.

Expérience utilisateur

Avertissement à 80%

Quand un utilisateur atteint 80 % de son plafond sur une ressource, l'interface affiche un message discret (ex. « 4/5 clients, bientôt la limite ») près de l'action concernée. Le composable usePlanLimits() expose nearCap(resource) pour câbler ce comportement.

Blocage à 100%

À l'atteinte du plafond :

  • Côté serveur : la Cloud Function rejette la création.
  • Côté client : la fenêtre UpgradeModal s'ouvre avec le contexte (« Limite de 5 clients atteinte. Passez à Starter pour continuer. ») et un bouton qui redirige vers /app/settings?tab=billing.

Bouton « Pro » sur fonctionnalités payantes

Pour les actions réservées aux plans payants :

  • Comptes Gratuit : bouton visible avec badge ; clic ouvre la fenêtre d'upsell.
  • Comptes Starter / Premium : bouton sans badge ; clic ouvre la fonctionnalité.

Le composable usePlanLimits().canBulk(feature) centralise la décision côté client. Le serveur applique sa propre vérification, indépendante du badge.

Relation avec Stripe

Le champ plan du document users/{uid} est synchronisé via le webhook Stripe (à venir, voir technical/stripe.md). Lorsque l'utilisateur change de plan, son champ plan change instantanément et toutes les vérifications de quota basculent vers les plafonds du nouveau plan lors de la requête suivante. Aucun cache local à invalider grâce aux bindings VueFire réactifs.

Conventions pour les futures fonctionnalités

Quand on ajoute une fonctionnalité qui consomme une ressource :

  1. Ajouter (ou réutiliser) une entrée dans LIMITS côté serveur et côté client (functions/src/lib/quotas.ts + src/constants/plans.ts, à garder en miroir).
  2. Si la ressource est nouvelle : ajouter le champ compteur sur users/{uid}, créer le trigger onCreate / onDelete, ajouter le champ à la liste des champs protégés dans firestore.rules, et étendre adminBackfillUsage.
  3. Côté Cloud Function d'écriture : appeler assertQuota() avant l'opération (transactionnel pour les ressources hot-path).
  4. Côté UI : utiliser usePlanLimits() pour les avertissements à 80 % et le composant UpgradeModal pour les blocages.
  5. Les valeurs exactes des plafonds restent à valider en interne avant toute communication externe.