Facturation des abonnements
Les formules et leurs limites, la page Billing, les passages à une formule supérieure facturés tout de suite et les retours à une formule inférieure planifiés au renouvellement, le paiement test intégré et Stripe, les essais et les renouvellements, les e-mails de facturation, les factures en PDF, et ce que changent un paiement échoué ou une suspension.
Pour le pack Full Stack
Les formules et leurs limites
Chaque espace de travail est sur l'une des trois formules mensuelles, en dollars américains :
| Formule | Prix | Places | Requêtes d'API | Stockage |
|---|---|---|---|---|
| Starter | 29 $ par mois | 3 | 10,000 | 5 Go |
| Pro | 99 $ par mois | 10 | 100,000 | 20 Go |
| Scale | 249 $ par mois | 30 | 500,000 | 100 Go |
- Un espace de travail créé dans l'onboarding démarre sur un Trial de Starter, pour la durée du paramètre de plateforme Trial length (
trial_days, 14 jours dans le seed). Le seed place Forma Studio sur Pro, avec trois factures payées. - Quand un essai arrive à son terme sans formule payante, l'espace de travail passe Past due à partir de ce moment, et le délai de grâce d'un paiement échoué commence (voir Un paiement échoué plus bas). La page Billing affiche « The trial has ended. Choose a paid plan before » la fin du délai de grâce, et la trace d'activité enregistre « The trial ended without a paid plan ».
- Les places sont appliquées : une invitation, et son acceptation, est refusée avec
seat_limit_reacheddès que toutes les places sont prises. - Les requêtes d'API comptent les appels faits avec les clés d'API de l'espace de travail, et le stockage les fichiers de projet qu'il contient. Les deux sont affichés par rapport à la formule et vérifiés avant un retour à une formule inférieure ; l'API ne refuse ni un appel ni un téléversement au-delà de la limite. Le compte des requêtes repart de zéro à chaque nouvelle période de facturation, celle d'un essai comprise.
La page Billing
Billing, sur /en/dashboard/billing, affiche l'abonnement de l'espace de travail :
- La formule avec son statut (Trial, Active, Past due, Ending, Canceled ou Suspended), son prix mensuel et la prochaine date qui compte, comme « Renews » ou « Trial ends ».
- Change plan (Choose a paid plan pendant un essai, après sa fin, et une fois l'espace de travail annulé) et Manage payment method, ou Resume subscription pendant que la formule se termine.
- Pendant qu'un retour à une formule inférieure attend le renouvellement, « Moves to Starter on » la date, avec Keep Pro (le nom de la formule actuelle) pour l'annuler.
- Usage : les requêtes d'API, les places et le stockage par rapport aux limites de la formule.
- Invoice history, avec un bouton Download sur chaque facture.
- Billing email, avec Edit : « Payment notices go to this address, and it is printed on every invoice. » Stripe Checkout la remplit aussi.
- Cancel subscription, tant que la formule est en essai, active ou en retard de paiement.
Un membre qui peut lire la facturation sans la modifier voit la même page avec « Only the owner and billing members change the plan. » à la place des boutons.
Changer de formule
Choisir une formule
Appuyez sur Change plan et choisissez une formule. Sous « What changes », la boîte de dialogue montre ce qui est Charged today et la Next invoice, tous deux issus de l'API. Pendant un essai, après sa fin et une fois l'espace de travail annulé, le bouton est Choose a paid plan, et chaque formule peut être choisie, l'actuelle comprise (« Your trial plan » pendant un essai).
Un passage à une formule supérieure : facturé tout de suite
Une formule plus chère prend effet tout de suite, et la date de renouvellement reste. Sur un abonnement Stripe en cours, la boîte de dialogue indique « Takes effect at once. The card on file is charged the prorated difference today, and the renewal date stays. », Charged today est le chiffre de Stripe lui-même, et Upgrade and pay now le facture au moyen de paiement enregistré sans page de paiement. Sur le paiement test, elle indique « Takes effect at once, prorated for the rest of this period. » et Continue to payment ouvre le paiement. Un premier paiement (un essai, un essai terminé ou un espace de travail annulé) est facturé au mois complet de la formule et démarre une nouvelle période de 30 jours : « The paid plan starts at once. The first month is charged in full. », avec « and ends the trial » pendant un essai.
Payer, puis revenir
Le paiement est le paiement test intégré, ou la page de Stripe une fois Stripe configuré. Un passage à une formule supérieure facturé sur la carte enregistrée se termine tout de suite par « The workspace is on the Pro plan. » De retour sur la page Billing depuis un paiement, elle indique « Confirming the payment... », puis « Payment received. The workspace is on the Pro plan. » avec la nouvelle formule, ses limites et une facture payée. Un paiement laissé inachevé affiche « A checkout for the Pro plan was started and not finished. » jusqu'à ce qu'on le ferme.
Un retour à une formule inférieure : planifié, rien n'est facturé
Une formule moins chère « Takes effect on » la date de renouvellement, « Nothing is charged today. », et Schedule the change l'enregistre ; le panneau de la formule indique alors « Moves to Starter on » cette date. Keep Pro à côté l'annule : « The workspace stays on the Pro plan. » Tant que les places, les requêtes d'API ou le stockage dépassent les limites de la formule plus petite, la boîte de dialogue les liste et refuse avec « Bring usage under the new plan's limits first. »
Une formule achetée par un paiement ne change que lorsque le fournisseur de paiement le confirme : par le webhook signé de Stripe, ou quand la page Billing interroge l'API au retour du visiteur et que l'API lit elle-même la session chez Stripe. L'adresse de retour seule ne change jamais une formule.
- Avec Stripe, un passage à une formule supérieure modifie l'abonnement en cours sur place : Stripe facture tout de suite la différence au prorata et débite le moyen de paiement enregistré. Le prix affiché vaut 30 minutes ; ensuite le passage est refusé (« The price shown is out of date. Check the new price, then confirm again. ») et la boîte de dialogue montre le nouveau chiffre. Une carte refusée, une banque qui veut confirmer le paiement, ou l'absence de moyen de paiement enregistré est refusée avec une phrase qui dit lequel, et la formule reste ce qu'elle était.
- Avec Stripe, un retour à une formule inférieure est un échéancier d'abonnement : la période en cours garde le prix payé, le renouvellement facture le prix plus petit, et rien n'est calculé au prorata. Quand ce renouvellement est payé, l'espace de travail passe à la nouvelle formule. Keep libère l'échéancier, et un passage à une formule supérieure entre-temps l'abandonne (et le rétablit si le débit échoue).
- Avec le paiement test, la période se renouvelle d'elle-même à son terme : une facture payée au prix de la formule, la période de 30 jours suivante, le compte d'usage remis à zéro, et un retour à une formule inférieure planifié appliqué.
Le paiement test intégré
Sans clé Stripe, chaque changement de formule passe par le paiement test du tableau de bord lui-même sur /en/dashboard/billing/checkout/<session>. Il montre l'espace de travail, la formule actuelle et la nouvelle, le montant et la personne facturée, indique « This is the built-in test checkout. It asks for no card and charges nothing. », et propose Test payment et Cancel.
- Test payment change la formule tout de suite et écrit une facture payée, exactement comme un paiement Stripe confirmé. Cancel ne débite rien : « Checkout canceled. Nothing was charged. »
- Seul un membre autorisé à gérer la facturation de cet espace de travail peut ouvrir la page.
BILLING_PROVIDER=simulatordans le.envde l'API garde le paiement test même avec des clés Stripe définies.- Manage payment method indique « The test checkout keeps no card, so there is no payment method to manage. »
Encaisser de vrais paiements avec Stripe
Définissez STRIPE_SECRET_KEY dans le .env de l'API et redémarrez-la. Le journal de l'API indique alors « Stripe is set up in test mode. » pour une clé sk_test_, ou qu'elle débite de vraies cartes pour une clé sk_live_.
- Un premier paiement ouvre Stripe Checkout en mode abonnement pour le prix mensuel de la formule, établi au nom de l'e-mail de facturation. Stripe ramène l'acheteur sur la page Billing, qui confirme le paiement auprès de l'API avant d'afficher la nouvelle formule.
- Rien n'a besoin d'être créé d'abord dans Stripe : le prix de chaque formule est créé la première fois qu'il est nécessaire, avec un produit nommé d'après la formule (
Northstack Pro) et la clé de recherchenorthstack_<plan>_usd_<cents>_month(northstack_pro_usd_9900_month), puis retrouvé par cette clé ensuite. Un nouveau prix de formule reçoit une nouvelle clé, et les abonnements sur l'ancien prix le gardent. - Ensuite, un passage à une formule supérieure modifie l'abonnement sur place et débite la carte enregistrée, et un retour à une formule inférieure est planifié pour le renouvellement, comme dans Changer de formule plus haut. Stripe renouvelle lui-même l'abonnement, et son
invoice.paidfait passer l'espace de travail à la période suivante. - Si un nouveau paiement Stripe remplace un abonnement que l'espace de travail a encore, l'API annule l'ancien, son temps inutilisé étant crédité sur la prochaine facture du client. Si Stripe refuse cette annulation, le journal de l'API le signale et nomme l'abonnement à annuler dans le dashboard de Stripe.
- Dès qu'un espace de travail a payé par Stripe, Manage payment method ouvre le portail client de Stripe et revient à la page Billing.
- Cancel subscription demande à Stripe de mettre fin à l'abonnement à la fin de la période, en abandonnant un retour à une formule inférieure planifié pour le renouvellement, et Resume subscription annule l'annulation.
- Avec des clés de test, aucun argent ne bouge : sur la page de Stripe, payez avec la carte
4242 4242 4242 4242, n'importe quelle date future et n'importe quel CVC.
Le webhook Stripe
Avant la mise en ligne, ajoutez un webhook dans Stripe sur l'adresse publique de votre API et mettez son secret de signature dans STRIPE_WEBHOOK_SECRET. Les abonnements et les commandes de licences du site partagent ce seul point de terminaison.
| Adresse | Événements |
|---|---|
https://<your-api>/api/billing/webhooks/stripe | checkout.session.completed, checkout.session.expired, invoice.paid, invoice.payment_failed, customer.subscription.deleted |
- Chaque envoi est d'abord vérifié avec la signature de Stripe, et une mauvaise signature est refusée avec un 400. Chaque identifiant d'événement n'est appliqué qu'une fois, quel que soit le nombre d'envois de Stripe.
- Avec
STRIPE_SECRET_KEYdéfini etSTRIPE_WEBHOOK_SECRETvide, le journal de l'API le signale au démarrage, et chaque envoi est refusé par un 400 dont le message nommeSTRIPE_WEBHOOK_SECRET. Tant qu'il n'est pas défini, les renouvellements, les paiements échoués et les annulations ne sont pas enregistrés, et un paiement ne compte que lorsque l'acheteur revient sur la page Billing. checkout.session.completedchange la formule.invoice.paidstocke une fois la facture de Stripe, avec son montant et la période qu'elle paie, et remet l'espace de travail à Active (ou Ending s'il avait été annulé). Une facture qui ouvre une période déplace la date de renouvellement à sa fin et remet le compte d'usage à zéro, et un renouvellement applique un retour à une formule inférieure planifié pour lui ; la facture au prorata d'un passage à une formule supérieure ne déplace rien.invoice.payment_failedmarque l'espace de travail Past due, etcustomer.subscription.deletedle marque Canceled.- Sur votre ordinateur, Stripe ne peut pas atteindre l'API, et un paiement test aboutit quand même, car la page Billing demande à l'API de lire la session chez Stripe au retour de l'acheteur.
Annuler et reprendre
Cancel subscription demande « Cancel the subscription? » : la formule reste active jusqu'à la date de renouvellement, puis l'espace de travail garde ses données mais cesse d'être facturé. Le statut devient Ending, le panneau indique « Ends » avec la date, et Resume subscription garde finalement la formule. Un retour à une formule inférieure planifié pour le renouvellement est abandonné, puisqu'il n'y a plus de renouvellement où l'appliquer.
Avec Stripe, Stripe met fin à l'abonnement à cette date et son webhook marque l'espace de travail Canceled. Sur le paiement test, l'espace de travail passe Canceled à la fin de la période. Un espace de travail annulé garde toutes les lectures, et ne peut ni démarrer de nouveaux projets, ni créer d'invitations ou de clés d'API tant qu'il n'est pas de nouveau sur une formule payante : Choose a paid plan achète n'importe quelle formule à son prix plein, dès ce jour.
Supprimer un espace de travail (son propriétaire, dans Settings, Danger zone) met fin à son abonnement Stripe tout de suite, sans crédit pour le reste de la période. Si Stripe est injoignable, la suppression est refusée avec un 409, « The subscription could not be canceled with the payment provider, so the workspace was kept. Try again in a few minutes. », si bien qu'un espace supprimé n'est jamais facturé.
Factures
- Une facture, numérotée
INV-avec l'année et un numéro courant, est écrite chaque fois qu'un changement de formule est payé, pour le montant alors facturé, à chaque renouvellement du paiement test, et avec Stripe pour chaque facture que Stripe déclare payée, renouvellements compris, avec le montant et la période de Stripe. Une facture Stripe n'est stockée qu'une fois, quel que soit le nombre de fois où elle est déclarée. Invoice history liste les 36 dernières, avec leur date, leur montant et leur statut (Paid, Open ou Void). - Download ouvre la facture en PDF : la formule, la période, la personne facturée et le total. Le lien est signé et fonctionne cinq minutes, sans connexion, et peut donc être ouvert dans un nouvel onglet.
- L'e-mail de facturation de la page est l'adresse que nomme la facture et celle que remplit Stripe Checkout.
Essais et renouvellements dans le temps
Ce que le calendrier rend exigible est appliqué par l'API elle-même, une fois chacun : un essai qui arrive à son terme, une période de paiement test qui se renouvelle, et un abonnement réglé pour finir avec sa période. Elle s'exécute chaque fois que la facturation d'un espace de travail est lue, et une fois par heure pour chaque espace de travail (le premier passage une minute après le démarrage de l'API), si bien qu'un serveur qui était éteint rattrape son retard à son retour.
- Stripe renouvelle ses propres abonnements ; pour ceux-ci, l'API suit les
invoice.paidetinvoice.payment_failedde Stripe. - Chaque changement n'est fait qu'une fois, même quand deux requêtes, ou deux serveurs d'API, règlent le même espace de travail au même moment.
- La trace d'activité enregistre un essai terminé (
billing.trial_ended), un changement de formule (billing.plan_changed, y compris un changement appliqué à un renouvellement) et un changement planifié annulé (billing.schedule_canceled).
E-mails de facturation
Quatre événements de facturation sont envoyés par e-mail au propriétaire et aux membres de facturation de l'espace de travail, chacun dans sa propre langue, ou dans celle de l'espace de travail quand il n'en a choisi aucune, et à l'e-mail de facturation dans la langue de l'espace de travail quand ce n'est pas déjà l'une des leurs, avec un lien vers la page Billing :
- un paiement échoué, avec la fin du délai de grâce ;
- un essai terminé sans formule payante, avec la même date ;
- un changement de formule payé ;
- un changement planifié appliqué au renouvellement.
L'interrupteur Email notifications de l'espace de travail (Settings, Notifications) désactive ces quatre e-mails pour tout le monde dans l'espace de travail. Les invitations, les réinitialisations de mot de passe et les reçus de licence sont toujours envoyés. Sans paramètres SMTP, chaque message est écrit plutôt dans le journal de l'API.
Un paiement échoué
Quand Stripe signale un paiement échoué, l'espace de travail passe Past due, et la page Billing indique « The last payment failed. Update the payment method before » la fin de son délai de grâce. Un essai terminé sans formule payante est en retard de paiement de la même façon, à partir de sa date de fin.
- Pendant le délai de grâce,
BILLING_GRACE_DAYSdans le.envde l'API (7 par défaut), tout continue de fonctionner. - Ensuite, l'espace de travail ne peut ni démarrer de nouveaux projets, ni créer d'invitations ou de clés d'API ; l'API les refuse avec
billing_grace_expired. Toutes les lectures et tous les enregistrements existants continuent de fonctionner, et rien n'est jamais supprimé pour un paiement échoué. - La prochaine facture payée remet l'espace de travail à Active ; après un essai terminé, c'est le premier paiement qui le fait.
Un espace de travail suspendu
Le personnel de la plateforme peut suspendre un espace de travail depuis l'administration de la plateforme. Ses membres peuvent toujours se connecter et tout lire, chaque modification est refusée avec workspace_suspended, les clés d'API ne peuvent que lire, et la page Billing indique « Suspended. Contact support to restore the workspace. »
Qui peut faire quoi
| Permission | Autorise | Rôles des données d'exemple |
|---|---|---|
billing.read | Ouvrir la page Billing, ses factures et leurs téléchargements | Owner, Billing |
billing.manage | Changer de formule, garder la formule plutôt qu'un changement planifié, le paiement test, le portail de paiement, l'annulation, la reprise et l'e-mail de facturation | Owner, Billing |
Les deux figurent dans la matrice de rôles de chaque espace de travail, le propriétaire peut donc les accorder à un autre rôle. Un rôle qui n'en détient aucune reçoit l'espace de travail sans son e-mail de facturation (billingEmail: null) de chaque route d'espace de travail ; le personnel de la plateforme le voit toujours sur la page de l'organisation.
Les routes derrière
GET /api/workspaces/:workspaceId/billingrépond l'abonnement, les formules, l'usage et tout paiement en attente ;.../billing/invoicesles 36 dernières factures.POST .../billing/previewavec{ "planId": "pro" }répond ce que coûte le changement et quand il s'applique. Pour un passage à une formule supérieure d'un abonnement Stripe en cours, il portechargesCardOnFile: trueet unquote, valable 30 minutes.POST .../billing/checkoutavec leplanId(et cequote) fait le changement :upgraded: truequand la carte enregistrée a été débitée, la page où payer (url) pour un paiement, ouscheduled: truepour un retour à une formule inférieure. Un retour à une formule inférieure au-delà des limites est un 409over_plan_limitqui les liste ; un devis expiré un 409preview_expired; un débit refusé un 402payment_declined,payment_needs_actionoupayment_method_missing.POST .../billing/keep-planannule un retour à une formule inférieure planifié, ou répond 409no_scheduled_change.POST .../billing/checkout/:sessionId/synclit un paiement revenu chez le fournisseur.POST .../billing/portal,.../billing/cancelet.../billing/resume, etPATCH .../billing/email, font ce que leur nom indique.GET .../billing/invoices/:invoiceId/download-linkrépond un lien signé versGET /api/billing/invoices/download?token=..., valable cinq minutes.POST /api/billing/webhooks/stripereçoit les événements de Stripe ;GET /api/billing/simulator/:sessionIdavecPOST .../completeetPOST .../cancelservent le paiement test.
Vendre vos propres formules
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Où les formules sont définies, et chaque endroit à modifier pour vendre vos propres formules.