Facturation
Clients, factures avec ventilation TPS et TVQ, paiement Stripe et Interac, récurrences, rappels et intérêts de retard.
@lrvo/module-billing ajoute une section « Facturation » à l'admin : un fichier clients, un catalogue d'articles, des factures avec ventilation TPS et TVQ, et une page publique où le client règle sa facture par carte ou par virement Interac.
Le module est autonome. Il porte ses propres clients plutôt que de dépendre d'un module externe, et se relie facultativement aux comptes du site par la colonne user_id.

Une facture ouverte dont l'échéance est passée affiche « En retard » dans la colonne « Statut », et le nombre de jours de retard sous l'échéance, alors que son statut stocké reste sent ou partial : c'est une déduction, pas un état stocké, et Facturation explique pourquoi. Le décompte sous l'échéance ne paraît que tant qu'un solde reste dû. Une facture payée, annulée ou en brouillon n'en porte aucun. Le brouillon en tête de liste n'a ni numéro ni lien public, il ne les reçoit qu'à l'émission.
Pages de cette section
| Page | Contenu |
|---|---|
| Installation | Installer le module, créer les tables, déclarer le webhook Stripe. |
| Configuration | Variables d'environnement, permissions, entrée d'admin. |
| Cycle de vie d'une facture | Brouillon, émission, encaissement, annulation. |
| Taxes | Profils, base de calcul, arrondi, numéros d'inscription. |
| Paiements | Stripe, Interac, saisie manuelle et remboursements. |
| Récurrences et rappels | Génération automatique, échelle de rappels, intérêts. |
| Courriels | Les six messages, leur contenu et leur non-répétition. |
| Modèle de données | Les douze tables lrvo_billing_*. |
| API | Routes HTTP et fonctions serveur importables. |
Ce que le module apporte
| Élément | Détail |
|---|---|
| Tables | Douze, toutes préfixées lrvo_billing_. |
| Entrée d'admin | Section « Facturation », icône InvoiceIcon, ordre 150, six items. |
| Tableau de bord | Un panneau « Facturation » sur /admin : revenus de la semaine, du mois et de l'année, à encaisser, en retard, et douze mois de revenus en graphique. |
| Permissions | billing.view et billing.manage. |
| Routes API | 44 routes d'admin, 4 routes publiques. |
| Rendu public | Une page de paiement à /lrvo/billing/<token> et deux visionneuses de documents, enregistrées par la sous-entrée ./public-page. |
| Tâches planifiées | Trois : intérêts, récurrences, rappels. |
| Documents | Facture et reçu en PDF, générés à la demande. |
| Courriels | Six, du courriel d'émission à l'avis de remboursement. Voir Courriels. |
Deux principes qui expliquent le reste
Le solde est calculé à un seul endroit. computeBalance dans money.js produit le montant dû, et c'est ce nombre qui sert à la session Stripe, au PDF, à la page publique, aux courriels, à la colonne Solde et au principal des intérêts. Aucune seconde formule ne peut diverger.
Le retard n'est pas un statut. Une facture est draft, sent, partial, paid ou cancelled. Le retard se déduit de la date d'échéance et du solde, à la lecture. Une facture en retard reste donc sent ou partial, et ne peut pas disparaître de la requête qui alimente les avis de retard.
Montants et unités
Tout est stocké en entiers, jamais en flottants ni en décimaux.
| Grandeur | Unité | Exemple |
|---|---|---|
| Montant | Cent | 11498 vaut 114,98 $ |
| Quantité | Millième | 1500 vaut 1,5 |
| Taux de taxe | Partie par million | 99750 vaut 9,975 % |
Une colonne DECIMAL revient de pg sous forme de chaîne, ce qui oblige à un parseFloat à chaque lecture et ouvre autant d'occasions d'erreur d'arrondi. Les cents correspondent en prime exactement à ce qu'attend l'API Stripe.
Notes
- La page publique est protégée par un jeton de 64 caractères hexadécimaux, et rien d'autre. Toute personne qui détient le lien voit la facture et peut la payer. Le jeton n'expire pas et ne se révoque pas.
- Les PDF publics s'affichent dans une visionneuse plutôt que de se télécharger. Le routeur du core sert par défaut en pièce jointe tout ce qui n'est pas une image ; les deux routes de document demandent explicitement l'affichage en ligne, ce qu'elles peuvent faire parce qu'elles rendent le document elles-mêmes au lieu de le relire depuis le stockage.
- Le webhook Stripe est servi par le core, sur
/lrvo/api/payments/stripe/webhook. Le module s'y abonne : le projet hôte n'a aucune route à créer, seulement l'endpoint à déclarer chez Stripe. Voir Installation. - Le champ
versiondu manifeste vaut1.0.0et ne suit pas la version du paquet. Se fier àpackage.json.
