import { useEffect, useRef, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { withDevOverrides } from '../utils/devOverrides.js'; /** Nom de fichier à partir de la question (slug, sans accents). */ function slugify(text) { return text .toLowerCase() .normalize('NFD').replace(new RegExp('[\\u0300-\\u036f]', 'g'), '') .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .slice(0, 60); } /* ── Accordéon FAQ ───────────────────────────────────────────── */ /* `openQuestion`/`setOpenQuestion` sont partagés par toutes les FaqItem d'une même page (état remonté dans le composant parent) : une seule question ouverte à la fois, ouvrir la suivante referme automatiquement les autres. */ function FaqItem({ question, children, openQuestion, setOpenQuestion }) { const open = openQuestion === question; const toggle = () => setOpenQuestion(open ? null : question); const [pdfState, setPdfState] = useState('idle'); // idle | generating | error const contentRef = useRef(null); const handleDownloadPdf = async () => { if (!contentRef.current || pdfState === 'generating') return; setPdfState('generating'); // Insère le titre directement dans le bloc réel (contentRef), le temps de // la capture uniquement, puis le retire — évite de le dupliquer en // permanence à l'écran tout en réutilisant l'élément réellement rendu // (un conteneur hors-écran séparé est capturé vide par html2canvas : // sa zone de rendu ne suit pas un élément poussé loin hors du viewport). let heading = null; try { const { default: html2pdf } = await import('html2pdf.js'); // Fond capturé = fond réel du bloc (var(--surface)) : reste cohérent // que le thème actif soit clair ou sombre, plutôt qu'un blanc forcé // qui casserait le contraste du texte en mode sombre. const bgColor = getComputedStyle(contentRef.current).backgroundColor || '#ffffff'; heading = document.createElement('h3'); heading.textContent = question; heading.style.margin = '0 0 12px'; heading.style.color = 'var(--text)'; heading.style.fontSize = '1.1rem'; contentRef.current.insertBefore(heading, contentRef.current.firstChild); await html2pdf() .set({ margin: 28, filename: `faq-${slugify(question) || 'crowdlending'}.pdf`, image: { type: 'jpeg', quality: 0.95 }, html2canvas: { scale: 2, useCORS: true, backgroundColor: bgColor }, jsPDF: { unit: 'pt', format: 'a4', orientation: 'portrait' }, // 'avoid-all' : ne coupe jamais un élément (image, bloc de code, // ligne de tableau…) au milieu — le pousse entièrement sur la page // suivante à la place. C'est ce qui manquait avec le moteur HTML // interne de jsPDF (doc.html()), qui tranchait au hasard. pagebreak: { mode: ['avoid-all', 'css'] }, }) .from(contentRef.current) .toPdf() .get('pdf') .then((pdf) => { // Numérotation en bas à droite, une fois le nombre total de pages connu. const total = pdf.internal.getNumberOfPages(); for (let i = 1; i <= total; i++) { pdf.setPage(i); pdf.setFontSize(9); pdf.setTextColor(150); pdf.text( `${i} / ${total}`, pdf.internal.pageSize.getWidth() - 28, pdf.internal.pageSize.getHeight() - 16, { align: 'right' } ); } }) .save(); setPdfState('idle'); } catch (e) { console.error('Échec de la génération du PDF :', e); setPdfState('error'); } finally { if (heading && heading.parentNode) heading.parentNode.removeChild(heading); } }; return (
La génération du PDF a échoué. Réessayez, ou imprimez la page (Ctrl+P / Cmd+P) et choisissez « Enregistrer en PDF ».
)}Le solde du porte-monnaie représente les liquidités disponibles sur une plateforme, c'est-à-dire l'argent que vous pouvez retirer ou réinvestir. Il est calculé comme suit :
Retraits manuels — seuls les retraits que vous avez saisis manuellement sont déduits. Les retraits générés automatiquement lors d'un remboursement en mode "compte courant" sont exclus, car ils ne représentent pas un vrai mouvement de porte-monnaie.
Remboursements crédités au porte-monnaie — uniquement les remboursements dont le mode est "Portefeuille" (et non "Compte courant"). Le montant crédité dépend de la fiscalité de la plateforme :
Capital investi — le montant que vous avez placé dans des prêts actifs (y compris les réinvestissements complémentaires) est soustrait du porte-monnaie, car ces fonds ne sont plus disponibles. Ils reviennent progressivement via les remboursements.
Frais — les frais liés aux investissements (voir la question dédiée ci-dessous) réduisent le solde lorsqu'ils sont réglés « à la source » (déduits du versement lors de la souscription) ou via le porte-monnaie. Les frais réglés depuis un compte courant du détenteur, ou retenus directement sur un remboursement, n'ont aucun impact ici — ils ne transitent jamais par le porte-monnaie de la plateforme.
Corrections de solde — ajustements manuels permettant de réconcilier de micro-écarts de calcul (par exemple un arrondi de centimes sur la fiscalité).
Certaines plateformes facturent des frais en dehors des intérêts et prélèvements fiscaux habituels : frais d'entrée à la souscription, frais de gestion, frais sur une distribution (retenus ou non sur un remboursement), ou autre. Le bloc Frais d'opération de la fiche d'un investissement les recense tous.
Dès qu'au moins un frais a été déclaré sur l'une de vos plateformes, une page Frais dédiée apparaît dans le menu de gauche (entre Remboursements et Fiscalité) — après un rechargement de la page qui suit cette première déclaration. Elle consolide, tous investissements confondus, le montant total, la répartition par catégorie et le détail de chaque opération, avec ajout/modification/suppression directement depuis cette vue (plus besoin de passer par la fiche de chaque investissement). Cette page remplace l'ancien onglet « Frais » qui se trouvait dans Remboursements.
Chaque frais est réglé de l'une des quatre façons suivantes, avec un impact différent :
Le KPI Gain net depuis le début du tableau de bord déduit tous les frais réellement payés, sauf ceux du mode « Déduit du remboursement » : ceux-là sont déjà comptés en creux dans les intérêts nets de ce remboursement (le retirer une 2ᵉ fois compterait la même dépense deux fois). Les frais « Déduit du versement lors de la souscription », « Porte-monnaie » et « Débité du compte courant » sont chacun une vraie sortie d'argent qui n'apparaît nulle part ailleurs dans ce total, donc ils sont bien soustraits.
Le TRI (XIRR) net d'un investissement suit une règle légèrement différente : seuls les frais « Porte-monnaie » et « Compte courant » y sont ajoutés comme sortie de trésorerie. Un frais « Déduit du versement lors de la souscription » n'y est pas rajouté séparément car il est déjà reflété dans le montant investi (net du frais dès la souscription) qui sert de point de départ au calcul — l'ajouter une 2ᵉ fois fausserait le TRI.
Le réinvestissement automatique permet de capitaliser les intérêts perçus après chaque remboursement, sans aucune saisie manuelle. Les intérêts sont automatiquement réinjectés dans le capital du prêt, ce qui augmente progressivement le montant investi et les intérêts futurs.
Une fois activé, le bloc Réinvestissements complémentaires apparaît sur la fiche avec un badge auto, même si aucun remboursement n'a encore eu lieu.
Le montant réinvesti après chaque remboursement dépend de la fiscalité de la plateforme :
Si les intérêts d'un remboursement sont nuls (remboursement de capital seul), aucun réinvestissement n'est créé.
Pour désactiver le réinvestissement automatique, cliquez sur ⋮ dans le bloc Informations du projet et choisissez Désactiver le réinvestissement auto. Les réinvestissements déjà créés sont conservés ; les prochains remboursements n'en génèreront plus.
La page Fiscalité (menu de gauche) reprend, année par année, les montants nécessaires pour préparer votre déclaration de revenus. Elle est organisée en cinq onglets, chacun correspondant à un formulaire CERFA officiel :
2561
|
IFU — Imprimé fiscal unique. Récapitulatif annuel transmis par les plateformes françaises soumises au prélèvement forfaitaire unique (PFU). |
2047
|
Revenus encaissés à l'étranger. Visible dès qu'une ou plusieurs de vos plateformes sont domiciliées hors de France ; détaille les intérêts perçus pays par pays et le crédit d'impôt associé. |
2778-SD
|
Prélèvement forfaitaire obligatoire (PFO), selon votre situation fiscale — déclaration mensuelle de l'acompte dû sur les intérêts de plateformes étrangères (voir la question suivante). |
2042
|
Déclaration des revenus. La déclaration principale : reprend les cases calculées à partir des trois formulaires ci-dessus (2TT, 2TR, 2BH, 2CK, 2TY). |
2042-C PRO
|
Intérêts d'emprunts sur une plateforme d'actif numérique (crowdlending sur RWA). Visible dès qu'une ou plusieurs de vos plateformes sont de type « Prestataire de Services sur Actifs Numériques » (PSAN) — des bénéfices non commerciaux (BNC), en régime micro (case 5HQ), indépendants des trois formulaires ci-dessus. |
Le sens de circulation des données est toujours le même :
2561 et 2047 alimentent directement la 2042.2778-SD (mensuelle) alimente la 2047 (annuelle), qui seule est ensuite reportée sur la 2042 — la 2778-SD n'est qu'un mécanisme d'acompte intermédiaire, jamais une déclaration de substitution à la 2047.2042-C PRO fonctionne à part : les intérêts de plateformes PSAN sont des bénéfices non commerciaux (BNC), pas des revenus de capitaux mobiliers — ils ne transitent ni par la 2047, ni par un crédit d'impôt, et ne sont pas repris dans les cases 2TT/2TR/2BH/2CK/2TY de la 2042. Ils se déclarent séparément, directement sur l'imprimé 2042-C PRO (voir la question dédiée ci-dessous).Un pavé « À quoi correspond chaque CERFA ? », avec un schéma récapitulatif, est affiché directement en haut de l'onglet 2047 lorsque vous avez des plateformes étrangères.
Important — ce module est une aide à la préparation de votre déclaration, il ne la remplace pas. Vérifiez chaque montant avant de le reporter sur le site des impôts : vous restez seul responsable de l'exactitude de votre déclaration fiscale, Crowdlending ne saurait être tenu responsable des données déclarées.
Cette question concerne le formulaire 2778-SD (prélèvement
forfaitaire obligatoire, ou PFO). Elle ne se pose que si vous détenez au moins une plateforme domiciliée
hors de France.
Le PFO s'applique aux personnes physiques fiscalement domiciliées en France dont le revenu fiscal de référence (RFR) de l'avant-dernière année est égal ou supérieur à :
Votre RFR figure sur votre avis d'imposition de l'année précédente (ligne « Revenu fiscal de référence »). En dessous de ces seuils, vous êtes dispensé du PFO — mais les prélèvements sociaux restent dus.
Ce réglage est global : une fois activé, l'onglet 2778-SD apparaît
dans la page Fiscalité, les cases 2BH / 2CK se
remplissent dans le report 2042, et les lignes de suivi mensuel du PFO (taux, montant à payer, intérêt net)
s'affichent dans les tableaux « Suivi mensuel » des onglets 2047 et 2778-SD. Si vous le désactivez, ces
éléments sont masqués car ils ne s'appliquent pas à votre situation.
À retenir — que le PFO s'applique ou non à vous, la déclaration annuelle via le CERFA 2047 reste obligatoire dès que vous avez perçu des intérêts d'une plateforme étrangère. Ce paramètre reflète votre propre situation fiscale : en cas de doute, vérifiez votre avis d'imposition ou consultez un professionnel.
Dans l'onglet 2047, vue
« Données 2047 », chaque plateforme étrangère est classée automatiquement selon la convention fiscale
signée entre la France et son pays de domiciliation.
Le pays a une convention fiscale active et n'impose pas l'imposition exclusivement dans le pays de résidence. Le crédit d'impôt (case 237) est égal à l'impôt réellement prélevé à l'étranger (case 236), plafonné au taux conventionnel du pays lorsque celui-ci est chiffré (case 234) — ou non plafonné pour certains pays dont la convention prévoit un crédit égal à l'impôt prélevé sans limite de taux.
Le pays est absent des conventions fiscales référencées, sa convention est suspendue ou caduque, ou elle prévoit une imposition exclusivement dans le pays de résidence. Dans ce cas, aucun crédit d'impôt n'est calculé.
Le formulaire papier 2047 se remplit par pays, pas par plateforme : si plusieurs de vos plateformes sont domiciliées dans le même pays, une ligne « Sous-total » apparaît automatiquement sous le groupe pour faciliter le report. Les totaux 8VL et 8PL (report 2042) ainsi que les cases 251/252 cumulent l'ensemble de vos plateformes étrangères, arrondis à l'euro comme l'exige le formulaire officiel.
Certaines plateformes de crowdlending prêtent sur des actifs numériques plutôt que sur des projets classiques (crowdlending sur RWA — Real World Asset tokenisés). Dans le référentiel Crowdlending, elles sont identifiées par la catégorie « Prestataire de Services sur Actifs Numériques » (PSAN), par opposition aux plateformes de financement participatif classiques (« Prestataire de Services de Financement Participatif », PSFP).
Les intérêts perçus via une plateforme PSAN ne sont pas des revenus de capitaux mobiliers (RCM) comme les autres — ce sont des bénéfices non commerciaux (BNC), quelle que soit la localisation de la plateforme (française ou étrangère). Conséquence directe :
2047, même si la plateforme est domiciliée hors de France.2042-C PRO, en régime micro-BNC, case 5HQ.Vous déclarez le montant brut des intérêts reçus (valorisés en euros au jour de leur réception) ; l'abattement forfaitaire de 34 % est appliqué automatiquement par l'administration fiscale, vous n'avez rien à calculer vous-même. Si vos recettes brutes dépassent 77 700 € sur l'année — ou si vous souhaitez déduire des charges réelles (matériel, électricité…) — vous basculez en régime réel (cases 5KO / 5KP), non géré par l'application.
Dès qu'au moins une de vos plateformes est catégorisée PSAN, un onglet CERFA
2042 C PRO apparaît sur la page Fiscalité, avec un suivi mensuel des intérêts bruts et la
case 5HQ à reporter — ainsi qu'un bloc dédié « Cases fiscales 2042 C PRO » affiché à côté du
récapitulatif principal. Vous pouvez vérifier ou modifier la catégorie d'une plateforme (PSFP /
PSAN) depuis Paramétrage → Plateformes.
Chaque onglet CERFA propose généralement plusieurs vues : un suivi
mensuel (le détail plateforme par plateforme, mois par mois), une vue « Données » (les
cases du formulaire lui-même), et une vue « Report 2042 » (ce
qui doit être reporté sur la déclaration principale). Exception : l'onglet 2042-C PRO ne
propose que les deux premières vues (Suivi mensuel / Données 2042 C PRO) — il n'existe pas de
report vers la 2042 classique, les BNC se déclarant sur un imprimé séparé (voir la question dédiée
aux plateformes PSAN ci-dessus).
2561 si vous avez des plateformes françaises soumises au PFU.2778-SD puis 2047 si vous avez des plateformes étrangères — le suivi mensuel du 2778-SD documente le détail, la vue « Données 2047 » regroupe l'annuel par pays.2042-C PRO si vous avez des plateformes de type PSAN (crowdlending sur actifs numériques) — indépendant des onglets précédents, la case 5HQ se reporte séparément sur l'imprimé 2042-C PRO.2042 en dernier : sa vue « Données 2042 » et sa synthèse fiscale récapitulent toutes les cases (2TT, 2TR, 2BH, 2CK, 2TY) à saisir sur le site des impôts.Les montants affichés dans les vues « Données » et les cases officielles sont arrondis à l'euro, comme l'exigent les formulaires CERFA (les montants intermédiaires du suivi mensuel restent au centime près, pour la traçabilité).
Comme rappelé sur la page elle-même : ce module est une aide à la préparation de votre déclaration, il ne s'y substitue pas. Contrôlez chaque case avant de la reporter — vous restez seul responsable de l'exactitude de votre déclaration.
Le serveur MCP tourne déjà en continu (service Docker crowdlending-mcp,
exposé via Traefik) — vous n'avez rien à installer ni à laisser tourner sur votre machine. Il
suffit de connecter Claude Desktop à l'URL publique.
{mcpConfigUrl}{appInfo.mcpUrl ? ' — déjà pré-rempli si vous ne l\'avez pas modifié' : ''}) ainsi que la clé générée.claude_desktop_config.json (Réglages
→ Développeur → Serveurs MCP locaux → Modifier la config) — le mécanisme passe par
mcp-remote (avec le wrapper cmd /c sous
Windows), généré automatiquement pour vous.crowdlending_fetch_url (lecture d'une page web arbitraire) reste
désactivé sur ce serveur.
Si la connexion reste bloquée sans erreur visible, la cause est presque toujours la même :
npx qui échoue silencieusement à joindre le registre npm — voir la
section Dépannage de Mon compte → Serveur MCP.
Une fois connecté, Claude (Desktop ou tout autre client MCP) peut consulter votre portefeuille en langage naturel — il choisit lui-même le bon outil selon votre question. Le serveur est strictement en lecture seule : aucune donnée n'est jamais créée, modifiée ou supprimée depuis une conversation. Toute saisie (nouvel investissement, remboursement…) reste manuelle dans l'application.
crowdlending_get_investisseur
|
Profil de l'investisseur lié à la clé API (nom, type famille/entreprise, régime fiscal). Avec une clé « Famille et entreprises », renvoie la liste des profils du foyer. |
crowdlending_get_dashboard
|
KPIs du portefeuille : capital investi, capital en risque, montant remboursé, intérêts bruts/nets, dépôts/retraits, gain net depuis le début (frais hors remboursement déduits) — filtrable par année. |
crowdlending_list_investissements
|
Liste des investissements (projet, émetteur, plateforme, montant, taux, durée, statut), filtrable par statut. |
crowdlending_get_investissement
|
Détail complet d'un investissement (par id), y compris ses remboursements réels perçus et les frais qui lui sont liés (souscription, gestion, distribution). |
crowdlending_list_remboursements
|
Historique des remboursements perçus (toutes plateformes), avec le frais éventuellement retenu sur chacun, filtrable par période. |
crowdlending_list_frais_operations
|
Frais liés aux investissements — souscription, gestion, distribution — toutes plateformes, filtrable par période. |
crowdlending_list_depots_retraits
|
Historique des mouvements de cash (dépôts et retraits), du plus récent au plus ancien. |
crowdlending_list_objectifs
|
Objectifs de versement et de capital investi (Paramétrage → Fixation des objectifs), à comparer au réalisé. Filtrable par type et par année. |
crowdlending_get_taxreport
|
Synthèse fiscale annuelle (CERFA 2042/2561/2047/2778-SD) — aide à la préparation de la déclaration, calculée avec les mêmes règles que la page Fiscalité. Ce n'est pas une source officielle : à vérifier avant tout report sur votre déclaration. |
crowdlending_fetch_url
|
Développement local uniquement, désactivé par défaut. Lit une page web (ex. annonce de projet sur une plateforme) et en extrait le texte propre — c'est à vous d'en reprendre les informations utiles pour créer l'investissement manuellement, l'outil ne saisit rien lui-même. |
crowdlending_fetch_url activé)Ces exemples fonctionnent aussi bien en dev qu'en prod dès lors que le serveur correspondant est connecté (voir les FAQ de configuration ci-dessus) — les neuf premiers outils sont identiques dans les deux environnements.
Comme le serveur MCP, Power Query s'appuie sur l'API v1 (lecture seule) via une clé API. Power Query est intégré nativement à Excel (365 / 2016 et plus, Windows ou Mac) — rien à installer. Chaque étape ci-dessous correspond à un écran que vous pouvez capturer pour illustrer votre propre guide.
Le classeur ci-dessus contient déjà les 7 requêtes ci-dessous, prêtes à charger — il ne
reste qu'à renseigner votre clé (étape 1). Vous pouvez aussi tout reconstruire à la main
avec les fichiers .pq individuels
proposés à chaque étape ci-dessous.
Dans Excel : Données → Obtenir des données → À partir d'autres sources → Requête vide. Une nouvelle requête « Requête1 » apparaît dans l'éditeur Power Query.
ApiBaseUrl (double-clic
sur son nom dans le volet Requêtes), puis Affichage → Éditeur avancé,
effacez le contenu par défaut et collez :
{`"http://localhost:4000/api/v1"`}
{ e.currentTarget.style.display = 'none'; }}
/>
ApiKey :
{`"clk_live_VOTRE_CLE_API"`}
{ e.currentTarget.style.display = 'none'; }}
/>
Remplacez par la clé copiée à l'étape 1, entre guillemets. Même chose : Terminé → Uniquement créer la connexion.
Une troisième requête vide, nommée fnApiGet,
fait l'appel HTTP et transmet la clé dans l'en-tête X-API-Key —
les requêtes suivantes la réutiliseront par son nom, sans la récrire :
{`(chemin as text, optional parametres as nullable record) as any =>
let
parametresBruts = if parametres = null then [] else parametres,
champsUtiles = List.Select(
Record.FieldNames(parametresBruts),
each Record.Field(parametresBruts, _) <> null and Record.Field(parametresBruts, _) <> ""
),
parametresNettoyes = Record.SelectFields(parametresBruts, champsUtiles),
reponse = Web.Contents(
ApiBaseUrl,
[
RelativePath = chemin,
Headers = [#"X-API-Key" = ApiKey, #"Accept" = "application/json"],
Query = parametresNettoyes
]
),
resultat = Json.Document(reponse)
in
resultat`}
{ e.currentTarget.style.display = 'none'; }}
/>
Terminé → Fermer et charger dans… → Uniquement créer la connexion (ce n'est pas une donnée à afficher).
Une nouvelle requête vide, nommée Investissements :
{`let
// Pour filtrer par statut, remplacez null par [statut = "rembourse"]
// Statuts possibles : en_cours, rembourse, en_retard, procedure, cloture
Source = fnApiGet("/investissements", null),
Resultat = Table.FromRecords(Source)
in
Resultat`}
{ e.currentTarget.style.display = 'none'; }}
/>
Cette fois-ci, Terminé → Fermer et charger (le bouton simple, pas « … ») : la requête s'ajoute comme tableau dans une nouvelle feuille, avec vos investissements en ligne et en colonnes.
Données → Actualiser tout (ou Ctrl+Alt+F5) à tout moment pour recharger les données depuis l'API — utile après un nouvel investissement ou remboursement saisi dans l'app.
Même principe (requête vide → nom exact → éditeur avancé → coller → charger) pour :
Investisseur
|
Profil investisseur (ou liste des membres si clé « Famille et entreprises »). |
|
Dashboard
|
KPIs du portefeuille, au format « Indicateur / Valeur » (facile à croiser dans un TCD). |
|
Remboursements
|
Historique des remboursements, filtrable par période. |
|
DépôtsRetraits
|
Historique des mouvements de cash. |
|
fnDetailInvestissement
|
Fonction avancée : sur la table Investissements, colonne personnalisée{' '}
= fnDetailInvestissement([id]){' '}
pour ramener le détail + les remboursements de chaque prêt.
|
|
Toutes ces requêtes sont déjà incluses dans le classeur téléchargeable en haut de cette fiche —
les fichiers .pq ci-dessus
ne sont utiles que si vous préférez les coller vous-même dans un classeur existant.
ApiBaseUrl est
incorrecte (vérifiez le port et le suffixe /api/v1).ApiKey.Comme le serveur MCP, ces requêtes sont strictement en lecture seule : aucune saisie n'est possible depuis Excel, toute modification reste à faire dans l'application.